summaryrefslogtreecommitdiff
path: root/src/mesa/program/ir_to_mesa.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/program/ir_to_mesa.cpp')
-rw-r--r--src/mesa/program/ir_to_mesa.cpp636
1 files changed, 345 insertions, 291 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 839d6f0467..d61698b4e4 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -577,239 +577,6 @@ ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
return NULL;
}
-struct statevar_element {
- const char *field;
- int tokens[STATE_LENGTH];
- int swizzle;
- bool array_indexed;
-};
-
-static struct statevar_element gl_DepthRange_elements[] = {
- {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
- {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
- {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
-};
-
-static struct statevar_element gl_ClipPlane_elements[] = {
- {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW}
-};
-
-static struct statevar_element gl_Point_elements[] = {
- {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX},
- {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY},
- {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
- {"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW},
- {"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX},
- {"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY},
- {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
-};
-
-static struct statevar_element gl_FrontMaterial_elements[] = {
- {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
- {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
- {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
- {"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
- {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
-};
-
-static struct statevar_element gl_BackMaterial_elements[] = {
- {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
- {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
- {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
- {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
- {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
-};
-
-static struct statevar_element gl_LightSource_elements[] = {
- {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
- {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
- {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
- {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW},
- {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW},
- {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW},
- {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW},
- {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX},
- {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW},
- {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX},
- {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY},
- {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
-};
-
-static struct statevar_element gl_LightModel_elements[] = {
- {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_FrontLightModelProduct_elements[] = {
- {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_BackLightModelProduct_elements[] = {
- {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_FrontLightProduct_elements[] = {
- {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
- {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
- {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_BackLightProduct_elements[] = {
- {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
- {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
- {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_TextureEnvColor_elements[] = {
- {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_EyePlaneS_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_EyePlaneT_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_EyePlaneR_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_EyePlaneQ_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_ObjectPlaneS_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_ObjectPlaneT_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_ObjectPlaneR_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_ObjectPlaneQ_elements[] = {
- {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW},
-};
-
-static struct statevar_element gl_Fog_elements[] = {
- {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW},
- {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
- {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
- {"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ},
- {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
-};
-
-#define MATRIX(name, statevar, modifier) \
- static struct statevar_element name ## _elements[] = { \
- { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \
- { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \
- { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \
- { NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW }, \
- }
-
-MATRIX(gl_ModelViewMatrix,
- STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE);
-MATRIX(gl_ModelViewMatrixInverse,
- STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS);
-MATRIX(gl_ModelViewMatrixTranspose,
- STATE_MODELVIEW_MATRIX, 0);
-MATRIX(gl_ModelViewMatrixInverseTranspose,
- STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE);
-
-MATRIX(gl_ProjectionMatrix,
- STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE);
-MATRIX(gl_ProjectionMatrixInverse,
- STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS);
-MATRIX(gl_ProjectionMatrixTranspose,
- STATE_PROJECTION_MATRIX, 0);
-MATRIX(gl_ProjectionMatrixInverseTranspose,
- STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE);
-
-MATRIX(gl_ModelViewProjectionMatrix,
- STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE);
-MATRIX(gl_ModelViewProjectionMatrixInverse,
- STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS);
-MATRIX(gl_ModelViewProjectionMatrixTranspose,
- STATE_MVP_MATRIX, 0);
-MATRIX(gl_ModelViewProjectionMatrixInverseTranspose,
- STATE_MVP_MATRIX, STATE_MATRIX_INVERSE);
-
-MATRIX(gl_TextureMatrix,
- STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE);
-MATRIX(gl_TextureMatrixInverse,
- STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS);
-MATRIX(gl_TextureMatrixTranspose,
- STATE_TEXTURE_MATRIX, 0);
-MATRIX(gl_TextureMatrixInverseTranspose,
- STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE);
-
-static struct statevar_element gl_NormalMatrix_elements[] = {
- { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
- { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
- { NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
- SWIZZLE_XYZW },
-};
-
-#undef MATRIX
-
-#define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
-
-static struct {
- const char *name;
- struct statevar_element *elements;
- int num_elements;
-} statevars[] = {
- STATEVAR(gl_DepthRange),
- STATEVAR(gl_ClipPlane),
- STATEVAR(gl_Point),
- STATEVAR(gl_FrontMaterial),
- STATEVAR(gl_BackMaterial),
- STATEVAR(gl_LightSource),
- STATEVAR(gl_LightModel),
- STATEVAR(gl_FrontLightModelProduct),
- STATEVAR(gl_BackLightModelProduct),
- STATEVAR(gl_FrontLightProduct),
- STATEVAR(gl_BackLightProduct),
- STATEVAR(gl_TextureEnvColor),
- STATEVAR(gl_EyePlaneS),
- STATEVAR(gl_EyePlaneT),
- STATEVAR(gl_EyePlaneR),
- STATEVAR(gl_EyePlaneQ),
- STATEVAR(gl_ObjectPlaneS),
- STATEVAR(gl_ObjectPlaneT),
- STATEVAR(gl_ObjectPlaneR),
- STATEVAR(gl_ObjectPlaneQ),
- STATEVAR(gl_Fog),
-
- STATEVAR(gl_ModelViewMatrix),
- STATEVAR(gl_ModelViewMatrixInverse),
- STATEVAR(gl_ModelViewMatrixTranspose),
- STATEVAR(gl_ModelViewMatrixInverseTranspose),
-
- STATEVAR(gl_ProjectionMatrix),
- STATEVAR(gl_ProjectionMatrixInverse),
- STATEVAR(gl_ProjectionMatrixTranspose),
- STATEVAR(gl_ProjectionMatrixInverseTranspose),
-
- STATEVAR(gl_ModelViewProjectionMatrix),
- STATEVAR(gl_ModelViewProjectionMatrixInverse),
- STATEVAR(gl_ModelViewProjectionMatrixTranspose),
- STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose),
-
- STATEVAR(gl_TextureMatrix),
- STATEVAR(gl_TextureMatrixInverse),
- STATEVAR(gl_TextureMatrixTranspose),
- STATEVAR(gl_TextureMatrixInverseTranspose),
-
- STATEVAR(gl_NormalMatrix),
-};
-
void
ir_to_mesa_visitor::visit(ir_variable *ir)
{
@@ -819,64 +586,6 @@ ir_to_mesa_visitor::visit(ir_variable *ir)
fp->OriginUpperLeft = ir->origin_upper_left;
fp->PixelCenterInteger = ir->pixel_center_integer;
}
-
- if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
- unsigned int i;
-
- struct variable_storage *entry;
- entry = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY,
- this->next_temp);
- this->variables.push_tail(entry);
- this->next_temp += type_size(ir->type);
-
- for (i = 0; i < Elements(statevars); i++) {
- if (strcmp(ir->name, statevars[i].name) == 0)
- break;
- }
-
- if (i == Elements(statevars)) {
- fail_link(this->shader_program,
- "Failed to find builtin uniform `%s'\n", ir->name);
- return;
- }
-
- ir_to_mesa_dst_reg dst =
- ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg(PROGRAM_TEMPORARY,
- entry->index, NULL));
-
- int array_count;
- if (ir->type->is_array()) {
- array_count = ir->type->length;
- } else {
- array_count = 1;
- }
-
- for (int a = 0; a < array_count; a++) {
- for (int j = 0; j < statevars[i].num_elements; j++) {
- struct statevar_element *element = &statevars[i].elements[j];
- int tokens[STATE_LENGTH];
-
- memcpy(tokens, element->tokens, sizeof(element->tokens));
- if (ir->type->is_array()) {
- tokens[1] = a;
- }
-
- int index = _mesa_add_state_reference(this->prog->Parameters,
- (gl_state_index *)tokens);
- ir_to_mesa_src_reg src(PROGRAM_STATE_VAR, index, NULL);
- src.swizzle = element->swizzle;
- ir_to_mesa_emit_op1(ir, OPCODE_MOV, dst, src);
- /* even a float takes up a whole vec4 reg in a struct/array. */
- dst.index++;
- }
- }
- if (dst.index != entry->index + type_size(ir->type)) {
- fail_link(this->shader_program,
- "failed to load builtin uniform `%s' (%d/%d regs loaded)\n",
- ir->name, dst.index - entry->index,
- type_size(ir->type));
- }
- }
}
void
@@ -1348,6 +1057,289 @@ ir_to_mesa_visitor::visit(ir_swizzle *ir)
this->result = src_reg;
}
+static const struct {
+ const char *name;
+ const char *field;
+ int tokens[STATE_LENGTH];
+ int swizzle;
+ bool array_indexed;
+} statevars[] = {
+ {"gl_DepthRange", "near",
+ {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX, false},
+ {"gl_DepthRange", "far",
+ {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY, false},
+ {"gl_DepthRange", "diff",
+ {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ, false},
+
+ {"gl_ClipPlane", NULL,
+ {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW, true}
+,
+ {"gl_Point", "size",
+ {STATE_POINT_SIZE}, SWIZZLE_XXXX, false},
+ {"gl_Point", "sizeMin",
+ {STATE_POINT_SIZE}, SWIZZLE_YYYY, false},
+ {"gl_Point", "sizeMax",
+ {STATE_POINT_SIZE}, SWIZZLE_ZZZZ, false},
+ {"gl_Point", "fadeThresholdSize",
+ {STATE_POINT_SIZE}, SWIZZLE_WWWW, false},
+ {"gl_Point", "distanceConstantAttenuation",
+ {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX, false},
+ {"gl_Point", "distanceLinearAttenuation",
+ {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY, false},
+ {"gl_Point", "distanceQuadraticAttenuation",
+ {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ, false},
+
+ {"gl_FrontMaterial", "emission",
+ {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW, false},
+ {"gl_FrontMaterial", "ambient",
+ {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW, false},
+ {"gl_FrontMaterial", "diffuse",
+ {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, false},
+ {"gl_FrontMaterial", "specular",
+ {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW, false},
+ {"gl_FrontMaterial", "shininess",
+ {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX, false},
+
+ {"gl_BackMaterial", "emission",
+ {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW, false},
+ {"gl_BackMaterial", "ambient",
+ {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW, false},
+ {"gl_BackMaterial", "diffuse",
+ {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, false},
+ {"gl_BackMaterial", "specular",
+ {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW, false},
+ {"gl_BackMaterial", "shininess",
+ {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX, false},
+
+ {"gl_LightSource", "ambient",
+ {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
+ {"gl_LightSource", "diffuse",
+ {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
+ {"gl_LightSource", "specular",
+ {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
+ {"gl_LightSource", "position",
+ {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW, true},
+ {"gl_LightSource", "halfVector",
+ {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW, true},
+ {"gl_LightSource", "spotDirection",
+ {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_XYZW, true},
+ {"gl_LightSource", "spotCosCutoff",
+ {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW, true},
+ {"gl_LightSource", "spotCutoff",
+ {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX, true},
+ {"gl_LightSource", "spotExponent",
+ {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW, true},
+ {"gl_LightSource", "constantAttenuation",
+ {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX, true},
+ {"gl_LightSource", "linearAttenuation",
+ {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY, true},
+ {"gl_LightSource", "quadraticAttenuation",
+ {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ, true},
+
+ {"gl_LightModel", "ambient",
+ {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW, false},
+
+ {"gl_FrontLightModelProduct", "sceneColor",
+ {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW, false},
+ {"gl_BackLightModelProduct", "sceneColor",
+ {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW, false},
+
+ {"gl_FrontLightProduct", "ambient",
+ {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW, true},
+ {"gl_FrontLightProduct", "diffuse",
+ {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
+ {"gl_FrontLightProduct", "specular",
+ {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW, true},
+
+ {"gl_BackLightProduct", "ambient",
+ {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW, true},
+ {"gl_BackLightProduct", "diffuse",
+ {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW, true},
+ {"gl_BackLightProduct", "specular",
+ {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW, true},
+
+ {"gl_TextureEnvColor", NULL,
+ {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW, true},
+
+ {"gl_EyePlaneS", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW, true},
+ {"gl_EyePlaneT", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW, true},
+ {"gl_EyePlaneR", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW, true},
+ {"gl_EyePlaneQ", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW, true},
+
+ {"gl_ObjectPlaneS", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW, true},
+ {"gl_ObjectPlaneT", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW, true},
+ {"gl_ObjectPlaneR", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW, true},
+ {"gl_ObjectPlaneQ", NULL,
+ {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW, true},
+
+ {"gl_Fog", "color",
+ {STATE_FOG_COLOR}, SWIZZLE_XYZW, false},
+ {"gl_Fog", "density",
+ {STATE_FOG_PARAMS}, SWIZZLE_XXXX, false},
+ {"gl_Fog", "start",
+ {STATE_FOG_PARAMS}, SWIZZLE_YYYY, false},
+ {"gl_Fog", "end",
+ {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ, false},
+ {"gl_Fog", "scale",
+ {STATE_FOG_PARAMS}, SWIZZLE_WWWW, false},
+};
+
+static ir_to_mesa_src_reg
+get_builtin_uniform_reg(struct gl_program *prog,
+ const char *name, int array_index, const char *field)
+{
+ unsigned int i;
+ ir_to_mesa_src_reg src_reg;
+ int tokens[STATE_LENGTH];
+
+ for (i = 0; i < Elements(statevars); i++) {
+ if (strcmp(statevars[i].name, name) != 0)
+ continue;
+ if (!field && statevars[i].field) {
+ assert(!"FINISHME: whole-structure state var dereference");
+ }
+ if (field && (!statevars[i].field || strcmp(statevars[i].field, field) != 0))
+ continue;
+ break;
+ }
+
+ if (i == Elements(statevars)) {
+ printf("builtin uniform %s%s%s not found\n",
+ name,
+ field ? "." : "",
+ field ? field : "");
+ abort();
+ }
+
+ memcpy(&tokens, statevars[i].tokens, sizeof(tokens));
+ if (statevars[i].array_indexed)
+ tokens[1] = array_index;
+
+ src_reg.file = PROGRAM_STATE_VAR;
+ src_reg.index = _mesa_add_state_reference(prog->Parameters,
+ (gl_state_index *)tokens);
+ src_reg.swizzle = statevars[i].swizzle;
+ src_reg.negate = 0;
+ src_reg.reladdr = false;
+
+ return src_reg;
+}
+
+static int
+add_matrix_ref(struct gl_program *prog, int *tokens)
+{
+ int base_pos = -1;
+ int i;
+
+ /* Add a ref for each column. It looks like the reason we do
+ * it this way is that _mesa_add_state_reference doesn't work
+ * for things that aren't vec4s, so the tokens[2]/tokens[3]
+ * range has to be equal.
+ */
+ for (i = 0; i < 4; i++) {
+ tokens[2] = i;
+ tokens[3] = i;
+ int pos = _mesa_add_state_reference(prog->Parameters,
+ (gl_state_index *)tokens);
+ if (base_pos == -1)
+ base_pos = pos;
+ else
+ assert(base_pos + i == pos);
+ }
+
+ return base_pos;
+}
+
+static variable_storage *
+get_builtin_matrix_ref(void *mem_ctx, struct gl_program *prog, ir_variable *var,
+ ir_rvalue *array_index)
+{
+ /*
+ * NOTE: The ARB_vertex_program extension specified that matrices get
+ * loaded in registers in row-major order. With GLSL, we want column-
+ * major order. So, we need to transpose all matrices here...
+ */
+ static const struct {
+ const char *name;
+ int matrix;
+ int modifier;
+ } matrices[] = {
+ { "gl_ModelViewMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE },
+ { "gl_ModelViewMatrixInverse", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS },
+ { "gl_ModelViewMatrixTranspose", STATE_MODELVIEW_MATRIX, 0 },
+ { "gl_ModelViewMatrixInverseTranspose", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
+
+ { "gl_ProjectionMatrix", STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE },
+ { "gl_ProjectionMatrixInverse", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS },
+ { "gl_ProjectionMatrixTranspose", STATE_PROJECTION_MATRIX, 0 },
+ { "gl_ProjectionMatrixInverseTranspose", STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE },
+
+ { "gl_ModelViewProjectionMatrix", STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE },
+ { "gl_ModelViewProjectionMatrixInverse", STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS },
+ { "gl_ModelViewProjectionMatrixTranspose", STATE_MVP_MATRIX, 0 },
+ { "gl_ModelViewProjectionMatrixInverseTranspose", STATE_MVP_MATRIX, STATE_MATRIX_INVERSE },
+
+ { "gl_TextureMatrix", STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE },
+ { "gl_TextureMatrixInverse", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS },
+ { "gl_TextureMatrixTranspose", STATE_TEXTURE_MATRIX, 0 },
+ { "gl_TextureMatrixInverseTranspose", STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE },
+
+ { "gl_NormalMatrix", STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE },
+
+ };
+ unsigned int i;
+ variable_storage *entry;
+
+ /* C++ gets angry when we try to use an int as a gl_state_index, so we use
+ * ints for gl_state_index. Make sure they're compatible.
+ */
+ assert(sizeof(gl_state_index) == sizeof(int));
+
+ for (i = 0; i < Elements(matrices); i++) {
+ if (strcmp(var->name, matrices[i].name) == 0) {
+ int tokens[STATE_LENGTH];
+ int base_pos = -1;
+
+ tokens[0] = matrices[i].matrix;
+ tokens[4] = matrices[i].modifier;
+ if (matrices[i].matrix == STATE_TEXTURE_MATRIX) {
+ ir_constant *index = array_index->constant_expression_value();
+ if (index) {
+ tokens[1] = index->value.i[0];
+ base_pos = add_matrix_ref(prog, tokens);
+ } else {
+ for (i = 0; i < var->type->length; i++) {
+ tokens[1] = i;
+ int pos = add_matrix_ref(prog, tokens);
+ if (base_pos == -1)
+ base_pos = pos;
+ else
+ assert(base_pos + (int)i * 4 == pos);
+ }
+ }
+ } else {
+ tokens[1] = 0; /* unused array index */
+ base_pos = add_matrix_ref(prog, tokens);
+ }
+
+ entry = new(mem_ctx) variable_storage(var,
+ PROGRAM_STATE_VAR,
+ base_pos);
+
+ return entry;
+ }
+ }
+
+ return NULL;
+}
+
void
ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
{
@@ -1356,6 +1348,11 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
if (!entry) {
switch (ir->var->mode) {
case ir_var_uniform:
+ entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, ir->var,
+ NULL);
+ if (entry)
+ break;
+
entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_UNIFORM,
ir->var->location);
this->variables.push_tail(entry);
@@ -1414,12 +1411,58 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
void
ir_to_mesa_visitor::visit(ir_dereference_array *ir)
{
+ ir_variable *var = ir->variable_referenced();
ir_constant *index;
ir_to_mesa_src_reg src_reg;
+ ir_dereference_variable *deref_var = ir->array->as_dereference_variable();
int element_size = type_size(ir->type);
index = ir->array_index->constant_expression_value();
+ if (deref_var && strncmp(deref_var->var->name,
+ "gl_TextureMatrix",
+ strlen("gl_TextureMatrix")) == 0) {
+ variable_storage *entry;
+
+ entry = get_builtin_matrix_ref(this->mem_ctx, this->prog, deref_var->var,
+ ir->array_index);
+ assert(entry);
+
+ ir_to_mesa_src_reg src_reg(entry->file, entry->index, ir->type);
+
+ if (index) {
+ src_reg.reladdr = NULL;
+ } else {
+ ir_to_mesa_src_reg index_reg = get_temp(glsl_type::float_type);
+
+ ir->array_index->accept(this);
+ ir_to_mesa_emit_op2(ir, OPCODE_MUL,
+ ir_to_mesa_dst_reg_from_src(index_reg),
+ this->result, src_reg_for_float(element_size));
+
+ src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
+ memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
+ }
+
+ this->result = src_reg;
+ return;
+ }
+
+ if (var &&
+ strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform &&
+ !var->type->is_matrix()) {
+ ir_dereference_record *record = NULL;
+ if (ir->array->ir_type == ir_type_dereference_record)
+ record = (ir_dereference_record *)ir->array;
+
+ assert(index || !"FINISHME: variable-indexed builtin uniform access");
+
+ this->result = get_builtin_uniform_reg(prog,
+ var->name,
+ index->value.i[0],
+ record ? record->field : NULL);
+ }
+
ir->array->accept(this);
src_reg = this->result;
@@ -1464,6 +1507,17 @@ ir_to_mesa_visitor::visit(ir_dereference_record *ir)
unsigned int i;
const glsl_type *struct_type = ir->record->type;
int offset = 0;
+ ir_variable *var = ir->record->variable_referenced();
+
+ if (strncmp(var->name, "gl_", 3) == 0 && var->mode == ir_var_uniform) {
+ assert(var);
+
+ this->result = get_builtin_uniform_reg(prog,
+ var->name,
+ 0,
+ ir->field);
+ return;
+ }
ir->record->accept(this);