Mesa (master): r600: fix fragment.position

Andre Maasikas andrem at kemper.freedesktop.org
Mon Dec 14 23:49:30 PST 2009


Module: Mesa
Branch: master
Commit: bae5e7f213b7df1d7e3381e64b69beffd1243dc4
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=bae5e7f213b7df1d7e3381e64b69beffd1243dc4

Author: Andre Maasikas <amaasikas at gmail.com>
Date:   Mon Dec 14 16:39:19 2009 +0200

r600: fix fragment.position

wpos.y seems inferted to what opengl expexts, so calculate correct
value from window dimension and replace references in fragmentprog
with calculated value

---

 src/mesa/drivers/dri/r600/r700_fragprog.c |   67 ++++++++++++++++++++++++++++-
 src/mesa/drivers/dri/r600/r700_fragprog.h |    2 +
 2 files changed, 68 insertions(+), 1 deletions(-)

diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.c b/src/mesa/drivers/dri/r600/r700_fragprog.c
index 3352e41..bc2c5d5 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.c
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.c
@@ -42,6 +42,65 @@
 
 #include "r700_debug.h"
 
+void insert_wpos_code(GLcontext *ctx, struct gl_fragment_program *fprog)
+{
+    static const gl_state_index winstate[STATE_LENGTH]
+         = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0};
+    struct prog_instruction *newInst, *inst;
+    const GLuint origLen = fprog->Base.NumInstructions;
+    const GLuint newLen = origLen + 1;
+    GLint  win_size;  /* state reference */
+    GLuint wpos_temp; /* temp register */
+    int i, j;
+
+    /* PARAM win_size = STATE_FB_SIZE */
+    win_size = _mesa_add_state_reference(fprog->Base.Parameters, winstate);
+
+    wpos_temp = fprog->Base.NumTemporaries++;
+
+    /* Alloc storage for new instructions */
+    newInst = _mesa_alloc_instructions(newLen);
+
+    _mesa_init_instructions(newInst,1);
+
+    /* invert wpos.y
+     * wpos_temp.xyzw = wpos.x-yzw + winsize.0y00 */
+    newInst[0].Opcode = OPCODE_ADD;
+    newInst[0].DstReg.File = PROGRAM_TEMPORARY;
+    newInst[0].DstReg.Index = wpos_temp;
+    newInst[0].DstReg.WriteMask = WRITEMASK_XYZW;
+
+    newInst[0].SrcReg[0].File = PROGRAM_INPUT;
+    newInst[0].SrcReg[0].Index = FRAG_ATTRIB_WPOS;
+    newInst[0].SrcReg[0].Swizzle = SWIZZLE_XYZW;
+    newInst[0].SrcReg[0].Negate = NEGATE_Y;
+
+    newInst[0].SrcReg[1].File = PROGRAM_STATE_VAR;
+    newInst[0].SrcReg[1].Index = win_size;
+    newInst[0].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ZERO);
+
+    /* scan program where WPOS is used and replace with wpos_temp */
+    inst = fprog->Base.Instructions;
+    for (i = 0; i < fprog->Base.NumInstructions; i++) {
+        for (j=0; j < 3; j++) {
+            if(inst->SrcReg[j].File == PROGRAM_INPUT && 
+               inst->SrcReg[j].Index == FRAG_ATTRIB_WPOS) {
+                inst->SrcReg[j].File = PROGRAM_TEMPORARY;
+                inst->SrcReg[j].Index = wpos_temp;
+            }
+        }
+        inst++;
+    }
+    /* Append original instructions after new instructions */
+    _mesa_copy_instructions (newInst + 1, fprog->Base.Instructions, origLen);
+    /* free old instructions */
+    _mesa_free_instructions(fprog->Base.Instructions, origLen);
+    /* install new instructions */
+    fprog->Base.Instructions = newInst;
+    fprog->Base.NumInstructions = newLen;
+
+}
+
 //TODO : Validate FP input with VP output.
 void Map_Fragment_Program(r700_AssemblerBase         *pAsm,
 						  struct gl_fragment_program *mesa_fp,
@@ -318,7 +377,13 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
 
     //Init_Program
 	Init_r700_AssemblerBase( SPT_FP, &(fp->r700AsmCode), &(fp->r700Shader) );
-	Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp, ctx); 
+
+    if(mesa_fp->Base.InputsRead & FRAG_BIT_WPOS)
+    {
+        insert_wpos_code(ctx, mesa_fp);
+    }
+
+    Map_Fragment_Program(&(fp->r700AsmCode), mesa_fp, ctx); 
 
     if( GL_FALSE == Find_Instruction_Dependencies_fp(fp, mesa_fp) )
 	{
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.h b/src/mesa/drivers/dri/r600/r700_fragprog.h
index e562bfa..39c59c9 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.h
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.h
@@ -48,6 +48,8 @@ struct r700_fragment_program
 };
 
 /* Internal */
+void insert_wpos_code(GLcontext *ctx, struct gl_fragment_program *fprog);
+
 void Map_Fragment_Program(r700_AssemblerBase         *pAsm,
 			  struct gl_fragment_program *mesa_fp,
                           GLcontext *ctx); 



More information about the mesa-commit mailing list