summaryrefslogtreecommitdiffstats
path: root/src/mesa/shader/slang/slang_emit.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2008-12-30 17:11:32 -0700
committerBrian Paul <[email protected]>2008-12-30 17:11:32 -0700
commitc6537ac8b8130cf2271c8d1e51137a575073c762 (patch)
treed51e85841d71823d778a61ade9890af7bf4f24c2 /src/mesa/shader/slang/slang_emit.c
parentca0540e25c86b8095511868b0cbe96d7e85f7437 (diff)
mesa: allow variable indexing into the predefined uniform variable arrays
This allows code such as "vec4 a = gl_LightSource[i].ambient;" to work. When a built-in uniform array is indexed with a variable index we need to "unroll" the whole array into the parameter list (aka constant buffer) because we don't know which elements may be accessed at compile-time. In the case of the gl_LightSource array of size [8], we emit 64 state references into the parameter array (8 elements times 8 vec4s per gl_LightSourceParameters struct). Previously, we only allowed constant-indexed references to uniform arrays (such as gl_LightSource[2].position) which resulted in a single state reference being added to the parameter array, not 64. We still optimize this case. Users should be aware that using "gl_LightSource[i].ambient" in their shaders is a bit expensive since state validation will involve updating all 64 light source entries in the parameter list.
Diffstat (limited to 'src/mesa/shader/slang/slang_emit.c')
-rw-r--r--src/mesa/shader/slang/slang_emit.c51
1 files changed, 39 insertions, 12 deletions
diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c
index 6587f9cf276..4f8e694a739 100644
--- a/src/mesa/shader/slang/slang_emit.c
+++ b/src/mesa/shader/slang/slang_emit.c
@@ -348,6 +348,10 @@ storage_to_src_reg(struct prog_src_register *src, const slang_ir_storage *st)
assert(index >= 0);
while (st->Parent) {
st = st->Parent;
+ if (st->Index < 0) {
+ /* an error should have been reported already */
+ return;
+ }
assert(st->Index >= 0);
index += st->Index;
swizzle = _slang_swizzle_swizzle(fix_swizzle(st->Swizzle), swizzle);
@@ -1841,9 +1845,17 @@ emit_array_element(slang_emit_info *emitInfo, slang_ir_node *n)
root = root->Parent;
if (root->File == PROGRAM_STATE_VAR) {
- GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters);
- assert(n->Store->Index == index);
- return NULL;
+ GLboolean direct;
+ GLint index =
+ _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+ if (index < 0) {
+ /* error */
+ return NULL;
+ }
+ if (direct) {
+ n->Store->Index = index;
+ return NULL; /* all done */
+ }
}
}
@@ -1967,19 +1979,23 @@ emit_struct_field(slang_emit_info *emitInfo, slang_ir_node *n)
* space for the ones that we actually use!
*/
if (root->File == PROGRAM_STATE_VAR) {
- root->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters);
- if (root->Index < 0) {
+ GLboolean direct;
+ GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+ if (index < 0) {
slang_info_log_error(emitInfo->log, "Error parsing state variable");
return NULL;
}
- return NULL;
- }
- else {
- /* do codegen for struct */
- emit(emitInfo, n->Children[0]);
- assert(n->Children[0]->Store->Index >= 0);
+ if (direct) {
+ root->Index = index;
+ return NULL; /* all done */
+ }
}
+ /* do codegen for struct */
+ emit(emitInfo, n->Children[0]);
+ assert(n->Children[0]->Store->Index >= 0);
+
+
fieldOffset = n->Store->Index;
fieldSize = n->Store->Size;
@@ -2077,7 +2093,18 @@ emit_var_ref(slang_emit_info *emitInfo, slang_ir_node *n)
assert(n->Store->File != PROGRAM_UNDEFINED);
if (n->Store->File == PROGRAM_STATE_VAR && n->Store->Index < 0) {
- n->Store->Index = _slang_alloc_statevar(n, emitInfo->prog->Parameters);
+ GLboolean direct;
+ GLint index = _slang_alloc_statevar(n, emitInfo->prog->Parameters, &direct);
+ if (index < 0) {
+ /* error */
+ char s[100];
+ snprintf(s, sizeof(s), "Undefined variable '%s'",
+ (char *) n->Var->a_name);
+ slang_info_log_error(emitInfo->log, s);
+ return NULL;
+ }
+
+ n->Store->Index = index;
}
else if (n->Store->File == PROGRAM_UNIFORM) {
/* mark var as used */