drm/i915/gt: Store the fence details on the fence

Make a copy of the object tiling parameters at the point of grabbing the
fence.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200401210104.15907-2-chris@chris-wilson.co.uk
This commit is contained in:
Chris Wilson 2020-04-01 22:01:03 +01:00
parent 63baf4f3d5
commit 725c9ee7fc
2 changed files with 37 additions and 60 deletions

View File

@ -68,8 +68,7 @@ static struct intel_uncore *fence_to_uncore(struct i915_fence_reg *fence)
return fence->ggtt->vm.gt->uncore;
}
static void i965_write_fence_reg(struct i915_fence_reg *fence,
struct i915_vma *vma)
static void i965_write_fence_reg(struct i915_fence_reg *fence)
{
i915_reg_t fence_reg_lo, fence_reg_hi;
int fence_pitch_shift;
@ -87,18 +86,16 @@ static void i965_write_fence_reg(struct i915_fence_reg *fence,
}
val = 0;
if (vma) {
unsigned int stride = i915_gem_object_get_stride(vma->obj);
if (fence->tiling) {
unsigned int stride = fence->stride;
GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma));
GEM_BUG_ON(!IS_ALIGNED(vma->node.start, I965_FENCE_PAGE));
GEM_BUG_ON(!IS_ALIGNED(vma->fence_size, I965_FENCE_PAGE));
GEM_BUG_ON(!IS_ALIGNED(stride, 128));
val = (vma->node.start + vma->fence_size - I965_FENCE_PAGE) << 32;
val |= vma->node.start;
val = fence->start + fence->size - I965_FENCE_PAGE;
val <<= 32;
val |= fence->start;
val |= (u64)((stride / 128) - 1) << fence_pitch_shift;
if (i915_gem_object_get_tiling(vma->obj) == I915_TILING_Y)
if (fence->tiling == I915_TILING_Y)
val |= BIT(I965_FENCE_TILING_Y_SHIFT);
val |= I965_FENCE_REG_VALID;
}
@ -125,21 +122,15 @@ static void i965_write_fence_reg(struct i915_fence_reg *fence,
}
}
static void i915_write_fence_reg(struct i915_fence_reg *fence,
struct i915_vma *vma)
static void i915_write_fence_reg(struct i915_fence_reg *fence)
{
u32 val;
val = 0;
if (vma) {
unsigned int tiling = i915_gem_object_get_tiling(vma->obj);
if (fence->tiling) {
unsigned int stride = fence->stride;
unsigned int tiling = fence->tiling;
bool is_y_tiled = tiling == I915_TILING_Y;
unsigned int stride = i915_gem_object_get_stride(vma->obj);
GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma));
GEM_BUG_ON(vma->node.start & ~I915_FENCE_START_MASK);
GEM_BUG_ON(!is_power_of_2(vma->fence_size));
GEM_BUG_ON(!IS_ALIGNED(vma->node.start, vma->fence_size));
if (is_y_tiled && HAS_128_BYTE_Y_TILING(fence_to_i915(fence)))
stride /= 128;
@ -147,10 +138,10 @@ static void i915_write_fence_reg(struct i915_fence_reg *fence,
stride /= 512;
GEM_BUG_ON(!is_power_of_2(stride));
val = vma->node.start;
val = fence->start;
if (is_y_tiled)
val |= BIT(I830_FENCE_TILING_Y_SHIFT);
val |= I915_FENCE_SIZE_BITS(vma->fence_size);
val |= I915_FENCE_SIZE_BITS(fence->size);
val |= ilog2(stride) << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID;
@ -165,25 +156,18 @@ static void i915_write_fence_reg(struct i915_fence_reg *fence,
}
}
static void i830_write_fence_reg(struct i915_fence_reg *fence,
struct i915_vma *vma)
static void i830_write_fence_reg(struct i915_fence_reg *fence)
{
u32 val;
val = 0;
if (vma) {
unsigned int stride = i915_gem_object_get_stride(vma->obj);
if (fence->tiling) {
unsigned int stride = fence->stride;
GEM_BUG_ON(!i915_vma_is_map_and_fenceable(vma));
GEM_BUG_ON(vma->node.start & ~I830_FENCE_START_MASK);
GEM_BUG_ON(!is_power_of_2(vma->fence_size));
GEM_BUG_ON(!is_power_of_2(stride / 128));
GEM_BUG_ON(!IS_ALIGNED(vma->node.start, vma->fence_size));
val = vma->node.start;
if (i915_gem_object_get_tiling(vma->obj) == I915_TILING_Y)
val = fence->start;
if (fence->tiling == I915_TILING_Y)
val |= BIT(I830_FENCE_TILING_Y_SHIFT);
val |= I830_FENCE_SIZE_BITS(vma->fence_size);
val |= I830_FENCE_SIZE_BITS(fence->size);
val |= ilog2(stride / 128) << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID;
}
@ -197,8 +181,7 @@ static void i830_write_fence_reg(struct i915_fence_reg *fence,
}
}
static void fence_write(struct i915_fence_reg *fence,
struct i915_vma *vma)
static void fence_write(struct i915_fence_reg *fence)
{
struct drm_i915_private *i915 = fence_to_i915(fence);
@ -209,18 +192,16 @@ static void fence_write(struct i915_fence_reg *fence,
*/
if (IS_GEN(i915, 2))
i830_write_fence_reg(fence, vma);
i830_write_fence_reg(fence);
else if (IS_GEN(i915, 3))
i915_write_fence_reg(fence, vma);
i915_write_fence_reg(fence);
else
i965_write_fence_reg(fence, vma);
i965_write_fence_reg(fence);
/*
* Access through the fenced region afterwards is
* ordered by the posting reads whilst writing the registers.
*/
fence->dirty = false;
}
static bool gpu_uses_fence_registers(struct i915_fence_reg *fence)
@ -237,6 +218,7 @@ static int fence_update(struct i915_fence_reg *fence,
struct i915_vma *old;
int ret;
fence->tiling = 0;
if (vma) {
GEM_BUG_ON(!i915_gem_object_get_stride(vma->obj) ||
!i915_gem_object_get_tiling(vma->obj));
@ -250,7 +232,13 @@ static int fence_update(struct i915_fence_reg *fence,
if (ret)
return ret;
}
fence->start = vma->node.start;
fence->size = vma->fence_size;
fence->stride = i915_gem_object_get_stride(vma->obj);
fence->tiling = i915_gem_object_get_tiling(vma->obj);
}
WRITE_ONCE(fence->dirty, false);
old = xchg(&fence->vma, NULL);
if (old) {
@ -293,7 +281,7 @@ static int fence_update(struct i915_fence_reg *fence,
}
WRITE_ONCE(fence->vma, vma);
fence_write(fence, vma);
fence_write(fence);
if (vma) {
vma->fence = fence;
@ -501,23 +489,8 @@ void intel_ggtt_restore_fences(struct i915_ggtt *ggtt)
{
int i;
rcu_read_lock(); /* keep obj alive as we dereference */
for (i = 0; i < ggtt->num_fences; i++) {
struct i915_fence_reg *reg = &ggtt->fence_regs[i];
struct i915_vma *vma = READ_ONCE(reg->vma);
GEM_BUG_ON(vma && vma->fence != reg);
/*
* Commit delayed tiling changes if we have an object still
* attached to the fence, otherwise just clear the fence.
*/
if (vma && !i915_gem_object_is_tiled(vma->obj))
vma = NULL;
fence_write(reg, vma);
}
rcu_read_unlock();
for (i = 0; i < ggtt->num_fences; i++)
fence_write(&ggtt->fence_regs[i]);
}
/**

View File

@ -54,6 +54,10 @@ struct i915_fence_reg {
* command (such as BLT on gen2/3), as a "fence".
*/
bool dirty;
u32 start;
u32 size;
u32 tiling;
u32 stride;
};
struct i915_fence_reg *i915_reserve_fence(struct i915_ggtt *ggtt);