Roland Scheidegger wrote:
> Rune Petersen wrote:
>> I hit a problem constructing this:
>>
>> - In order to do range mapping in the vertex shader (if I so choose)
>> I will need a constant (0.5), but how to add it?
> I think this might work similar to what is used for position invariant
> programs, instead of using _mesa_add_state_reference you could try
> _mesa_add_named_parameter. Otherwise, you could always "construct" 0.5
> in the shader itself, since you always have the constants 0 and 1
> available thanks to the powerful swizzling capabilities, though
> surprsingly it seems somewhat complicated. Either use 2 instructions
> (ADD 1+1, RCP). Or try EX2/EXP though I'm not sure about performance of
> these, but I guess the approximated EXP should do (2^-1).
> 

This math in this patch appear sound. the doom3-demo issue appear
unrelated to fragment.position.

This version makes use of existing instructions to calculate
result.position.

split into 2 parts:
        - select_vertex_shader changes
        - The actual fragment.position changes

This patch assumes that:

- That the temp used to calculate result.position is safe to use (true
for std. use).

- That fragment.position.x & y wont be used (mostly true, except for
exotic programs.)
   In order to fix this, I'll need to know the window size, but how?


- That select_vertex_shader changes (by Aapo Tahkola) is acceptable for
  the r300 driver.


Rune Petersen
diff -Naur -x '*.o' -x '*.so' -x Entries -x depend r300-dev/r300_fragprog.c 
r300_fragprog.c
--- r300_fragprog.c     2006-09-17 13:49:38.000000000 +0200
+++ r300_fragprog.c     2006-10-05 18:59:57.000000000 +0200
@@ -1400,6 +1400,13 @@
        }
        InputsRead &= ~FRAG_BITS_TEX_ANY;
 
+       /* fragment position treated as a texcoord */
+       if (InputsRead & FRAG_BIT_WPOS) {
+               cs->inputs[FRAG_ATTRIB_WPOS].refcount = 0;
+               cs->inputs[FRAG_ATTRIB_WPOS].reg = get_hw_temp(rp);
+       }
+       InputsRead &= ~FRAG_BIT_WPOS;
+
        /* Then primary colour */
        if (InputsRead & FRAG_BIT_COL0) {
                cs->inputs[FRAG_ATTRIB_COL0].refcount = 0;
diff -Naur -x '*.o' -x '*.so' -x Entries -x depend r300_state.c r300_state.c
--- r300_state.c        2006-09-17 13:49:36.000000000 +0200
+++ r300_state.c        2006-10-04 22:58:14.000000000 +0200
@@ -1305,6 +1305,20 @@
 
        r300->hw.rr.cmd[R300_RR_ROUTE_1] = 0;
        
+       if (InputsRead & FRAG_BIT_WPOS){
+               for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+                       if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
+                               break;
+
+               if(i == ctx->Const.MaxTextureUnits){
+                       fprintf(stderr, "\tno free texcoord found...\n");
+                       exit(0);
+               }
+
+               InputsRead |= (FRAG_BIT_TEX0 << i);
+               InputsRead &= ~FRAG_BIT_WPOS;
+       }
+       
        for (i=0;i<ctx->Const.MaxTextureUnits;i++) {
                r300->hw.ri.cmd[R300_RI_INTERP_0+i] = 0
                                | R300_RS_INTERP_USED
diff -Naur -x '*.o' -x '*.so' -x Entries -x depend r300_vertexprog.c 
r300_vertexprog.c
--- r300_vertexprog.c   2006-10-05 19:04:22.000000000 +0200
+++ r300_vertexprog.c   2006-10-05 19:05:10.000000000 +0200
@@ -950,6 +950,133 @@
        //_mesa_print_program(&mesa_vp->Base);
 }
 
+int wpos_idx;
+
+static void insert_pos(struct gl_program *prog, int pos)
+{
+       struct prog_instruction *vpi;
+       struct prog_instruction *vpi_insert;
+       GLuint temp_index, temp_index2;
+       int i = 0;
+       
+       vpi = malloc((prog->NumInstructions + 5) * sizeof(struct 
prog_instruction));
+       memcpy(vpi, prog->Instructions, (pos+1) * sizeof(struct 
prog_instruction));
+       
+       vpi_insert = &vpi[pos];
+
+       /* make a copy before outputting VERT_RESULT_HPOS */
+       vpi_insert->DstReg.File = vpi_insert->SrcReg[2].File;
+       vpi_insert->DstReg.Index = temp_index = vpi_insert->SrcReg[2].Index;
+       
+       vpi_insert++;
+       memset(vpi_insert, 0, 5 * sizeof(struct prog_instruction));
+
+       vpi_insert[i].Opcode = OPCODE_MOV;
+
+       vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
+       vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS;
+       vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
+       vpi_insert[i].DstReg.CondMask = COND_TR;
+
+       vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[0].Index = temp_index;
+       vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, 
SWIZZLE_Z, SWIZZLE_W);
+       i++;
+
+       /* perspective divide */
+       vpi_insert[i].Opcode = OPCODE_RCP;
+
+       vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+       vpi_insert[i].DstReg.Index = temp_index;
+       vpi_insert[i].DstReg.WriteMask = WRITEMASK_W;
+       vpi_insert[i].DstReg.CondMask = COND_TR;
+
+       vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[0].Index = temp_index;
+       vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, 
SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
+       i++;
+
+       vpi_insert[i].Opcode = OPCODE_MUL;
+
+       vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+       vpi_insert[i].DstReg.Index = temp_index;
+       vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZ;
+       vpi_insert[i].DstReg.CondMask = COND_TR;
+
+       vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[0].Index = temp_index;
+       vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, 
SWIZZLE_Z, SWIZZLE_ZERO);
+
+       vpi_insert[i].SrcReg[1].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[1].Index = temp_index;
+       vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_W, SWIZZLE_W, 
SWIZZLE_W, SWIZZLE_ZERO);
+       i++;
+
+       /* map to range [0 1] */
+       
+       /* get temp */
+       temp_index2 = prog->NumTemporaries++;
+
+       vpi_insert[i].Opcode = OPCODE_EXP;
+
+       vpi_insert[i].DstReg.File = PROGRAM_TEMPORARY;
+       vpi_insert[i].DstReg.Index = temp_index2;
+       vpi_insert[i].DstReg.WriteMask = WRITEMASK_Z;
+       vpi_insert[i].DstReg.CondMask = COND_TR;
+
+       vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[0].Index = temp_index2;
+       vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, 
SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO);
+       vpi_insert[i].SrcReg[0].NegateBase = VSF_FLAG_ALL;
+       i++;
+
+       vpi_insert[i].Opcode = OPCODE_MAD;
+
+       vpi_insert[i].DstReg.File = PROGRAM_OUTPUT;
+       vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0+wpos_idx;
+       vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW;
+       vpi_insert[i].DstReg.CondMask = COND_TR;
+
+       vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[0].Index = temp_index;
+       vpi_insert[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, 
SWIZZLE_Z, SWIZZLE_W);
+
+       vpi_insert[i].SrcReg[1].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[1].Index = temp_index2;
+       vpi_insert[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, 
SWIZZLE_ONE, SWIZZLE_Z, SWIZZLE_ONE);
+
+       vpi_insert[i].SrcReg[2].File = PROGRAM_TEMPORARY;
+       vpi_insert[i].SrcReg[2].Index = temp_index2;
+       vpi_insert[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ZERO, 
SWIZZLE_ZERO, SWIZZLE_Z, SWIZZLE_ZERO);
+       i++;
+
+       memcpy(&vpi_insert[i], &prog->Instructions[pos+1], 
(prog->NumInstructions-(pos+1)) * sizeof(struct prog_instruction));
+
+       free(prog->Instructions);
+
+       prog->Instructions = vpi;
+
+       prog->NumInstructions += i;
+       vpi = &prog->Instructions[prog->NumInstructions-1];
+
+       assert(vpi->Opcode == OPCODE_END);
+}
+
+static void pos_as_texcoord(struct gl_program *prog)
+{
+       struct prog_instruction *vpi;
+       int inst = 0;
+       
+       for(vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++, inst++){
+               if( vpi->DstReg.File == PROGRAM_OUTPUT &&
+                   vpi->DstReg.Index == VERT_RESULT_HPOS ){
+                       insert_pos(prog, inst);
+                       break;
+               }
+       }
+
+}
+
 static struct r300_vertex_program *build_program(struct 
r300_vertex_program_key *wanted_key,
                                                 struct r300_vertex_program_key 
*curr_key,
                                                 struct gl_vertex_program 
*mesa_vp)
@@ -959,9 +1086,20 @@
        vp = _mesa_calloc(sizeof(*vp));
        _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
 
+fprintf(stderr, "__vertex__\n");
+_mesa_print_program(&mesa_vp->Base);
+fflush(stdout);
+
        if(mesa_vp->IsPositionInvariant)
                position_invariant(&mesa_vp->Base);
 
+       if(wpos_idx > -1)
+               pos_as_texcoord(&mesa_vp->Base);
+
+fprintf(stderr, "__vertex2__\n");
+_mesa_print_program(&mesa_vp->Base);
+fflush(stdout);
+
        assert(mesa_vp->Base.NumInstructions);
 
        vp->num_temporaries=mesa_vp->Base.NumTemporaries;
@@ -985,7 +1123,22 @@
 
        wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
 
-       if (InputsRead & FRAG_BIT_COL0)
+       wpos_idx = -1;
+       if (InputsRead & FRAG_BIT_WPOS){
+               for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+                       if (!(InputsRead & (FRAG_BIT_TEX0 << i)))
+                               break;
+               
+               if(i == ctx->Const.MaxTextureUnits){
+                       fprintf(stderr, "\tno free texcoord found\n");
+                       exit(0);
+               }
+
+               InputsRead |= (FRAG_BIT_TEX0 << i);
+               wpos_idx = i;
+       }
+
+       //if (InputsRead & FRAG_BIT_COL0)
                wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
 
        if ((InputsRead & FRAG_BIT_COL1) /*||
? server
Index: r300_context.h
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_context.h,v
retrieving revision 1.104
diff -u -r1.104 r300_context.h
--- r300_context.h      12 Sep 2006 18:34:43 -0000      1.104
+++ r300_context.h      5 Oct 2006 19:10:19 -0000
@@ -592,7 +592,8 @@
        
 extern int hw_tcl_on;
 
-#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current)
+//#define CURRENT_VERTEX_SHADER(ctx) (ctx->VertexProgram._Current)
+#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp)
 
 /* Should but doesnt work */
 //#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->curr_vp)
@@ -607,12 +608,18 @@
 /* r300_vertex_shader_state and r300_vertex_program should probably be merged 
together someday.
  * Keeping them them seperate for now should ensure fixed pipeline keeps 
functioning properly.
  */    
+
+struct r300_vertex_program_key {
+       GLuint InputsRead;
+       GLuint OutputsWritten;
+};
+
 struct r300_vertex_program {
-       struct gl_vertex_program mesa_program; /* Must be first */
+       struct r300_vertex_program *next;
+       struct r300_vertex_program_key key;
        int translated;
        
        struct r300_vertex_shader_fragment program;
-       struct r300_vertex_shader_fragment params;
        
        int pos_end;
        int num_temporaries; /* Number of temp vars used by program */
@@ -623,6 +630,12 @@
        int use_ref_count;
 };
 
+struct r300_vertex_program_cont {
+       struct gl_vertex_program mesa_program; /* Must be first */
+       struct r300_vertex_shader_fragment params;
+       struct r300_vertex_program *progs;
+};
+
 #define PFS_MAX_ALU_INST       64
 #define PFS_MAX_TEX_INST       64
 #define PFS_MAX_TEX_INDIRECT 4
@@ -797,6 +810,7 @@
        struct r300_cmdbuf cmdbuf;
        struct r300_state state;
        struct gl_vertex_program *curr_vp;
+       struct r300_vertex_program *selected_vp;
 
        /* Vertex buffers
         */
@@ -854,9 +868,9 @@
 
 extern int r300_get_num_verts(r300ContextPtr rmesa, int num_verts, int prim);
 
-void r300_translate_vertex_shader(struct r300_vertex_program *vp);
+extern void r300_select_vertex_shader(r300ContextPtr r300);
 extern void r300InitShaderFuncs(struct dd_function_table *functions);
-extern int r300VertexProgUpdateParams(GLcontext *ctx, struct 
r300_vertex_program *vp, float *dst);
+extern int r300VertexProgUpdateParams(GLcontext *ctx, struct 
r300_vertex_program_cont *vp, float *dst);
 extern int r300Fallback(GLcontext *ctx);
 
 extern void radeon_vb_to_rvb(r300ContextPtr rmesa, struct radeon_vertex_buffer 
*rvb, struct vertex_buffer *vb);
Index: r300_maos.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_maos.c,v
retrieving revision 1.39
diff -u -r1.39 r300_maos.c
--- r300_maos.c 14 Sep 2006 16:17:06 -0000      1.39
+++ r300_maos.c 5 Oct 2006 19:10:21 -0000
@@ -407,8 +407,8 @@
        if (hw_tcl_on) {
                struct r300_vertex_program *prog=(struct r300_vertex_program 
*)CURRENT_VERTEX_SHADER(ctx);
                inputs = prog->inputs;
-               InputsRead = CURRENT_VERTEX_SHADER(ctx)->Base.InputsRead;
-               OutputsWritten = 
CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
+               InputsRead = CURRENT_VERTEX_SHADER(ctx)->key.InputsRead;
+               OutputsWritten = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
        } else {
                DECLARE_RENDERINPUTS(inputs_bitset);
                inputs = r300->state.sw_tcl_inputs;
Index: r300_shader.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_shader.c,v
retrieving revision 1.18
diff -u -r1.18 r300_shader.c
--- r300_shader.c       20 Jul 2006 16:49:57 -0000      1.18
+++ r300_shader.c       5 Oct 2006 19:10:21 -0000
@@ -12,13 +12,13 @@
 {
        
        r300ContextPtr rmesa = R300_CONTEXT(ctx);
-       struct r300_vertex_program *vp=(void *)prog;
+       struct r300_vertex_program_cont *vp=(void *)prog;
        
        
        switch(target){
                case GL_VERTEX_PROGRAM_ARB:
-               rmesa->curr_vp = (struct gl_vertex_program *)vp;
-               vp->ref_count++;
+               //rmesa->curr_vp = (struct gl_vertex_program *)vp;
+               //vp->ref_count++;
 #if 0
                if((vp->ref_count % 1500) == 0) {
                        fprintf(stderr, "id %p, ref_count %d\n", vp, 
vp->ref_count);
@@ -37,13 +37,13 @@
 static struct gl_program *
 r300NewProgram(GLcontext *ctx, GLenum target, GLuint id)
 {
-       struct r300_vertex_program *vp;
+       struct r300_vertex_program_cont *vp;
        struct r300_fragment_program *fp;
        
        switch(target){
                case GL_VERTEX_STATE_PROGRAM_NV:
                case GL_VERTEX_PROGRAM_ARB:
-                       vp=CALLOC_STRUCT(r300_vertex_program);
+                       vp=CALLOC_STRUCT(r300_vertex_program_cont);
                        return _mesa_init_vertex_program(ctx, 
&vp->mesa_program, target, id);
                case GL_FRAGMENT_PROGRAM_ARB:
                        fp=CALLOC_STRUCT(r300_fragment_program);
@@ -77,13 +77,14 @@
 static void
 r300ProgramStringNotify(GLcontext *ctx, GLenum target, struct gl_program *prog)
 {
-       struct r300_vertex_program *vp=(void *)prog;
+       struct r300_vertex_program_cont *vp=(void *)prog;
        struct r300_fragment_program *fp = (struct r300_fragment_program *) 
prog;
        
        switch(target) {
        case GL_VERTEX_PROGRAM_ARB:
-               vp->translated = GL_FALSE;
-               memset(&vp->translated, 0, sizeof(struct r300_vertex_program) - 
sizeof(struct gl_vertex_program));
+               vp->progs = NULL;
+               /*vp->translated = GL_FALSE;
+               memset(&vp->translated, 0, sizeof(struct r300_vertex_program) - 
sizeof(struct gl_vertex_program));*/
                /*r300_translate_vertex_shader(vp);*/
        break;
        case GL_FRAGMENT_PROGRAM_ARB:
Index: r300_state.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_state.c,v
retrieving revision 1.165
diff -u -r1.165 r300_state.c
--- r300_state.c        12 Sep 2006 18:34:43 -0000      1.165
+++ r300_state.c        5 Oct 2006 19:10:27 -0000
@@ -1286,7 +1286,7 @@
        int i;
 
        if(hw_tcl_on)
-               OutputsWritten.vp_outputs = 
CURRENT_VERTEX_SHADER(ctx)->Base.OutputsWritten;
+               OutputsWritten.vp_outputs = 
CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
        else
                RENDERINPUTS_COPY( OutputsWritten.index_bitset, 
r300->state.render_inputs_bitset );
 
@@ -1611,7 +1611,7 @@
 
        ((drm_r300_cmd_header_t*)rmesa->hw.vpp.cmd)->vpu.count = 0;
        R300_STATECHANGE(rmesa, vpp);
-       param_count = r300VertexProgUpdateParams(ctx, prog, (float 
*)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
+       param_count = r300VertexProgUpdateParams(ctx, (struct 
r300_vertex_program_cont *)ctx->VertexProgram._Current/*prog*/, (float 
*)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
        bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
        param_count /= 4;
        
@@ -1670,9 +1670,10 @@
                        TNL_CONTEXT(ctx)->vb.AttribPtr[i] = 
rmesa->temp_attrib[i];
                }
                
+               r300_select_vertex_shader(rmesa);
                vp = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
-               if (vp->translated == GL_FALSE)
-                       r300_translate_vertex_shader(vp);
+               /*if (vp->translated == GL_FALSE)
+                       r300_translate_vertex_shader(vp);*/
                if (vp->translated == GL_FALSE) {
                        fprintf(stderr, "Failing back to sw-tcl\n");
                        hw_tcl_on = future_hw_tcl_on = 0;
Index: r300_texstate.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_texstate.c,v
retrieving revision 1.49
diff -u -r1.49 r300_texstate.c
--- r300_texstate.c     20 Sep 2006 19:11:56 -0000      1.49
+++ r300_texstate.c     5 Oct 2006 19:10:39 -0000
@@ -217,7 +217,7 @@
        t->tile_bits = 0;
 
        /* figure out if this texture is suitable for tiling. */
-#if 0 /* Disabled for now */
+#if 1 /* Disabled for now */
        if (texelBytes) {
                if (rmesa->texmicrotile  && (tObj->Target != 
GL_TEXTURE_RECTANGLE_NV) &&
                   /* texrect might be able to use micro tiling too in theory? 
*/
Index: r300_vertexprog.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/r300_vertexprog.c,v
retrieving revision 1.62
diff -u -r1.62 r300_vertexprog.c
--- r300_vertexprog.c   28 Aug 2006 19:42:41 -0000      1.62
+++ r300_vertexprog.c   5 Oct 2006 19:10:39 -0000
@@ -95,7 +95,7 @@
 };
 #undef OPN
        
-int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp, 
float *dst)
+int r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program_cont 
*vp, float *dst)
 {
        int pi;
        struct gl_vertex_program *mesa_vp = &vp->mesa_program;
@@ -384,10 +384,8 @@
                u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
        } while (0)
 
-void r300_translate_vertex_shader(struct r300_vertex_program *vp)
+static void r300_translate_vertex_shader(struct r300_vertex_program *vp, 
struct prog_instruction *vpi)
 {
-       struct gl_vertex_program *mesa_vp= &vp->mesa_program;
-       struct prog_instruction *vpi;
        int i, cur_reg=0;
        VERTEX_SHADER_INSTRUCTION *o_inst;
        unsigned long operands;
@@ -399,131 +397,9 @@
        int u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1;
        struct prog_src_register src[3];
 
-       if (mesa_vp->Base.NumInstructions == 0)
-               return;
-
-       if (getenv("R300_VP_SAFETY")) {
-               WARN_ONCE("R300_VP_SAFETY enabled.\n");
-               
-               vpi = malloc((mesa_vp->Base.NumInstructions + 
VSF_MAX_FRAGMENT_TEMPS) * sizeof(struct prog_instruction));
-               memset(vpi, 0, VSF_MAX_FRAGMENT_TEMPS * sizeof(struct 
prog_instruction));
-               
-               for (i=0; i < VSF_MAX_FRAGMENT_TEMPS; i++) {
-                       vpi[i].Opcode = OPCODE_MOV;
-                       vpi[i].StringPos = 0;
-                       vpi[i].Data = 0;
-                       
-                       vpi[i].DstReg.File = PROGRAM_TEMPORARY;
-                       vpi[i].DstReg.Index = i;
-                       vpi[i].DstReg.WriteMask = WRITEMASK_XYZW;
-                       vpi[i].DstReg.CondMask = COND_TR;
-                                       
-                       vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
-                       vpi[i].SrcReg[0].Index = 0;
-                       vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, 
SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE);
-               }
-               
-               memcpy(&vpi[i], mesa_vp->Base.Instructions, 
mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
-               
-               free(mesa_vp->Base.Instructions);
-               
-               mesa_vp->Base.Instructions = vpi;
-               
-               mesa_vp->Base.NumInstructions += VSF_MAX_FRAGMENT_TEMPS;
-               vpi = 
&mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
-               
-               assert(vpi->Opcode == OPCODE_END);
-       }
-       
-       if (mesa_vp->IsPositionInvariant) {
-               struct gl_program_parameter_list *paramList;
-               GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, 
STATE_MATRIX };
-
-#ifdef PREFER_DP4
-               tokens[5] = STATE_MATRIX;
-#else
-               tokens[5] = STATE_MATRIX_TRANSPOSE;
-#endif
-               paramList = mesa_vp->Base.Parameters;
-               
-               vpi = malloc((mesa_vp->Base.NumInstructions + 4) * 
sizeof(struct prog_instruction));
-               memset(vpi, 0, 4 * sizeof(struct prog_instruction));
-               
-               for (i=0; i < 4; i++) {
-                       GLint idx;
-                       tokens[3] = tokens[4] = i;
-                       idx = _mesa_add_state_reference(paramList, tokens);
-#ifdef PREFER_DP4
-                       vpi[i].Opcode = OPCODE_DP4;
-                       vpi[i].StringPos = 0;
-                       vpi[i].Data = 0;
-                       
-                       vpi[i].DstReg.File = PROGRAM_OUTPUT;
-                       vpi[i].DstReg.Index = VERT_RESULT_HPOS;
-                       vpi[i].DstReg.WriteMask = 1 << i;
-                       vpi[i].DstReg.CondMask = COND_TR;
-                                       
-                       vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
-                       vpi[i].SrcReg[0].Index = idx;
-                       vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, 
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-                       
-                       vpi[i].SrcReg[1].File = PROGRAM_INPUT;
-                       vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
-                       vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, 
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-#else
-                       if (i == 0)
-                               vpi[i].Opcode = OPCODE_MUL;
-                       else
-                               vpi[i].Opcode = OPCODE_MAD;
-                       
-                       vpi[i].StringPos = 0;
-                       vpi[i].Data = 0;
-                       
-                       if (i == 3)
-                               vpi[i].DstReg.File = PROGRAM_OUTPUT;
-                       else
-                               vpi[i].DstReg.File = PROGRAM_TEMPORARY;
-                       vpi[i].DstReg.Index = 0;
-                       vpi[i].DstReg.WriteMask = 0xf;
-                       vpi[i].DstReg.CondMask = COND_TR;
-                                       
-                       vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
-                       vpi[i].SrcReg[0].Index = idx;
-                       vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, 
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-                       
-                       vpi[i].SrcReg[1].File = PROGRAM_INPUT;
-                       vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
-                       vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
-                       
-                       if (i > 0) {
-                               vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
-                               vpi[i].SrcReg[2].Index = 0;
-                               vpi[i].SrcReg[2].Swizzle = 
MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
-                       }
-#endif                                 
-               }
-               
-               memcpy(&vpi[i], mesa_vp->Base.Instructions, 
mesa_vp->Base.NumInstructions * sizeof(struct prog_instruction));
-               
-               free(mesa_vp->Base.Instructions);
-               
-               mesa_vp->Base.Instructions = vpi;
-               
-               mesa_vp->Base.NumInstructions += 4;
-               vpi = 
&mesa_vp->Base.Instructions[mesa_vp->Base.NumInstructions-1];
-               
-               assert(vpi->Opcode == OPCODE_END);
-               
-               mesa_vp->Base.InputsRead |= (1 << VERT_ATTRIB_POS);
-               mesa_vp->Base.OutputsWritten |= (1 << VERT_RESULT_HPOS);
-               
-               //fprintf(stderr, "IsPositionInvariant is set!\n");
-               //_mesa_print_program(&mesa_vp->Base);
-       }
-       
        vp->pos_end=0; /* Not supported yet */
        vp->program.length=0;
-       vp->num_temporaries=mesa_vp->Base.NumTemporaries;
+       /*vp->num_temporaries=mesa_vp->Base.NumTemporaries;*/
        
        for(i=0; i < VERT_ATTRIB_MAX; i++)
                vp->inputs[i] = -1;
@@ -531,41 +407,41 @@
        for(i=0; i < VERT_RESULT_MAX; i++)
                vp->outputs[i] = -1;
        
-       assert(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS));
+       assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS));
        
        /* Assign outputs */
-       if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))
+       if(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS))
                vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
        
-       if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ))
+       if(vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ))
                vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
        
-       if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL0))
+       if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL0))
                vp->outputs[VERT_RESULT_COL0] = cur_reg++;
        
-       if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_COL1))
+       if(vp->key.OutputsWritten & (1 << VERT_RESULT_COL1))
                vp->outputs[VERT_RESULT_COL1] = cur_reg++;
        
 #if 0 /* Not supported yet */
-       if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0))
+       if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0))
                vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
        
-       if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1))
+       if(vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1))
                vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
        
-       if(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_FOGC))
+       if(vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC))
                vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
 #endif
        
        for(i=VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++)
-               if(mesa_vp->Base.OutputsWritten & (1 << i))
+               if(vp->key.OutputsWritten & (1 << i))
                        vp->outputs[i] = cur_reg++;
        
        vp->translated = GL_TRUE;
        vp->native = GL_TRUE;
        
        o_inst=vp->program.body.i;
-       for(vpi=mesa_vp->Base.Instructions; vpi->Opcode != OPCODE_END; vpi++, 
o_inst++){
+       for(; vpi->Opcode != OPCODE_END; vpi++, o_inst++){
                FREE_TEMPS();
                
                operands=op_operands(vpi->Opcode);
@@ -987,3 +863,156 @@
 #endif
 }
 
+static void position_invariant(struct gl_program *prog)
+{
+       struct prog_instruction *vpi;
+       struct gl_program_parameter_list *paramList;
+       int i;
+
+       GLint tokens[6] = { STATE_MATRIX, STATE_MVP, 0, 0, 0, STATE_MATRIX };
+
+#ifdef PREFER_DP4
+       tokens[5] = STATE_MATRIX;
+#else
+       tokens[5] = STATE_MATRIX_TRANSPOSE;
+#endif
+       paramList = prog->Parameters;
+
+       vpi = malloc((prog->NumInstructions + 4) * sizeof(struct 
prog_instruction));
+       memset(vpi, 0, 4 * sizeof(struct prog_instruction));
+
+       for (i=0; i < 4; i++) {
+               GLint idx;
+               tokens[3] = tokens[4] = i;
+               idx = _mesa_add_state_reference(paramList, tokens);
+#ifdef PREFER_DP4
+               vpi[i].Opcode = OPCODE_DP4;
+               vpi[i].StringPos = 0;
+               vpi[i].Data = 0;
+
+               vpi[i].DstReg.File = PROGRAM_OUTPUT;
+               vpi[i].DstReg.Index = VERT_RESULT_HPOS;
+               vpi[i].DstReg.WriteMask = 1 << i;
+               vpi[i].DstReg.CondMask = COND_TR;
+
+               vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+               vpi[i].SrcReg[0].Index = idx;
+               vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, 
SWIZZLE_Z, SWIZZLE_W);
+
+               vpi[i].SrcReg[1].File = PROGRAM_INPUT;
+               vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+               vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, 
SWIZZLE_Z, SWIZZLE_W);
+#else
+               if (i == 0)
+                       vpi[i].Opcode = OPCODE_MUL;
+               else
+                       vpi[i].Opcode = OPCODE_MAD;
+
+               vpi[i].StringPos = 0;
+               vpi[i].Data = 0;
+
+               if (i == 3)
+                       vpi[i].DstReg.File = PROGRAM_OUTPUT;
+               else
+                       vpi[i].DstReg.File = PROGRAM_TEMPORARY;
+               vpi[i].DstReg.Index = 0;
+               vpi[i].DstReg.WriteMask = 0xf;
+               vpi[i].DstReg.CondMask = COND_TR;
+
+               vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR;
+               vpi[i].SrcReg[0].Index = idx;
+               vpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, 
SWIZZLE_Z, SWIZZLE_W);
+
+               vpi[i].SrcReg[1].File = PROGRAM_INPUT;
+               vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS;
+               vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i);
+
+               if (i > 0) {
+                       vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY;
+                       vpi[i].SrcReg[2].Index = 0;
+                       vpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, 
SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W);
+               }
+#endif                                 
+       }
+
+       memcpy(&vpi[i], prog->Instructions, prog->NumInstructions * 
sizeof(struct prog_instruction));
+
+       free(prog->Instructions);
+
+       prog->Instructions = vpi;
+
+       prog->NumInstructions += 4;
+       vpi = &prog->Instructions[prog->NumInstructions-1];
+
+       assert(vpi->Opcode == OPCODE_END);
+
+       //fprintf(stderr, "IsPositionInvariant is set!\n");
+       //_mesa_print_program(&mesa_vp->Base);
+}
+
+static struct r300_vertex_program *build_program(struct 
r300_vertex_program_key *wanted_key,
+                                                struct r300_vertex_program_key 
*curr_key,
+                                                struct gl_vertex_program 
*mesa_vp)
+{
+       struct r300_vertex_program *vp;
+
+       vp = _mesa_calloc(sizeof(*vp));
+       _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
+
+       if(mesa_vp->IsPositionInvariant)
+               position_invariant(&mesa_vp->Base);
+
+       assert(mesa_vp->Base.NumInstructions);
+
+       vp->num_temporaries=mesa_vp->Base.NumTemporaries;
+
+       r300_translate_vertex_shader(vp, mesa_vp->Base.Instructions/*vpi*/);
+
+       return vp;      
+}
+
+void r300_select_vertex_shader(r300ContextPtr r300)
+{
+       GLcontext *ctx = ctx = r300->radeon.glCtx;
+       GLuint InputsRead;
+       struct r300_vertex_program_key curr_key, wanted_key = { 0 };
+       GLint i;
+       struct r300_vertex_program_cont *vpc;
+       struct r300_vertex_program *vp;
+
+       vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+       InputsRead = ctx->FragmentProgram._Current->Base.InputsRead;
+
+       wanted_key.OutputsWritten |= 1 << VERT_RESULT_HPOS;
+
+       if (InputsRead & FRAG_BIT_COL0)
+               wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL0;
+
+       if ((InputsRead & FRAG_BIT_COL1) /*||
+           (InputsRead & FRAG_BIT_FOGC)*/)
+               wanted_key.OutputsWritten |= 1 << VERT_RESULT_COL1;
+       
+       for (i = 0; i < ctx->Const.MaxTextureUnits; i++)
+               if (InputsRead & (FRAG_BIT_TEX0 << i))
+                       wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + 
i);
+
+       wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead;
+       //wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+
+       for (vp = vpc->progs; vp; vp = vp->next)
+               if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) == 
0) {
+                       r300->selected_vp = vp;
+                       return ;
+               }
+
+       curr_key.InputsRead = vpc->mesa_program.Base.InputsRead;
+       curr_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten;
+
+       //_mesa_print_program(&vpc->mesa_program.Base);
+
+       vp = build_program(&wanted_key, &curr_key, 
&vpc->mesa_program/*vpc->mesa_program.Base.Instructions*/);
+       vp->next = vpc->progs;
+       vpc->progs = vp;
+
+       r300->selected_vp = vp;
+}
Index: radeon_vtxfmt_a.c
===================================================================
RCS file: /cvs/mesa/Mesa/src/mesa/drivers/dri/r300/radeon_vtxfmt_a.c,v
retrieving revision 1.22
diff -u -r1.22 radeon_vtxfmt_a.c
--- radeon_vtxfmt_a.c   23 Aug 2006 23:18:39 -0000      1.22
+++ radeon_vtxfmt_a.c   5 Oct 2006 19:10:39 -0000
@@ -111,7 +111,12 @@
        ctx = rmesa->radeon.glCtx;
        i = r300Fallback(ctx);
        if (i)
+       {
+               if (RADEON_DEBUG & DEBUG_FALLBACKS)
+                       fprintf(stderr, "FALLBACK(%s): .\n",
+                           __FUNCTION__);
                return i;
+       }
 
        memset(rmesa->state.VB.AttribPtr, 0, VERT_ATTRIB_MAX*sizeof(struct dt));
        
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
--
_______________________________________________
Dri-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to