675,7 → 675,14 |
static void render_ring_cleanup(struct intel_engine_cs *ring) |
{ |
struct drm_device *dev = ring->dev; |
struct drm_i915_private *dev_priv = dev->dev_private; |
|
if (dev_priv->semaphore_obj) { |
i915_gem_object_ggtt_unpin(dev_priv->semaphore_obj); |
drm_gem_object_unreference(&dev_priv->semaphore_obj->base); |
dev_priv->semaphore_obj = NULL; |
} |
|
if (ring->scratch.obj == NULL) |
return; |
|
1353,53 → 1360,65 |
|
/* Just userspace ABI convention to limit the wa batch bo to a resonable size */ |
#define I830_BATCH_LIMIT (256*1024) |
#define I830_TLB_ENTRIES (2) |
#define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT) |
static int |
i830_dispatch_execbuffer(struct intel_engine_cs *ring, |
u64 offset, u32 len, |
unsigned flags) |
{ |
u32 cs_offset = ring->scratch.gtt_offset; |
int ret; |
|
if (flags & I915_DISPATCH_PINNED) { |
ret = intel_ring_begin(ring, 4); |
ret = intel_ring_begin(ring, 6); |
if (ret) |
return ret; |
|
intel_ring_emit(ring, MI_BATCH_BUFFER); |
intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
intel_ring_emit(ring, offset + len - 8); |
/* Evict the invalid PTE TLBs */ |
intel_ring_emit(ring, COLOR_BLT_CMD | BLT_WRITE_RGBA); |
intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | 4096); |
intel_ring_emit(ring, I830_TLB_ENTRIES << 16 | 4); /* load each page */ |
intel_ring_emit(ring, cs_offset); |
intel_ring_emit(ring, 0xdeadbeef); |
intel_ring_emit(ring, MI_NOOP); |
intel_ring_advance(ring); |
} else { |
u32 cs_offset = ring->scratch.gtt_offset; |
|
if ((flags & I915_DISPATCH_PINNED) == 0) { |
if (len > I830_BATCH_LIMIT) |
return -ENOSPC; |
|
ret = intel_ring_begin(ring, 9+3); |
ret = intel_ring_begin(ring, 6 + 2); |
if (ret) |
return ret; |
/* Blit the batch (which has now all relocs applied) to the stable batch |
* scratch bo area (so that the CS never stumbles over its tlb |
* invalidation bug) ... */ |
intel_ring_emit(ring, XY_SRC_COPY_BLT_CMD | |
XY_SRC_COPY_BLT_WRITE_ALPHA | |
XY_SRC_COPY_BLT_WRITE_RGB); |
intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_GXCOPY | 4096); |
intel_ring_emit(ring, 0); |
intel_ring_emit(ring, (DIV_ROUND_UP(len, 4096) << 16) | 1024); |
|
/* Blit the batch (which has now all relocs applied) to the |
* stable batch scratch bo area (so that the CS never |
* stumbles over its tlb invalidation bug) ... |
*/ |
intel_ring_emit(ring, SRC_COPY_BLT_CMD | BLT_WRITE_RGBA); |
intel_ring_emit(ring, BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096); |
intel_ring_emit(ring, DIV_ROUND_UP(len, 4096) << 16 | 1024); |
intel_ring_emit(ring, cs_offset); |
intel_ring_emit(ring, 0); |
intel_ring_emit(ring, 4096); |
intel_ring_emit(ring, offset); |
|
intel_ring_emit(ring, MI_FLUSH); |
intel_ring_emit(ring, MI_NOOP); |
intel_ring_advance(ring); |
|
/* ... and execute it. */ |
offset = cs_offset; |
} |
|
ret = intel_ring_begin(ring, 4); |
if (ret) |
return ret; |
|
intel_ring_emit(ring, MI_BATCH_BUFFER); |
intel_ring_emit(ring, cs_offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
intel_ring_emit(ring, cs_offset + len - 8); |
intel_ring_emit(ring, offset | (flags & I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE)); |
intel_ring_emit(ring, offset + len - 8); |
intel_ring_emit(ring, MI_NOOP); |
intel_ring_advance(ring); |
} |
|
return 0; |
} |
2179,7 → 2198,7 |
|
/* Workaround batchbuffer to combat CS tlb bug. */ |
if (HAS_BROKEN_CS_TLB(dev)) { |
obj = i915_gem_alloc_object(dev, I830_BATCH_LIMIT); |
obj = i915_gem_alloc_object(dev, I830_WA_SIZE); |
if (obj == NULL) { |
DRM_ERROR("Failed to allocate batch bo\n"); |
return -ENOMEM; |