Add support for GL_ARB_fragment_program_shadow.
authorIan Romanick <idr@us.ibm.com>
Thu, 7 Jun 2007 20:58:50 +0000 (13:58 -0700)
committerIan Romanick <idr@us.ibm.com>
Thu, 7 Jun 2007 20:58:50 +0000 (13:58 -0700)
src/mesa/main/extensions.c
src/mesa/main/mtypes.h
src/mesa/main/texstate.c
src/mesa/shader/arbprogparse.c
src/mesa/swrast/s_fragprog.c

index a4a6cdae366dd8af2dfa0281074901b5e7966320..80dce56c0c12c63bbb28fd95eb20b191f62d6556 100644 (file)
@@ -47,6 +47,7 @@ static const struct {
    { OFF, "GL_ARB_depth_texture",              F(ARB_depth_texture) },
    { OFF, "GL_ARB_draw_buffers",               F(ARB_draw_buffers) },
    { OFF, "GL_ARB_fragment_program",           F(ARB_fragment_program) },
+   { OFF, "GL_ARB_fragment_program_shadow",    F(ARB_fragment_program_shadow) },
    { OFF, "GL_ARB_fragment_shader",            F(ARB_fragment_shader) },
    { OFF, "GL_ARB_half_float_pixel",           F(ARB_half_float_pixel) },
    { OFF, "GL_ARB_imaging",                    F(ARB_imaging) },
@@ -184,6 +185,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
    ctx->Extensions.ARB_draw_buffers = GL_TRUE;
 #if FEATURE_ARB_fragment_program
    ctx->Extensions.ARB_fragment_program = GL_TRUE;
+   ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
 #endif
 #if FEATURE_ARB_fragment_shader
    ctx->Extensions.ARB_fragment_shader = GL_TRUE;
index 6cbbf145a19ed75d4da08158bd7e6e99ec2e1ad2..49332501d274e0c49ba4ead8d3fbb1d6a64bfa35 100644 (file)
@@ -1903,6 +1903,7 @@ struct gl_program
    GLbitfield InputsRead;     /**< Bitmask of which input regs are read */
    GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */
    GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS];  /**< TEXTURE_x_BIT bitmask */
+   GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
 
    /** Named parameters, constants, etc. from program text */
    struct gl_program_parameter_list *Parameters;
@@ -2532,6 +2533,7 @@ struct gl_extensions
    GLboolean ARB_depth_texture;
    GLboolean ARB_draw_buffers;
    GLboolean ARB_fragment_program;
+   GLboolean ARB_fragment_program_shadow;
    GLboolean ARB_fragment_shader;
    GLboolean ARB_half_float_pixel;
    GLboolean ARB_imaging;
index fb024437798a50be2252c88efb7388341fdf1b27..18afaf4eddeafe97df548f1c5f844507d5739193 100644 (file)
@@ -1527,6 +1527,8 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
                           "glTexParameter(bad GL_DEPTH_TEXTURE_MODE_ARB)");
                return;
             }
+
+           _mesa_update_texture_compare_function(texObj, GL_FALSE);
          }
          else {
             _mesa_error(ctx, GL_INVALID_ENUM,
index 9af3fd0764da078f8ca26669166fa8faea70fd35..5d8f763741fabcb6dc00e47d9684bcfaa3eaae89 100644 (file)
@@ -71,6 +71,7 @@ struct arb_program
 
    /* ARB_fragment_program specifics */
    GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; 
+   GLbitfield ShadowSamplers;
    GLuint NumAluInstructions; 
    GLuint NumTexInstructions;
    GLuint NumTexIndirections;
@@ -2661,6 +2662,7 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
    GLuint texcoord;
    GLubyte instClass, type, code;
    GLboolean rel;
+   GLuint shadow_tex = 0;
 
    _mesa_init_instructions(fp, 1);
 
@@ -2978,35 +2980,54 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
 
          /* texTarget */
          switch (*(*inst)++) {
+            case TEXTARGET_SHADOW1D:
+               shadow_tex = 1 << texcoord;
+               /* FALLTHROUGH */
             case TEXTARGET_1D:
                fp->TexSrcTarget = TEXTURE_1D_INDEX;
                break;
+            case TEXTARGET_SHADOW2D:
+               shadow_tex = 1 << texcoord;
+               /* FALLTHROUGH */
             case TEXTARGET_2D:
                fp->TexSrcTarget = TEXTURE_2D_INDEX;
                break;
             case TEXTARGET_3D:
                fp->TexSrcTarget = TEXTURE_3D_INDEX;
                break;
+            case TEXTARGET_SHADOWRECT:
+               shadow_tex = 1 << texcoord;
+               /* FALLTHROUGH */
             case TEXTARGET_RECT:
                fp->TexSrcTarget = TEXTURE_RECT_INDEX;
                break;
             case TEXTARGET_CUBE:
                fp->TexSrcTarget = TEXTURE_CUBE_INDEX;
                break;
-            case TEXTARGET_SHADOW1D:
-            case TEXTARGET_SHADOW2D:
             case TEXTARGET_SHADOW1D_ARRAY:
-            case TEXTARGET_SHADOW2D_ARRAY:
-            case TEXTARGET_SHADOWRECT:
-               /* TODO ARB_fragment_program_shadow code */
-               break;
+               shadow_tex = 1 << texcoord;
+               /* FALLTHROUGH */
             case TEXTARGET_1D_ARRAY:
                fp->TexSrcTarget = TEXTURE_1D_ARRAY_INDEX;
                break;
+            case TEXTARGET_SHADOW2D_ARRAY:
+               shadow_tex = 1 << texcoord;
+               /* FALLTHROUGH */
             case TEXTARGET_2D_ARRAY:
                fp->TexSrcTarget = TEXTURE_2D_ARRAY_INDEX;
                break;
          }
+
+         /* Don't test the first time a particular sampler is seen.  Each time
+          * after that, make sure the shadow state is the same.
+          */
+         if ((_mesa_bitcount(Program->TexturesUsed[texcoord]) > 0)
+             && ((Program->ShadowSamplers & (1 << texcoord)) != shadow_tex)) {
+            program_error(ctx, Program->Position,
+                          "texture image unit used for shadow sampling and non-shadow sampling");
+            return 1;
+         }
+
          Program->TexturesUsed[texcoord] |= (1 << fp->TexSrcTarget);
          /* Check that both "2D" and "CUBE" (for example) aren't both used */
          if (_mesa_bitcount(Program->TexturesUsed[texcoord]) > 1) {
@@ -3014,6 +3035,9 @@ parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
                           "multiple targets used on one texture image unit");
             return 1;
          }
+      
+
+         Program->ShadowSamplers |= shadow_tex;
          break;
 
       case OP_TEX_KIL:
@@ -3604,10 +3628,10 @@ enable_parser_extensions(GLcontext *ctx, grammar id)
    if (ctx->Extensions.ARB_matrix_palette
        && !enable_ext(ctx, id, "matrix_palette"))
       return GL_FALSE;
+#endif
    if (ctx->Extensions.ARB_fragment_program_shadow
        && !enable_ext(ctx, id, "fragment_program_shadow"))
       return GL_FALSE;
-#endif
    if (ctx->Extensions.EXT_point_parameters
        && !enable_ext(ctx, id, "point_parameters"))
       return GL_FALSE;
@@ -3804,6 +3828,7 @@ _mesa_parse_arb_program(GLcontext *ctx, GLenum target,
    program->HintPositionInvariant = GL_FALSE;
    for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
       program->TexturesUsed[a] = 0x0;
+   program->ShadowSamplers = 0x0;
    program->NumAluInstructions =
    program->NumTexInstructions =
    program->NumTexIndirections = 0;
@@ -3884,6 +3909,7 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
    program->Base.OutputsWritten  = ap.Base.OutputsWritten;
    for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
       program->Base.TexturesUsed[i] = ap.TexturesUsed[i];
+   program->Base.ShadowSamplers = ap.ShadowSamplers;
    program->FogOption          = ap.FogOption;
    program->UsesKill          = ap.UsesKill;
 
index f5ffe41fc19bdc3409e026c6a399f7a40ed7ada8..a36c1ba491978fd49b45714c72cf69309c4d76ec 100644 (file)
@@ -211,8 +211,9 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span )
 
    for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
       if (ctx->Texture.Unit[i]._Current != NULL) {
+         const GLboolean enable_shadow = ((1 << i) & program->Base.ShadowSamplers);
          _mesa_update_texture_compare_function(ctx->Texture.Unit[i]._Current,
-                                               GL_TRUE);
+                                               !enable_shadow);
       }
    }