#include "radeon_program.h"
+#include <stdio.h>
+
#include "radeon_compiler.h"
-#include "shader/prog_print.h"
/**
* one instruction at a time.
*/
void radeonLocalTransform(
- struct gl_program *program,
+ struct radeon_compiler * c,
int num_transformations,
struct radeon_program_transformation* transformations)
{
- struct radeon_transform_context ctx;
- int ip;
-
- ctx.Program = program;
- ctx.OldInstructions = program->Instructions;
- ctx.OldNumInstructions = program->NumInstructions;
-
- program->Instructions = 0;
- program->NumInstructions = 0;
+ struct rc_instruction * inst = c->Program.Instructions.Next;
- for(ip = 0; ip < ctx.OldNumInstructions; ++ip) {
- struct prog_instruction *instr = ctx.OldInstructions + ip;
+ while(inst != &c->Program.Instructions) {
+ struct rc_instruction * current = inst;
int i;
+ inst = inst->Next;
+
for(i = 0; i < num_transformations; ++i) {
struct radeon_program_transformation* t = transformations + i;
- if (t->function(&ctx, instr, t->userData))
+ if (t->function(c, current, t->userData))
break;
}
-
- if (i >= num_transformations) {
- struct prog_instruction* dest = radeonAppendInstructions(program, 1);
- _mesa_copy_instructions(dest, instr, 1);
- }
- }
-
- _mesa_free_instructions(ctx.OldInstructions, ctx.OldNumInstructions);
-}
-
-
-static void scan_instructions(GLboolean* used, const struct prog_instruction* insts, GLuint count)
-{
- GLuint i;
- for (i = 0; i < count; i++) {
- const struct prog_instruction *inst = insts + i;
- const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
- GLuint k;
-
- for (k = 0; k < n; k++) {
- if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
- used[inst->SrcReg[k].Index] = GL_TRUE;
- }
- }
-}
-
-GLint radeonFindFreeTemporary(struct radeon_transform_context *t)
-{
- GLboolean used[MAX_PROGRAM_TEMPS];
- GLuint i;
-
- _mesa_memset(used, 0, sizeof(used));
- scan_instructions(used, t->Program->Instructions, t->Program->NumInstructions);
- scan_instructions(used, t->OldInstructions, t->OldNumInstructions);
-
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
- if (!used[i])
- return i;
}
-
- return -1;
}
-
/**
- * Append the given number of instructions to the program and return a
- * pointer to the first new instruction.
+ * Left multiplication of a register with a swizzle
*/
-struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count)
+struct rc_src_register lmul_swizzle(unsigned int swizzle, struct rc_src_register srcreg)
{
- int oldnum = program->NumInstructions;
- _mesa_insert_instructions(program, oldnum, count);
- return program->Instructions + oldnum;
+ struct rc_src_register tmp = srcreg;
+ int i;
+ tmp.Swizzle = 0;
+ tmp.Negate = 0;
+ for(i = 0; i < 4; ++i) {
+ rc_swizzle swz = GET_SWZ(swizzle, i);
+ if (swz < 4) {
+ tmp.Swizzle |= GET_SWZ(srcreg.Swizzle, swz) << (i*3);
+ tmp.Negate |= GET_BIT(srcreg.Negate, swz) << i;
+ } else {
+ tmp.Swizzle |= swz << (i*3);
+ }
+ }
+ return tmp;
}
-
-GLint rc_find_free_temporary(struct radeon_compiler * c)
+unsigned int rc_find_free_temporary(struct radeon_compiler * c)
{
- GLboolean used[MAX_PROGRAM_TEMPS];
- GLuint i;
+ char used[RC_REGISTER_MAX_INDEX];
+ unsigned int i;
memset(used, 0, sizeof(used));
for (struct rc_instruction * rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
- const struct prog_instruction *inst = &rcinst->I;
- const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
- GLuint k;
+ const struct rc_sub_instruction *inst = &rcinst->I;
+ const struct rc_opcode_info *opcode = rc_get_opcode_info(inst->Opcode);
+ unsigned int k;
- for (k = 0; k < n; k++) {
- if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
- used[inst->SrcReg[k].Index] = GL_TRUE;
+ for (k = 0; k < opcode->NumSrcRegs; k++) {
+ if (inst->SrcReg[k].File == RC_FILE_TEMPORARY)
+ used[inst->SrcReg[k].Index] = 1;
+ }
+
+ if (opcode->HasDstReg) {
+ if (inst->DstReg.File == RC_FILE_TEMPORARY)
+ used[inst->DstReg.Index] = 1;
}
}
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+ for (i = 0; i < RC_REGISTER_MAX_INDEX; i++) {
if (!used[i])
return i;
}
- return -1;
+ rc_error(c, "Ran out of temporary registers\n");
+ return 0;
}
{
struct rc_instruction * inst = memory_pool_malloc(&c->Pool, sizeof(struct rc_instruction));
- inst->Prev = 0;
- inst->Next = 0;
+ memset(inst, 0, sizeof(struct rc_instruction));
- _mesa_init_instructions(&inst->I, 1);
+ inst->I.Opcode = RC_OPCODE_ILLEGAL_OPCODE;
+ inst->I.DstReg.WriteMask = RC_MASK_XYZW;
+ inst->I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW;
+ inst->I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZW;
+ inst->I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZW;
return inst;
}
return inst;
}
+void rc_remove_instruction(struct rc_instruction * inst)
+{
+ inst->Prev->Next = inst->Next;
+ inst->Next->Prev = inst->Prev;
+}
-void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program)
+/**
+ * Return the number of instructions in the program.
+ */
+unsigned int rc_recompute_ips(struct radeon_compiler * c)
{
- struct prog_instruction *source;
+ unsigned int ip = 0;
- for(source = program->Instructions; source->Opcode != OPCODE_END; ++source) {
- struct rc_instruction * dest = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
- dest->I = *source;
+ for(struct rc_instruction * inst = c->Program.Instructions.Next;
+ inst != &c->Program.Instructions;
+ inst = inst->Next) {
+ inst->IP = ip++;
}
- c->Program.ShadowSamplers = program->ShadowSamplers;
- c->Program.InputsRead = program->InputsRead;
-}
+ c->Program.Instructions.IP = 0xcafedead;
+ return ip;
+}