From 84d1b24647c0719551e8bcd5fa4601fbd3b1d555 Mon Sep 17 00:00:00 2001 From: Ian Romanick Date: Thu, 7 Jun 2007 13:38:06 -0700 Subject: Fix ARB_fp spec conformance bug WRT shadow sampling. The ARB_fp (and other assembly-level fragment program specs) say that the depth comparison function is always GL_NONE in fragment program mode. --- src/mesa/main/mtypes.h | 4 ++++ src/mesa/main/texstate.c | 35 +++++++++++++++++++++++++++++++++++ src/mesa/main/texstate.h | 4 ++++ src/mesa/swrast/s_fragprog.c | 16 ++++++++++++++++ src/mesa/swrast/s_texfilter.c | 20 +------------------- 5 files changed, 60 insertions(+), 19 deletions(-) (limited to 'src/mesa') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 7397199a11..6cbbf145a1 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1426,6 +1426,10 @@ struct gl_texture_object GLfloat ShadowAmbient; /**< GL_ARB_shadow_ambient */ GLenum CompareMode; /**< GL_ARB_shadow */ GLenum CompareFunc; /**< GL_ARB_shadow */ + GLenum _Function; /**< Comparison function derrived from + * \c CompareOperator, \c CompareMode, and + * \c CompareFunc. + */ GLenum DepthMode; /**< GL_ARB_depth_texture */ GLint _MaxLevel; /**< actual max mipmap level (q in the spec) */ GLfloat _MaxLambda; /**< = _MaxLevel - BaseLevel (q - b in spec) */ diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index d15af22b7d..fb02443779 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -1178,6 +1178,36 @@ _mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ) } +/** + * Update derrived compare function state. + */ +void +_mesa_update_texture_compare_function(struct gl_texture_object *tObj, + GLboolean in_frag_prog) +{ + if (in_frag_prog) { + tObj->_Function = GL_NONE; + } + else if (tObj->CompareFlag) { + /* GL_SGIX_shadow */ + if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) { + tObj->_Function = GL_LEQUAL; + } + else { + ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX); + tObj->_Function = GL_GEQUAL; + } + } + else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) { + /* GL_ARB_shadow */ + tObj->_Function = tObj->CompareFunc; + } + else { + tObj->_Function = GL_NONE; /* pass depth through as grayscale */ + } +} + + void GLAPIENTRY _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) { @@ -1385,6 +1415,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) if (ctx->Extensions.SGIX_shadow) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE; + _mesa_update_texture_compare_function(texObj, GL_FALSE); } else { _mesa_error(ctx, GL_INVALID_ENUM, @@ -1399,6 +1430,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) op == GL_TEXTURE_GEQUAL_R_SGIX) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); texObj->CompareOperator = op; + _mesa_update_texture_compare_function(texObj, GL_FALSE); } else { _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(param)"); @@ -1437,6 +1469,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) if (mode == GL_NONE || mode == GL_COMPARE_R_TO_TEXTURE_ARB) { FLUSH_VERTICES(ctx, _NEW_TEXTURE); texObj->CompareMode = mode; + _mesa_update_texture_compare_function(texObj, GL_FALSE); } else { _mesa_error(ctx, GL_INVALID_ENUM, @@ -1472,6 +1505,8 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) "glTexParameter(bad GL_TEXTURE_COMPARE_FUNC_ARB)"); return; } + + _mesa_update_texture_compare_function(texObj, GL_FALSE); } else { _mesa_error(ctx, GL_INVALID_ENUM, diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h index ca29c6a23f..df468ecf9b 100644 --- a/src/mesa/main/texstate.h +++ b/src/mesa/main/texstate.h @@ -41,6 +41,10 @@ _mesa_copy_texture_state( const GLcontext *src, GLcontext *dst ); extern void _mesa_print_texunit_state( GLcontext *ctx, GLuint unit ); +extern void +_mesa_update_texture_compare_function(struct gl_texture_object *tObj, + GLboolean in_frag_prog); + /** * \name Called from API diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index e47dbbdaf3..f5ffe41fc1 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -26,6 +26,7 @@ #include "colormac.h" #include "context.h" #include "prog_instruction.h" +#include "texstate.h" #include "s_fragprog.h" #include "s_span.h" @@ -199,6 +200,7 @@ void _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) { const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + GLuint i; /* incoming colors should be floats */ if (program->Base.InputsRead & FRAG_BIT_COL0) { @@ -207,8 +209,22 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { + if (ctx->Texture.Unit[i]._Current != NULL) { + _mesa_update_texture_compare_function(ctx->Texture.Unit[i]._Current, + GL_TRUE); + } + } + run_program(ctx, span, 0, span->end); + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { + if (ctx->Texture.Unit[i]._Current != NULL) { + _mesa_update_texture_compare_function(ctx->Texture.Unit[i]._Current, + GL_FALSE); + } + } + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR)) { span->interpMask &= ~SPAN_RGBA; span->arrayMask |= SPAN_RGBA; diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c index 2c8e443daf..d4516f6faa 100644 --- a/src/mesa/swrast/s_texfilter.c +++ b/src/mesa/swrast/s_texfilter.c @@ -2893,25 +2893,7 @@ sample_depth_texture( GLcontext *ctx, /* XXXX if tObj->MinFilter != tObj->MagFilter, we're ignoring lambda */ - /* XXX this could be precomputed and saved in the texture object */ - if (tObj->CompareFlag) { - /* GL_SGIX_shadow */ - if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) { - function = GL_LEQUAL; - } - else { - ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX); - function = GL_GEQUAL; - } - } - else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) { - /* GL_ARB_shadow */ - function = tObj->CompareFunc; - } - else { - function = GL_NONE; /* pass depth through as grayscale */ - } - + function = tObj->_Function; if (tObj->MagFilter == GL_NEAREST) { GLuint i; for (i = 0; i < n; i++) { -- cgit v1.2.3