* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */
/*
+ * New fixes:
+ * Daniel Borca <dborca@users.sourceforge.net>, 19 Jul 2004
+ *
* Original rewrite:
* Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
*
*
*/
-#include "mtypes.h"
-#include "colormac.h"
-#include "texformat.h"
-#include "texstore.h"
-#include "teximage.h"
+#include "main/mtypes.h"
+#include "main/colormac.h"
+#include "main/texstore.h"
+#include "main/teximage.h"
#include "swrast/swrast.h"
-#include "array_cache/acache.h"
+#include "vbo/vbo.h"
#include "tnl/tnl.h"
#include "tnl/t_pipeline.h"
#include "swrast_setup/swrast_setup.h"
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
GrCmpFnc_t func;
GrAlphaBlendFnc_t srcRGB, dstRGB, srcA, dstA;
+ GrAlphaBlendOp_t eqRGB, eqA;
GrAlpha_t ref = (GLint) (ctx->Color.AlphaRef * 255.0);
+
+ GLboolean isNapalm = TDFX_IS_NAPALM(fxMesa);
+ GLboolean have32bpp = (ctx->Visual.greenBits == 8);
+ GLboolean haveAlpha = fxMesa->haveHwAlpha;
if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) {
fprintf( stderr, "%s()\n", __FUNCTION__ );
}
if ( ctx->Color.AlphaEnabled ) {
- switch ( ctx->Color.AlphaFunc ) {
- case GL_NEVER:
- func = GR_CMP_NEVER;
- break;
- case GL_LESS:
- func = GR_CMP_LESS;
- break;
- case GL_LEQUAL:
- func = GR_CMP_LEQUAL;
- break;
- case GL_EQUAL:
- func = GR_CMP_EQUAL;
- break;
- case GL_GEQUAL:
- func = GR_CMP_GEQUAL;
- break;
- case GL_GREATER:
- func = GR_CMP_GREATER;
- break;
- case GL_NOTEQUAL:
- func = GR_CMP_NOTEQUAL;
- break;
- case GL_ALWAYS:
- default:
- func = GR_CMP_ALWAYS;
- break;
- }
+ func = ctx->Color.AlphaFunc - GL_NEVER + GR_CMP_NEVER;
} else {
func = GR_CMP_ALWAYS;
}
srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
- srcRGB = GR_BLEND_DST_ALPHA;
+ srcRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
break;
case GL_ONE_MINUS_DST_ALPHA:
- srcRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
+ srcRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
break;
case GL_SRC_ALPHA_SATURATE:
srcRGB = GR_BLEND_ALPHA_SATURATE;
break;
+ case GL_SRC_COLOR:
+ if (isNapalm) {
+ srcRGB = GR_BLEND_SAME_COLOR_EXT;
+ break;
+ }
+ case GL_ONE_MINUS_SRC_COLOR:
+ if (isNapalm) {
+ srcRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
+ break;
+ }
default:
srcRGB = GR_BLEND_ONE;
}
case GL_ONE:
srcA = GR_BLEND_ONE;
break;
- case GL_DST_COLOR:
- srcA = GR_BLEND_DST_ALPHA; /* Napalm only */
- break;
- case GL_ONE_MINUS_DST_COLOR:
- srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */
- break;
+ case GL_SRC_COLOR:
case GL_SRC_ALPHA:
- srcA = GR_BLEND_SRC_ALPHA; /* Napalm only */
+ srcA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/;
break;
+ case GL_ONE_MINUS_SRC_COLOR:
case GL_ONE_MINUS_SRC_ALPHA:
- srcA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */
+ srcA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/;
break;
+ case GL_DST_COLOR:
case GL_DST_ALPHA:
- srcA = GR_BLEND_DST_ALPHA; /* Napalm only */
+ srcA = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
break;
+ case GL_ONE_MINUS_DST_COLOR:
case GL_ONE_MINUS_DST_ALPHA:
- srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */
+ srcA = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
break;
case GL_SRC_ALPHA_SATURATE:
srcA = GR_BLEND_ONE;
dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA;
break;
case GL_DST_ALPHA:
- dstRGB = GR_BLEND_DST_ALPHA;
+ dstRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
break;
case GL_ONE_MINUS_DST_ALPHA:
- dstRGB = GR_BLEND_ONE_MINUS_DST_ALPHA;
+ dstRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
break;
+ case GL_DST_COLOR:
+ if (isNapalm) {
+ dstRGB = GR_BLEND_SAME_COLOR_EXT;
+ break;
+ }
+ case GL_ONE_MINUS_DST_COLOR:
+ if (isNapalm) {
+ dstRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT;
+ break;
+ }
default:
dstRGB = GR_BLEND_ZERO;
}
dstA = GR_BLEND_ONE;
break;
case GL_SRC_COLOR:
- dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */
- break;
- case GL_ONE_MINUS_SRC_COLOR:
- dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */
- break;
case GL_SRC_ALPHA:
- dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */
+ dstA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/;
break;
+ case GL_ONE_MINUS_SRC_COLOR:
case GL_ONE_MINUS_SRC_ALPHA:
- dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */
+ dstA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/;
break;
+ case GL_DST_COLOR:
case GL_DST_ALPHA:
- dstA = GR_BLEND_DST_ALPHA; /* Napalm only */
+ dstA = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/;
break;
+ case GL_ONE_MINUS_DST_COLOR:
case GL_ONE_MINUS_DST_ALPHA:
- dstA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */
+ dstA = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/;
break;
default:
dstA = GR_BLEND_ZERO;
}
+
+ switch ( ctx->Color.BlendEquationRGB ) {
+ case GL_FUNC_SUBTRACT:
+ eqRGB = GR_BLEND_OP_SUB;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqRGB = GR_BLEND_OP_REVSUB;
+ break;
+ case GL_FUNC_ADD:
+ default:
+ eqRGB = GR_BLEND_OP_ADD;
+ break;
+ }
+
+ switch ( ctx->Color.BlendEquationA ) {
+ case GL_FUNC_SUBTRACT:
+ eqA = GR_BLEND_OP_SUB;
+ break;
+ case GL_FUNC_REVERSE_SUBTRACT:
+ eqA = GR_BLEND_OP_REVSUB;
+ break;
+ case GL_FUNC_ADD:
+ default:
+ eqA = GR_BLEND_OP_ADD;
+ break;
+ }
} else {
/* blend disabled */
srcRGB = GR_BLEND_ONE;
dstRGB = GR_BLEND_ZERO;
+ eqRGB = GR_BLEND_OP_ADD;
srcA = GR_BLEND_ONE;
dstA = GR_BLEND_ZERO;
+ eqA = GR_BLEND_OP_ADD;
}
if ( fxMesa->Color.AlphaFunc != func ) {
if ( fxMesa->Color.BlendSrcRGB != srcRGB ||
fxMesa->Color.BlendDstRGB != dstRGB ||
+ fxMesa->Color.BlendEqRGB != eqRGB ||
fxMesa->Color.BlendSrcA != srcA ||
- fxMesa->Color.BlendDstA != dstA )
+ fxMesa->Color.BlendDstA != dstA ||
+ fxMesa->Color.BlendEqA != eqA )
{
fxMesa->Color.BlendSrcRGB = srcRGB;
fxMesa->Color.BlendDstRGB = dstRGB;
+ fxMesa->Color.BlendEqRGB = eqRGB;
fxMesa->Color.BlendSrcA = srcA;
fxMesa->Color.BlendDstA = dstA;
+ fxMesa->Color.BlendEqA = eqA;
fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC;
}
}
bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE);
if ( ctx->Depth.Test ) {
- switch ( ctx->Depth.Func ) {
- case GL_NEVER:
- func = GR_CMP_NEVER;
- break;
- case GL_LESS:
- func = GR_CMP_LESS;
- break;
- case GL_LEQUAL:
- func = GR_CMP_LEQUAL;
- break;
- case GL_EQUAL:
- func = GR_CMP_EQUAL;
- break;
- case GL_GEQUAL:
- func = GR_CMP_GEQUAL;
- break;
- case GL_GREATER:
- func = GR_CMP_GREATER;
- break;
- case GL_NOTEQUAL:
- func = GR_CMP_NOTEQUAL;
- break;
- case GL_ALWAYS:
- default:
- func = GR_CMP_ALWAYS;
- break;
- }
-
- if ( ctx->Depth.Mask ) {
- mask = FXTRUE;
- }
- else {
- mask = FXFALSE;
- }
+ func = ctx->Depth.Func - GL_NEVER + GR_CMP_NEVER;
+ mask = ctx->Depth.Mask;
}
else {
/* depth testing disabled */
mask = FXFALSE; /* zbuffer is not touched */
}
- fxMesa->Depth.Clear = (FxU32) (((1 << fxMesa->glCtx->Visual.depthBits) - 1)
- * ctx->Depth.Clear);
+ fxMesa->Depth.Clear = (FxU32) (ctx->DrawBuffer->_DepthMaxF * ctx->Depth.Clear);
if ( fxMesa->Depth.Bias != bias ) {
fxMesa->Depth.Bias = bias;
}
if (fxMesa->haveHwStencil) {
- if (ctx->Stencil.Enabled) {
- fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER;
- fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0];
- fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0];
- fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0];
+ if (ctx->Stencil._Enabled) {
+ fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER + GR_CMP_NEVER;
+ fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0] & 0xff;
+ fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0] & 0xff;
+ fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0] & 0xff;
fxMesa->Stencil.FailFunc = convertGLStencilOp(ctx->Stencil.FailFunc[0]);
fxMesa->Stencil.ZFailFunc = convertGLStencilOp(ctx->Stencil.ZFailFunc[0]);
fxMesa->Stencil.ZPassFunc = convertGLStencilOp(ctx->Stencil.ZPassFunc[0]);
}
-static void tdfxDDStencilFunc( GLcontext *ctx, GLenum func,
- GLint ref, GLuint mask )
+static void
+tdfxDDStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
+ GLint ref, GLuint mask )
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
fxMesa->new_state |= TDFX_NEW_STENCIL;
}
-static void tdfxDDStencilMask( GLcontext *ctx, GLuint mask )
+static void
+tdfxDDStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
fxMesa->new_state |= TDFX_NEW_STENCIL;
}
-static void tdfxDDStencilOp( GLcontext *ctx, GLenum sfail,
- GLenum zfail, GLenum zpass )
+static void
+tdfxDDStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum sfail,
+ GLenum zfail, GLenum zpass )
{
tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx);
}
if ( ctx->Fog.Enabled ) {
- mode = GR_FOG_WITH_TABLE_ON_Q;
+ if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) {
+ mode = GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT;
+ } else {
+ mode = GR_FOG_WITH_TABLE_ON_Q;
+ }
} else {
mode = GR_FOG_DISABLE;
}
if ( fxMesa->Fog.Mode != mode ) {
fxMesa->Fog.Mode = mode;
fxMesa->dirty |= TDFX_UPLOAD_FOG_MODE;
+ fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT;/*JJJ*/
}
if ( fxMesa->Fog.Color != color ) {
fxMesa->Fog.Color = color;
FLUSH_BATCH( fxMesa );
fxMesa->new_state |= TDFX_NEW_FOG;
+
+ switch (pname) {
+ case GL_FOG_COORDINATE_SOURCE_EXT: {
+ GLenum p = (GLenum)*param;
+ if (p == GL_FOG_COORDINATE_EXT) {
+ _swrast_allow_vertex_fog(ctx, GL_TRUE);
+ _swrast_allow_pixel_fog(ctx, GL_FALSE);
+ _tnl_allow_vertex_fog( ctx, GL_TRUE);
+ _tnl_allow_pixel_fog( ctx, GL_FALSE);
+ } else {
+ _swrast_allow_vertex_fog(ctx, GL_FALSE);
+ _swrast_allow_pixel_fog(ctx, GL_TRUE);
+ _tnl_allow_vertex_fog( ctx, GL_FALSE);
+ _tnl_allow_pixel_fog( ctx, GL_TRUE);
+ }
+ break;
+ }
+ default:
+ ;
+ }
}
* Clipping
*/
-static int intersect_rect( XF86DRIClipRectPtr out,
- const XF86DRIClipRectPtr a,
- const XF86DRIClipRectPtr b)
+static int intersect_rect( drm_clip_rect_t *out,
+ const drm_clip_rect_t *a,
+ const drm_clip_rect_t *b)
{
*out = *a;
if (b->x1 > out->x1) out->x1 = b->x1;
/* intersect OpenGL scissor box with all cliprects to make a new
* list of cliprects.
*/
- XF86DRIClipRectRec scissor;
+ drm_clip_rect_t scissor;
int x1 = ctx->Scissor.X + fxMesa->x_offset;
int y1 = fxMesa->screen_height - fxMesa->y_delta
- ctx->Scissor.Y - ctx->Scissor.Height;
assert(scissor.y2 >= scissor.y1);
fxMesa->pClipRects = malloc(dPriv->numClipRects
- * sizeof(XF86DRIClipRectRec));
+ * sizeof(drm_clip_rect_t));
if (fxMesa->pClipRects) {
int i;
fxMesa->numClipRects = 0;
fxMesa->new_state |= TDFX_NEW_ALPHA;
FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP,
(ctx->Color.ColorLogicOpEnabled &&
- ctx->Color.LogicOp != GL_COPY));
+ ctx->Color.LogicOp != GL_COPY)/*JJJ - more blending*/);
break;
case GL_CULL_FACE:
case GL_STENCIL_TEST:
FLUSH_BATCH( fxMesa );
FALLBACK( fxMesa, TDFX_FALLBACK_STENCIL, state && !fxMesa->haveHwStencil);
+ fxMesa->new_state |= TDFX_NEW_STENCIL;
break;
- case GL_TEXTURE_1D:
case GL_TEXTURE_3D:
FLUSH_BATCH( fxMesa );
- FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_1D_3D, state); /* wrong */
+ FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_MAP, state); /* wrong */
fxMesa->new_state |= TDFX_NEW_TEXTURE;
break;
+ case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
FLUSH_BATCH( fxMesa );
fxMesa->new_state |= TDFX_NEW_TEXTURE;
FLUSH_BATCH( fxMesa );
- /*
- * _DrawDestMask is easier to cope with than <mode>.
- */
- switch ( ctx->Color._DrawDestMask ) {
- case FRONT_LEFT_BIT:
+ if (ctx->DrawBuffer->_NumColorDrawBuffers > 1) {
+ FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE );
+ return;
+ }
+
+ switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
+ case BUFFER_FRONT_LEFT:
fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_FRONTBUFFER;
fxMesa->new_state |= TDFX_NEW_RENDER;
FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
- case BACK_LEFT_BIT:
+ case BUFFER_BACK_LEFT:
fxMesa->DrawBuffer = fxMesa->ReadBuffer = GR_BUFFER_BACKBUFFER;
fxMesa->new_state |= TDFX_NEW_RENDER;
FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
- case 0:
+ case -1:
FX_grColorMaskv( ctx, false4 );
FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_FALSE );
break;
FALLBACK( fxMesa, TDFX_FALLBACK_DRAW_BUFFER, GL_TRUE );
break;
}
-
- /* We want to update the s/w rast state too so that tdfxDDSetBuffer()
- * gets called.
- */
- _swrast_DrawBuffer(ctx, mode);
}
{
_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 );
TDFX_CONTEXT(ctx)->new_gl_state |= new_state;
}
ctx->Driver.UpdateState = tdfxDDInvalidateState;
-
- /* State notification callbacks:
- */
ctx->Driver.ClearColor = tdfxDDClearColor;
ctx->Driver.DrawBuffer = tdfxDDDrawBuffer;
ctx->Driver.ReadBuffer = tdfxDDReadBuffer;
- ctx->Driver.ColorMask = tdfxDDColorMask;
-
ctx->Driver.AlphaFunc = tdfxDDAlphaFunc;
ctx->Driver.BlendEquationSeparate = tdfxDDBlendEquationSeparate;
ctx->Driver.BlendFuncSeparate = tdfxDDBlendFuncSeparate;
ctx->Driver.ClearDepth = tdfxDDClearDepth;
+ ctx->Driver.ColorMask = tdfxDDColorMask;
ctx->Driver.CullFace = tdfxDDCullFace;
ctx->Driver.FrontFace = tdfxDDFrontFace;
ctx->Driver.DepthFunc = tdfxDDDepthFunc;
ctx->Driver.ShadeModel = tdfxDDShadeModel;
if ( fxMesa->haveHwStencil ) {
- ctx->Driver.StencilFunc = tdfxDDStencilFunc;
- ctx->Driver.StencilMask = tdfxDDStencilMask;
- ctx->Driver.StencilOp = tdfxDDStencilOp;
+ ctx->Driver.StencilFuncSeparate = tdfxDDStencilFuncSeparate;
+ ctx->Driver.StencilMaskSeparate = tdfxDDStencilMaskSeparate;
+ ctx->Driver.StencilOpSeparate = tdfxDDStencilOpSeparate;
}
ctx->Driver.Viewport = tdfxDDViewport;
-
- /* Swrast hooks for imaging extensions:
- */
- ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
- ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
- ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
- ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
}