From ff42a00402deab3034163c2b76c2082cce39d901 Mon Sep 17 00:00:00 2001 From: Nicolai Haehnle Date: Sun, 17 Oct 2004 20:26:06 +0000 Subject: - FIX: flickering - Scissor support works now --- src/mesa/drivers/dri/r300/r200_context.h | 10 -- src/mesa/drivers/dri/r300/r200_state.h | 1 - src/mesa/drivers/dri/r300/r300_cmdbuf.c | 12 +-- src/mesa/drivers/dri/r300/r300_context.c | 8 +- src/mesa/drivers/dri/r300/r300_state.c | 35 ++++++- src/mesa/drivers/dri/r300/r300_state.h | 2 + src/mesa/drivers/dri/r300/radeon_context.c | 17 +++ src/mesa/drivers/dri/r300/radeon_context.h | 11 ++ src/mesa/drivers/dri/r300/radeon_lock.c | 10 +- src/mesa/drivers/dri/r300/radeon_span.c | 71 ++++++------- src/mesa/drivers/dri/r300/radeon_state.c | 163 ++++++++++++++++++++++++++++- src/mesa/drivers/dri/r300/radeon_state.h | 15 +-- 12 files changed, 274 insertions(+), 81 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/r300/r200_context.h b/src/mesa/drivers/dri/r300/r200_context.h index b5ba1f9258..bc4ac00dfe 100644 --- a/src/mesa/drivers/dri/r300/r200_context.h +++ b/src/mesa/drivers/dri/r300/r200_context.h @@ -80,15 +80,6 @@ struct r200_depthbuffer_state { GLfloat scale; }; -struct r200_scissor_state { - drm_clip_rect_t rect; - GLboolean enabled; - - GLuint numClipRects; /* Cliprects active */ - GLuint numAllocedClipRects; /* Cliprects available */ - drm_clip_rect_t *pClipRects; -}; - struct r200_stencilbuffer_state { GLboolean hwBuffer; GLuint clear; /* rb3d_stencilrefmask value */ @@ -502,7 +493,6 @@ struct r200_state { */ struct r200_colorbuffer_state color; struct r200_depthbuffer_state depth; - struct r200_scissor_state scissor; struct r200_stencilbuffer_state stencil; struct r200_stipple_state stipple; struct r200_texture_state texture; diff --git a/src/mesa/drivers/dri/r300/r200_state.h b/src/mesa/drivers/dri/r300/r200_state.h index cba8e497df..3e1a9c8ba1 100644 --- a/src/mesa/drivers/dri/r300/r200_state.h +++ b/src/mesa/drivers/dri/r300/r200_state.h @@ -45,7 +45,6 @@ extern void r200InitTnlFuncs(GLcontext * ctx); extern void r200UpdateMaterial(GLcontext * ctx); -extern void r200RecalcScissorRects(r200ContextPtr rmesa); extern void r200UpdateViewportOffset(GLcontext * ctx); extern void r200UpdateWindow(GLcontext * ctx); diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index 7d124d7285..7c68f33cff 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -80,17 +80,13 @@ int r300FlushCmdBuf(r300ContextPtr r300, const char* caller) cmd.buf = (char*)(r300->cmdbuf.cmd_buf + start); cmd.bufsz = (r300->cmdbuf.count_used - start) * 4; -#if 0 // TODO: scissors - if (rmesa->state.scissor.enabled) { - cmd.nbox = rmesa->state.scissor.numClipRects; - cmd.boxes = (drm_clip_rect_t *) rmesa->state.scissor.pClipRects; + if (r300->radeon.state.scissor.enabled) { + cmd.nbox = r300->radeon.state.scissor.numClipRects; + cmd.boxes = (drm_clip_rect_t *)r300->radeon.state.scissor.pClipRects; } else { -#endif cmd.nbox = r300->radeon.numClipRects; - cmd.boxes = (drm_clip_rect_t *) r300->radeon.pClipRects; -#if 0 + cmd.boxes = (drm_clip_rect_t *)r300->radeon.pClipRects; } -#endif if (cmd.nbox) { ret = drmCommandWrite(r300->radeon.dri.fd, diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c index 271ea17e1e..6e98bd1e72 100644 --- a/src/mesa/drivers/dri/r300/r300_context.c +++ b/src/mesa/drivers/dri/r300/r300_context.c @@ -156,7 +156,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, assert(screen); /* Allocate the R300 context */ - r300 = (r300ContextPtr) CALLOC(sizeof(*r300)); + r300 = (r300ContextPtr)CALLOC(sizeof(*r300)); if (!r300) return GL_FALSE; @@ -172,7 +172,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual, */ _mesa_init_driver_functions(&functions); r300InitIoctlFuncs(&functions); - //r200InitStateFuncs(&functions); + r300InitStateFuncs(&functions); //r200InitTextureFuncs(&functions); if (!radeonInitContext(&r300->radeon, &functions, @@ -296,9 +296,7 @@ void r300DestroyContext(__DRIcontextPrivate * driContextPriv) r300DestroyCmdBuf(r300); - /* free the Mesa context */ - r300->radeon.glCtx->DriverCtx = NULL; - _mesa_destroy_context(r300->radeon.glCtx); + radeonCleanupContext(&r300->radeon); /* free the option cache */ driDestroyOptionCache(&r300->radeon.optionCache); diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 43cfe2b69b..9c5138c279 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -37,6 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "glheader.h" #include "state.h" #include "imports.h" +#include "enums.h" #include "macros.h" #include "context.h" #include "dd.h" @@ -49,6 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tnl/tnl.h" #include "radeon_ioctl.h" +#include "radeon_state.h" #include "r300_context.h" #include "r300_ioctl.h" #include "r300_state.h" @@ -56,6 +58,24 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r300_program.h" +/** + * Handle glEnable()/glDisable(). + */ +static void r300Enable(GLcontext* ctx, GLenum cap, GLboolean state) +{ + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(cap), + state ? "GL_TRUE" : "GL_FALSE"); + + switch (cap) { + default: + radeonEnable(ctx, cap, state); + return; + } +} + + /** * Called by Mesa after an internal state update. */ @@ -317,6 +337,7 @@ void r300ResetHwState(r300ContextPtr r300) } + /** * Calculate initial hardware state and register state functions. * Assumes that the command buffer and state atoms have been @@ -324,12 +345,20 @@ void r300ResetHwState(r300ContextPtr r300) */ void r300InitState(r300ContextPtr r300) { - struct dd_function_table* functions; + radeonInitState(&r300->radeon); r300ResetHwState(r300); +} + + +/** + * Initialize driver's state callback functions + */ +void r300InitStateFuncs(struct dd_function_table* functions) +{ + radeonInitStateFuncs(functions); - /* Setup state functions */ - functions = &r300->radeon.glCtx->Driver; functions->UpdateState = r300InvalidateState; + functions->Enable= r300Enable; } diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h index 59d76e33df..9c945c4cdd 100644 --- a/src/mesa/drivers/dri/r300/r300_state.h +++ b/src/mesa/drivers/dri/r300/r300_state.h @@ -44,6 +44,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. } while(0) extern void r300ResetHwState(r300ContextPtr r300); + extern void r300InitState(r300ContextPtr r300); +extern void r300InitStateFuncs(struct dd_function_table* functions); #endif /* __R300_STATE_H__ */ diff --git a/src/mesa/drivers/dri/r300/radeon_context.c b/src/mesa/drivers/dri/r300/radeon_context.c index d04045d971..b2cb9cfb5f 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.c +++ b/src/mesa/drivers/dri/r300/radeon_context.c @@ -206,6 +206,23 @@ GLboolean radeonInitContext(radeonContextPtr radeon, } +/** + * Cleanup common context fields. + * Called by r200DestroyContext/r300DestroyContext + */ +void radeonCleanupContext(radeonContextPtr radeon) +{ + /* free the Mesa context */ + radeon->glCtx->DriverCtx = NULL; + _mesa_destroy_context(radeon->glCtx); + + if (radeon->state.scissor.pClipRects) { + FREE(radeon->state.scissor.pClipRects); + radeon->state.scissor.pClipRects = 0; + } +} + + /** * Swap front and back buffer. */ diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h index d51cf4c09d..b3661cdf45 100644 --- a/src/mesa/drivers/dri/r300/radeon_context.h +++ b/src/mesa/drivers/dri/r300/radeon_context.h @@ -113,6 +113,15 @@ struct radeon_dri_mirror { /** * Derived state for internal purposes. */ +struct radeon_scissor_state { + drm_clip_rect_t rect; + GLboolean enabled; + + GLuint numClipRects; /* Cliprects active */ + GLuint numAllocedClipRects; /* Cliprects available */ + drm_clip_rect_t *pClipRects; +}; + struct radeon_colorbuffer_state { GLuint clear; GLint drawOffset, drawPitch; @@ -125,6 +134,7 @@ struct radeon_pixel_state { struct radeon_state { struct radeon_colorbuffer_state color; struct radeon_pixel_state pixel; + struct radeon_scissor_state scissor; }; /** @@ -187,6 +197,7 @@ extern GLboolean radeonInitContext(radeonContextPtr radeon, const __GLcontextModes * glVisual, __DRIcontextPrivate * driContextPriv, void *sharedContextPrivate); +extern void radeonCleanupContext(radeonContextPtr radeon); extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv, __DRIdrawablePrivate * driDrawPriv, __DRIdrawablePrivate * driReadPriv); diff --git a/src/mesa/drivers/dri/r300/radeon_lock.c b/src/mesa/drivers/dri/r300/radeon_lock.c index 79b7c5ada2..4579bc4ac4 100644 --- a/src/mesa/drivers/dri/r300/radeon_lock.c +++ b/src/mesa/drivers/dri/r300/radeon_lock.c @@ -53,7 +53,7 @@ static void radeonUpdatePageFlipping(radeonContextPtr radeon) radeon->doPageFlip = radeon->sarea->pfState; - use_back = (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT); + use_back = (radeon->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT); use_back ^= (radeon->sarea->pfCurrentPage == 1); if (use_back) { @@ -82,7 +82,7 @@ static void r200RegainedLock(r200ContextPtr r200) r200->hw.ctx.cmd[CTX_RB3D_COLORPITCH] = r200->radeon.state.color.drawPitch; - if (r200->radeon.glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT) + if (r200->radeon.glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) radeonSetCliprects(&r200->radeon, GL_BACK_LEFT); else radeonSetCliprects(&r200->radeon, GL_FRONT_LEFT); @@ -102,14 +102,12 @@ static void r300RegainedLock(radeonContextPtr radeon) if (radeon->lastStamp != dPriv->lastStamp) { radeonUpdatePageFlipping(radeon); - if (radeon->glCtx->Color._DrawDestMask == DD_BACK_LEFT_BIT) + if (radeon->glCtx->Color._DrawDestMask[0] == DD_BACK_LEFT_BIT) radeonSetCliprects(radeon, GL_BACK_LEFT); else radeonSetCliprects(radeon, GL_FRONT_LEFT); -#if 0 - r200UpdateViewportOffset(r200->radeon.glCtx); -#endif + radeonUpdateScissor(radeon->glCtx); radeon->lastStamp = dPriv->lastStamp; } diff --git a/src/mesa/drivers/dri/r300/radeon_span.c b/src/mesa/drivers/dri/r300/radeon_span.c index 7b548754e6..93c4da9085 100644 --- a/src/mesa/drivers/dri/r300/radeon_span.c +++ b/src/mesa/drivers/dri/r300/radeon_span.c @@ -330,53 +330,46 @@ static void radeonSetBuffer(GLcontext * ctx, GLframebuffer * colorBuffer, GLuint bufferBit) { radeonContextPtr radeon = RADEON_CONTEXT(ctx); + int buffer; switch (bufferBit) { case DD_FRONT_LEFT_BIT: - if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) { - radeon->state.pixel.readOffset = - radeon->radeonScreen->backOffset; - radeon->state.pixel.readPitch = - radeon->radeonScreen->backPitch; - radeon->state.color.drawOffset = - radeon->radeonScreen->backOffset; - radeon->state.color.drawPitch = - radeon->radeonScreen->backPitch; - } else { - radeon->state.pixel.readOffset = - radeon->radeonScreen->frontOffset; - radeon->state.pixel.readPitch = - radeon->radeonScreen->frontPitch; - radeon->state.color.drawOffset = - radeon->radeonScreen->frontOffset; - radeon->state.color.drawPitch = - radeon->radeonScreen->frontPitch; - } + buffer = 0; break; + case DD_BACK_LEFT_BIT: - if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) { - radeon->state.pixel.readOffset = - radeon->radeonScreen->frontOffset; - radeon->state.pixel.readPitch = - radeon->radeonScreen->frontPitch; - radeon->state.color.drawOffset = - radeon->radeonScreen->frontOffset; - radeon->state.color.drawPitch = - radeon->radeonScreen->frontPitch; - } else { - radeon->state.pixel.readOffset = - radeon->radeonScreen->backOffset; - radeon->state.pixel.readPitch = - radeon->radeonScreen->backPitch; - radeon->state.color.drawOffset = - radeon->radeonScreen->backOffset; - radeon->state.color.drawPitch = - radeon->radeonScreen->backPitch; - } + buffer = 1; break; + default: _mesa_problem(ctx, "Bad bufferBit in %s", __FUNCTION__); - break; + return; + } + + if (radeon->doPageFlip && radeon->sarea->pfCurrentPage == 1) + buffer ^= 1; + + fprintf(stderr, "%s: using %s buffer\n", __FUNCTION__, + buffer ? "back" : "front"); + + if (buffer) { + radeon->state.pixel.readOffset = + radeon->radeonScreen->backOffset; + radeon->state.pixel.readPitch = + radeon->radeonScreen->backPitch; + radeon->state.color.drawOffset = + radeon->radeonScreen->backOffset; + radeon->state.color.drawPitch = + radeon->radeonScreen->backPitch; + } else { + radeon->state.pixel.readOffset = + radeon->radeonScreen->frontOffset; + radeon->state.pixel.readPitch = + radeon->radeonScreen->frontPitch; + radeon->state.color.drawOffset = + radeon->radeonScreen->frontOffset; + radeon->state.color.drawPitch = + radeon->radeonScreen->frontPitch; } } 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; +} diff --git a/src/mesa/drivers/dri/r300/radeon_state.h b/src/mesa/drivers/dri/r300/radeon_state.h index 8b2698d9bc..636bf5d008 100644 --- a/src/mesa/drivers/dri/r300/radeon_state.h +++ b/src/mesa/drivers/dri/r300/radeon_state.h @@ -1,9 +1,5 @@ /* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. +Copyright (C) 2004 Nicolai Haehnle. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -29,7 +25,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Keith Whitwell + * Nicolai Haehnle */ #ifndef __RADEON_STATE_H__ @@ -37,6 +33,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "radeon_context.h" +extern void radeonRecalcScissorRects(radeonContextPtr radeon); extern void radeonSetCliprects(radeonContextPtr radeon, GLenum mode); +extern void radeonUpdateScissor(GLcontext* ctx); + +extern void radeonEnable(GLcontext* ctx, GLenum cap, GLboolean state); + +extern void radeonInitState(radeonContextPtr radeon); +extern void radeonInitStateFuncs(struct dd_function_table* functions); #endif -- cgit v1.2.3