Skip to content

Commit

Permalink
drm/i915/ringbuffer: Handle cliprects in the caller
Browse files Browse the repository at this point in the history
This makes the various rings more consistent by removing the anomalous
handing of the rendering ring execbuffer dispatch.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
  • Loading branch information
Chris Wilson committed Nov 30, 2010
1 parent 70eac33 commit c4e7a41
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 79 deletions.
22 changes: 11 additions & 11 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -352,16 +352,16 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords)

int
i915_emit_box(struct drm_device *dev,
struct drm_clip_rect *boxes,
int i, int DR1, int DR4)
struct drm_clip_rect *box,
int DR1, int DR4)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_clip_rect box = boxes[i];
int ret;

if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
if (box->y2 <= box->y1 || box->x2 <= box->x1 ||
box->y2 <= 0 || box->x2 <= 0) {
DRM_ERROR("Bad box %d,%d..%d,%d\n",
box.x1, box.y1, box.x2, box.y2);
box->x1, box->y1, box->x2, box->y2);
return -EINVAL;
}

Expand All @@ -371,8 +371,8 @@ i915_emit_box(struct drm_device *dev,
return ret;

OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
OUT_RING((box->x1 & 0xffff) | (box->y1 << 16));
OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16));
OUT_RING(DR4);
} else {
ret = BEGIN_LP_RING(6);
Expand All @@ -381,8 +381,8 @@ i915_emit_box(struct drm_device *dev,

OUT_RING(GFX_OP_DRAWRECT_INFO);
OUT_RING(DR1);
OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
OUT_RING((box->x1 & 0xffff) | (box->y1 << 16));
OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16));
OUT_RING(DR4);
OUT_RING(0);
}
Expand Down Expand Up @@ -434,7 +434,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev,

for (i = 0; i < count; i++) {
if (i < nbox) {
ret = i915_emit_box(dev, cliprects, i,
ret = i915_emit_box(dev, &cliprects[i],
cmd->DR1, cmd->DR4);
if (ret)
return ret;
Expand Down Expand Up @@ -467,7 +467,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
count = nbox ? nbox : 1;
for (i = 0; i < count; i++) {
if (i < nbox) {
ret = i915_emit_box(dev, cliprects, i,
ret = i915_emit_box(dev, &cliprects[i],
batch->DR1, batch->DR4);
if (ret)
return ret;
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -966,8 +966,8 @@ extern int i915_driver_device_is_agp(struct drm_device * dev);
extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
extern int i915_emit_box(struct drm_device *dev,
struct drm_clip_rect *boxes,
int i, int DR1, int DR4);
struct drm_clip_rect *box,
int DR1, int DR4);
extern int i915_reset(struct drm_device *dev, u8 flags);
extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv);
extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
Expand Down
30 changes: 25 additions & 5 deletions drivers/gpu/drm/i915/i915_gem_execbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
struct drm_i915_gem_object *batch_obj;
struct drm_clip_rect *cliprects = NULL;
struct intel_ring_buffer *ring;
u32 exec_start, exec_len;
int ret, i;

if (!i915_gem_check_execbuffer(args)) {
Expand Down Expand Up @@ -871,6 +872,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
}

if (args->num_cliprects != 0) {
if (ring != &dev_priv->render_ring) {
DRM_ERROR("clip rectangles are only valid with the render ring\n");
return -EINVAL;
}

cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects),
GFP_KERNEL);
if (cliprects == NULL) {
Expand Down Expand Up @@ -959,11 +965,25 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
if (ret)
goto err;

ret = ring->dispatch_execbuffer(ring,
args, cliprects,
batch_obj->gtt_offset);
if (ret)
goto err;
exec_start = batch_obj->gtt_offset + args->batch_start_offset;
exec_len = args->batch_len;
if (cliprects) {
for (i = 0; i < args->num_cliprects; i++) {
ret = i915_emit_box(dev, &cliprects[i],
args->DR1, args->DR4);
if (ret)
goto err;

ret = ring->dispatch_execbuffer(ring,
exec_start, exec_len);
if (ret)
goto err;
}
} else {
ret = ring->dispatch_execbuffer(ring, exec_start, exec_len);
if (ret)
goto err;
}

i915_gem_execbuffer_move_to_active(&objects, ring);
i915_gem_execbuffer_retire_commands(dev, file, ring);
Expand Down
86 changes: 28 additions & 58 deletions drivers/gpu/drm/i915/intel_ringbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,84 +508,59 @@ ring_status_page_get_seqno(struct intel_ring_buffer *ring)
}

static int
ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
struct drm_i915_gem_execbuffer2 *exec,
struct drm_clip_rect *cliprects,
uint64_t exec_offset)
ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length)
{
uint32_t exec_start;
int ret;

exec_start = (uint32_t) exec_offset + exec->batch_start_offset;

ret = intel_ring_begin(ring, 2);
if (ret)
return ret;

intel_ring_emit(ring,
MI_BATCH_BUFFER_START |
(2 << 6) |
MI_BATCH_BUFFER_START | (2 << 6) |
MI_BATCH_NON_SECURE_I965);
intel_ring_emit(ring, exec_start);
intel_ring_emit(ring, offset);
intel_ring_advance(ring);

return 0;
}

static int
render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
struct drm_i915_gem_execbuffer2 *exec,
struct drm_clip_rect *cliprects,
uint64_t exec_offset)
u32 offset, u32 len)
{
struct drm_device *dev = ring->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
int nbox = exec->num_cliprects;
uint32_t exec_start, exec_len;
int i, count, ret;

exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
exec_len = (uint32_t) exec->batch_len;
int ret;

trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1);

count = nbox ? nbox : 1;
for (i = 0; i < count; i++) {
if (i < nbox) {
ret = i915_emit_box(dev, cliprects, i,
exec->DR1, exec->DR4);
if (ret)
return ret;
}
if (IS_I830(dev) || IS_845G(dev)) {
ret = intel_ring_begin(ring, 4);
if (ret)
return ret;

if (IS_I830(dev) || IS_845G(dev)) {
ret = intel_ring_begin(ring, 4);
if (ret)
return ret;
intel_ring_emit(ring, MI_BATCH_BUFFER);
intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE);
intel_ring_emit(ring, offset + len - 8);
intel_ring_emit(ring, 0);
} else {
ret = intel_ring_begin(ring, 2);
if (ret)
return ret;

intel_ring_emit(ring, MI_BATCH_BUFFER);
intel_ring_emit(ring, exec_start | MI_BATCH_NON_SECURE);
intel_ring_emit(ring, exec_start + exec_len - 4);
intel_ring_emit(ring, 0);
if (INTEL_INFO(dev)->gen >= 4) {
intel_ring_emit(ring,
MI_BATCH_BUFFER_START | (2 << 6) |
MI_BATCH_NON_SECURE_I965);
intel_ring_emit(ring, offset);
} else {
ret = intel_ring_begin(ring, 2);
if (ret)
return ret;

if (INTEL_INFO(dev)->gen >= 4) {
intel_ring_emit(ring,
MI_BATCH_BUFFER_START | (2 << 6)
| MI_BATCH_NON_SECURE_I965);
intel_ring_emit(ring, exec_start);
} else {
intel_ring_emit(ring, MI_BATCH_BUFFER_START
| (2 << 6));
intel_ring_emit(ring, exec_start |
MI_BATCH_NON_SECURE);
}
intel_ring_emit(ring,
MI_BATCH_BUFFER_START | (2 << 6));
intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE);
}
intel_ring_advance(ring);
}
intel_ring_advance(ring);

return 0;
}
Expand Down Expand Up @@ -904,22 +879,17 @@ static void gen6_ring_flush(struct intel_ring_buffer *ring,

static int
gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring,
struct drm_i915_gem_execbuffer2 *exec,
struct drm_clip_rect *cliprects,
uint64_t exec_offset)
u32 offset, u32 len)
{
uint32_t exec_start;
int ret;

exec_start = (uint32_t) exec_offset + exec->batch_start_offset;

ret = intel_ring_begin(ring, 2);
if (ret)
return ret;

intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965);
/* bit0-7 is the length on GEN6+ */
intel_ring_emit(ring, exec_start);
intel_ring_emit(ring, offset);
intel_ring_advance(ring);

return 0;
Expand Down
4 changes: 1 addition & 3 deletions drivers/gpu/drm/i915/intel_ringbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,7 @@ struct intel_ring_buffer {
u32 *seqno);
u32 (*get_seqno)(struct intel_ring_buffer *ring);
int (*dispatch_execbuffer)(struct intel_ring_buffer *ring,
struct drm_i915_gem_execbuffer2 *exec,
struct drm_clip_rect *cliprects,
uint64_t exec_offset);
u32 offset, u32 length);
void (*cleanup)(struct intel_ring_buffer *ring);

/**
Expand Down

0 comments on commit c4e7a41

Please sign in to comment.