r300compiler, r300 classic, r300g: Add support for MRTs in the frag shader.
authorCorbin Simpson <MostAwesomeDude@gmail.com>
Wed, 11 Nov 2009 11:06:51 +0000 (03:06 -0800)
committerCorbin Simpson <MostAwesomeDude@gmail.com>
Tue, 2 Feb 2010 12:53:12 +0000 (04:53 -0800)
This maybe breaks the vert compiler. Hopefully not.

src/gallium/drivers/r300/r300_fs.c
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.h
src/mesa/drivers/dri/r300/compiler/radeon_pair_translate.c
src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
src/mesa/drivers/dri/r300/r300_fragprog_common.c

index 60ea9c171d5d9eef7090986dcf8080ce4fb1d8f7..39bcdc8fe60c9e6837262a366dd2fd7b376d8bcf 100644 (file)
@@ -77,17 +77,21 @@ void r300_shader_read_fs_inputs(struct tgsi_shader_info* info,
 static void find_output_registers(struct r300_fragment_program_compiler * compiler,
                                   struct r300_fragment_shader * fs)
 {
-    unsigned i;
+    unsigned i, colorbuf_count = 0;
 
     /* Mark the outputs as not present initially */
-    compiler->OutputColor = fs->info.num_outputs;
+    compiler->OutputColor[0] = fs->info.num_outputs;
+    compiler->OutputColor[1] = fs->info.num_outputs;
+    compiler->OutputColor[2] = fs->info.num_outputs;
+    compiler->OutputColor[3] = fs->info.num_outputs;
     compiler->OutputDepth = fs->info.num_outputs;
 
     /* Now see where they really are. */
     for(i = 0; i < fs->info.num_outputs; ++i) {
         switch(fs->info.output_semantic_name[i]) {
             case TGSI_SEMANTIC_COLOR:
-                compiler->OutputColor = i;
+                compiler->OutputColor[colorbuf_count] = i;
+                colorbuf_count++;
                 break;
             case TGSI_SEMANTIC_POSITION:
                 compiler->OutputDepth = i;
index 375838d98e76a4c8a969babfe7525e5d978fc17f..cc552aee176d210f5e6ca9723f67dd263bf74aa1 100644 (file)
@@ -176,7 +176,9 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i
                        (inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT);
        }
        if (inst->RGB.OutputWriteMask) {
-               code->alu.inst[ip].rgb_addr |= (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT);
+               code->alu.inst[ip].rgb_addr |=
+            (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT) |
+            R300_RGB_TARGET(inst->RGB.Target);
                emit->node_flags |= R300_RGBA_OUT;
        }
 
@@ -187,7 +189,8 @@ static int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* i
                        R300_ALU_DSTA_REG;
        }
        if (inst->Alpha.OutputWriteMask) {
-               code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT;
+               code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT |
+            R300_ALPHA_TARGET(inst->Alpha.Target);
                emit->node_flags |= R300_RGBA_OUT;
        }
        if (inst->Alpha.DepthWriteMask) {
index 5581f25352dcc3c24d76b8a1292110a020ba38c9..c2d5dc27b4902fc599e03b7330785ca4b7e48080 100644 (file)
@@ -35,7 +35,10 @@ static void dataflow_outputs_mark_use(void * userdata, void * data,
                void (*callback)(void *, unsigned int, unsigned int))
 {
        struct r300_fragment_program_compiler * c = userdata;
-       callback(data, c->OutputColor, RC_MASK_XYZW);
+       callback(data, c->OutputColor[0], RC_MASK_XYZW);
+       callback(data, c->OutputColor[1], RC_MASK_XYZW);
+       callback(data, c->OutputColor[2], RC_MASK_XYZW);
+       callback(data, c->OutputColor[3], RC_MASK_XYZW);
        callback(data, c->OutputDepth, RC_MASK_W);
 }
 
index b1b14394b6e8c5c0c84465dd6e6b226ac46615ff..c2eb613b23f26c92d86affa3dd0ab6875221a046 100644 (file)
@@ -241,6 +241,9 @@ static void emit_paired(struct r300_fragment_program_compiler *c, struct rc_pair
        code->inst[ip].inst4 |= translate_arg_alpha(inst, 1) << R500_ALPHA_SEL_B_SHIFT;
        code->inst[ip].inst5 |= translate_arg_alpha(inst, 2) << R500_ALU_RGBA_ALPHA_SEL_C_SHIFT;
 
+    code->inst[ip].inst3 |= R500_ALU_RGB_TARGET(inst->RGB.Target);
+    code->inst[ip].inst4 |= R500_ALPHA_TARGET(inst->Alpha.Target);
+
        if (inst->WriteALUResult) {
                code->inst[ip].inst3 |= R500_ALU_RGB_WMASK;
 
index f27f858652e3556acef6d27f3573bcc9284a6baf..6bfda0574f64c5793a7904ae8926caae3cf44a91 100644 (file)
@@ -83,8 +83,10 @@ struct r300_fragment_program_compiler {
        struct rX00_fragment_program_code *code;
        struct r300_fragment_program_external_state state;
        unsigned is_r500;
+    /* Register corresponding to the depthbuffer. */
        unsigned OutputDepth;
-       unsigned OutputColor;
+    /* Registers corresponding to the four colorbuffers. */
+       unsigned OutputColor[4];
 
        void * UserData;
        void (*AllocateHwInputs)(
index 72117682725982887d2fa08409243f9c858760d0..80cc5ffe9555de40a22d9f976b680e1bc4de3ab9 100644 (file)
@@ -203,12 +203,21 @@ static void set_pair_instruction(struct r300_fragment_program_compiler *c,
 
        /* Destination handling */
        if (inst->DstReg.File == RC_FILE_OUTPUT) {
-               if (inst->DstReg.Index == c->OutputColor) {
-                       pair->RGB.OutputWriteMask |= inst->DstReg.WriteMask & RC_MASK_XYZ;
-                       pair->Alpha.OutputWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
-               } else if (inst->DstReg.Index == c->OutputDepth) {
-                       pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
-               }
+        if (inst->DstReg.Index == c->OutputDepth) {
+            pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
+        } else {
+            for (i = 0; i < 4; i++) {
+                if (inst->DstReg.Index == c->OutputColor[i]) {
+                    pair->RGB.Target = inst->DstReg.Index;
+                    pair->Alpha.Target = inst->DstReg.Index;
+                    pair->RGB.OutputWriteMask |=
+                        inst->DstReg.WriteMask & RC_MASK_XYZ;
+                    pair->Alpha.OutputWriteMask |=
+                        GET_BIT(inst->DstReg.WriteMask, 3);
+                    break;
+                }
+            }
+        }
        } else {
                if (needrgb) {
                        pair->RGB.DestIndex = inst->DstReg.Index;
index 6685ade3ea844eea7224264083395530f908f6cf..511cc707a38d987321e5af382d4414c2d3f49ee4 100644 (file)
@@ -60,6 +60,7 @@ struct radeon_pair_instruction_rgb {
        unsigned int Opcode:8;
        unsigned int DestIndex:RC_REGISTER_INDEX_BITS;
        unsigned int WriteMask:3;
+    unsigned int Target:2;
        unsigned int OutputWriteMask:3;
        unsigned int Saturate:1;
 
@@ -77,6 +78,7 @@ struct radeon_pair_instruction_alpha {
        unsigned int Opcode:8;
        unsigned int DestIndex:RC_REGISTER_INDEX_BITS;
        unsigned int WriteMask:1;
+    unsigned int Target:2;
        unsigned int OutputWriteMask:1;
        unsigned int DepthWriteMask:1;
        unsigned int Saturate:1;
index e41aeff91a44a40e47c73ab3f56788865062976d..3ec43e62bd9ace1f2abd944ed38e6a90ff85ca6e 100644 (file)
@@ -221,7 +221,7 @@ static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_prog
        compiler.state = fp->state;
        compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE;
        compiler.OutputDepth = FRAG_RESULT_DEPTH;
-       compiler.OutputColor = FRAG_RESULT_COLOR;
+       compiler.OutputColor[0] = FRAG_RESULT_COLOR;
        compiler.AllocateHwInputs = &allocate_hw_inputs;
 
        if (compiler.Base.Debug) {