summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/r300/radeon_state.c
diff options
context:
space:
mode:
authorNicolai Haehnle <prefect_@gmx.net>2004-10-17 20:26:06 +0000
committerNicolai Haehnle <prefect_@gmx.net>2004-10-17 20:26:06 +0000
commitff42a00402deab3034163c2b76c2082cce39d901 (patch)
tree0c81aba24705d6643d0b888265270e494ce344ce /src/mesa/drivers/dri/r300/radeon_state.c
parent158a251a6b8ffa02387c767a00dc960b49098022 (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.c163
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;
+}