-/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.8 2002/12/16 16:18:58 dawes Exp $ */
/**************************************************************************
Copyright 2000, 2001 VA Linux Systems Inc., Fremont, California.
* Keith Whitwell <keith@tungstengraphics.com>
*/
-#include "glheader.h"
-#include "imports.h"
-#include "api_arrayelt.h"
-#include "enums.h"
-#include "colormac.h"
-#include "state.h"
-#include "buffers.h"
-#include "context.h"
+#include "main/glheader.h"
+#include "main/imports.h"
+#include "main/api_arrayelt.h"
+#include "main/enums.h"
+#include "main/light.h"
+#include "main/state.h"
+#include "main/context.h"
+#include "main/framebuffer.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
-#include "main/light.h"
#include "swrast_setup/swrast_setup.h"
#include "radeon_context.h"
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_swtcl.h"
-#include "radeon_vtxfmt.h"
#include "drirenderbuffer.h"
+static void radeonUpdateSpecular( GLcontext *ctx );
+
/* =============================================================
* Alpha blending
*/
if ( !fallback ) {
RADEON_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_RB3D_BLENDCNTL] = b;
- if ( ctx->Color._LogicOpEnabled ) {
+ if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
+ && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
} else {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
union { int i; float f; } c, d;
GLchan col[4];
- c.i = rmesa->hw.fog.cmd[FOG_C];
- d.i = rmesa->hw.fog.cmd[FOG_D];
-
switch (pname) {
case GL_FOG_MODE:
if (!ctx->Fog.Enabled)
switch (ctx->Fog.Mode) {
case GL_LINEAR:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_LINEAR;
- if (ctx->Fog.Start == ctx->Fog.End) {
- c.f = 1.0F;
- d.f = 1.0F;
- }
- else {
- c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
- d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
- }
break;
case GL_EXP:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP;
- c.f = 0.0;
- d.f = ctx->Fog.Density;
break;
case GL_EXP2:
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] |= RADEON_TCL_FOG_EXP2;
- c.f = 0.0;
- d.f = -(ctx->Fog.Density * ctx->Fog.Density);
break;
default:
return;
}
- break;
+ /* fallthrough */
case GL_FOG_DENSITY:
+ case GL_FOG_START:
+ case GL_FOG_END:
+ if (!ctx->Fog.Enabled)
+ return;
+ c.i = rmesa->hw.fog.cmd[FOG_C];
+ d.i = rmesa->hw.fog.cmd[FOG_D];
switch (ctx->Fog.Mode) {
case GL_EXP:
c.f = 0.0;
- d.f = ctx->Fog.Density;
+ /* While this is the opposite sign from the DDK, it makes the fog test
+ * pass, and matches r200.
+ */
+ d.f = -ctx->Fog.Density;
break;
case GL_EXP2:
c.f = 0.0;
d.f = -(ctx->Fog.Density * ctx->Fog.Density);
break;
- default:
- break;
- }
- break;
- case GL_FOG_START:
- case GL_FOG_END:
- if (ctx->Fog.Mode == GL_LINEAR) {
+ case GL_LINEAR:
if (ctx->Fog.Start == ctx->Fog.End) {
c.f = 1.0F;
d.f = 1.0F;
} else {
c.f = ctx->Fog.End/(ctx->Fog.End-ctx->Fog.Start);
- d.f = 1.0/(ctx->Fog.End-ctx->Fog.Start);
+ /* While this is the opposite sign from the DDK, it makes the fog
+ * test pass, and matches r200.
+ */
+ d.f = -1.0/(ctx->Fog.End-ctx->Fog.Start);
}
+ break;
+ default:
+ break;
+ }
+ if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
+ RADEON_STATECHANGE( rmesa, fog );
+ rmesa->hw.fog.cmd[FOG_C] = c.i;
+ rmesa->hw.fog.cmd[FOG_D] = d.i;
}
break;
case GL_FOG_COLOR:
RADEON_STATECHANGE( rmesa, ctx );
UNCLAMPED_FLOAT_TO_RGB_CHAN( col, ctx->Fog.Color );
- rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] =
+ rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] &= ~RADEON_FOG_COLOR_MASK;
+ rmesa->hw.ctx.cmd[CTX_PP_FOG_COLOR] |=
radeonPackColor( 4, col[0], col[1], col[2], 0 );
break;
- case GL_FOG_COORDINATE_SOURCE_EXT:
- /* What to do?
- */
+ case GL_FOG_COORD_SRC:
+ radeonUpdateSpecular( ctx );
break;
default:
return;
}
-
- if (c.i != rmesa->hw.fog.cmd[FOG_C] || d.i != rmesa->hw.fog.cmd[FOG_D]) {
- RADEON_STATECHANGE( rmesa, fog );
- rmesa->hw.fog.cmd[FOG_C] = c.i;
- rmesa->hw.fog.cmd[FOG_D] = d.i;
- }
}
GLfloat factor, GLfloat units )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLfloat constant = units * rmesa->state.depth.scale;
+ float_ui32_type constant = { units * rmesa->state.depth.scale };
+ float_ui32_type factoru = { factor };
RADEON_STATECHANGE( rmesa, zbs );
- rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = *(GLuint *)&factor;
- rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = *(GLuint *)&constant;
+ rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_FACTOR] = factoru.ui32;
+ rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
}
static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask )
static void radeonUpdateSpecular( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- u_int32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
+ uint32_t p = rmesa->hw.ctx.cmd[CTX_PP_CNTL];
+ GLuint flag = 0;
RADEON_STATECHANGE( rmesa, tcl );
}
if (ctx->Fog.Enabled) {
- rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_PK_SPEC;
-
- /* Bizzare: have to leave lighting enabled to get fog.
- */
- rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
+ if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH) {
+ rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] |= RADEON_TCL_COMPUTE_SPECULAR;
+ /* Bizzare: have to leave lighting enabled to get fog. */
+ rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] |= RADEON_LIGHTING_ENABLE;
+ }
+ else {
+ /* cannot do tcl fog factor calculation with fog coord source
+ * (send precomputed factors). Cannot use precomputed fog
+ * factors together with tcl spec light (need tcl fallback) */
+ flag = (rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] &
+ RADEON_TCL_COMPUTE_SPECULAR) != 0;
+ }
}
+
+ TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_FOGCOORDSPEC, flag);
if (NEED_SECONDARY_COLOR(ctx)) {
assert( (p & RADEON_SPECULAR_ENABLE) != 0 );
* Stencil
*/
-static void radeonStencilFunc( GLcontext *ctx, GLenum func,
- GLint ref, GLuint mask )
+static void
+radeonStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- GLuint refmask = ((ctx->Stencil.Ref[0] << RADEON_STENCIL_REF_SHIFT) |
- (ctx->Stencil.ValueMask[0] << RADEON_STENCIL_MASK_SHIFT));
+ GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << RADEON_STENCIL_REF_SHIFT) |
+ ((ctx->Stencil.ValueMask[0] & 0xff) << RADEON_STENCIL_MASK_SHIFT));
RADEON_STATECHANGE( rmesa, ctx );
RADEON_STATECHANGE( rmesa, msk );
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |= refmask;
}
-static void radeonStencilMask( GLcontext *ctx, GLuint mask )
+static void
+radeonStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
RADEON_STATECHANGE( rmesa, msk );
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] &= ~RADEON_STENCIL_WRITE_MASK;
rmesa->hw.msk.cmd[MSK_RB3D_STENCILREFMASK] |=
- (ctx->Stencil.WriteMask[0] << RADEON_STENCIL_WRITEMASK_SHIFT);
+ ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT);
}
-static void radeonStencilOp( GLcontext *ctx, GLenum fail,
- GLenum zfail, GLenum zpass )
+static void radeonStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
+ GLenum zfail, GLenum zpass )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
GLuint tempRADEON_STENCIL_ZPASS_DEC_WRAP;
GLuint tempRADEON_STENCIL_ZPASS_INC_WRAP;
- if (rmesa->radeonScreen->chipset & RADEON_CHIPSET_BROKEN_STENCIL) {
+ if (rmesa->radeonScreen->chip_flags & RADEON_CHIPSET_BROKEN_STENCIL) {
tempRADEON_STENCIL_FAIL_DEC_WRAP = RADEON_STENCIL_FAIL_DEC;
tempRADEON_STENCIL_FAIL_INC_WRAP = RADEON_STENCIL_FAIL_INC;
tempRADEON_STENCIL_ZFAIL_DEC_WRAP = RADEON_STENCIL_ZFAIL_DEC;
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
rmesa->state.stencil.clear =
- ((GLuint) ctx->Stencil.Clear |
+ ((GLuint) (ctx->Stencil.Clear & 0xff) |
(0xff << RADEON_STENCIL_MASK_SHIFT) |
- (ctx->Stencil.WriteMask[0] << RADEON_STENCIL_WRITEMASK_SHIFT));
+ ((ctx->Stencil.WriteMask[0] & 0xff) << RADEON_STENCIL_WRITEMASK_SHIFT));
}
GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
const GLfloat *v = ctx->Viewport._WindowMap.m;
- GLfloat sx = v[MAT_SX];
- GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
- GLfloat sy = - v[MAT_SY];
- GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
- GLfloat sz = v[MAT_SZ] * rmesa->state.depth.scale;
- GLfloat tz = v[MAT_TZ] * rmesa->state.depth.scale;
+ float_ui32_type sx = { v[MAT_SX] };
+ float_ui32_type tx = { v[MAT_TX] + xoffset + SUBPIXEL_X };
+ float_ui32_type sy = { - v[MAT_SY] };
+ float_ui32_type ty = { (- v[MAT_TY]) + yoffset + SUBPIXEL_Y };
+ float_ui32_type sz = { v[MAT_SZ] * rmesa->state.depth.scale };
+ float_ui32_type tz = { v[MAT_TZ] * rmesa->state.depth.scale };
+
RADEON_FIREVERTICES( rmesa );
RADEON_STATECHANGE( rmesa, vpt );
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = *(GLuint *)&sx;
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx;
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = *(GLuint *)&sy;
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty;
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = *(GLuint *)&sz;
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = *(GLuint *)&tz;
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_XSCALE] = sx.ui32;
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_YSCALE] = sy.ui32;
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZSCALE] = sz.ui32;
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
}
-
static void radeonViewport( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height )
{
- /* update size of Mesa/software ancillary buffers */
- _mesa_ResizeBuffersMESA();
/* Don't pipeline viewport changes, conflict with window offset
* setting below. Could apply deltas to rescue pipelined viewport
* values, or keep the originals hanging around.
*/
- RADEON_FIREVERTICES( RADEON_CONTEXT(ctx) );
radeonUpdateWindow( ctx );
}
GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h;
const GLfloat *v = ctx->Viewport._WindowMap.m;
- GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X;
- GLfloat ty = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
+ float_ui32_type tx;
+ float_ui32_type ty;
+
+ tx.f = v[MAT_TX] + xoffset + SUBPIXEL_X;
+ ty.f = (- v[MAT_TY]) + yoffset + SUBPIXEL_Y;
- if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != *(GLuint *)&tx ||
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != *(GLuint *)&ty )
+ if ( rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] != tx.ui32 ||
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] != ty.ui32 )
{
/* Note: this should also modify whatever data the context reset
* code uses...
*/
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = *(GLuint *)&tx;
- rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = *(GLuint *)&ty;
-
+ RADEON_STATECHANGE( rmesa, vpt );
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_XOFFSET] = tx.ui32;
+ rmesa->hw.vpt.cmd[VPT_SE_VPORT_YOFFSET] = ty.ui32;
+
/* update polygon stipple x/y screen offset */
{
GLuint stx, sty;
*/
void radeonSetCliprects( radeonContextPtr rmesa )
{
- __DRIdrawablePrivate *dPriv = rmesa->dri.drawable;
+ __DRIdrawablePrivate *const drawable = rmesa->dri.drawable;
+ __DRIdrawablePrivate *const readable = rmesa->dri.readable;
+ GLframebuffer *const draw_fb = (GLframebuffer*) drawable->driverPrivate;
+ GLframebuffer *const read_fb = (GLframebuffer*) readable->driverPrivate;
- if (rmesa->glCtx->DrawBuffer->_ColorDrawBufferMask[0]
- == BUFFER_BIT_BACK_LEFT) {
+ if (draw_fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
/* Can't ignore 2d windows if we are page flipping.
*/
- if ( dPriv->numBackClipRects == 0 || rmesa->doPageFlip ) {
- rmesa->numClipRects = dPriv->numClipRects;
- rmesa->pClipRects = dPriv->pClipRects;
+ if ( drawable->numBackClipRects == 0 || rmesa->doPageFlip ) {
+ rmesa->numClipRects = drawable->numClipRects;
+ rmesa->pClipRects = drawable->pClipRects;
}
else {
- rmesa->numClipRects = dPriv->numBackClipRects;
- rmesa->pClipRects = dPriv->pBackClipRects;
+ rmesa->numClipRects = drawable->numBackClipRects;
+ rmesa->pClipRects = drawable->pBackClipRects;
}
}
else {
/* front buffer (or none, or multiple buffers */
- rmesa->numClipRects = dPriv->numClipRects;
- rmesa->pClipRects = dPriv->pClipRects;
+ rmesa->numClipRects = drawable->numClipRects;
+ rmesa->pClipRects = drawable->pClipRects;
+ }
+
+ if ((draw_fb->Width != drawable->w) || (draw_fb->Height != drawable->h)) {
+ _mesa_resize_framebuffer(rmesa->glCtx, draw_fb,
+ drawable->w, drawable->h);
+ draw_fb->Initialized = GL_TRUE;
+ }
+
+ if (drawable != readable) {
+ if ((read_fb->Width != readable->w) || (read_fb->Height != readable->h)) {
+ _mesa_resize_framebuffer(rmesa->glCtx, read_fb,
+ readable->w, readable->h);
+ read_fb->Initialized = GL_TRUE;
+ }
}
if (rmesa->state.scissor.enabled)
radeonRecalcScissorRects( rmesa );
+
+ rmesa->lastStamp = drawable->lastStamp;
}
RADEON_FIREVERTICES(rmesa); /* don't pipeline cliprect changes */
- /*
- * _ColorDrawBufferMask is easier to cope with than <mode>.
- * Check for software fallback, update cliprects.
- */
- switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) {
- case BUFFER_BIT_FRONT_LEFT:
- case BUFFER_BIT_BACK_LEFT:
+ if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
+ /* 0 (GL_NONE) buffers or multiple color drawing buffers */
+ FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ return;
+ }
+
+ switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
+ case BUFFER_FRONT_LEFT:
+ case BUFFER_BACK_LEFT:
FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
default:
- /* 0 (GL_NONE) buffers or multiple color drawing buffers */
FALLBACK( rmesa, RADEON_FALLBACK_DRAW_BUFFER, GL_TRUE );
return;
}
} else {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ALPHA_BLEND_ENABLE;
}
- if ( ctx->Color._LogicOpEnabled ) {
+ if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
+ && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
} else {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
rmesa->hw.tcl.cmd[TCL_UCP_VERT_BLEND_CTL] &= ~RADEON_TCL_FOG_MASK;
}
radeonUpdateSpecular( ctx ); /* for PK_SPEC */
- if (rmesa->TclFallback)
- radeonChooseVertexState( ctx );
_mesa_allow_light_in_model( ctx, !state );
break;
case GL_COLOR_LOGIC_OP:
RADEON_STATECHANGE( rmesa, ctx );
- if ( ctx->Color._LogicOpEnabled ) {
+ if ( (ctx->Color.ColorLogicOpEnabled || (ctx->Color.BlendEnabled
+ && ctx->Color.BlendEquationRGB == GL_LOGIC_OP)) ) {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] |= RADEON_ROP_ENABLE;
} else {
rmesa->hw.ctx.cmd[CTX_RB3D_CNTL] &= ~RADEON_ROP_ENABLE;
break;
case GL_POLYGON_OFFSET_POINT:
- if (rmesa->dri.drmMinor == 1) {
- radeonChooseRenderState( ctx );
- }
- else {
- RADEON_STATECHANGE( rmesa, set );
- if ( state ) {
- rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
- } else {
- rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
- }
+ RADEON_STATECHANGE( rmesa, set );
+ if ( state ) {
+ rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_POINT;
+ } else {
+ rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_POINT;
}
break;
case GL_POLYGON_OFFSET_LINE:
- if (rmesa->dri.drmMinor == 1) {
- radeonChooseRenderState( ctx );
- }
- else {
- RADEON_STATECHANGE( rmesa, set );
- if ( state ) {
- rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
- } else {
- rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
- }
+ RADEON_STATECHANGE( rmesa, set );
+ if ( state ) {
+ rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_LINE;
+ } else {
+ rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_LINE;
}
break;
case GL_POLYGON_OFFSET_FILL:
- if (rmesa->dri.drmMinor == 1) {
- radeonChooseRenderState( ctx );
- }
- else {
- RADEON_STATECHANGE( rmesa, set );
- if ( state ) {
- rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
- } else {
- rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
- }
+ RADEON_STATECHANGE( rmesa, set );
+ if ( state ) {
+ rmesa->hw.set.cmd[SET_SE_CNTL] |= RADEON_ZBIAS_ENABLE_TRI;
+ } else {
+ rmesa->hw.set.cmd[SET_SE_CNTL] &= ~RADEON_ZBIAS_ENABLE_TRI;
}
break;
*/
+void radeonUploadTexMatrix( radeonContextPtr rmesa,
+ int unit, GLboolean swapcols )
+{
+/* Here's how this works: on r100, only 3 tex coords can be submitted, so the
+ vector looks like this probably: (s t r|q 0) (not sure if the last coord
+ is hardwired to 0, could be 1 too). Interestingly, it actually looks like
+ texgen generates all 4 coords, at least tests with projtex indicated that.
+ So: if we need the q coord in the end (solely determined by the texture
+ target, i.e. 2d / 1d / texrect targets) we swap the third and 4th row.
+ Additionally, if we don't have texgen but 4 tex coords submitted, we swap
+ column 3 and 4 (for the 2d / 1d / texrect targets) since the the q coord
+ will get submitted in the "wrong", i.e. 3rd, slot.
+ If an app submits 3 coords for 2d targets, we assume it is saving on vertex
+ size and using the texture matrix to swap the r and q coords around (ut2k3
+ does exactly that), so we don't need the 3rd / 4th column swap - still need
+ the 3rd / 4th row swap of course. This will potentially break for apps which
+ use TexCoord3x just for fun. Additionally, it will never work if an app uses
+ an "advanced" texture matrix and relies on all 4 texcoord inputs to generate
+ the maximum needed 3. This seems impossible to do with hw tcl on r100, and
+ incredibly hard to detect so we can't just fallback in such a case. Assume
+ it never happens... - rs
+*/
+
+ int idx = TEXMAT_0 + unit;
+ float *dest = ((float *)RADEON_DB_STATE( mat[idx] )) + MAT_ELT_0;
+ int i;
+ struct gl_texture_unit tUnit = rmesa->glCtx->Texture.Unit[unit];
+ GLfloat *src = rmesa->tmpmat[unit].m;
+
+ rmesa->TexMatColSwap &= ~(1 << unit);
+ if ((tUnit._ReallyEnabled & (TEXTURE_3D_BIT | TEXTURE_CUBE_BIT)) == 0) {
+ if (swapcols) {
+ rmesa->TexMatColSwap |= 1 << unit;
+ /* attention some elems are swapped 2 times! */
+ *dest++ = src[0];
+ *dest++ = src[4];
+ *dest++ = src[12];
+ *dest++ = src[8];
+ *dest++ = src[1];
+ *dest++ = src[5];
+ *dest++ = src[13];
+ *dest++ = src[9];
+ *dest++ = src[2];
+ *dest++ = src[6];
+ *dest++ = src[15];
+ *dest++ = src[11];
+ /* those last 4 are probably never used */
+ *dest++ = src[3];
+ *dest++ = src[7];
+ *dest++ = src[14];
+ *dest++ = src[10];
+ }
+ else {
+ for (i = 0; i < 2; i++) {
+ *dest++ = src[i];
+ *dest++ = src[i+4];
+ *dest++ = src[i+8];
+ *dest++ = src[i+12];
+ }
+ for (i = 3; i >= 2; i--) {
+ *dest++ = src[i];
+ *dest++ = src[i+4];
+ *dest++ = src[i+8];
+ *dest++ = src[i+12];
+ }
+ }
+ }
+ else {
+ for (i = 0 ; i < 4 ; i++) {
+ *dest++ = src[i];
+ *dest++ = src[i+4];
+ *dest++ = src[i+8];
+ *dest++ = src[i+12];
+ }
+ }
+
+ RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.mat[idx] );
+}
static void upload_matrix( radeonContextPtr rmesa, GLfloat *src, int idx )
GLuint tpc = rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL];
GLuint vs = rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL];
int unit;
-
- rmesa->TexMatEnabled = 0;
-
- for (unit = 0 ; unit < 2; unit++) {
- if (!ctx->Texture.Unit[unit]._ReallyEnabled) {
- }
- else if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
- GLuint inputshift = RADEON_TEXGEN_0_INPUT_SHIFT + unit*4;
-
- rmesa->TexMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE|
- RADEON_TEXMAT_0_ENABLE) << unit;
-
- if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
- /* Need to preconcatenate any active texgen
- * obj/eyeplane matrices:
- */
- _math_matrix_mul_matrix( &rmesa->tmpmat,
- &rmesa->TexGenMatrix[unit],
- ctx->TextureMatrixStack[unit].Top );
- upload_matrix( rmesa, rmesa->tmpmat.m, TEXMAT_0+unit );
- }
- else {
- rmesa->TexMatEnabled |=
- (RADEON_TEXGEN_INPUT_TEXCOORD_0+unit) << inputshift;
- upload_matrix( rmesa, ctx->TextureMatrixStack[unit].Top->m,
- TEXMAT_0+unit );
+ GLuint texMatEnabled = 0;
+ rmesa->NeedTexMatrix = 0;
+ rmesa->TexMatColSwap = 0;
+
+ for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++) {
+ if (ctx->Texture.Unit[unit]._ReallyEnabled) {
+ GLboolean needMatrix = GL_FALSE;
+ if (ctx->TextureMatrixStack[unit].Top->type != MATRIX_IDENTITY) {
+ needMatrix = GL_TRUE;
+ texMatEnabled |= (RADEON_TEXGEN_TEXMAT_0_ENABLE |
+ RADEON_TEXMAT_0_ENABLE) << unit;
+
+ if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
+ /* Need to preconcatenate any active texgen
+ * obj/eyeplane matrices:
+ */
+ _math_matrix_mul_matrix( &rmesa->tmpmat[unit],
+ ctx->TextureMatrixStack[unit].Top,
+ &rmesa->TexGenMatrix[unit] );
+ }
+ else {
+ _math_matrix_copy( &rmesa->tmpmat[unit],
+ ctx->TextureMatrixStack[unit].Top );
+ }
+ }
+ else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
+ _math_matrix_copy( &rmesa->tmpmat[unit], &rmesa->TexGenMatrix[unit] );
+ needMatrix = GL_TRUE;
+ }
+ if (needMatrix) {
+ rmesa->NeedTexMatrix |= 1 << unit;
+ radeonUploadTexMatrix( rmesa, unit,
+ !ctx->Texture.Unit[unit].TexGenEnabled );
}
- }
- else if (rmesa->TexGenEnabled & (RADEON_TEXMAT_0_ENABLE << unit)) {
- upload_matrix( rmesa, rmesa->TexGenMatrix[unit].m,
- TEXMAT_0+unit );
}
}
+ tpc = (texMatEnabled | rmesa->TexGenEnabled);
- tpc = (rmesa->TexMatEnabled | rmesa->TexGenEnabled);
-
- vs &= ~((0xf << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
- (0xf << RADEON_TCL_TEX_1_OUTPUT_SHIFT));
-
- if (tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE)
- vs |= RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
- else
- vs |= RADEON_TCL_TEX_INPUT_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT;
+ /* TCL_TEX_COMPUTED_x is TCL_TEX_INPUT_x | 0x8 */
+ vs &= ~((RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_0_OUTPUT_SHIFT) |
+ (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_1_OUTPUT_SHIFT) |
+ (RADEON_TCL_TEX_COMPUTED_TEX_0 << RADEON_TCL_TEX_2_OUTPUT_SHIFT));
- if (tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE)
- vs |= RADEON_TCL_TEX_COMPUTED_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
- else
- vs |= RADEON_TCL_TEX_INPUT_TEX_1 << RADEON_TCL_TEX_1_OUTPUT_SHIFT;
+ vs |= (((tpc & RADEON_TEXGEN_TEXMAT_0_ENABLE) <<
+ (RADEON_TCL_TEX_0_OUTPUT_SHIFT + 3)) |
+ ((tpc & RADEON_TEXGEN_TEXMAT_1_ENABLE) <<
+ (RADEON_TCL_TEX_1_OUTPUT_SHIFT + 2)) |
+ ((tpc & RADEON_TEXGEN_TEXMAT_2_ENABLE) <<
+ (RADEON_TCL_TEX_2_OUTPUT_SHIFT + 1)));
if (tpc != rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] ||
vs != rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL]) {
-
+
RADEON_STATECHANGE(rmesa, tcl);
rmesa->hw.tcl.cmd[TCL_TEXTURE_PROC_CTL] = tpc;
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXSEL] = vs;
struct gl_framebuffer *fb = ctx->DrawBuffer;
driRenderbuffer *drb;
- if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT) {
+ if (fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT) {
/* draw to front */
drb = (driRenderbuffer *) fb->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
}
- else if (fb->_ColorDrawBufferMask[0] == BUFFER_BIT_BACK_LEFT) {
+ else if (fb->_ColorDrawBufferIndexes[0] == BUFFER_BACK_LEFT) {
/* draw to back */
drb = (driRenderbuffer *) fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer;
}
*/
if (new_state & _NEW_TEXTURE_MATRIX) {
update_texturematrix( ctx );
- }
+ }
if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW|_MESA_NEW_NEED_EYE_COORDS)) {
update_light( ctx );
{
_swrast_InvalidateState( ctx, new_state );
_swsetup_InvalidateState( ctx, new_state );
- _ac_InvalidateState( ctx, new_state );
+ _vbo_InvalidateState( ctx, new_state );
_tnl_InvalidateState( ctx, new_state );
_ae_invalidate_state( ctx, new_state );
RADEON_CONTEXT(ctx)->NewGLState |= new_state;
- radeonVtxfmtInvalidate( ctx );
}
ctx->Driver.LineWidth = radeonLineWidth;
ctx->Driver.LogicOpcode = radeonLogicOpCode;
ctx->Driver.PolygonMode = radeonPolygonMode;
-
- if (RADEON_CONTEXT(ctx)->dri.drmMinor > 1)
- ctx->Driver.PolygonOffset = radeonPolygonOffset;
-
+ ctx->Driver.PolygonOffset = radeonPolygonOffset;
ctx->Driver.PolygonStipple = radeonPolygonStipple;
ctx->Driver.RenderMode = radeonRenderMode;
ctx->Driver.Scissor = radeonScissor;
ctx->Driver.ShadeModel = radeonShadeModel;
- ctx->Driver.StencilFunc = radeonStencilFunc;
- ctx->Driver.StencilMask = radeonStencilMask;
- ctx->Driver.StencilOp = radeonStencilOp;
+ ctx->Driver.StencilFuncSeparate = radeonStencilFuncSeparate;
+ ctx->Driver.StencilMaskSeparate = radeonStencilMaskSeparate;
+ ctx->Driver.StencilOpSeparate = radeonStencilOpSeparate;
ctx->Driver.Viewport = radeonViewport;
TNL_CONTEXT(ctx)->Driver.NotifyMaterialChange = radeonUpdateMaterial;