r600: support depth compare functions & shadow_ambient
authorAndre Maasikas <amaasikas@gmail.com>
Tue, 5 Jan 2010 11:44:06 +0000 (13:44 +0200)
committerAndre Maasikas <amaasikas@gmail.com>
Tue, 5 Jan 2010 11:48:04 +0000 (13:48 +0200)
src/mesa/drivers/dri/r600/r600_context.c
src/mesa/drivers/dri/r600/r600_texstate.c
src/mesa/drivers/dri/r600/r700_assembler.c
src/mesa/drivers/dri/r600/r700_assembler.h
src/mesa/drivers/dri/r600/r700_fragprog.c

index 45bbc3c..8f6264a 100644 (file)
@@ -99,6 +99,7 @@ static const struct dri_extension card_extensions[] = {
   {"GL_ARB_depth_clamp",                NULL},
   {"GL_ARB_depth_texture",             NULL},
   {"GL_ARB_fragment_program",          NULL},
+  {"GL_ARB_fragment_program_shadow",   NULL},
   {"GL_ARB_occlusion_query",            GL_ARB_occlusion_query_functions},
   {"GL_ARB_multitexture",              NULL},
   {"GL_ARB_point_parameters",          GL_ARB_point_parameters_functions},
@@ -163,6 +164,7 @@ static const struct dri_extension gl_20_extension[] = {
 #else
   {"GL_VERSION_2_0",                   GL_VERSION_2_0_functions },
 #endif /* R600_ENABLE_GLSL_TEST */
+  {NULL, NULL}
 };
 
 static const struct tnl_pipeline_stage *r600_pipeline[] = {
index 2a4a6e6..937f127 100644 (file)
@@ -626,6 +626,31 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, gl_format mesa
        return GL_TRUE;
 }
 
+static GLuint r600_translate_shadow_func(GLenum func)
+{
+   switch (func) {
+   case GL_NEVER:
+      return SQ_TEX_DEPTH_COMPARE_NEVER;
+   case GL_LESS:
+      return SQ_TEX_DEPTH_COMPARE_LESS;
+   case GL_LEQUAL:
+      return SQ_TEX_DEPTH_COMPARE_LESSEQUAL;
+   case GL_GREATER:
+      return SQ_TEX_DEPTH_COMPARE_GREATER;
+   case GL_GEQUAL:
+      return SQ_TEX_DEPTH_COMPARE_GREATEREQUAL;
+   case GL_NOTEQUAL:
+      return SQ_TEX_DEPTH_COMPARE_NOTEQUAL;
+   case GL_EQUAL:
+      return SQ_TEX_DEPTH_COMPARE_EQUAL;
+   case GL_ALWAYS:
+      return SQ_TEX_DEPTH_COMPARE_ALWAYS;
+   default:
+      WARN_ONCE("Unknown shadow compare function! %d", func);
+      return 0;
+   }
+}
+
 void r600SetDepthTexMode(struct gl_texture_object *tObj)
 {
        radeonTexObjPtr t;
@@ -711,6 +736,15 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
                SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask);
                SETfield(t->SQ_TEX_RESOURCE5, t->maxLod - t->minLod, LAST_LEVEL_shift, LAST_LEVEL_mask);
        }
+       if(texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB)
+       {
+               SETfield(t->SQ_TEX_SAMPLER0, r600_translate_shadow_func(texObj->CompareFunc), DEPTH_COMPARE_FUNCTION_shift, DEPTH_COMPARE_FUNCTION_mask);
+       }
+       else
+       {
+               CLEARfield(t->SQ_TEX_SAMPLER0, DEPTH_COMPARE_FUNCTION_mask);
+       }
+
 }
 
 /**
index 1ff89e1..0ff16b4 100644 (file)
@@ -4397,7 +4397,10 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
             pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE_L;
             break;
         default:
-            pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+            if(pAsm->pILInst[pAsm->uiCurInst].TexShadow == 1)
+                pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE_C;
+            else
+                pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
     }
 
     pAsm->is_tex = GL_TRUE;
@@ -4443,11 +4446,46 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
         pAsm->S[0].src.swizzlew = SQ_SEL_Y;
     }
  
+    if(pAsm->pILInst[pAsm->uiCurInst].TexShadow == 1)
+    {
+        /* compare value goes to w chan ? */
+        pAsm->S[0].src.swizzlew = SQ_SEL_Z;
+    }
+
     if ( GL_FALSE == next_ins(pAsm) )
         {
             return GL_FALSE;
         }
 
+    /* add ARB shadow ambient but clamp to 0..1 */
+    if(pAsm->pILInst[pAsm->uiCurInst].TexShadow == 1)
+    {
+       /* ADD_SAT dst,  dst,  ambient[texunit] */
+       pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
+
+       if( GL_FALSE == assemble_dst(pAsm) )
+       {
+           return GL_FALSE;
+       }
+       pAsm->D2.dst2.SaturateMode = 1;
+
+       pAsm->S[0].src.rtype = pAsm->D.dst.rtype;
+       pAsm->S[0].src.reg = pAsm->D.dst.reg;
+       noswizzle_PVSSRC(&(pAsm->S[0].src));
+       noneg_PVSSRC(&(pAsm->S[0].src));
+
+       pAsm->S[1].src.rtype = SRC_REG_CONSTANT;
+       pAsm->S[1].src.reg = pAsm->shadow_regs[pAsm->pILInst[pAsm->uiCurInst].TexSrcUnit];
+       noswizzle_PVSSRC(&(pAsm->S[1].src));
+       noneg_PVSSRC(&(pAsm->S[1].src));
+
+       if( GL_FALSE == next_ins(pAsm) )
+       {
+           return GL_FALSE;
+       }
+
+    }
+
     return GL_TRUE;
 }
 
index 86342b8..56baf5b 100644 (file)
@@ -487,6 +487,8 @@ typedef struct r700_AssemblerBase
 
     GLuint    unVetTexBits;
 
+    GLuint    shadow_regs[R700_MAX_TEXTURE_UNITS];
+
 } r700_AssemblerBase;
 
 //Internal use
index ce2d9fd..84d51e6 100644 (file)
@@ -362,8 +362,11 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
 {
        GLuint    number_of_colors_exported;
        GLboolean z_enabled = GL_FALSE;
-       GLuint    unBit;
+       GLuint    unBit, shadow_unit;
        int i;
+       struct prog_instruction *inst;
+       gl_state_index shadow_ambient[STATE_LENGTH]
+           = { STATE_INTERNAL, STATE_SHADOW_AMBIENT, 0, 0, 0};
 
     //Init_Program
        Init_r700_AssemblerBase( SPT_FP, &(fp->r700AsmCode), &(fp->r700Shader) );
@@ -373,6 +376,23 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
         insert_wpos_code(ctx, mesa_fp);
     }
 
+    /* add/map  consts for ARB_shadow_ambient */
+    if(mesa_fp->Base.ShadowSamplers)
+    {
+        inst = mesa_fp->Base.Instructions;
+        for (i = 0; i < mesa_fp->Base.NumInstructions; i++)
+        {
+            if(inst->TexShadow == 1)
+            {
+                shadow_unit = inst->TexSrcUnit;
+                shadow_ambient[2] = shadow_unit;
+                fp->r700AsmCode.shadow_regs[shadow_unit] = 
+                    _mesa_add_state_reference(mesa_fp->Base.Parameters, shadow_ambient);
+            }
+            inst++;
+        }
+    }
+
     Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp, ctx); 
 
     if( GL_FALSE == Find_Instruction_Dependencies_fp(fp, mesa_fp) )