r300: Introduce rc_program and use it in radeon_pair
authorNicolai Hähnle <nhaehnle@gmail.com>
Wed, 22 Jul 2009 20:10:13 +0000 (22:10 +0200)
committerNicolai Hähnle <nhaehnle@gmail.com>
Mon, 27 Jul 2009 18:32:05 +0000 (20:32 +0200)
The goal is to convert both Mesa and TGSI programs into an intermediate format
that happens to be convenient for us.

Signed-off-by: Nicolai Hähnle <nhaehnle@gmail.com>
src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
src/mesa/drivers/dri/r300/compiler/radeon_program.c
src/mesa/drivers/dri/r300/compiler/radeon_program.h
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
src/mesa/drivers/dri/r300/r300_fragprog_common.c

index 861d532d072076bd46f78f44417aca8435f2928c..672b36532c9a6bfd6fa0b10ab84f446680a5fab0 100644 (file)
@@ -334,7 +334,7 @@ GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *
        code->node[0].alu_end = -1;
        code->node[0].tex_end = -1;
 
-       if (!radeonPairProgram(&compiler->Base, compiler->program, &pair_handler, compiler))
+       if (!radeonPairProgram(&compiler->Base, &pair_handler, compiler))
                return GL_FALSE;
 
        if (!finish_node(compiler))
index d4a6205e7002604e43888bb3b1f4f7b5254f4548..30fedb42118a0de32baac15c2f81b02518ab31a7 100644 (file)
@@ -297,6 +297,8 @@ GLboolean r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c
                fflush(stdout);
        }
 
+       rc_mesa_to_rc_program(&c->Base, c->program);
+
        if (c->is_r500) {
                success = r500BuildFragmentProgramHwCode(c);
        } else {
index a0cc88da9caba80fc52a3f6cbad4f549a3a1f1f3..f8a1dc5fbebea8f6dffaf36e31acb716d19a2fa5 100644 (file)
@@ -310,7 +310,7 @@ GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *
        code->inst_offset = 0;
        code->inst_end = -1;
 
-       if (!radeonPairProgram(&compiler->Base, compiler->program, &pair_handler, compiler))
+       if (!radeonPairProgram(&compiler->Base, &pair_handler, compiler))
                return GL_FALSE;
 
        if ((code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {
index 20af4a651aac55ba9d318ac438ee12856a78c61a..17c9b17682cb54ccc10673f9c21545ded536174b 100644 (file)
@@ -28,6 +28,9 @@ void rc_init(struct radeon_compiler * c)
        memset(c, 0, sizeof(*c));
 
        memory_pool_init(&c->Pool);
+       c->Program.Instructions.Prev = &c->Program.Instructions;
+       c->Program.Instructions.Next = &c->Program.Instructions;
+       c->Program.Instructions.I.Opcode = OPCODE_END;
 }
 
 void rc_destroy(struct radeon_compiler * c)
index 6c5a2e5c8c33b94ded84157753dd12eb49a0233f..9b9b9c5c6545746677c29b95d8879fee48f44997 100644 (file)
@@ -150,8 +150,26 @@ struct rX00_fragment_program_code {
        gl_frag_attrib fog_attr;
 };
 
+struct rc_instruction {
+       struct rc_instruction * Prev;
+       struct rc_instruction * Next;
+       struct prog_instruction I;
+};
+
+struct rc_program {
+       /**
+        * Instructions.Next points to the first instruction,
+        * Instructions.Prev points to the last instruction.
+        */
+       struct rc_instruction Instructions;
+
+       GLbitfield InputsRead;
+       GLbitfield ShadowSamplers; /**< Texture units used for shadow sampling. */
+};
+
 struct radeon_compiler {
        struct memory_pool Pool;
+       struct rc_program Program;
        GLboolean Debug;
 };
 
index 0022d0a76ce92f90f892abf24270b5ef24fa87f8..d6cc62ff8bd422e9bd0348b9e4a60e8037f8b061 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "radeon_program.h"
 
+#include "radeon_compiler.h"
 #include "shader/prog_print.h"
 
 
@@ -124,3 +125,72 @@ struct prog_instruction *radeonAppendInstructions(struct gl_program *program, in
        _mesa_insert_instructions(program, oldnum, count);
        return program->Instructions + oldnum;
 }
+
+
+GLint rc_find_free_temporary(struct radeon_compiler * c)
+{
+       GLboolean used[MAX_PROGRAM_TEMPS];
+       GLuint 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;
+
+               for (k = 0; k < n; k++) {
+                       if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
+                               used[inst->SrcReg[k].Index] = GL_TRUE;
+               }
+       }
+
+       for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+               if (!used[i])
+                       return i;
+       }
+
+       return -1;
+}
+
+
+struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c)
+{
+       struct rc_instruction * inst = memory_pool_malloc(&c->Pool, sizeof(struct rc_instruction));
+
+       inst->Prev = 0;
+       inst->Next = 0;
+
+       _mesa_init_instructions(&inst->I, 1);
+
+       return inst;
+}
+
+
+struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after)
+{
+       struct rc_instruction * inst = rc_alloc_instruction(c);
+
+       inst->Prev = after;
+       inst->Next = after->Next;
+
+       inst->Prev->Next = inst;
+       inst->Next->Prev = inst;
+
+       return inst;
+}
+
+
+void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program)
+{
+       struct prog_instruction *source;
+
+       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;
+       }
+
+       c->Program.ShadowSamplers = program->ShadowSamplers;
+       c->Program.InputsRead = program->InputsRead;
+}
+
index 5b42883812a209f503f8e2a92886630f717a06fa..7e0f25448376f1143cd0dc9721b077ea61e49080 100644 (file)
@@ -34,6 +34,8 @@
 #include "shader/program.h"
 #include "shader/prog_instruction.h"
 
+struct radeon_compiler;
+struct rc_instruction;
 
 enum {
        PROGRAM_BUILTIN = PROGRAM_FILE_MAX /**< not a real register, but a special swizzle constant */
@@ -120,4 +122,11 @@ GLint radeonFindFreeTemporary(struct radeon_transform_context *ctx);
 
 struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count);
 
+GLint rc_find_free_temporary(struct radeon_compiler * c);
+
+struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
+struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after);
+
+void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program);
+
 #endif
index 5e0484f29604aafdfa7a54f43d91af4e4bfda6e7..ffc218b5ecc8f707dcf7f6f2d71d1e35372b126a 100644 (file)
@@ -120,7 +120,6 @@ struct pair_register_translation {
 
 struct pair_state {
        struct radeon_compiler * Compiler;
-       struct gl_program *Program;
        const struct radeon_pair_handler *Handler;
        GLboolean Error;
        GLboolean Verbose;
@@ -335,16 +334,16 @@ static void classify_instruction(struct pair_state *s,
  */
 static void scan_instructions(struct pair_state *s)
 {
-       struct prog_instruction *source;
+       struct rc_instruction *source;
        GLuint ip;
 
-       for(source = s->Program->Instructions, ip = 0;
-           source->Opcode != OPCODE_END;
-           ++source, ++ip) {
+       for(source = s->Compiler->Program.Instructions.Next, ip = 0;
+           source != &s->Compiler->Program.Instructions;
+           source = source->Next, ++ip) {
                struct pair_state_instruction *pairinst = memory_pool_malloc(&s->Compiler->Pool, sizeof(*pairinst));
                memset(pairinst, 0, sizeof(struct pair_state_instruction));
 
-               pairinst->Instruction = *source;
+               pairinst->Instruction = source->I;
                pairinst->IP = ip;
                final_rewrite(s, &pairinst->Instruction);
                classify_instruction(s, pairinst);
@@ -438,7 +437,7 @@ static void scan_instructions(struct pair_state *s)
  */
 static void allocate_input_registers(struct pair_state *s)
 {
-       GLuint InputsRead = s->Program->InputsRead;
+       GLuint InputsRead = s->Compiler->Program.InputsRead;
        int i;
        GLuint hwindex = 0;
 
@@ -876,14 +875,12 @@ static void emit_alu(struct pair_state *s)
 
 GLboolean radeonPairProgram(
        struct radeon_compiler * compiler,
-       struct gl_program *program,
        const struct radeon_pair_handler* handler, void *userdata)
 {
        struct pair_state s;
 
        _mesa_bzero(&s, sizeof(s));
        s.Compiler = compiler;
-       s.Program = program;
        s.Handler = handler;
        s.UserData = userdata;
        s.Verbose = GL_FALSE && s.Compiler->Debug;
index 2e6bdf90390b33679deed89ab05d12460d279777..3992082662b570ade881b41ac0241558f3279485 100644 (file)
@@ -143,7 +143,6 @@ struct radeon_pair_handler {
 
 GLboolean radeonPairProgram(
        struct radeon_compiler * compiler,
-       struct gl_program *program,
        const struct radeon_pair_handler*, void *userdata);
 
 void radeonPrintPairInstruction(struct radeon_pair_instruction *inst);
index 5216f5904ad1a14bee54db84375f88fd225cc2ce..a89dbb004999781c95a74c5f81fe0063b748d1e9 100644 (file)
@@ -100,7 +100,7 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog
        if (!r3xx_compile_fragment_program(&compiler))
                fp->error = GL_TRUE;
 
-       fp->InputsRead = compiler.program->InputsRead;
+       fp->InputsRead = compiler.Base.Program.InputsRead;
        fp->Base = compiler.program;
 
        rc_destroy(&compiler.Base);