diff options
| -rw-r--r-- | src/mesa/shader/slang/slang_builtin.c | 192 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_builtin.h | 5 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_codegen.c | 14 | ||||
| -rw-r--r-- | src/mesa/shader/slang/slang_emit.c | 18 | 
4 files changed, 217 insertions, 12 deletions
diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c index a92efa875b..b4aecdb3ad 100644 --- a/src/mesa/shader/slang/slang_builtin.c +++ b/src/mesa/shader/slang/slang_builtin.c @@ -152,6 +152,10 @@ _slang_lookup_statevar(const char *name, GLint index,        { "gl_BackLightModelProduct.sceneColor", 1, SWIZZLE_NOOP,          { STATE_LIGHTMODEL_SCENECOLOR, 1, 0, 0, 0, 0 } }, +      { "gl_FrontLightProduct", 1, SWIZZLE_NOOP, +        { STATE_LIGHTPROD, 0, STATE_AMBIENT, 0, 0, 0 } }, + +        { "gl_Fog", 1, SWIZZLE_NOOP,          { STATE_FOG_COLOR, 0, 0, 0, 0, 0 } },        { "gl_Fog.color", 1, SWIZZLE_NOOP, @@ -165,6 +169,8 @@ _slang_lookup_statevar(const char *name, GLint index,        { "gl_Fog.scale", 1, SWIZZLE_WWWW,          { STATE_FOG_PARAMS, 0, 0, 0, 0, 0 } }, +      { "gl_ClipPlane", 1, SWIZZLE_NOOP, +        { STATE_CLIPPLANE, 0, 0, 0, 0, 0 } },        { NULL, 0, 0, {0, 0, 0, 0, 0, 0} }     }; @@ -230,3 +236,189 @@ _slang_lookup_statevar_field(const char *base, const char *field,  } +struct field_info { +   const char *Name; +   gl_state_index Token; +   GLint TokenPos; +   GLuint Swizzle; +}; + +#define MT_FIELD { NULL, 0, -1, 0 } +#define MAX_FIELDS 5 +#define INDEX_POS 1000 + +struct state_uniform_info { +   const char *Name; +   gl_state_index StateTokens[2]; +   struct field_info Fields[MAX_FIELDS]; +}; + + + +static const struct state_uniform_info Uniforms[] = { +   { "gl_ModelViewMatrix", { STATE_MATRIX, STATE_MODELVIEW }, +     { MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD} +   }, +   { "gl_ProjectionMatrix", { STATE_MATRIX, STATE_PROJECTION }, +     { MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD} +   }, +   { "gl_ModelViewProjectionMatrix", { STATE_MATRIX, STATE_MVP }, +     { MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD} +   }, +   { "gl_NormalMatrix", { STATE_MATRIX, STATE_MODELVIEW }, +     { MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD} +   }, +   { "gl_TextureMatrix", { STATE_MATRIX, STATE_TEXTURE }, +     { MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD} +   }, + +   { "gl_ClipPlane", { STATE_CLIPPLANE, INDEX_POS }, +     { MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD} +   }, + +   { "gl_DepthRange", { STATE_DEPTH_RANGE, 0 }, +     { +        { "near", 0, -1, SWIZZLE_XXXX }, +        { "far", 0, -1, SWIZZLE_YYYY }, +        { "diff", 0, -1, SWIZZLE_ZZZZ }, +        MT_FIELD, +        MT_FIELD +     } +   }, + +   { "gl_Fog", { 0, 0 }, +     { +        { "color", STATE_FOG_COLOR, 0, SWIZZLE_NOOP }, +        { "density", STATE_FOG_PARAMS, 0, SWIZZLE_XXXX }, +        { "start", STATE_FOG_PARAMS, 0, SWIZZLE_YYYY }, +        { "end", STATE_FOG_PARAMS, 0, SWIZZLE_ZZZZ }, +        { "scale", STATE_FOG_PARAMS, 0, SWIZZLE_WWWW } +     } +   }, + +   { NULL, { 0, 0 }, +     { MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD, MT_FIELD } +   } +}; + + +static GLint +lookup_statevar(const char *var, GLint index, const char *field, +                GLuint *swizzleOut, +                struct gl_program_parameter_list *paramList) +{ +   gl_state_index tokens[STATE_LENGTH]; +   GLuint i, j; +   GLint pos; + +   for (i = 0; i < STATE_LENGTH; i++) { +      tokens[i] = 0; +   } + +   for (i = 0; Uniforms[i].Name; i++) { +      if (strcmp(var, Uniforms[i].Name) == 0) { +         /* found the uniform */ + +         for (j = 0; j < 2; j++) { +            tokens[j] = Uniforms[i].StateTokens[j]; +            if (tokens[j] == INDEX_POS) { +               /* replace INDEX_POS with actual array index */ +               assert(index >= 0); +               tokens[j] = index; +            } +         } + +         if (field) { +            /* extra work for var.field */ +            for (j = 0; j < MAX_FIELDS; j++) { +               if (!Uniforms[i].Fields[j].Name) { +                  /* field not found! */ +                  _mesa_problem(NULL, "field not found"); +                  return -1; +               } +               else if (strcmp(field, Uniforms[i].Fields[j].Name) == 0) { +                  /* found the field */ +                  GLint tokenPos = Uniforms[i].Fields[j].TokenPos; +                  if (tokenPos>= 0) { +                     tokens[tokenPos] = Uniforms[i].Fields[j].Token; +                  } +                  *swizzleOut = Uniforms[i].Fields[j].Swizzle; +                  break; +               } + +            } +         } + +         if (tokens[0] == STATE_MATRIX) { +            /* a matrix */ +            GLuint j; +            GLint pos[4]; +            gl_state_index indexesCopy[STATE_LENGTH]; +            /* make copy of state tokens */ +            for (j = 0; j < STATE_LENGTH; j++) +               indexesCopy[j] = tokens[j]; +            /* load rows */ +            for (j = 0; j < 4/*state[i].NumRows*/; j++) { +               indexesCopy[3] = indexesCopy[4] = j; /* jth row of matrix */ +               pos[j] = _mesa_add_state_reference(paramList, (GLint*) indexesCopy); +               assert(pos[j] >= 0); +            } +            return pos[0] + index; +         } + +         pos = _mesa_add_state_reference(paramList, (GLint *) tokens); +         assert(pos >= 0); +         return pos; +      } +   } +   return -1; +} + + + +/** + * Allocate storage for a pre-defined uniform (a GL state variable). + * As a memory-saving optimization, we try to only allocate storage for + * state vars that are actually used. + * For example, the "gl_LightSource" uniform is huge.  If we only use + * a handful of gl_LightSource fields, we don't want to allocate storage + * for all of gl_LightSource. + * + * Currently, all pre-defined uniforms are in one of these forms: + *   var + *   var[index] + *   var.field + *   var[index].field + */ +GLint +_slang_alloc_statevar(slang_ir_node *n, +                      struct gl_program_parameter_list *paramList) +{ +   const char *field = NULL, *var; +   GLint index = -1, pos; +   GLuint swizzle; + +   if (n->Opcode == IR_FIELD) { +      field = n->Target; +      n = n->Children[0]; +   } + +   if (n->Opcode == IR_ELEMENT) { +      /* XXX can only handle constant indexes for now */ +      assert(n->Children[1]->Opcode == IR_FLOAT); +      index = (GLint) n->Children[1]->Value[0]; +      n = n->Children[0]; +   } + +   assert(n->Opcode == IR_VAR); +   var = (char *) n->Var->a_name; + +   pos = lookup_statevar(var, index, field, &swizzle, paramList); +   assert(pos >= 0); +   if (pos >= 0) { +      n->Store->Index = pos; +      n->Store->Swizzle = swizzle; +   } +   return pos; +} + diff --git a/src/mesa/shader/slang/slang_builtin.h b/src/mesa/shader/slang/slang_builtin.h index a521e73eb9..368a16b234 100644 --- a/src/mesa/shader/slang/slang_builtin.h +++ b/src/mesa/shader/slang/slang_builtin.h @@ -28,6 +28,7 @@  #include "prog_parameter.h"  #include "slang_utility.h" +#include "slang_ir.h"  extern GLint @@ -41,5 +42,9 @@ _slang_lookup_statevar_field(const char *base, const char *field,                               struct gl_program_parameter_list *paramList,                               GLuint *swizzleOut); +extern GLint +_slang_alloc_statevar(slang_ir_node *n, +                      struct gl_program_parameter_list *paramList); +  #endif /* SLANG_BUILTIN_H */ diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 789ab8a50b..d78f45a437 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -205,18 +205,7 @@ slang_allocate_storage(slang_assemble_ctx *A, slang_ir_node *n)           struct gl_program *prog = A->program;           assert(prog); -         /* determine storage location for this var. -          * This is probably a pre-defined uniform or constant. -          * We don't allocate storage for these until they're actually -          * used to avoid wasting registers. -          */ -         if (n->Store->File == PROGRAM_STATE_VAR) { -            GLint i = _slang_lookup_statevar(varName, 0, prog->Parameters, -                                             &n->Store->Swizzle); -            assert(i >= 0); -            n->Store->Index = i; -         } -         else if (n->Store->File == PROGRAM_CONSTANT) { +         if (n->Store->File == PROGRAM_CONSTANT) {              /* XXX compile-time constants should be converted to literals */              GLint i = slang_lookup_constant(varName, prog->Parameters,                                              &n->Store->Swizzle); @@ -2262,6 +2251,7 @@ _slang_gen_subscript(slang_assemble_ctx * A, slang_operation *oper)           elem->Store = _slang_new_ir_storage(array->Store->File,                                               array->Store->Index,                                               elemSize); +         /* XXX try to do some array bounds checking here */           return elem;        }        else { diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index d993fbddc5..7584857493 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1319,6 +1319,13 @@ emit_array_element(slang_var_table *vt, slang_ir_node *n,     assert(n->Store);     assert(n->Store->File != PROGRAM_UNDEFINED);     assert(n->Store->Size > 0); + +   if (n->Store->File == PROGRAM_STATE_VAR) { +      n->Store->Index = _slang_alloc_statevar(n, prog->Parameters); +      return NULL; +   } + +     if (n->Children[1]->Opcode == IR_FLOAT) {        /* Constant index */        const GLint arrayAddr = n->Children[0]->Store->Index; @@ -1343,6 +1350,11 @@ static struct prog_instruction *  emit_struct_field(slang_var_table *vt, slang_ir_node *n,                    struct gl_program *prog)  { +   if (n->Store->File == PROGRAM_STATE_VAR) { +      n->Store->Index = _slang_alloc_statevar(n, prog->Parameters); +      return NULL; +   } +     if (n->Children[0]->Store->File == PROGRAM_STATE_VAR) {        /* state variable sub-field */        GLint pos; @@ -1421,6 +1433,12 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog)         */        assert(n->Store);        assert(n->Store->File != PROGRAM_UNDEFINED); + +      if (n->Store->File == PROGRAM_STATE_VAR && +          n->Store->Index < 0) { +         n->Store->Index = _slang_alloc_statevar(n, prog->Parameters); +      } +        if (n->Store->Index < 0) {           printf("#### VAR %s not allocated!\n", (char*)n->Var->a_name);        }  | 
