[Intel-gfx] [PATCH 2/4] drm/i915: introduce i915_gem_object_adjust_fencing
Daniel Vetter
daniel.vetter at ffwll.ch
Thu Apr 22 22:12:50 CEST 2010
Pipelining tiling changes will complicate all places that need
a correct fence register to be set up. So hide this complexity
behind a small helper function.
i915_gem_object_get_fence loses all it's external callers by these
changes, so convert it into a static function
Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
drivers/gpu/drm/i915/i915_drv.h | 2 +-
drivers/gpu/drm/i915/i915_gem.c | 52 ++++++++++++++++++++++++++++-----
drivers/gpu/drm/i915/intel_display.c | 16 ++--------
3 files changed, 49 insertions(+), 21 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 242993b..7aec3ec 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -918,7 +918,7 @@ void i915_gem_release_mmap(struct drm_gem_object *obj);
void i915_gem_lastclose(struct drm_device *dev);
uint32_t i915_get_gem_seqno(struct drm_device *dev);
bool i915_seqno_passed(uint32_t seq1, uint32_t seq2);
-int i915_gem_object_get_fence_reg(struct drm_gem_object *obj);
+int i915_gem_object_adjust_fencing(struct drm_gem_object *obj);
int i915_gem_object_put_fence_reg(struct drm_gem_object *obj);
void i915_gem_retire_requests(struct drm_device *dev);
void i915_gem_retire_work_handler(struct work_struct *work);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 47c46ed..8e73a12 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -974,6 +974,10 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
ret = i915_gem_phys_pwrite(dev, obj, args, file_priv);
else if (obj_priv->tiling_mode == I915_TILING_NONE &&
dev->gtt_total != 0) {
+ ret = i915_gem_object_adjust_fencing(obj);
+ if (ret != 0)
+ return ret;
+
ret = i915_gem_gtt_pwrite_fast(dev, obj, args, file_priv);
if (ret == -EFAULT) {
ret = i915_gem_gtt_pwrite_slow(dev, obj, args,
@@ -1191,12 +1195,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
goto unlock;
}
- /* Need a new fence register? */
- if (obj_priv->tiling_mode != I915_TILING_NONE) {
- ret = i915_gem_object_get_fence_reg(obj);
- if (ret)
- goto unlock;
- }
+ ret = i915_gem_object_adjust_fencing(obj);
+ if (ret)
+ goto unlock;
pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) +
page_offset;
@@ -2475,7 +2476,7 @@ static int i915_find_fence_reg(struct drm_device *dev)
* It then sets up the reg based on the object's properties: address, pitch
* and tiling format.
*/
-int
+static int
i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
{
struct drm_device *dev = obj->dev;
@@ -2536,6 +2537,41 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj)
}
/**
+ * i915_gem_object_adjust_fencing - ensure correct fencing for an object
+ * @obj: object to map through a fence reg
+ *
+ * Tiling changes may be delayed untill fenced access is actually needed.
+ * Batchbuffer submitted via execbuf2 may not need a fence, so delaying
+ * gtt remapping and fence register changes (which all stall the gpu) as
+ * long as possible is beneficial.
+ *
+ * This function ensures that all delayed operations have been carried out and
+ * the object can be correctly accessed via fences.
+ */
+int
+i915_gem_object_adjust_fencing(struct drm_gem_object *obj)
+{
+ struct drm_i915_gem_object *obj_priv = to_intel_bo(obj);
+ int ret;
+
+ if (!i915_gem_object_fence_offset_ok(obj, obj_priv->tiling_mode)) {
+ ret = i915_gem_object_unbind(obj);
+ if (ret != 0)
+ return ret;
+ ret = i915_gem_object_bind_to_gtt(obj, 0);
+ if (ret != 0)
+ return ret;
+ }
+
+ if (obj_priv->tiling_mode != I915_TILING_NONE) {
+ ret = i915_gem_object_get_fence_reg(obj);
+ if (ret != 0)
+ return ret;
+ }
+ return 0;
+}
+
+/**
* i915_gem_clear_fence_reg - clear out fence register info
* @obj: object to clear
*
@@ -3309,7 +3345,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
* properly handle blits to/from tiled surfaces.
*/
if (need_fence) {
- ret = i915_gem_object_get_fence_reg(obj);
+ ret = i915_gem_object_adjust_fencing(obj);
if (ret != 0) {
if (ret != -EBUSY && ret != -ERESTARTSYS)
DRM_ERROR("Failure to install fence: %d\n",
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3836f56..56b673d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1249,18 +1249,10 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_gem_object *obj)
if (ret != 0)
return ret;
- /* Install a fence for tiled scan-out. Pre-i965 always needs a
- * fence, whereas 965+ only requires a fence if using
- * framebuffer compression. For simplicity, we always install
- * a fence as the cost is not that onerous.
- */
- if (obj_priv->fence_reg == I915_FENCE_REG_NONE &&
- obj_priv->tiling_mode != I915_TILING_NONE) {
- ret = i915_gem_object_get_fence_reg(obj);
- if (ret != 0) {
- i915_gem_object_unpin(obj);
- return ret;
- }
+ ret = i915_gem_object_adjust_fencing(obj);
+ if (ret != 0) {
+ i915_gem_object_unpin(obj);
+ return ret;
}
return 0;
--
1.6.6.1
More information about the Intel-gfx
mailing list