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.
This commit is contained in:
Eric Anholt
2008-10-19 17:46:41 -07:00
parent e92a457ac0
commit 0cade4de4f
17 changed files with 271 additions and 291 deletions

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

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);

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

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);
}

View File

@@ -282,12 +282,11 @@ 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
@@ -295,11 +294,9 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
* 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);
intel_batchbuffer_require_space(intel->batch, intel->batch->size / 4,
LOOP_CLIPRECTS);
{
/* Set the first primitive early, ahead of validate_state:
*/
brw_set_prim(brw, prim[0].mode);

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.

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;

View File

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

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

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;

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 */

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)
void
intel_get_cliprects(struct intel_context *intel,
struct drm_clip_rect **cliprects,
unsigned int *num_cliprects,
int *x_off, int *y_off)
{
/* 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);
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct intel_framebuffer *intel_fb = dPriv->driverPrivate;
assert(intel->ctx.DrawBuffer->Width > 0);
assert(intel->ctx.DrawBuffer->Height > 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;
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)
{
__DRIdrawablePrivate *dPriv = intel->driDrawable;
struct intel_framebuffer *intel_fb;
if (!dPriv)
return;
intel_fb = dPriv->driverPrivate;
if (intel_fb->pf_active || dPriv->numBackClipRects == 0) {
*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;
}
}

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 */

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) {

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;

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

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;
@@ -156,9 +152,6 @@ static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
tile_stride = (irb->pfPitch * irb->region->cpp) << 3;
x += intel->drawX;
y += intel->drawY;
xbyte = x * irb->region->cpp;
x_tile_off = xbyte & 0x1ff;
@@ -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;
@@ -215,9 +207,6 @@ static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
tile_stride = (irb->pfPitch * irb->region->cpp) << 5;
x += intel->drawX;
y += intel->drawY;
xbyte = x * irb->region->cpp;
x_tile_off = xbyte & 0x7f;
@@ -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,16 +583,12 @@ 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));
}
}
}
/* color read buffers */
if (map)