{ "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,
{ "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} }
};
}
+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;
+}
+