diff options
author | Eric Anholt <[email protected]> | 2010-09-01 16:06:32 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2010-09-07 13:59:29 -0700 |
commit | 6c0ba32fd1466e8c1700acab3003dc1fe1deb337 (patch) | |
tree | 08815f9b81e5faee71ca2a02b777d94dda29b130 /src/mesa/program | |
parent | 956f049fd24eb5239361e68a1f27e1bebb3315a0 (diff) |
ir_to_mesa: Move the STATE_VAR elements of a builtin uniform to a temp (v2).
Like the constant handling and the handling of other uniforms, we add
the whole thing to the Parameters, avoiding messy, incomplete logic
for adding just the elements of a builting uniform that get used.
This means that a driver that relies only on ParameterValues[] for its
parameters will have an increased parameter load, but drivers
generally don't do that (since they have other params they need to
handle, too).
Fixes glsl-fs-statevar-call (testcase for Ember). Bug #29687.
v2: Continue referencing the STATE_VAR[] file directly when the
uniform will land in STATE_VAR[] formatted exactly as we'd put into a
temporary. When there's array dereferencing, we don't copy-propagate
in Mesa IR (not knowing where the array is in register space), so
smarts here are required or we'll massively increase the temp count.
Diffstat (limited to 'src/mesa/program')
-rw-r--r-- | src/mesa/program/ir_to_mesa.cpp | 671 |
1 files changed, 326 insertions, 345 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index d61698b4e44..b48b9912a5c 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -577,6 +577,239 @@ 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 const struct statevar { + const char *name; + struct statevar_element *elements; + unsigned 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) { @@ -586,6 +819,99 @@ 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; + + 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; + } + + const struct statevar *statevar = &statevars[i]; + + int array_count; + if (ir->type->is_array()) { + array_count = ir->type->length; + } else { + array_count = 1; + } + + /* Check if this statevar's setup in the STATE file exactly + * matches how we'll want to reference it as a + * struct/array/whatever. If not, then we need to move it into + * temporary storage and hope that it'll get copy-propagated + * out. + */ + for (i = 0; i < statevar->num_elements; i++) { + if (statevar->elements[i].swizzle != SWIZZLE_XYZW) { + break; + } + } + + struct variable_storage *storage; + ir_to_mesa_dst_reg dst; + if (i == statevar->num_elements) { + /* We'll set the index later. */ + storage = new(mem_ctx) variable_storage(ir, PROGRAM_STATE_VAR, -1); + this->variables.push_tail(storage); + + dst = ir_to_mesa_undef_dst; + } else { + storage = new(mem_ctx) variable_storage(ir, PROGRAM_TEMPORARY, + this->next_temp); + this->variables.push_tail(storage); + this->next_temp += type_size(ir->type); + + dst = ir_to_mesa_dst_reg_from_src(ir_to_mesa_src_reg(PROGRAM_TEMPORARY, + storage->index, + NULL)); + } + + + for (int a = 0; a < array_count; a++) { + for (unsigned int i = 0; i < statevar->num_elements; i++) { + struct statevar_element *element = &statevar->elements[i]; + 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); + + if (storage->file == PROGRAM_STATE_VAR) { + if (storage->index == -1) { + storage->index = index; + } else { + assert(index == (storage->index + + a * statevar->num_elements + i)); + } + } else { + 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 (storage->file == PROGRAM_TEMPORARY && + dst.index != storage->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 - storage->index, + type_size(ir->type)); + } + } } void @@ -1057,289 +1383,6 @@ 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) { @@ -1348,11 +1391,6 @@ 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); @@ -1411,58 +1449,12 @@ 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; @@ -1507,17 +1499,6 @@ 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); |