glsl: fix an array indexing bug

This fixes a bug found with swizzled array indexes such as in "array[index.z]"
where "index" is an ivec4.
This commit is contained in:
Brian Paul 2009-02-17 16:10:32 -07:00
parent edd8cb8c87
commit 6eabfc27f1
1 changed files with 43 additions and 10 deletions

View File

@ -451,7 +451,7 @@ emit_arl_load(slang_emit_info *emitInfo,
struct prog_instruction *inst = new_instruction(emitInfo, OPCODE_ARL);
inst->SrcReg[0].File = file;
inst->SrcReg[0].Index = index;
inst->SrcReg[0].Swizzle = swizzle;
inst->SrcReg[0].Swizzle = fix_swizzle(swizzle);
inst->DstReg.File = PROGRAM_ADDRESS;
inst->DstReg.Index = 0;
inst->DstReg.WriteMask = WRITEMASK_X;
@ -873,6 +873,7 @@ emit_compare(slang_emit_info *emitInfo, slang_ir_node *n)
if (n->Children[0]->Store->Size != n->Children[1]->Store->Size) {
slang_info_log_error(emitInfo->log, "invalid operands to == or !=");
n->Store = NULL;
return NULL;
}
@ -902,6 +903,7 @@ emit_compare(slang_emit_info *emitInfo, slang_ir_node *n)
slang_ir_storage tempStore;
if (!alloc_local_temp(emitInfo, &tempStore, 4)) {
n->Store = NULL;
return NULL;
/* out of temps */
}
@ -1813,6 +1815,25 @@ emit_cont_break_if_true(slang_emit_info *emitInfo, slang_ir_node *n)
}
/**
* Return the size of a swizzle mask given that some swizzle components
* may be NIL/undefined. For example:
* swizzle_size(".zzxx") = 4
* swizzle_size(".xy??") = 2
* swizzle_size(".xyz?") = 1
*/
static GLuint
swizzle_size(GLuint swizzle)
{
GLuint i;
for (i = 0; i < 4; i++) {
if (GET_SWZ(swizzle, i) == SWIZZLE_NIL)
return i;
}
return 4;
}
static struct prog_instruction *
emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
{
@ -1820,14 +1841,24 @@ emit_swizzle(slang_emit_info *emitInfo, slang_ir_node *n)
inst = emit(emitInfo, n->Children[0]);
#if 0
assert(n->Store->Parent);
/* Apply this node's swizzle to parent's storage */
GLuint swizzle = n->Store->Swizzle;
_slang_copy_ir_storage(n->Store, n->Store->Parent);
n->Store->Swizzle = _slang_swizzle_swizzle(n->Store->Swizzle, swizzle);
assert(!n->Store->Parent);
#endif
if (n->Children[0]->Opcode == IR_VAR ||
n->Children[0]->Opcode == IR_SWIZZLE ||
n->Children[0]->Opcode == IR_ELEMENT) {
/* We can resolve the swizzle now. Other swizzles will be resolved
* in storage_to_src_reg().
*/
const GLuint swizzle = n->Store->Swizzle;
assert(n->Store->Parent);
/* new storage is parent storage with updated Swizzle + Size fields */
_slang_copy_ir_storage(n->Store, n->Store->Parent);
/* Apply this node's swizzle to parent's storage */
n->Store->Swizzle = _slang_swizzle_swizzle(n->Store->Swizzle, swizzle);
/* Update size */
n->Store->Size = swizzle_size(n->Store->Swizzle);
assert(!n->Store->Parent);
assert(n->Store->Index >= 0);
}
return inst;
}
@ -2428,7 +2459,9 @@ _slang_emit_code(slang_ir_node *n, slang_var_table *vt,
maxUniforms = ctx->Const.VertexProgram.MaxUniformComponents / 4;
}
if (prog->Parameters->NumParameters > maxUniforms) {
slang_info_log_error(log, "Constant/uniform register limit exceeded");
slang_info_log_error(log, "Constant/uniform register limit exceeded "
"(max=%u vec4)", maxUniforms);
return GL_FALSE;
}