struct pair_state_instruction {
GLuint IsTex:1; /**< Is a texture instruction */
+ GLuint IsOutput:1; /**< Is output instruction */
GLuint NeedRGB:1; /**< Needs the RGB ALU */
GLuint NeedAlpha:1; /**< Needs the Alpha ALU */
GLuint IsTranscendent:1; /**< Is a special transcendent instruction */
GLboolean Debug;
GLboolean Verbose;
void *UserData;
+ GLubyte NumKillInsts;
/**
* Translate Mesa registers to hardware registers
struct pair_state_instruction *ReadyAlpha;
struct pair_state_instruction *ReadyTEX;
+ /**
+ * Linked list of deferred instructions
+ */
+ struct pair_state_instruction *DeferredInsts;
+
/**
* Pool of @ref reg_value structures for fast allocation.
*/
if (s->Verbose)
_mesa_printf("instruction_ready(%i)\n", ip);
- if (pairinst->IsTex)
+ if (s->NumKillInsts > 0 && pairinst->IsOutput)
+ add_pairinst_to_list(&s->DeferredInsts, pairinst);
+ else if (pairinst->IsTex)
add_pairinst_to_list(&s->ReadyTEX, pairinst);
else if (!pairinst->NeedAlpha)
add_pairinst_to_list(&s->ReadyRGB, pairinst);
error("Unknown opcode %d\n", inst->Opcode);
break;
}
+
+ pairinst->IsOutput = (inst->DstReg.File == PROGRAM_OUTPUT);
}
struct prog_instruction *inst = s->Program->Instructions + ip;
commit_instruction(s, ip);
- if (inst->Opcode != OPCODE_KIL)
+ if (inst->Opcode == OPCODE_KIL)
+ --s->NumKillInsts;
+ else
inst->DstReg.Index = get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index);
+
inst->SrcReg[0].Index = get_hw_reg(s, inst->SrcReg[0].File, inst->SrcReg[0].Index);
if (s->Debug) {
s->Error = s->Error || !s->Handler->EmitPaired(s->UserData, &pair);
}
+static GLubyte countKillInsts(struct gl_program *prog)
+{
+ GLubyte i, count = 0;
+
+ for (i = 0; i < prog->NumInstructions; ++i) {
+ if (prog->Instructions[i].Opcode == OPCODE_KIL)
+ ++count;
+ }
+
+ return count;
+}
GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program,
const struct radeon_pair_handler* handler, void *userdata)
s.UserData = userdata;
s.Debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE;
s.Verbose = GL_FALSE && s.Debug;
+ s.NumKillInsts = countKillInsts(program);
s.Instructions = (struct pair_state_instruction*)_mesa_calloc(
sizeof(struct pair_state_instruction)*s.Program->NumInstructions);
if (s.ReadyTEX)
emit_all_tex(&s);
+ if (!s.NumKillInsts) {
+ struct pair_state_instruction *pairinst = s.DeferredInsts;
+ while (pairinst) {
+ if (!pairinst->NeedAlpha)
+ add_pairinst_to_list(&s.ReadyRGB, pairinst);
+ else if (!pairinst->NeedRGB)
+ add_pairinst_to_list(&s.ReadyAlpha, pairinst);
+ else
+ add_pairinst_to_list(&s.ReadyFullALU, pairinst);
+
+ pairinst = pairinst->NextReady;
+ }
+ s.DeferredInsts = NULL;
+ }
+
while(s.ReadyFullALU || s.ReadyRGB || s.ReadyAlpha)
emit_alu(&s);
}