map_register_file(
enum register_file file,
GLuint index,
- const GLuint immediateMapping[] )
+ const GLuint immediateMapping[],
+ GLboolean indirectAccess )
{
switch( file ) {
case PROGRAM_UNDEFINED:
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
case PROGRAM_UNIFORM:
- if (immediateMapping && immediateMapping[index] != ~0)
+ if (!indirectAccess && immediateMapping && immediateMapping[index] != ~0)
return TGSI_FILE_IMMEDIATE;
else
return TGSI_FILE_CONSTANT;
case PROGRAM_CONSTANT:
+ if (indirectAccess)
+ return TGSI_FILE_CONSTANT;
return TGSI_FILE_IMMEDIATE;
case PROGRAM_INPUT:
return TGSI_FILE_INPUT;
GLuint index,
const GLuint inputMapping[],
const GLuint outputMapping[],
- const GLuint immediateMapping[])
+ const GLuint immediateMapping[],
+ GLboolean indirectAccess )
{
switch( file ) {
case TGSI_FILE_INPUT:
return outputMapping[index];
case TGSI_FILE_IMMEDIATE:
+ if (indirectAccess)
+ return index;
return immediateMapping[index];
default:
const GLuint inputMapping[],
const GLuint outputMapping[],
const GLuint immediateMapping[],
+ GLboolean indirectAccess,
GLuint preamble_size,
GLuint processor,
GLboolean *insideSubroutine)
fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );
fulldst = &fullinst->FullDstRegisters[0];
- fulldst->DstRegister.File = map_register_file( inst->DstReg.File, 0, NULL );
+ fulldst->DstRegister.File = map_register_file( inst->DstReg.File, 0, NULL, GL_FALSE );
fulldst->DstRegister.Index = map_register_file_index(
fulldst->DstRegister.File,
inst->DstReg.Index,
inputMapping,
outputMapping,
- NULL
- );
+ NULL,
+ GL_FALSE );
fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );
- for( i = 0; i < fullinst->Instruction.NumSrcRegs; i++ ) {
+ for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
GLuint j;
fullsrc = &fullinst->FullSrcRegisters[i];
- fullsrc->SrcRegister.File = map_register_file( inst->SrcReg[i].File,
- inst->SrcReg[i].Index,
- immediateMapping );
+ fullsrc->SrcRegister.File = map_register_file(
+ inst->SrcReg[i].File,
+ inst->SrcReg[i].Index,
+ immediateMapping,
+ indirectAccess );
fullsrc->SrcRegister.Index = map_register_file_index(
fullsrc->SrcRegister.File,
inst->SrcReg[i].Index,
inputMapping,
outputMapping,
- immediateMapping);
+ immediateMapping,
+ indirectAccess );
/* swizzle (ext swizzle also depends on negation) */
{
GLuint immediates[1000];
GLuint numImmediates = 0;
GLboolean insideSubroutine = GL_FALSE;
+ GLboolean indirectAccess = GL_FALSE;
assert(procType == TGSI_PROCESSOR_FRAGMENT ||
procType == TGSI_PROCESSOR_VERTEX);
inside_range = GL_FALSE;
fulldecl = make_temp_decl( start_range, i - 1 );
ti += tgsi_build_full_declaration(
- &fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
+ &fulldecl,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
}
}
}
- /* Address register.
+ /* Declare address register.
*/
if (program->NumAddressRegs > 0) {
struct tgsi_full_declaration fulldecl;
&tokens[ti],
header,
maxTokens - ti );
+
+ indirectAccess = GL_TRUE;
}
/* immediates/literals */
memset(immediates, ~0, sizeof(immediates));
- for (i = 0; program->Parameters && i < program->Parameters->NumParameters;
- i++) {
- if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) {
- struct tgsi_full_immediate fullimm
- = make_immediate(program->Parameters->ParameterValues[i], 4);
- ti += tgsi_build_full_immediate(&fullimm,
- &tokens[ti],
- header,
- maxTokens - ti);
- immediates[i] = numImmediates;
- numImmediates++;
+ /* Emit immediates only when there is no address register in use.
+ * FIXME: Be smarter and recognize param arrays -- indirect addressing is
+ * only valid within the referenced array.
+ */
+ if (program->Parameters && !indirectAccess) {
+ for (i = 0; i < program->Parameters->NumParameters; i++) {
+ if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) {
+ struct tgsi_full_immediate fullimm;
+
+ fullimm = make_immediate( program->Parameters->ParameterValues[i], 4 );
+ ti += tgsi_build_full_immediate(
+ &fullimm,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
+ immediates[i] = numImmediates;
+ numImmediates++;
+ }
}
}
/* constant buffer refs */
- {
+ if (program->Parameters) {
GLint start = -1, end = -1;
- for (i = 0;
- program->Parameters && i < program->Parameters->NumParameters;
- i++) {
+ for (i = 0; i < program->Parameters->NumParameters; i++) {
GLboolean emit = (i == program->Parameters->NumParameters - 1);
+ GLboolean matches;
switch (program->Parameters->Parameters[i].Type) {
case PROGRAM_ENV_PARAM:
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
case PROGRAM_UNIFORM:
+ matches = GL_TRUE;
+ break;
+ case PROGRAM_CONSTANT:
+ matches = indirectAccess;
+ break;
+ default:
+ matches = GL_FALSE;
+ }
+
+ if (matches) {
if (start == -1) {
/* begin a sequence */
start = i;
/* continue sequence */
end = i;
}
- break;
- default:
+ }
+ else {
if (start != -1) {
/* end of sequence */
emit = GL_TRUE;
if (emit && start >= 0) {
struct tgsi_full_declaration fulldecl;
+
fulldecl = make_constant_decl( start, end );
- ti += tgsi_build_full_declaration(&fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti);
+ ti += tgsi_build_full_declaration(
+ &fulldecl,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
start = end = -1;
}
}
for (i = 0; i < 8; i++) {
if (program->SamplersUsed & (1 << i)) {
struct tgsi_full_declaration fulldecl;
+
fulldecl = make_sampler_decl( i );
- ti += tgsi_build_full_declaration(&fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
+ ti += tgsi_build_full_declaration(
+ &fulldecl,
+ &tokens[ti],
+ header,
+ maxTokens - ti );
}
}
-
- for( i = 0; i < program->NumInstructions; i++ ) {
+ for (i = 0; i < program->NumInstructions; i++) {
compile_instruction(
- &program->Instructions[i],
- &fullinst,
- inputMapping,
- outputMapping,
- immediates,
- preamble_size,
- procType,
- &insideSubroutine);
+ &program->Instructions[i],
+ &fullinst,
+ inputMapping,
+ outputMapping,
+ immediates,
+ indirectAccess,
+ preamble_size,
+ procType,
+ &insideSubroutine );
ti += tgsi_build_full_instruction(
&fullinst,
return ti;
}
-