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 */
*/
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;
extern void r200UpdateMaterial(GLcontext * ctx);
-extern void r200RecalcScissorRects(r200ContextPtr rmesa);
extern void r200UpdateViewportOffset(GLcontext * ctx);
extern void r200UpdateWindow(GLcontext * ctx);
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,
assert(screen);
/* Allocate the R300 context */
- r300 = (r300ContextPtr) CALLOC(sizeof(*r300));
+ r300 = (r300ContextPtr)CALLOC(sizeof(*r300));
if (!r300)
return GL_FALSE;
*/
_mesa_init_driver_functions(&functions);
r300InitIoctlFuncs(&functions);
- //r200InitStateFuncs(&functions);
+ r300InitStateFuncs(&functions);
//r200InitTextureFuncs(&functions);
if (!radeonInitContext(&r300->radeon, &functions,
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);
#include "glheader.h"
#include "state.h"
#include "imports.h"
+#include "enums.h"
#include "macros.h"
#include "context.h"
#include "dd.h"
#include "tnl/tnl.h"
#include "radeon_ioctl.h"
+#include "radeon_state.h"
#include "r300_context.h"
#include "r300_ioctl.h"
#include "r300_state.h"
#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.
*/
}
+
/**
* Calculate initial hardware state and register state functions.
* Assumes that the command buffer and state atoms have been
*/
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;
}
} while(0)
extern void r300ResetHwState(r300ContextPtr r300);
+
extern void r300InitState(r300ContextPtr r300);
+extern void r300InitStateFuncs(struct dd_function_table* functions);
#endif /* __R300_STATE_H__ */
}
+/**
+ * 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.
*/
/**
* 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;
struct radeon_state {
struct radeon_colorbuffer_state color;
struct radeon_pixel_state pixel;
+ struct radeon_scissor_state scissor;
};
/**
const __GLcontextModes * glVisual,
__DRIcontextPrivate * driContextPriv,
void *sharedContextPrivate);
+extern void radeonCleanupContext(radeonContextPtr radeon);
extern GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
__DRIdrawablePrivate * driDrawPriv,
__DRIdrawablePrivate * driReadPriv);
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) {
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);
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;
}
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;
}
}
#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);
+ }
+}
/**
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;
+}
/*
-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
/*
* Authors:
- * Keith Whitwell <keith@tungstengraphics.com>
+ * Nicolai Haehnle <prefect_@gmx.net>
*/
#ifndef __RADEON_STATE_H__
#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