diff options
author | Nicolai Haehnle <prefect_@gmx.net> | 2004-10-17 20:26:06 +0000 |
---|---|---|
committer | Nicolai Haehnle <prefect_@gmx.net> | 2004-10-17 20:26:06 +0000 |
commit | ff42a00402deab3034163c2b76c2082cce39d901 (patch) | |
tree | 0c81aba24705d6643d0b888265270e494ce344ce /src/mesa/drivers/dri/r300/radeon_state.c | |
parent | 158a251a6b8ffa02387c767a00dc960b49098022 (diff) |
- FIX: flickering
- Scissor support works now
Diffstat (limited to 'src/mesa/drivers/dri/r300/radeon_state.c')
-rw-r--r-- | src/mesa/drivers/dri/r300/radeon_state.c | 163 |
1 files changed, 160 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/r300/radeon_state.c b/src/mesa/drivers/dri/r300/radeon_state.c index 19af781d7b..0cacbb5ebf 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.c +++ b/src/mesa/drivers/dri/r300/radeon_state.c @@ -50,6 +50,106 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_ioctl.h" #include "radeon_state.h" #include "r200_state.h" +#include "r300_ioctl.h" + + +/* ============================================================= + * Scissoring + */ + +static GLboolean intersect_rect(drm_clip_rect_t * out, + drm_clip_rect_t * a, drm_clip_rect_t * b) +{ + *out = *a; + if (b->x1 > out->x1) + out->x1 = b->x1; + if (b->y1 > out->y1) + out->y1 = b->y1; + if (b->x2 < out->x2) + out->x2 = b->x2; + if (b->y2 < out->y2) + out->y2 = b->y2; + if (out->x1 >= out->x2) + return GL_FALSE; + if (out->y1 >= out->y2) + return GL_FALSE; + return GL_TRUE; +} + +void radeonRecalcScissorRects(radeonContextPtr radeon) +{ + drm_clip_rect_t *out; + int i; + + /* Grow cliprect store? + */ + if (radeon->state.scissor.numAllocedClipRects < radeon->numClipRects) { + while (radeon->state.scissor.numAllocedClipRects < + radeon->numClipRects) { + radeon->state.scissor.numAllocedClipRects += 1; /* zero case */ + radeon->state.scissor.numAllocedClipRects *= 2; + } + + if (radeon->state.scissor.pClipRects) + FREE(radeon->state.scissor.pClipRects); + + radeon->state.scissor.pClipRects = + MALLOC(radeon->state.scissor.numAllocedClipRects * + sizeof(drm_clip_rect_t)); + + if (radeon->state.scissor.pClipRects == NULL) { + radeon->state.scissor.numAllocedClipRects = 0; + return; + } + } + + out = radeon->state.scissor.pClipRects; + radeon->state.scissor.numClipRects = 0; + + for (i = 0; i < radeon->numClipRects; i++) { + if (intersect_rect(out, + &radeon->pClipRects[i], + &radeon->state.scissor.rect)) { + radeon->state.scissor.numClipRects++; + out++; + } + } +} + +void radeonUpdateScissor(GLcontext* ctx) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + assert(radeon->state.scissor.enabled == ctx->Scissor.Enabled); + + if (radeon->dri.drawable) { + __DRIdrawablePrivate *dPriv = radeon->dri.drawable; + int x1 = dPriv->x + ctx->Scissor.X; + int y1 = dPriv->y + dPriv->h - (ctx->Scissor.Y + ctx->Scissor.Height); + + radeon->state.scissor.rect.x1 = x1; + radeon->state.scissor.rect.y1 = y1; + radeon->state.scissor.rect.x2 = x1 + ctx->Scissor.Width - 1; + radeon->state.scissor.rect.y2 = y1 + ctx->Scissor.Height - 1; + + radeonRecalcScissorRects(radeon); + } +} + +static void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + if (ctx->Scissor.Enabled) { + /* We don't pipeline cliprect changes */ + if (IS_FAMILY_R200(radeon)) + R200_FIREVERTICES((r200ContextPtr)radeon); + else + r300Flush(ctx); + + radeonUpdateScissor(ctx); + } +} /** @@ -77,12 +177,69 @@ void radeonSetCliprects(radeonContextPtr radeon, GLenum mode) break; default: fprintf(stderr, "bad mode in radeonSetCliprects\n"); + radeon->numClipRects = 0; + radeon->pClipRects = 0; + return; + } + + if (radeon->state.scissor.enabled) + radeonRecalcScissorRects(radeon); +} + + +/** + * Handle common enable bits. + * Called as a fallback by r200Enable/r300Enable. + */ +void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state) +{ + radeonContextPtr radeon = RADEON_CONTEXT(ctx); + + switch(cap) { + case GL_SCISSOR_TEST: + /* We don't pipeline cliprect & scissor changes */ + if (IS_FAMILY_R200(radeon)) + R200_FIREVERTICES((r200ContextPtr)radeon); + else + r300Flush(ctx); + + radeon->state.scissor.enabled = state; + radeonUpdateScissor(ctx); + break; + + default: return; } +} - if (IS_FAMILY_R200(radeon)) { - if (((r200ContextPtr)radeon)->state.scissor.enabled) - r200RecalcScissorRects((r200ContextPtr)radeon); + +/** + * Initialize default state. + * This function is called once at context init time from + * r200InitState/r300InitState + */ +void radeonInitState(radeonContextPtr radeon) +{ + radeon->Fallback = 0; + + if (radeon->glCtx->Visual.doubleBufferMode && radeon->sarea->pfCurrentPage == 0) { + radeon->state.color.drawOffset = radeon->radeonScreen->backOffset; + radeon->state.color.drawPitch = radeon->radeonScreen->backPitch; + } else { + radeon->state.color.drawOffset = radeon->radeonScreen->frontOffset; + radeon->state.color.drawPitch = radeon->radeonScreen->frontPitch; } + + radeon->state.pixel.readOffset = radeon->state.color.drawOffset; + radeon->state.pixel.readPitch = radeon->state.color.drawPitch; } + +/** + * Initialize common state functions. + * Called by r200InitStateFuncs/r300InitStateFuncs + */ +void radeonInitStateFuncs(struct dd_function_table *functions) +{ + functions->Scissor = radeonScissor; +} |