Emit cliprects in the userspace driver as required, rather than
passing them to the kernel. This works because all drawing commands in the 965 driver are emitted with the lock held and the batchbuffer is always flushed prior to releasing the lock. This allows multiple cliprects to be dealt with, without replaying entire batchbuffers and redundantly re-emitting state.
This commit is contained in:
@@ -39,7 +39,7 @@ static void flush_and_fence( struct aub_state *s )
|
||||
buf[0] = intel->vtbl.flush_cmd();
|
||||
buf[1] = 0;
|
||||
|
||||
intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf), GL_TRUE);
|
||||
intel_cmd_ioctl(intel, (char *)&buf, sizeof(buf));
|
||||
|
||||
intelWaitIrq( intel, intelEmitIrqLocked( intel ));
|
||||
}
|
||||
@@ -64,7 +64,7 @@ static void flush_cmds( struct aub_state *s,
|
||||
* This differs slightly from how the stream was executed
|
||||
* initially as this would have been a batchbuffer.
|
||||
*/
|
||||
intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE);
|
||||
intel_cmd_ioctl(s->intel, (void *)data, len);
|
||||
|
||||
if (1)
|
||||
flush_and_fence(s);
|
||||
@@ -345,7 +345,7 @@ static int parse_block_header( struct aub_state *s )
|
||||
}
|
||||
case BH_COMMAND_WRITE:
|
||||
#if 0
|
||||
intel_cmd_ioctl(s->intel, (void *)data, len, GL_TRUE);
|
||||
intel_cmd_ioctl(s->intel, (void *)data, len);
|
||||
#else
|
||||
if (parse_commands(s, data, len) != 0)
|
||||
_mesa_printf("parse_commands failed\n");
|
||||
|
||||
@@ -123,6 +123,23 @@ static GLuint trim(GLenum prim, GLuint length)
|
||||
}
|
||||
|
||||
|
||||
static void brw_emit_cliprect( struct brw_context *brw,
|
||||
const drm_clip_rect_t *rect )
|
||||
{
|
||||
struct brw_drawrect bdr;
|
||||
|
||||
bdr.header.opcode = CMD_DRAW_RECT;
|
||||
bdr.header.length = sizeof(bdr)/4 - 2;
|
||||
bdr.xmin = rect->x1;
|
||||
bdr.xmax = rect->x2 - 1;
|
||||
bdr.ymin = rect->y1;
|
||||
bdr.ymax = rect->y2 - 1;
|
||||
bdr.xorg = brw->intel.drawX;
|
||||
bdr.yorg = brw->intel.drawY;
|
||||
|
||||
intel_batchbuffer_data( brw->intel.batch, &bdr, sizeof(bdr),
|
||||
INTEL_BATCH_NO_CLIPRECTS);
|
||||
}
|
||||
|
||||
|
||||
static void brw_emit_prim( struct brw_context *brw,
|
||||
@@ -149,7 +166,7 @@ static void brw_emit_prim( struct brw_context *brw,
|
||||
|
||||
if (prim_packet.verts_per_instance) {
|
||||
intel_batchbuffer_data( brw->intel.batch, &prim_packet, sizeof(prim_packet),
|
||||
INTEL_BATCH_CLIPRECTS);
|
||||
INTEL_BATCH_NO_CLIPRECTS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,7 +294,7 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
|
||||
struct intel_context *intel = intel_context(ctx);
|
||||
struct brw_context *brw = brw_context(ctx);
|
||||
GLboolean retval = GL_FALSE;
|
||||
GLuint i;
|
||||
GLuint i, j;
|
||||
|
||||
if (ctx->NewState)
|
||||
_mesa_update_state( ctx );
|
||||
@@ -294,8 +311,17 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
|
||||
*/
|
||||
|
||||
LOCK_HARDWARE(intel);
|
||||
|
||||
if (brw->intel.numClipRects == 0) {
|
||||
assert(intel->batch->ptr == intel->batch->map + intel->batch->offset);
|
||||
UNLOCK_HARDWARE(intel);
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
{
|
||||
assert(intel->locked);
|
||||
|
||||
|
||||
|
||||
/* Set the first primitive early, ahead of validate_state:
|
||||
*/
|
||||
@@ -322,10 +348,25 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Emit prims to batchbuffer:
|
||||
/* For single cliprect, state is already emitted:
|
||||
*/
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
brw_emit_prim(brw, &prim[i]);
|
||||
if (brw->intel.numClipRects == 1) {
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
brw_emit_prim(brw, &prim[i]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Otherwise, explicitly do the cliprects at this point:
|
||||
*/
|
||||
for (j = 0; j < brw->intel.numClipRects; j++) {
|
||||
brw_emit_cliprect(brw, &brw->intel.pClipRects[j]);
|
||||
|
||||
/* Emit prims to batchbuffer:
|
||||
*/
|
||||
for (i = 0; i < nr_prims; i++) {
|
||||
brw_emit_prim(brw, &prim[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intel->need_flush = GL_TRUE;
|
||||
|
||||
@@ -74,7 +74,6 @@ const struct brw_tracked_state brw_blend_constant_color = {
|
||||
/***********************************************************************
|
||||
* Drawing rectangle -- Need for AUB file only.
|
||||
*/
|
||||
|
||||
static void upload_drawing_rect(struct brw_context *brw)
|
||||
{
|
||||
struct intel_context *intel = &brw->intel;
|
||||
@@ -83,13 +82,12 @@ static void upload_drawing_rect(struct brw_context *brw)
|
||||
int x1, y1;
|
||||
int x2, y2;
|
||||
|
||||
if (!brw->intel.aub_file)
|
||||
/* If there is a single cliprect, set it here. Otherwise iterate
|
||||
* over them in brw_draw_prim().
|
||||
*/
|
||||
if (brw->intel.numClipRects > 1)
|
||||
return;
|
||||
|
||||
/* Basically calculate a single cliprect for the whole window.
|
||||
* Don't bother iterating over cliprects at the moment.
|
||||
*/
|
||||
|
||||
x1 = dPriv->x;
|
||||
y1 = dPriv->y;
|
||||
x2 = dPriv->x + dPriv->w;
|
||||
@@ -110,7 +108,10 @@ static void upload_drawing_rect(struct brw_context *brw)
|
||||
bdr.xorg = dPriv->x;
|
||||
bdr.yorg = dPriv->y;
|
||||
|
||||
BRW_CACHED_BATCH_STRUCT(brw, &bdr);
|
||||
/* Can't use BRW_CACHED_BATCH_STRUCT because this is also emitted
|
||||
* uncached in brw_draw.c:
|
||||
*/
|
||||
BRW_BATCH_STRUCT(brw, &bdr);
|
||||
}
|
||||
|
||||
const struct brw_tracked_state brw_drawing_rect = {
|
||||
|
||||
@@ -1307,7 +1307,7 @@ unsigned bmSetFence( struct intel_context *intel )
|
||||
GLuint dword[2];
|
||||
dword[0] = intel->vtbl.flush_cmd();
|
||||
dword[1] = 0;
|
||||
intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword), GL_TRUE);
|
||||
intel_cmd_ioctl(intel, (char *)&dword, sizeof(dword));
|
||||
|
||||
intel->bm->last_fence = intelEmitIrqLocked( intel );
|
||||
|
||||
|
||||
@@ -128,7 +128,6 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch )
|
||||
struct intel_context *intel = batch->intel;
|
||||
GLuint used = batch->ptr - (batch->map + batch->offset);
|
||||
GLuint offset;
|
||||
GLboolean ignore_cliprects = (batch->flags & INTEL_BATCH_CLIPRECTS) ? GL_FALSE : GL_TRUE;
|
||||
GLint retval = GL_TRUE;
|
||||
|
||||
assert(intel->locked);
|
||||
@@ -138,22 +137,6 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch )
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
/* Throw away non-effective packets.
|
||||
*/
|
||||
if (intel->numClipRects == 0 && !ignore_cliprects) {
|
||||
batch->ptr = batch->map + batch->offset;
|
||||
bmReleaseBuffers( batch->intel );
|
||||
intel->vtbl.lost_hardware(intel);
|
||||
batch->flags = 0;
|
||||
|
||||
UNLOCK_HARDWARE(intel);
|
||||
sched_yield();
|
||||
LOCK_HARDWARE(intel);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/* Add the MI_BATCH_BUFFER_END. Always add an MI_FLUSH - this is a
|
||||
* performance drain that we would like to avoid.
|
||||
*/
|
||||
@@ -204,8 +187,7 @@ GLboolean intel_batchbuffer_flush( struct intel_batchbuffer *batch )
|
||||
*/
|
||||
intel_batch_ioctl(batch->intel,
|
||||
offset + batch->offset,
|
||||
used,
|
||||
ignore_cliprects);
|
||||
used);
|
||||
|
||||
if (intel->aub_file &&
|
||||
intel->ctx.DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT)
|
||||
|
||||
@@ -210,6 +210,12 @@ void intelWindowMoved( struct intel_context *intel )
|
||||
|
||||
intel->NewGLState |= _NEW_SCISSOR;
|
||||
}
|
||||
|
||||
/* This works because the lock is always grabbed before emitting
|
||||
* commands and commands are always flushed prior to releasing
|
||||
* the lock.
|
||||
*/
|
||||
intel->NewGLState |= _NEW_WINDOW_POS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -577,12 +577,6 @@ static void intelContendedLock( struct intel_context *intel, GLuint flags )
|
||||
if (dPriv && intel->lastStamp != dPriv->lastStamp) {
|
||||
intelWindowMoved( intel );
|
||||
intel->lastStamp = dPriv->lastStamp;
|
||||
|
||||
/* This works because the lock is always grabbed before emitting
|
||||
* commands and commands are always flushed prior to releasing
|
||||
* the lock.
|
||||
*/
|
||||
intel->NewGLState |= _NEW_WINDOW_POS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -105,8 +105,7 @@ void intelWaitIrq( struct intel_context *intel, int seq )
|
||||
|
||||
void intel_batch_ioctl( struct intel_context *intel,
|
||||
GLuint start_offset,
|
||||
GLuint used,
|
||||
GLboolean ignore_cliprects)
|
||||
GLuint used)
|
||||
{
|
||||
drmI830BatchBuffer batch;
|
||||
|
||||
@@ -114,27 +113,24 @@ void intel_batch_ioctl( struct intel_context *intel,
|
||||
assert(used);
|
||||
|
||||
if (0)
|
||||
fprintf(stderr, "%s used %d offset %x..%x ignore_cliprects %d\n",
|
||||
fprintf(stderr, "%s used %d offset %x..%x\n",
|
||||
__FUNCTION__,
|
||||
used,
|
||||
start_offset,
|
||||
start_offset + used,
|
||||
ignore_cliprects);
|
||||
start_offset + used);
|
||||
|
||||
batch.start = start_offset;
|
||||
batch.used = used;
|
||||
batch.cliprects = intel->pClipRects;
|
||||
batch.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
|
||||
batch.cliprects = NULL;
|
||||
batch.num_cliprects = 0;
|
||||
batch.DR1 = 0;
|
||||
batch.DR4 = ((((GLuint)intel->drawX) & 0xffff) |
|
||||
(((GLuint)intel->drawY) << 16));
|
||||
batch.DR4 = 0;
|
||||
|
||||
if (INTEL_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
|
||||
fprintf(stderr, "%s: 0x%x..0x%x\n",
|
||||
__FUNCTION__,
|
||||
batch.start,
|
||||
batch.start + batch.used * 4,
|
||||
batch.DR4, batch.num_cliprects);
|
||||
batch.start + batch.used * 4);
|
||||
|
||||
if (!intel->no_hw) {
|
||||
if (drmCommandWrite (intel->driFd, DRM_I830_BATCHBUFFER, &batch,
|
||||
@@ -148,8 +144,7 @@ void intel_batch_ioctl( struct intel_context *intel,
|
||||
|
||||
void intel_cmd_ioctl( struct intel_context *intel,
|
||||
char *buf,
|
||||
GLuint used,
|
||||
GLboolean ignore_cliprects)
|
||||
GLuint used)
|
||||
{
|
||||
drmI830CmdBuffer cmd;
|
||||
|
||||
@@ -159,17 +154,15 @@ void intel_cmd_ioctl( struct intel_context *intel,
|
||||
cmd.buf = buf;
|
||||
cmd.sz = used;
|
||||
cmd.cliprects = intel->pClipRects;
|
||||
cmd.num_cliprects = ignore_cliprects ? 0 : intel->numClipRects;
|
||||
cmd.num_cliprects = 0;
|
||||
cmd.DR1 = 0;
|
||||
cmd.DR4 = ((((GLuint)intel->drawX) & 0xffff) |
|
||||
(((GLuint)intel->drawY) << 16));
|
||||
cmd.DR4 = 0;
|
||||
|
||||
if (INTEL_DEBUG & DEBUG_DMA)
|
||||
fprintf(stderr, "%s: 0x%x..0x%x DR4: %x cliprects: %d\n",
|
||||
fprintf(stderr, "%s: 0x%x..0x%x\n",
|
||||
__FUNCTION__,
|
||||
0,
|
||||
0 + cmd.sz,
|
||||
cmd.DR4, cmd.num_cliprects);
|
||||
0 + cmd.sz);
|
||||
|
||||
if (!intel->no_hw) {
|
||||
if (drmCommandWrite (intel->driFd, DRM_I830_CMDBUFFER, &cmd,
|
||||
|
||||
@@ -35,12 +35,10 @@ int intelEmitIrqLocked( struct intel_context *intel );
|
||||
|
||||
void intel_batch_ioctl( struct intel_context *intel,
|
||||
GLuint start_offset,
|
||||
GLuint used,
|
||||
GLboolean ignore_cliprects);
|
||||
GLuint used);
|
||||
|
||||
void intel_cmd_ioctl( struct intel_context *intel,
|
||||
char *buf,
|
||||
GLuint used,
|
||||
GLboolean ignore_cliprects);
|
||||
GLuint used);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -272,7 +272,7 @@ static GLboolean intelInitDriver(__DRIscreenPrivate *sPriv)
|
||||
volatile drmI830Sarea *sarea;
|
||||
|
||||
if (sPriv->devPrivSize != sizeof(I830DRIRec)) {
|
||||
fprintf(stderr,"\nERROR! sizeof(I830DRIRec) (%ld) does not match passed size from device driver (%d)\n", sizeof(I830DRIRec), sPriv->devPrivSize);
|
||||
fprintf(stderr,"\nERROR! sizeof(I830DRIRec) (%ld) does not match passed size from device driver (%d)\n", (unsigned long)sizeof(I830DRIRec), sPriv->devPrivSize);
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user