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.
This commit is contained in:
parent
956f049fd2
commit
6c0ba32fd1
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue