Browse Source

intel: Don't keep intel->pClipRects, and instead just calculate it when needed.

This avoids issues with dereferencing stale cliprects around intel_draw_buffer
time.  Additionally, take advantage of cliprects staying constant for FBOs and
DRI2, and emit cliprects in the batchbuffer instead of having to flush batch
each time they change.
tags/mesa_7_3_rc1
Eric Anholt 17 years ago
parent
commit
0cade4de4f

+ 7
- 1
src/mesa/drivers/dri/i915/i830_context.h View File

@@ -57,7 +57,13 @@
#define I830_DESTREG_SR0 7
#define I830_DESTREG_SR1 8
#define I830_DESTREG_SR2 9
#define I830_DEST_SETUP_SIZE 10
#define I830_DESTREG_DRAWRECT0 10
#define I830_DESTREG_DRAWRECT1 11
#define I830_DESTREG_DRAWRECT2 12
#define I830_DESTREG_DRAWRECT3 13
#define I830_DESTREG_DRAWRECT4 14
#define I830_DESTREG_DRAWRECT5 15
#define I830_DEST_SETUP_SIZE 16

#define I830_CTXREG_STATE1 0
#define I830_CTXREG_STATE2 1

+ 29
- 0
src/mesa/drivers/dri/i915/i830_vtbl.c View File

@@ -513,6 +513,16 @@ i830_emit_state(struct intel_context *intel)
OUT_BATCH(state->Buffer[I830_DESTREG_SR0]);
OUT_BATCH(state->Buffer[I830_DESTREG_SR1]);
OUT_BATCH(state->Buffer[I830_DESTREG_SR2]);

if (intel->constant_cliprect) {
assert(state->Buffer[I830_DESTREG_DRAWRECT0] != MI_NOOP);
OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT0]);
OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT1]);
OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT2]);
OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT3]);
OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT4]);
OUT_BATCH(state->Buffer[I830_DESTREG_DRAWRECT5]);
}
ADVANCE_BATCH();
}
@@ -592,6 +602,7 @@ i830_state_draw_region(struct intel_context *intel,
struct intel_region *depth_region)
{
struct i830_context *i830 = i830_context(&intel->ctx);
GLcontext *ctx = &intel->ctx;
GLuint value;

ASSERT(state == &i830->state || state == &i830->meta);
@@ -644,6 +655,24 @@ i830_state_draw_region(struct intel_context *intel,
}
state->Buffer[I830_DESTREG_DV1] = value;

if (intel->constant_cliprect) {
state->Buffer[I830_DESTREG_DRAWRECT0] = _3DSTATE_DRAWRECT_INFO;
state->Buffer[I830_DESTREG_DRAWRECT1] = 0;
state->Buffer[I830_DESTREG_DRAWRECT2] = 0; /* xmin, ymin */
state->Buffer[I830_DESTREG_DRAWRECT3] =
(ctx->DrawBuffer->Width & 0xffff) |
(ctx->DrawBuffer->Height << 16);
state->Buffer[I830_DESTREG_DRAWRECT4] = 0; /* xoff, yoff */
state->Buffer[I830_DESTREG_DRAWRECT5] = 0;
} else {
state->Buffer[I830_DESTREG_DRAWRECT0] = MI_NOOP;
state->Buffer[I830_DESTREG_DRAWRECT1] = MI_NOOP;
state->Buffer[I830_DESTREG_DRAWRECT2] = MI_NOOP;
state->Buffer[I830_DESTREG_DRAWRECT3] = MI_NOOP;
state->Buffer[I830_DESTREG_DRAWRECT4] = MI_NOOP;
state->Buffer[I830_DESTREG_DRAWRECT5] = MI_NOOP;
}

I830_STATECHANGE(i830, I830_UPLOAD_BUFFERS);



+ 7
- 1
src/mesa/drivers/dri/i915/i915_context.h View File

@@ -65,7 +65,13 @@
#define I915_DESTREG_SR0 9
#define I915_DESTREG_SR1 10
#define I915_DESTREG_SR2 11
#define I915_DEST_SETUP_SIZE 12
#define I915_DESTREG_DRAWRECT0 12
#define I915_DESTREG_DRAWRECT1 13
#define I915_DESTREG_DRAWRECT2 14
#define I915_DESTREG_DRAWRECT3 15
#define I915_DESTREG_DRAWRECT4 16
#define I915_DESTREG_DRAWRECT5 17
#define I915_DEST_SETUP_SIZE 18

#define I915_CTXREG_STATE4 0
#define I915_CTXREG_LI 1

+ 30
- 0
src/mesa/drivers/dri/i915/i915_vtbl.c View File

@@ -399,6 +399,17 @@ i915_emit_state(struct intel_context *intel)
OUT_BATCH(state->Buffer[I915_DESTREG_SR0]);
OUT_BATCH(state->Buffer[I915_DESTREG_SR1]);
OUT_BATCH(state->Buffer[I915_DESTREG_SR2]);

if (intel->constant_cliprect) {
assert(state->Buffer[I915_DESTREG_DRAWRECT0] != MI_NOOP);
OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT0]);
OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT1]);
OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT2]);
OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT3]);
OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT4]);
OUT_BATCH(state->Buffer[I915_DESTREG_DRAWRECT5]);
}

ADVANCE_BATCH();
}

@@ -521,6 +532,7 @@ i915_state_draw_region(struct intel_context *intel,
struct intel_region *depth_region)
{
struct i915_context *i915 = i915_context(&intel->ctx);
GLcontext *ctx = &intel->ctx;
GLuint value;

ASSERT(state == &i915->state || state == &i915->meta);
@@ -573,6 +585,24 @@ i915_state_draw_region(struct intel_context *intel,
}
state->Buffer[I915_DESTREG_DV1] = value;

if (intel->constant_cliprect) {
state->Buffer[I915_DESTREG_DRAWRECT0] = _3DSTATE_DRAWRECT_INFO;
state->Buffer[I915_DESTREG_DRAWRECT1] = 0;
state->Buffer[I915_DESTREG_DRAWRECT2] = 0; /* xmin, ymin */
state->Buffer[I915_DESTREG_DRAWRECT3] =
(ctx->DrawBuffer->Width & 0xffff) |
(ctx->DrawBuffer->Height << 16);
state->Buffer[I915_DESTREG_DRAWRECT4] = 0; /* xoff, yoff */
state->Buffer[I915_DESTREG_DRAWRECT5] = 0;
} else {
state->Buffer[I915_DESTREG_DRAWRECT0] = MI_NOOP;
state->Buffer[I915_DESTREG_DRAWRECT1] = MI_NOOP;
state->Buffer[I915_DESTREG_DRAWRECT2] = MI_NOOP;
state->Buffer[I915_DESTREG_DRAWRECT3] = MI_NOOP;
state->Buffer[I915_DESTREG_DRAWRECT4] = MI_NOOP;
state->Buffer[I915_DESTREG_DRAWRECT5] = MI_NOOP;
}

I915_STATECHANGE(i915, I915_UPLOAD_BUFFERS);
}


+ 10
- 13
src/mesa/drivers/dri/i965/brw_draw.c View File

@@ -282,24 +282,21 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,

LOCK_HARDWARE(intel);

if (brw->intel.numClipRects == 0) {
if (!intel->constant_cliprect && intel->driDrawable->numClipRects == 0) {
UNLOCK_HARDWARE(intel);
return GL_TRUE;
}

/* Flush the batch if it's approaching full, so that we don't wrap while
* we've got validated state that needs to be in the same batch as the
* primitives. This fraction is just a guess (minimal full state plus
* a primitive is around 512 bytes), and would be better if we had
* an upper bound of how much we might emit in a single
* brw_try_draw_prims().
*/
intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
LOOP_CLIPRECTS);
{
/* Flush the batch if it's approaching full, so that we don't wrap while
* we've got validated state that needs to be in the same batch as the
* primitives. This fraction is just a guess (minimal full state plus
* a primitive is around 512 bytes), and would be better if we had
* an upper bound of how much we might emit in a single
* brw_try_draw_prims().
*/
if (intel->batch->ptr - intel->batch->map > intel->batch->size * 3 / 4
/* brw_emit_prim may change the cliprect_mode to LOOP_CLIPRECTS */
|| intel->batch->cliprect_mode != LOOP_CLIPRECTS)
intel_batchbuffer_flush(intel->batch);

/* Set the first primitive early, ahead of validate_state:
*/
brw_set_prim(brw, prim[0].mode);

+ 27
- 0
src/mesa/drivers/dri/i965/brw_misc_state.c View File

@@ -71,6 +71,33 @@ const struct brw_tracked_state brw_blend_constant_color = {
.emit = upload_blend_constant_color
};

/* Constant single cliprect for framebuffer object or DRI2 drawing */
static void upload_drawing_rect(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
GLcontext *ctx = &intel->ctx;

if (!intel->constant_cliprect)
return;

BEGIN_BATCH(4, NO_LOOP_CLIPRECTS);
OUT_BATCH(_3DSTATE_DRAWRECT_INFO_I965);
OUT_BATCH(0); /* xmin, ymin */
OUT_BATCH(((ctx->DrawBuffer->Width - 1) & 0xffff) |
((ctx->DrawBuffer->Height - 1) << 16));
OUT_BATCH(0);
ADVANCE_BATCH();
}

const struct brw_tracked_state brw_drawing_rect = {
.dirty = {
.mesa = _NEW_BUFFERS,
.brw = 0,
.cache = 0
},
.emit = upload_drawing_rect
};

/**
* Upload the binding table pointers, which point each stage's array of surface
* state pointers.

+ 1
- 0
src/mesa/drivers/dri/i965/brw_state.h View File

@@ -79,6 +79,7 @@ const struct brw_tracked_state brw_pipe_control;
const struct brw_tracked_state brw_clear_surface_cache;
const struct brw_tracked_state brw_clear_batch_cache;

const struct brw_tracked_state brw_drawing_rect;
const struct brw_tracked_state brw_indices;
const struct brw_tracked_state brw_vertices;


+ 1
- 0
src/mesa/drivers/dri/i965/brw_state_upload.c View File

@@ -99,6 +99,7 @@ const struct brw_tracked_state *atoms[] =
&brw_psp_urb_cbs,
#endif

&brw_drawing_rect,
&brw_indices,
&brw_vertices,


+ 16
- 14
src/mesa/drivers/dri/intel/intel_batchbuffer.c View File

@@ -30,6 +30,7 @@
#include "intel_decode.h"
#include "intel_reg.h"
#include "intel_bufmgr.h"
#include "intel_buffers.h"

/* Relocations in kernel space:
* - pass dma buffer seperately
@@ -133,6 +134,9 @@ do_flush_locked(struct intel_batchbuffer *batch,
{
struct intel_context *intel = batch->intel;
int ret = 0;
unsigned int num_cliprects = 0;
struct drm_clip_rect *cliprects = NULL;
int x_off = 0, y_off = 0;

if (batch->buffer)
dri_bo_subdata (batch->buf, 0, used, batch->buffer);
@@ -142,23 +146,21 @@ do_flush_locked(struct intel_batchbuffer *batch,
batch->map = NULL;
batch->ptr = NULL;

/* Throw away non-effective packets. Won't work once we have
* hardware contexts which would preserve statechanges beyond a
* single buffer.
*/

if (!(intel->numClipRects == 0 &&
batch->cliprect_mode == LOOP_CLIPRECTS) || intel->no_hw) {
dri_bo_exec(batch->buf, used,
intel->pClipRects,
batch->cliprect_mode != LOOP_CLIPRECTS ?
0 : intel->numClipRects,
(((GLuint) intel->drawX) & 0xffff) |
(((GLuint) intel->drawY) << 16));
if (batch->cliprect_mode == LOOP_CLIPRECTS) {
intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
}
/* Dispatch the batchbuffer, if it has some effect (nonzero cliprects).
* Can't short-circuit like this once we have hardware contexts, but we
* should always be in DRI2 mode by then anyway.
*/
if ((batch->cliprect_mode != LOOP_CLIPRECTS ||
num_cliprects != 0) && !intel->no_hw) {
dri_bo_exec(batch->buf, used, cliprects, num_cliprects,
(x_off & 0xffff) | (y_off << 16));
}

if (intel->numClipRects == 0 &&
batch->cliprect_mode == LOOP_CLIPRECTS) {
if (batch->cliprect_mode == LOOP_CLIPRECTS && num_cliprects == 0) {
if (allow_unlock) {
/* If we are not doing any actual user-visible rendering,
* do a sched_yield to keep the app from pegging the cpu while

+ 11
- 1
src/mesa/drivers/dri/intel/intel_batchbuffer.h View File

@@ -19,6 +19,9 @@ enum cliprect_mode {
/**
* Batchbuffer contents require looping over per cliprect at batch submit
* time.
*
* This will be upgraded to NO_LOOP_CLIPRECTS when there's a single
* constant cliprect, as in DRI2 or FBO rendering.
*/
LOOP_CLIPRECTS,
/**
@@ -29,8 +32,10 @@ enum cliprect_mode {
/**
* Batchbuffer contents contain drawing that already handles cliprects, such
* as 2D drawing to front/back/depth that doesn't respect DRAWING_RECTANGLE.
*
* Equivalent behavior to NO_LOOP_CLIPRECTS, but may not persist in batch
* outside of LOCK/UNLOCK.
* outside of LOCK/UNLOCK. This is upgraded to just NO_LOOP_CLIPRECTS when
* there's a constant cliprect, as in DRI2 or FBO rendering.
*/
REFERENCES_CLIPRECTS
};
@@ -115,6 +120,11 @@ intel_batchbuffer_require_space(struct intel_batchbuffer *batch,
if (intel_batchbuffer_space(batch) < sz)
intel_batchbuffer_flush(batch);

if ((cliprect_mode == LOOP_CLIPRECTS ||
cliprect_mode == REFERENCES_CLIPRECTS) &&
batch->intel->constant_cliprect)
cliprect_mode = NO_LOOP_CLIPRECTS;

if (cliprect_mode != IGNORE_CLIPRECTS) {
if (batch->cliprect_mode == IGNORE_CLIPRECTS) {
batch->cliprect_mode = cliprect_mode;

+ 10
- 6
src/mesa/drivers/dri/intel/intel_blit.c View File

@@ -422,6 +422,9 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
struct gl_framebuffer *fb = ctx->DrawBuffer;
GLuint clear_depth;
GLbitfield skipBuffers = 0;
unsigned int num_cliprects;
struct drm_clip_rect *cliprects;
int x_off, y_off;
BATCH_LOCALS;

/*
@@ -446,7 +449,8 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
intelFlush(&intel->ctx);
LOCK_HARDWARE(intel);

if (intel->numClipRects) {
intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
if (num_cliprects) {
GLint cx, cy, cw, ch;
drm_clip_rect_t clear;
int i;
@@ -461,15 +465,15 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
/* clearing a window */

/* flip top to bottom */
clear.x1 = cx + intel->drawX;
clear.x1 = cx + x_off;
clear.y1 = intel->driDrawable->y + intel->driDrawable->h - cy - ch;
clear.x2 = clear.x1 + cw;
clear.y2 = clear.y1 + ch;
}
else {
/* clearing FBO */
assert(intel->numClipRects == 1);
assert(intel->pClipRects == &intel->fboRect);
assert(num_cliprects == 1);
assert(cliprects == &intel->fboRect);
clear.x1 = cx;
clear.y1 = cy;
clear.x2 = clear.x1 + cw;
@@ -477,8 +481,8 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
/* no change to mask */
}

for (i = 0; i < intel->numClipRects; i++) {
const drm_clip_rect_t *box = &intel->pClipRects[i];
for (i = 0; i < num_cliprects; i++) {
const drm_clip_rect_t *box = &cliprects[i];
drm_clip_rect_t b;
GLuint buf;
GLuint clearMask = mask; /* use copy, since we modify it below */

+ 41
- 132
src/mesa/drivers/dri/intel/intel_buffers.c View File

@@ -123,99 +123,40 @@ intel_readbuf_region(struct intel_context *intel)
return NULL;
}



/**
* Update the following fields for rendering to a user-created FBO:
* intel->numClipRects
* intel->pClipRects
* intel->drawX
* intel->drawY
*/
static void
intelSetRenderbufferClipRects(struct intel_context *intel)
{
/* If the batch contents require looping over cliprects, flush them before
* we go changing which cliprects get referenced when that happens.
*/
if (intel->batch->cliprect_mode == LOOP_CLIPRECTS &&
(intel->fboRect.x2 != intel->ctx.DrawBuffer->Width ||
intel->fboRect.x2 != intel->ctx.DrawBuffer->Height))
intel_batchbuffer_flush(intel->batch);

assert(intel->ctx.DrawBuffer->Width > 0);
assert(intel->ctx.DrawBuffer->Height > 0);
intel->fboRect.x1 = 0;
intel->fboRect.y1 = 0;
intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;
intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;
intel->numClipRects = 1;
intel->pClipRects = &intel->fboRect;
intel->drawX = 0;
intel->drawY = 0;
}


/**
* As above, but for rendering to front buffer of a window.
* \sa intelSetRenderbufferClipRects
*/
static void
intelSetFrontClipRects(struct intel_context *intel)
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;

if (!dPriv)
return;

/* If the batch contents require looping over cliprects, flush them before
* we go changing which cliprects get referenced when that happens.
*/
if (intel->batch->cliprect_mode == LOOP_CLIPRECTS &&
intel->pClipRects != dPriv->pClipRects)
intel_batchbuffer_flush(intel->batch);
intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
}


/**
* As above, but for rendering to back buffer of a window.
*/
static void
intelSetBackClipRects(struct intel_context *intel)
void
intel_get_cliprects(struct intel_context *intel,
struct drm_clip_rect **cliprects,
unsigned int *num_cliprects,
int *x_off, int *y_off)
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct intel_framebuffer *intel_fb;

if (!dPriv)
return;

intel_fb = dPriv->driverPrivate;
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;

if (intel_fb->pf_active || dPriv->numBackClipRects == 0) {
if (intel->constant_cliprect) {
/* FBO or DRI2 rendering, which can just use the fb's size. */
intel->fboRect.x1 = 0;
intel->fboRect.y1 = 0;
intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;
intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;

*cliprects = &intel->fboRect;
*num_cliprects = 1;
*x_off = 0;
*y_off = 0;
} else if (intel->front_cliprects ||
intel_fb->pf_active || dPriv->numBackClipRects == 0) {
/* use the front clip rects */
if (intel->batch->cliprect_mode == LOOP_CLIPRECTS &&
intel->pClipRects != dPriv->pClipRects)
intel_batchbuffer_flush(intel->batch);

intel->numClipRects = dPriv->numClipRects;
intel->pClipRects = dPriv->pClipRects;
intel->drawX = dPriv->x;
intel->drawY = dPriv->y;
*cliprects = dPriv->pClipRects;
*num_cliprects = dPriv->numClipRects;
*x_off = dPriv->x;
*y_off = dPriv->y;
}
else {
/* use the back clip rects */
if (intel->batch->cliprect_mode == LOOP_CLIPRECTS &&
intel->pClipRects != dPriv->pBackClipRects)
intel_batchbuffer_flush(intel->batch);

intel->numClipRects = dPriv->numBackClipRects;
intel->pClipRects = dPriv->pBackClipRects;
intel->drawX = dPriv->backX;
intel->drawY = dPriv->backY;
*num_cliprects = dPriv->numBackClipRects;
*cliprects = dPriv->pBackClipRects;
*x_off = dPriv->backX;
*y_off = dPriv->backY;
}
}

@@ -300,29 +241,6 @@ intelWindowMoved(struct intel_context *intel)
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;

if (!intel->ctx.DrawBuffer) {
/* when would this happen? -BP */
intelSetFrontClipRects(intel);
}
else if (intel->ctx.DrawBuffer->Name != 0) {
/* drawing to user-created FBO - do nothing */
/* Cliprects would be set from intelDrawBuffer() */
}
else {
/* drawing to a window */
switch (intel_fb->Base._ColorDrawBufferIndexes[0]) {
case BUFFER_FRONT_LEFT:
intelSetFrontClipRects(intel);
break;
case BUFFER_BACK_LEFT:
intelSetBackClipRects(intel);
break;
default:
intelSetFrontClipRects(intel);
}
}

if (!intel->intelScreen->driScrnPriv->dri2.enabled &&
intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
volatile struct drm_i915_sarea *sarea = intel->sarea;
@@ -894,7 +812,6 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
struct intel_context *intel = intel_context(ctx);
struct intel_region *colorRegions[MAX_DRAW_BUFFERS], *depthRegion = NULL;
struct intel_renderbuffer *irbDepth = NULL, *irbStencil = NULL;
int front = 0; /* drawing to front color buffer? */

if (!fb) {
/* this can happen during the initial context initialization */
@@ -927,52 +844,44 @@ intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb)
*/
if (fb->_NumColorDrawBuffers == 0) {
/* writing to 0 */
FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_TRUE);
colorRegions[0] = NULL;

if (fb->Name != 0)
intelSetRenderbufferClipRects(intel);
intel->constant_cliprect = GL_TRUE;
} else if (fb->_NumColorDrawBuffers > 1) {
int i;
struct intel_renderbuffer *irb;
FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);

if (fb->Name != 0)
intelSetRenderbufferClipRects(intel);
for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
irb = intel_renderbuffer(fb->_ColorDrawBuffers[i]);
colorRegions[i] = (irb && irb->region) ? irb->region : NULL;
colorRegions[i] = irb ? irb->region : NULL;
}
intel->constant_cliprect = GL_TRUE;
}
else {
/* draw to exactly one color buffer */
/*_mesa_debug(ctx, "Hardware rendering\n");*/
FALLBACK(intel, INTEL_FALLBACK_DRAW_BUFFER, GL_FALSE);
if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
front = 1;
}

/*
* Get the intel_renderbuffer for the colorbuffer we're drawing into.
* And set up cliprects.
/* Get the intel_renderbuffer for the single colorbuffer we're drawing
* into, and set up cliprects if it's .
*/
if (fb->Name == 0) {
intel->constant_cliprect = intel->driScreen->dri2.enabled;
/* drawing to window system buffer */
if (front) {
intelSetFrontClipRects(intel);
if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
if (!intel->constant_cliprect && !intel->front_cliprects)
intel_batchbuffer_flush(intel->batch);
intel->front_cliprects = GL_TRUE;
colorRegions[0] = intel_get_rb_region(fb, BUFFER_FRONT_LEFT);
}
else {
intelSetBackClipRects(intel);
if (!intel->constant_cliprect && intel->front_cliprects)
intel_batchbuffer_flush(intel->batch);
intel->front_cliprects = GL_FALSE;
colorRegions[0]= intel_get_rb_region(fb, BUFFER_BACK_LEFT);
}
}
else {
/* drawing to user-created FBO */
struct intel_renderbuffer *irb;
intelSetRenderbufferClipRects(intel);
irb = intel_renderbuffer(fb->_ColorDrawBuffers[0]);
colorRegions[0] = (irb && irb->region) ? irb->region : NULL;
intel->constant_cliprect = GL_TRUE;
}
}


+ 7
- 0
src/mesa/drivers/dri/intel/intel_buffers.h View File

@@ -29,6 +29,8 @@
#ifndef INTEL_BUFFERS_H
#define INTEL_BUFFERS_H

#include "dri_util.h"
#include "drm.h"

struct intel_context;
struct intel_framebuffer;
@@ -53,4 +55,9 @@ extern void intel_draw_buffer(GLcontext * ctx, struct gl_framebuffer *fb);

extern void intelInitBufferFuncs(struct dd_function_table *functions);

void intel_get_cliprects(struct intel_context *intel,
struct drm_clip_rect **cliprects,
unsigned int *num_cliprects,
int *x_off, int *y_off);

#endif /* INTEL_BUFFERS_H */

+ 0
- 35
src/mesa/drivers/dri/intel/intel_context.c View File

@@ -588,9 +588,6 @@ intelInitContext(struct intel_context *intel,
intel->driFd = sPriv->fd;
intel->driHwLock = sPriv->lock;

intel->width = intelScreen->width;
intel->height = intelScreen->height;

driParseConfigFiles(&intel->optionCache, &intelScreen->optionCache,
intel->driScreen->myNum,
IS_965(intelScreen->deviceID) ? "i965" : "i915");
@@ -932,38 +929,6 @@ intelContendedLock(struct intel_context *intel, GLuint flags)
sarea->ctxOwner, intel->hHWContext);
}

if (sarea->width != intel->width || sarea->height != intel->height) {
int numClipRects = intel->numClipRects;

/*
* FIXME: Really only need to do this when drawing to a
* common back- or front buffer.
*/

/*
* This will essentially drop the outstanding batchbuffer on
* the floor.
*/
intel->numClipRects = 0;

if (intel->Fallback)
_swrast_flush(&intel->ctx);

if (!IS_965(intel->intelScreen->deviceID))
INTEL_FIREVERTICES(intel);

if (intel->batch->map != intel->batch->ptr)
intel_batchbuffer_flush(intel->batch);

intel->numClipRects = numClipRects;

/* force window update */
intel->lastStamp = 0;

intel->width = sarea->width;
intel->height = sarea->height;
}

/* Drawable changed?
*/
if (dPriv && intel->lastStamp != dPriv->lastStamp) {

+ 11
- 7
src/mesa/drivers/dri/intel/intel_context.h View File

@@ -235,10 +235,18 @@ struct intel_context

/* These refer to the current drawing buffer:
*/
int drawX, drawY; /**< origin of drawing area within region */
GLuint numClipRects; /**< cliprects for drawing */
drm_clip_rect_t *pClipRects;
struct gl_texture_object *frame_buffer_texobj;
/**
* Set to true if a single constant cliprect should be used in the
* batchbuffer. Otherwise, cliprects must be calculated at batchbuffer
* flush time while the lock is held.
*/
GLboolean constant_cliprect;
/**
* In !constant_cliprect mode, set to true if the front cliprects should be
* used instead of back.
*/
GLboolean front_cliprects;
drm_clip_rect_t fboRect; /**< cliprect for FBO rendering */

int perf_boxes;
@@ -271,10 +279,6 @@ struct intel_context
*/
driOptionCache optionCache;

/* Last seen width/height of the screen */
int width;
int height;

int64_t swap_ust;
int64_t swap_missed_ust;


+ 5
- 0
src/mesa/drivers/dri/intel/intel_reg.h View File

@@ -29,6 +29,8 @@
#define CMD_2D (0x2 << 29)
#define CMD_3D (0x3 << 29)

#define MI_NOOP (CMD_MI | 0)

#define MI_BATCH_BUFFER_END (CMD_MI | 0xA << 23)

#define MI_FLUSH (CMD_MI | (4 << 23))
@@ -44,6 +46,9 @@
#define _3DSTATE_LOAD_STATE_IMMEDIATE_1 (CMD_3D | (0x1d<<24) | (0x04<<16))
#define I1_LOAD_S(n) (1<<(4+n))

#define _3DSTATE_DRAWRECT_INFO (CMD_3D | (0x1d<<24) | (0x80<<16) | 0x3)
#define _3DSTATE_DRAWRECT_INFO_I965 (CMD_3D | (3 << 27) | (1 << 24) | 0x2)

/** @{
*
* PIPE_CONTROL operation, a combination MI_FLUSH and register write with

+ 59
- 82
src/mesa/drivers/dri/intel/intel_span.c View File

@@ -30,6 +30,7 @@
#include "main/mtypes.h"
#include "main/colormac.h"

#include "intel_buffers.h"
#include "intel_fbo.h"
#include "intel_screen.h"
#include "intel_span.h"
@@ -131,12 +132,8 @@ pwrite_8(struct intel_renderbuffer *irb, uint32_t offset, uint8_t val)
}

static uint32_t no_tile_swizzle(struct intel_renderbuffer *irb,
struct intel_context *intel,
int x, int y)
{
x += intel->drawX;
y += intel->drawY;

return (y * irb->region->pitch + x) * irb->region->cpp;
}

@@ -145,7 +142,6 @@ static uint32_t no_tile_swizzle(struct intel_renderbuffer *irb,
*/

static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
struct intel_context *intel,
int x, int y)
{
int tile_stride;
@@ -155,9 +151,6 @@ static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
int tile_off, tile_base;
tile_stride = (irb->pfPitch * irb->region->cpp) << 3;
x += intel->drawX;
y += intel->drawY;

xbyte = x * irb->region->cpp;

@@ -204,7 +197,6 @@ static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
}

static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
struct intel_context *intel,
int x, int y)
{
int tile_stride;
@@ -214,9 +206,6 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
int tile_off, tile_base;
tile_stride = (irb->pfPitch * irb->region->cpp) << 5;
x += intel->drawX;
y += intel->drawY;

xbyte = x * irb->region->cpp;

@@ -268,8 +257,12 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
const GLint yScale = irb->RenderToTexture ? 1 : -1; \
const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
unsigned int num_cliprects; \
struct drm_clip_rect *cliprects; \
int x_off, y_off; \
GLuint p; \
(void) p;
(void) p; \
intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);

/* XXX FBO: this is identical to the macro in spantmp2.h except we get
* the cliprect info from the context, not the driDrawable.
@@ -277,12 +270,12 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
*/
#define HW_CLIPLOOP() \
do { \
int _nc = intel->numClipRects; \
int _nc = num_cliprects; \
while ( _nc-- ) { \
int minx = intel->pClipRects[_nc].x1 - intel->drawX; \
int miny = intel->pClipRects[_nc].y1 - intel->drawY; \
int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \
int maxy = intel->pClipRects[_nc].y2 - intel->drawY;
int minx = cliprects[_nc].x1 - x_off; \
int miny = cliprects[_nc].y1 - y_off; \
int maxx = cliprects[_nc].x2 - x_off; \
int maxy = cliprects[_nc].y2 - y_off;
#if 0
}}
@@ -295,6 +288,11 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define HW_UNLOCK()

/* Convenience macros to avoid typing the swizzle argument over and over */
#define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
#define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
#define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)

/* 16 bit, RGB565 color spanline and pixel functions
*/
#define SPANTMP_PIXEL_FMT GL_RGB
@@ -302,8 +300,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel##x##_RGB565
#define TAG2(x,y) intel##x##_RGB565##y
#define GET_VALUE(X, Y) pread_16(irb, no_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_16(irb, no_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_16(irb, NO_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_16(irb, NO_TILE(X, Y), V)
#include "spantmp2.h"

/* 32 bit, ARGB8888 color spanline and pixel functions
@@ -313,8 +311,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel##x##_ARGB8888
#define TAG2(x,y) intel##x##_ARGB8888##y
#define GET_VALUE(X, Y) pread_32(irb, no_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_32(irb, no_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_32(irb, NO_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_32(irb, NO_TILE(X, Y), V)
#include "spantmp2.h"

/* 32 bit, xRGB8888 color spanline and pixel functions
@@ -324,8 +322,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel##x##_xRGB8888
#define TAG2(x,y) intel##x##_xRGB8888##y
#define GET_VALUE(X, Y) pread_xrgb8888(irb, no_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, no_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_xrgb8888(irb, NO_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, NO_TILE(X, Y), V)
#include "spantmp2.h"

/* 16 bit RGB565 color tile spanline and pixel functions
@@ -336,8 +334,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel_XTile_##x##_RGB565
#define TAG2(x,y) intel_XTile_##x##_RGB565##y
#define GET_VALUE(X, Y) pread_16(irb, x_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_16(irb, x_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_16(irb, X_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_16(irb, X_TILE(X, Y), V)
#include "spantmp2.h"

#define SPANTMP_PIXEL_FMT GL_RGB
@@ -345,8 +343,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel_YTile_##x##_RGB565
#define TAG2(x,y) intel_YTile_##x##_RGB565##y
#define GET_VALUE(X, Y) pread_16(irb, y_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_16(irb, y_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_16(irb, Y_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_16(irb, Y_TILE(X, Y), V)
#include "spantmp2.h"

/* 32 bit ARGB888 color tile spanline and pixel functions
@@ -357,8 +355,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel_XTile_##x##_ARGB8888
#define TAG2(x,y) intel_XTile_##x##_ARGB8888##y
#define GET_VALUE(X, Y) pread_32(irb, x_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_32(irb, x_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_32(irb, X_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_32(irb, X_TILE(X, Y), V)
#include "spantmp2.h"

#define SPANTMP_PIXEL_FMT GL_BGRA
@@ -366,8 +364,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel_YTile_##x##_ARGB8888
#define TAG2(x,y) intel_YTile_##x##_ARGB8888##y
#define GET_VALUE(X, Y) pread_32(irb, y_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_32(irb, y_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_32(irb, Y_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_32(irb, Y_TILE(X, Y), V)
#include "spantmp2.h"

/* 32 bit xRGB888 color tile spanline and pixel functions
@@ -378,8 +376,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel_XTile_##x##_xRGB8888
#define TAG2(x,y) intel_XTile_##x##_xRGB8888##y
#define GET_VALUE(X, Y) pread_xrgb8888(irb, x_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, x_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_xrgb8888(irb, X_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, X_TILE(X, Y), V)
#include "spantmp2.h"

#define SPANTMP_PIXEL_FMT GL_BGRA
@@ -387,15 +385,19 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

#define TAG(x) intel_YTile_##x##_xRGB8888
#define TAG2(x,y) intel_YTile_##x##_xRGB8888##y
#define GET_VALUE(X, Y) pread_xrgb8888(irb, y_tile_swizzle(irb, intel, X, Y))
#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, y_tile_swizzle(irb, intel, X, Y), V)
#define GET_VALUE(X, Y) pread_xrgb8888(irb, Y_TILE(X, Y))
#define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, Y_TILE(X, Y), V)
#include "spantmp2.h"

#define LOCAL_DEPTH_VARS \
struct intel_context *intel = intel_context(ctx); \
struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
const GLint yScale = irb->RenderToTexture ? 1 : -1; \
const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1;
const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
unsigned int num_cliprects; \
struct drm_clip_rect *cliprects; \
int x_off, y_off; \
intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);


#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
@@ -404,10 +406,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
** 16-bit depthbuffer functions.
**/
#define VALUE_TYPE GLushort
#define WRITE_DEPTH(_x, _y, d) \
pwrite_16(irb, no_tile_swizzle(irb, intel, _x, _y), d)
#define READ_DEPTH(d, _x, _y) \
d = pread_16(irb, no_tile_swizzle(irb, intel, _x, _y))
#define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, NO_TILE(_x, _y), d)
#define READ_DEPTH(d, _x, _y) d = pread_16(irb, NO_TILE(_x, _y))
#define TAG(x) intel##x##_z16
#include "depthtmp.h"

@@ -416,10 +416,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
** 16-bit x tile depthbuffer functions.
**/
#define VALUE_TYPE GLushort
#define WRITE_DEPTH(_x, _y, d) \
pwrite_16(irb, x_tile_swizzle(irb, intel, _x, _y), d)
#define READ_DEPTH(d, _x, _y) \
d = pread_16(irb, x_tile_swizzle(irb, intel, _x, _y))
#define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, X_TILE(_x, _y), d)
#define READ_DEPTH(d, _x, _y) d = pread_16(irb, X_TILE(_x, _y))
#define TAG(x) intel_XTile_##x##_z16
#include "depthtmp.h"

@@ -427,10 +425,8 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
** 16-bit y tile depthbuffer functions.
**/
#define VALUE_TYPE GLushort
#define WRITE_DEPTH(_x, _y, d) \
pwrite_16(irb, y_tile_swizzle(irb, intel, _x, _y), d)
#define READ_DEPTH(d, _x, _y) \
d = pread_16(irb, y_tile_swizzle(irb, intel, _x, _y))
#define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, Y_TILE(_x, _y), d)
#define READ_DEPTH(d, _x, _y) d = pread_16(irb, Y_TILE(_x, _y))
#define TAG(x) intel_YTile_##x##_z16
#include "depthtmp.h"

@@ -445,12 +441,11 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

/* Change ZZZS -> SZZZ */
#define WRITE_DEPTH(_x, _y, d) \
pwrite_32(irb, no_tile_swizzle(irb, intel, _x, _y), \
((d) >> 8) | ((d) << 24))
pwrite_32(irb, NO_TILE(_x, _y), ((d) >> 8) | ((d) << 24))

/* Change SZZZ -> ZZZS */
#define READ_DEPTH( d, _x, _y ) { \
GLuint tmp = pread_32(irb, no_tile_swizzle(irb, intel, _x, _y)); \
GLuint tmp = pread_32(irb, NO_TILE(_x, _y)); \
d = (tmp << 8) | (tmp >> 24); \
}

@@ -468,12 +463,11 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

/* Change ZZZS -> SZZZ */
#define WRITE_DEPTH(_x, _y, d) \
pwrite_32(irb, x_tile_swizzle(irb, intel, _x, _y), \
((d) >> 8) | ((d) << 24)) \
pwrite_32(irb, X_TILE(_x, _y), ((d) >> 8) | ((d) << 24))

/* Change SZZZ -> ZZZS */
#define READ_DEPTH( d, _x, _y ) { \
GLuint tmp = pread_32(irb, x_tile_swizzle(irb, intel, _x, _y)); \
GLuint tmp = pread_32(irb, X_TILE(_x, _y)); \
d = (tmp << 8) | (tmp >> 24); \
}

@@ -490,12 +484,11 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,

/* Change ZZZS -> SZZZ */
#define WRITE_DEPTH(_x, _y, d) \
pwrite_32(irb, y_tile_swizzle(irb, intel, _x, _y), \
((d) >> 8) | ((d) << 24))
pwrite_32(irb, Y_TILE(_x, _y), ((d) >> 8) | ((d) << 24))

/* Change SZZZ -> ZZZS */
#define READ_DEPTH( d, _x, _y ) { \
GLuint tmp = pread_32(irb, y_tile_swizzle(irb, intel, _x, _y)); \
GLuint tmp = pread_32(irb, Y_TILE(_x, _y)); \
d = (tmp << 8) | (tmp >> 24); \
}

@@ -506,36 +499,24 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
/**
** 8-bit stencil function (XXX FBO: This is obsolete)
**/
#define WRITE_STENCIL(_x, _y, d) \
pwrite_8(irb, no_tile_swizzle(irb, intel, _x, _y) + 3, d)

#define READ_STENCIL(d, _x, _y) \
d = pread_8(irb, no_tile_swizzle(irb, intel, _x, _y) + 3);

#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, NO_TILE(_x, _y) + 3, d)
#define READ_STENCIL(d, _x, _y) d = pread_8(irb, NO_TILE(_x, _y) + 3);
#define TAG(x) intel##x##_z24_s8
#include "stenciltmp.h"

/**
** 8-bit x-tile stencil function (XXX FBO: This is obsolete)
**/
#define WRITE_STENCIL(_x, _y, d) \
pwrite_8(irb, x_tile_swizzle(irb, intel, _x, _y) + 3, d)

#define READ_STENCIL(d, _x, _y) \
d = pread_8(irb, x_tile_swizzle(irb, intel, _x, _y) + 3);

#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, X_TILE(_x, _y) + 3, d)
#define READ_STENCIL(d, _x, _y) d = pread_8(irb, X_TILE(_x, _y) + 3);
#define TAG(x) intel_XTile_##x##_z24_s8
#include "stenciltmp.h"

/**
** 8-bit y-tile stencil function (XXX FBO: This is obsolete)
**/
#define WRITE_STENCIL(_x, _y, d) \
pwrite_8(irb, y_tile_swizzle(irb, intel, _x, _y) + 3, d)

#define READ_STENCIL(d, _x, _y) \
d = pread_8(irb, y_tile_swizzle(irb, intel, _x, _y) + 3)

#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, Y_TILE(_x, _y) + 3, d)
#define READ_STENCIL(d, _x, _y) d = pread_8(irb, Y_TILE(_x, _y) + 3)
#define TAG(x) intel_YTile_##x##_z24_s8
#include "stenciltmp.h"

@@ -602,14 +583,10 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
if (tex) {
/* render to texture */
ASSERT(att->Renderbuffer);
if (map) {
struct gl_texture_image *texImg;
texImg = tex->Image[att->CubeMapFace][att->TextureLevel];
if (map)
intel_tex_map_images(intel, intel_texture_object(tex));
}
else {
else
intel_tex_unmap_images(intel, intel_texture_object(tex));
}
}
}


Loading…
Cancel
Save