ir_to_mesa: Add support for variable array indexing of builtin varyings.

That is to say, gl_TexCoord[i] now works, fixing glsl-texcoord-array
on swrast.
This commit is contained in:
Eric Anholt
2010-07-13 09:46:26 -07:00
parent f8a2b65bc9
commit 4d5da50b94

View File

@@ -1145,39 +1145,30 @@ ir_to_mesa_visitor::visit(ir_dereference_array *ir)
ir->array->accept(this); ir->array->accept(this);
src_reg = this->result; src_reg = this->result;
if (src_reg.file == PROGRAM_INPUT || if (index) {
src_reg.file == PROGRAM_OUTPUT) { src_reg.index += index->value.i[0] * element_size;
assert(index); /* FINISHME: Handle variable indexing of builtins. */
src_reg.index += index->value.i[0];
} else { } else {
if (index) { ir_to_mesa_src_reg array_base = this->result;
src_reg.index += index->value.i[0] * element_size; /* Variable index array dereference. It eats the "vec4" of the
* base of the array and an index that offsets the Mesa register
* index.
*/
ir->array_index->accept(this);
ir_to_mesa_src_reg index_reg;
if (element_size == 1) {
index_reg = this->result;
} else { } else {
ir_to_mesa_src_reg array_base = this->result; index_reg = get_temp(glsl_type::float_type);
/* Variable index array dereference. It eats the "vec4" of the
* base of the array and an index that offsets the Mesa register
* index.
*/
ir->array_index->accept(this);
ir_to_mesa_src_reg index_reg; ir_to_mesa_emit_op2(ir, OPCODE_MUL,
ir_to_mesa_dst_reg_from_src(index_reg),
if (element_size == 1) { this->result, src_reg_for_float(element_size));
index_reg = this->result;
} else {
index_reg = get_temp(glsl_type::float_type);
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;
} }
src_reg.reladdr = talloc(mem_ctx, ir_to_mesa_src_reg);
memcpy(src_reg.reladdr, &index_reg, sizeof(index_reg));
} }
/* If the type is smaller than a vec4, replicate the last channel out. */ /* If the type is smaller than a vec4, replicate the last channel out. */
@@ -1717,6 +1708,44 @@ print_program(struct prog_instruction *mesa_instructions,
} }
} }
static void
mark_input(struct gl_program *prog,
int index,
GLboolean reladdr)
{
prog->InputsRead |= BITFIELD64_BIT(index);
int i;
if (reladdr) {
if (index >= FRAG_ATTRIB_TEX0 && index <= FRAG_ATTRIB_TEX7) {
for (i = 0; i < 8; i++) {
prog->InputsRead |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
}
} else {
assert(!"FINISHME: Mark InputsRead for varying arrays");
}
}
}
static void
mark_output(struct gl_program *prog,
int index,
GLboolean reladdr)
{
prog->OutputsWritten |= BITFIELD64_BIT(index);
int i;
if (reladdr) {
if (index >= VERT_RESULT_TEX0 && index <= VERT_RESULT_TEX7) {
for (i = 0; i < 8; i++) {
prog->OutputsWritten |= BITFIELD64_BIT(FRAG_ATTRIB_TEX0 + i);
}
} else {
assert(!"FINISHME: Mark OutputsWritten for varying arrays");
}
}
}
static void static void
count_resources(struct gl_program *prog) count_resources(struct gl_program *prog)
{ {
@@ -1732,10 +1761,10 @@ count_resources(struct gl_program *prog)
switch (inst->DstReg.File) { switch (inst->DstReg.File) {
case PROGRAM_OUTPUT: case PROGRAM_OUTPUT:
prog->OutputsWritten |= BITFIELD64_BIT(inst->DstReg.Index); mark_output(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
break; break;
case PROGRAM_INPUT: case PROGRAM_INPUT:
prog->InputsRead |= BITFIELD64_BIT(inst->DstReg.Index); mark_input(prog, inst->DstReg.Index, inst->DstReg.RelAddr);
break; break;
default: default:
break; break;
@@ -1744,10 +1773,11 @@ count_resources(struct gl_program *prog)
for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) { for (reg = 0; reg < _mesa_num_inst_src_regs(inst->Opcode); reg++) {
switch (inst->SrcReg[reg].File) { switch (inst->SrcReg[reg].File) {
case PROGRAM_OUTPUT: case PROGRAM_OUTPUT:
prog->OutputsWritten |= BITFIELD64_BIT(inst->SrcReg[reg].Index); mark_output(prog, inst->SrcReg[reg].Index,
inst->SrcReg[reg].RelAddr);
break; break;
case PROGRAM_INPUT: case PROGRAM_INPUT:
prog->InputsRead |= BITFIELD64_BIT(inst->SrcReg[reg].Index); mark_input(prog, inst->SrcReg[reg].Index, inst->SrcReg[reg].RelAddr);
break; break;
default: default:
break; break;