r300: cleanup vertex program related functions
authorMaciej Cencora <m.cencora@gmail.com>
Thu, 14 May 2009 00:21:09 +0000 (02:21 +0200)
committerAlex Deucher <alexdeucher@gmail.com>
Sat, 16 May 2009 15:42:03 +0000 (11:42 -0400)
- move vertex program related functions to r300_vertprog.c
- use _mesa_bitcount instead of self-made bit_count function
- remove duplicated field in r300_vertex_shader_fragment.body union
- rename r300_vertex_shader_fragment to r300_vertex_shader_hw_code
- rename r300_vertex_program field native to error
- remove unnecessary r300_vertex_shader_state structure
- remove unused r300_vertex_program and r300_vertex_program_cont fields
- remove disabled code

src/mesa/drivers/dri/r300/r300_context.h
src/mesa/drivers/dri/r300/r300_emit.c
src/mesa/drivers/dri/r300/r300_state.c
src/mesa/drivers/dri/r300/r300_state.h
src/mesa/drivers/dri/r300/r300_vertprog.c
src/mesa/drivers/dri/r300/r300_vertprog.h

index 4111fa2d81a8e778516ac761ed91e3e9923278f4..2ea064ed4529dbe1ab77f374be0cfac8a63fe0e2 100644 (file)
@@ -399,56 +399,40 @@ struct r300_hw_state {
 #define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
 #define STATE_R300_TEXRECT_FACTOR (STATE_INTERNAL_DRIVER+1)
 
-struct r300_vertex_shader_fragment {
-       int length;
-       union {
-               GLuint d[VSF_MAX_FRAGMENT_LENGTH];
-               float f[VSF_MAX_FRAGMENT_LENGTH];
-               GLuint i[VSF_MAX_FRAGMENT_LENGTH];
-       } body;
-};
-
-struct r300_vertex_shader_state {
-       struct r300_vertex_shader_fragment program;
-};
-
 #define COLOR_IS_RGBA
 #define TAG(x) r300##x
 #include "tnl_dd/t_dd_vertex.h"
 #undef TAG
 
-#define CURRENT_VERTEX_SHADER(ctx) (R300_CONTEXT(ctx)->selected_vp)
-
-/* 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;
-       GLuint OutputsAdded;
-};
-
 struct r300_vertex_program {
        struct r300_vertex_program *next;
-       struct r300_vertex_program_key key;
-       int translated;
 
-       struct r300_vertex_shader_fragment program;
+       struct r300_vertex_program_key {
+               GLuint InputsRead;
+               GLuint OutputsWritten;
+               GLuint OutputsAdded;
+       } key;
+       
+       struct r300_vertex_shader_hw_code {
+               int length;
+               union {
+                       GLuint d[VSF_MAX_FRAGMENT_LENGTH];
+                       float f[VSF_MAX_FRAGMENT_LENGTH];
+               } body;
+       } hw_code;
+
+       GLboolean translated;
+       GLboolean error;
 
        int pos_end;
        int num_temporaries;    /* Number of temp vars used by program */
        int wpos_idx;
        int inputs[VERT_ATTRIB_MAX];
        int outputs[VERT_RESULT_MAX];
-       int native;
-       int ref_count;
-       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;
 };
 
@@ -632,7 +616,6 @@ struct r300_context {
 
        struct r300_hw_state hw;
 
-       struct r300_vertex_shader_state vertex_shader;
        struct r300_vertex_program *selected_vp;
 
        /* Vertex buffers
index 45e7074002e9e0583edd6f678869575eb6e1c80d..1e79a76b47fed093c48d34ccc3d062f9604b8864 100644 (file)
@@ -210,8 +210,7 @@ void r300EmitArrays(GLcontext * ctx)
        int vir_inputs[VERT_ATTRIB_MAX];
        GLint tab[VERT_ATTRIB_MAX];
        int swizzle[VERT_ATTRIB_MAX][4];
-       struct r300_vertex_program *prog =
-           (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
+       struct r300_vertex_program *prog = rmesa->selected_vp;
 
        if (rmesa->options.hw_tcl_enabled) {
                inputs = prog->inputs;
index af9e553eb596a1507918cc0905cb6b968e57fbae..91f9acd5bfb152d12fc9f44cfdef6f304f0d9bde 100644 (file)
@@ -65,6 +65,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "r300_fragprog.h"
 #include "r500_fragprog.h"
 #include "r300_render.h"
+#include "r300_vertprog.h"
 
 #include "drirenderbuffer.h"
 
@@ -1455,8 +1456,9 @@ static void r300SetupRSUnit(GLcontext * ctx)
        int i, count, col_fmt, hw_tcl_on;
 
        hw_tcl_on = r300->options.hw_tcl_enabled;
+
        if (hw_tcl_on)
-               OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
+               OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten;
        else
                RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
 
@@ -1587,8 +1589,9 @@ static void r500SetupRSUnit(GLcontext * ctx)
        int i, count, col_fmt, hw_tcl_on;
 
        hw_tcl_on = r300->options.hw_tcl_enabled;
+
        if (hw_tcl_on)
-               OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten;
+               OutputsWritten.vp_outputs = r300->selected_vp->key.OutputsWritten;
        else
                RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
 
@@ -1717,58 +1720,9 @@ static void r500SetupRSUnit(GLcontext * ctx)
                WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead);
 }
 
-
-
-
-#define bump_vpu_count(ptr, new_count)   do{\
-       drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\
-       int _nc=(new_count)/4; \
-       assert(_nc < 256); \
-       if(_nc>_p->vpu.count)_p->vpu.count=_nc;\
-       }while(0)
-
-static INLINE void r300SetupVertexProgramFragment(r300ContextPtr r300, int dest, struct r300_vertex_shader_fragment *vsf)
-{
-       int i;
-
-       if (vsf->length == 0)
-               return;
-
-       if (vsf->length & 0x3) {
-               fprintf(stderr, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n");
-               _mesa_exit(-1);
-       }
-
-       switch ((dest >> 8) & 0xf) {
-       case 0:
-               R300_STATECHANGE(r300, vpi);
-               for (i = 0; i < vsf->length; i++)
-                       r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]);
-               bump_vpu_count(r300->hw.vpi.cmd, vsf->length + 4 * (dest & 0xff));
-               break;
-
-       case 2:
-               R300_STATECHANGE(r300, vpp);
-               for (i = 0; i < vsf->length; i++)
-                       r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]);
-               bump_vpu_count(r300->hw.vpp.cmd, vsf->length + 4 * (dest & 0xff));
-               break;
-       case 4:
-               R300_STATECHANGE(r300, vps);
-               for (i = 0; i < vsf->length; i++)
-                       r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]);
-               bump_vpu_count(r300->hw.vps.cmd, vsf->length + 4 * (dest & 0xff));
-               break;
-       default:
-               fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);
-               _mesa_exit(-1);
-       }
-}
-
 #define MIN3(a, b, c)  ((a) < (b) ? MIN2(a, c) : MIN2(b, c))
 
-
-static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
+void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
                        GLuint output_count, GLuint temp_count)
 {
     int vtx_mem_size;
@@ -1822,115 +1776,6 @@ static void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
 
 }
 
-static void r300SetupDefaultVertexProgram(r300ContextPtr rmesa)
-{
-       struct r300_vertex_shader_state *prog = &(rmesa->vertex_shader);
-       GLuint o_reg = 0;
-       GLuint i_reg = 0;
-       int i;
-       int inst_count = 0;
-       int param_count = 0;
-       int program_end = 0;
-
-       for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) {
-               if (rmesa->swtcl.sw_tcl_inputs[i] != -1) {
-                       prog->program.body.i[program_end + 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY, GL_FALSE, GL_FALSE, o_reg++, VSF_FLAG_ALL, PVS_DST_REG_OUT);
-                       prog->program.body.i[program_end + 1] = PVS_SRC_OPERAND(rmesa->swtcl.sw_tcl_inputs[i], PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
-                       prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->swtcl.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
-                       prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->swtcl.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
-                       program_end += 4;
-                       i_reg++;
-               }
-       }
-
-       prog->program.length = program_end;
-
-       r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START,
-                                      &(prog->program));
-       inst_count = (prog->program.length / 4) - 1;
-
-       r300VapCntl(rmesa, i_reg, o_reg, 0);
-
-       R300_STATECHANGE(rmesa, pvs);
-       rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
-           (0 << R300_PVS_FIRST_INST_SHIFT) |
-           (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
-           (inst_count << R300_PVS_LAST_INST_SHIFT);
-       rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
-           (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |
-           (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);
-       rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
-           (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
-}
-
-static int bit_count (int x)
-{
-    x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);
-    x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);
-    x = (x >> 16) + (x & 0xffff);
-    x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);
-    return (x >> 8) + (x & 0x00ff);
-}
-
-static void r300SetupRealVertexProgram(r300ContextPtr rmesa)
-{
-       GLcontext *ctx = rmesa->radeon.glCtx;
-       struct r300_vertex_program *prog = (struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx);
-       int inst_count = 0;
-       int param_count = 0;
-
-       /* FIXME: r300SetupVertexProgramFragment */
-       R300_STATECHANGE(rmesa, vpp);
-       param_count =
-           r300VertexProgUpdateParams(ctx,
-                                      (struct r300_vertex_program_cont *)
-                                      ctx->VertexProgram._Current,
-                                      (float *)&rmesa->hw.vpp.
-                                      cmd[R300_VPP_PARAM_0]);
-       bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
-       param_count /= 4;
-
-       r300SetupVertexProgramFragment(rmesa, R300_PVS_CODE_START, &(prog->program));
-       inst_count = (prog->program.length / 4) - 1;
-
-       r300VapCntl(rmesa, bit_count(prog->key.InputsRead),
-                   bit_count(prog->key.OutputsWritten), prog->num_temporaries);
-
-       R300_STATECHANGE(rmesa, pvs);
-       rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] =
-         (0 << R300_PVS_FIRST_INST_SHIFT) |
-         (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
-         (inst_count << R300_PVS_LAST_INST_SHIFT);
-       rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] =
-         (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) |
-         (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);
-       rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] =
-         (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
-}
-
-
-static void r300SetupVertexProgram(r300ContextPtr rmesa)
-{
-       GLcontext *ctx = rmesa->radeon.glCtx;
-
-       /* Reset state, in case we don't use something */
-       ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0;
-       ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
-       ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
-
-       /* Not sure why this doesnt work...
-          0x400 area might have something to do with pixel shaders as it appears right after pfs programming.
-          0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */
-       //setup_vertex_shader_fragment(rmesa, 0x406, &unk4);
-       if (rmesa->options.hw_tcl_enabled && ((struct r300_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->translated) {
-               r300SetupRealVertexProgram(rmesa);
-       } else {
-               /* FIXME: This needs to be replaced by vertex shader generation code. */
-               r300SetupDefaultVertexProgram(rmesa);
-       }
-
-}
-
 /**
  * Enable/Disable states.
  *
@@ -2227,7 +2072,6 @@ static void r300ResetHwState(r300ContextPtr r300)
 void r300UpdateShaders(r300ContextPtr rmesa)
 {
        GLcontext *ctx;
-       struct r300_vertex_program *vp;
        struct r300_fragment_program *fp;
        int i;
 
@@ -2257,8 +2101,7 @@ void r300UpdateShaders(r300ContextPtr rmesa)
                }
 
                r300SelectVertexShader(rmesa);
-               vp = (struct r300_vertex_program *) CURRENT_VERTEX_SHADER(ctx);
-               r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, !vp->native);
+               r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, rmesa->selected_vp->error);
        }
 
        if (!fp->translated || rmesa->radeon.NewGLState)
@@ -2432,8 +2275,12 @@ void r300UpdateShaderStates(r300ContextPtr rmesa)
 
        rmesa->vtbl.SetupRSUnit(ctx);
 
-       if (rmesa->options.hw_tcl_enabled)
-               r300SetupVertexProgram(rmesa);
+       if (rmesa->options.hw_tcl_enabled) {
+               if (rmesa->fallback & R300_FALLBACK_VERTEX_PROGRAM)
+                       r300SetupSwtclVertexProgram(rmesa);
+               else
+                       r300SetupVertexProgram(rmesa);
+       }
 }
 
 /**
index 3921efa8e3ab4934b07164b8ccb76ff77208fa02..cac639d7c66159c0b076e2ba9781a015d0db7afb 100644 (file)
@@ -57,5 +57,6 @@ void r300UpdateShaders (r300ContextPtr rmesa);
 void r300UpdateShaderStates (r300ContextPtr rmesa);
 void r300InitState (r300ContextPtr r300);
 void r300InitStateFuncs (struct dd_function_table *functions);
+void r300VapCntl(r300ContextPtr rmesa, GLuint input_count, GLuint output_count, GLuint temp_count);
 
 #endif                         /* __R300_STATE_H__ */
index 146daa367cd62b226c6663ad221048370870379e..949c0b499c4ccc8b6d8e440329a7de40ea2fdb1f 100644 (file)
@@ -38,6 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include "tnl/tnl.h"
 
 #include "r300_context.h"
+#include "r300_state.h"
 
 /* TODO: Get rid of t_src_class call */
 #define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \
@@ -64,7 +65,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
                int u_temp_used = (VSF_MAX_FRAGMENT_TEMPS - 1) - u_temp_i; \
                if((vp->num_temporaries + u_temp_used) > VSF_MAX_FRAGMENT_TEMPS) { \
                        WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_used); \
-                       vp->native = GL_FALSE; \
+                       vp->error = GL_TRUE; \
                } \
                u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
        } while (0)
@@ -1007,14 +1008,13 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
        struct prog_src_register src[3];
 
        vp->pos_end = 0;        /* Not supported yet */
-       vp->program.length = 0;
-       /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */
+       vp->hw_code.length = 0;
        vp->translated = GL_TRUE;
-       vp->native = GL_TRUE;
+       vp->error = GL_FALSE;
 
        t_inputs_outputs(vp);
 
-       for (inst = vp->program.body.i; vpi->Opcode != OPCODE_END;
+       for (inst = vp->hw_code.body.d; vpi->Opcode != OPCODE_END;
             vpi++, inst += 4) {
 
                FREE_TEMPS();
@@ -1176,7 +1176,7 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
                                                      &u_temp_i);
                        break;
                default:
-                       assert(0);
+                       vp->error = GL_TRUE;
                        break;
                }
        }
@@ -1198,16 +1198,10 @@ static void r300TranslateVertexShader(struct r300_vertex_program *vp,
                }
        }
 
-       vp->program.length = (inst - vp->program.body.i);
-       if (vp->program.length >= VSF_MAX_FRAGMENT_LENGTH) {
-               vp->program.length = 0;
-               vp->native = GL_FALSE;
+       vp->hw_code.length = (inst - vp->hw_code.body.d);
+       if (vp->hw_code.length >= VSF_MAX_FRAGMENT_LENGTH) {
+               vp->error = GL_TRUE;
        }
-#if 0
-       fprintf(stderr, "hw program:\n");
-       for (i = 0; i < vp->program.length; i++)
-               fprintf(stderr, "%08x\n", vp->program.body.d[i]);
-#endif
 }
 
 /* DP4 version seems to trigger some hw peculiarity */
@@ -1466,3 +1460,124 @@ void r300SelectVertexShader(r300ContextPtr r300)
        vpc->progs = vp;
        r300->selected_vp = vp;
 }
+
+#define bump_vpu_count(ptr, new_count)   do { \
+               drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr)); \
+               int _nc=(new_count)/4; \
+               assert(_nc < 256); \
+               if(_nc>_p->vpu.count)_p->vpu.count=_nc; \
+       } while(0)
+
+static void r300EmitVertexProgram(r300ContextPtr r300, int dest, struct r300_vertex_shader_hw_code *code)
+{
+       int i;
+
+       assert((code->length > 0) && (code->length % 4 == 0));
+
+       switch ((dest >> 8) & 0xf) {
+               case 0:
+                       R300_STATECHANGE(r300, vpi);
+                       for (i = 0; i < code->length; i++)
+                               r300->hw.vpi.cmd[R300_VPI_INSTR_0 + i + 4 * (dest & 0xff)] = (code->body.d[i]);
+                       bump_vpu_count(r300->hw.vpi.cmd, code->length + 4 * (dest & 0xff));
+                       break;
+               case 2:
+                       R300_STATECHANGE(r300, vpp);
+                       for (i = 0; i < code->length; i++)
+                               r300->hw.vpp.cmd[R300_VPP_PARAM_0 + i + 4 * (dest & 0xff)] = (code->body.d[i]);
+                       bump_vpu_count(r300->hw.vpp.cmd, code->length + 4 * (dest & 0xff));
+                       break;
+               case 4:
+                       R300_STATECHANGE(r300, vps);
+                       for (i = 0; i < code->length; i++)
+                               r300->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = (code->body.d[i]);
+                       bump_vpu_count(r300->hw.vps.cmd, code->length + 4 * (dest & 0xff));
+                       break;
+               default:
+                       fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest);
+                       _mesa_exit(-1);
+       }
+}
+
+void r300SetupSwtclVertexProgram(r300ContextPtr rmesa)
+{
+       struct r300_vertex_shader_hw_code *hw_code;
+       GLuint o_reg = 0;
+       GLuint i_reg = 0;
+       int i;
+       int inst_count = 0;
+       int param_count = 0;
+       int program_end = 0;
+
+       /* Reset state, in case we don't use something */
+       ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0;
+       ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
+       ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
+
+       hw_code = _mesa_malloc(sizeof(struct r300_vertex_shader_hw_code));
+
+       for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) {
+               if (rmesa->swtcl.sw_tcl_inputs[i] != -1) {
+                       hw_code->body.d[program_end + 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY, GL_FALSE, GL_FALSE, o_reg++, VSF_FLAG_ALL, PVS_DST_REG_OUT);
+                       hw_code->body.d[program_end + 1] = PVS_SRC_OPERAND(rmesa->swtcl.sw_tcl_inputs[i], PVS_SRC_SELECT_X,
+                                       PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+                       hw_code->body.d[program_end + 2] = PVS_SRC_OPERAND(rmesa->swtcl.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1,
+                                       PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+                       hw_code->body.d[program_end + 3] = PVS_SRC_OPERAND(rmesa->swtcl.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1,
+                                       PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+                       program_end += 4;
+                       i_reg++;
+               }
+       }
+
+       hw_code->length = program_end;
+
+       r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, hw_code);
+       inst_count = (hw_code->length / 4) - 1;
+
+       r300VapCntl(rmesa, i_reg, o_reg, 0);
+
+       R300_STATECHANGE(rmesa, pvs);
+       rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
+               (inst_count << R300_PVS_LAST_INST_SHIFT);
+
+       rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);
+       rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
+
+       _mesa_free(hw_code);
+}
+
+void r300SetupVertexProgram(r300ContextPtr rmesa)
+{
+       GLcontext *ctx = rmesa->radeon.glCtx;
+       struct r300_vertex_program *prog = rmesa->selected_vp;
+       int inst_count = 0;
+       int param_count = 0;
+       
+       /* Reset state, in case we don't use something */
+       ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0;
+       ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
+       ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
+       
+       R300_STATECHANGE(rmesa, vpp);
+       param_count = r300VertexProgUpdateParams(ctx,
+                                                               (struct r300_vertex_program_cont *)
+                                                               ctx->VertexProgram._Current,
+                                                               (float *)&rmesa->hw.vpp.
+                                                               cmd[R300_VPP_PARAM_0]);
+       bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
+       param_count /= 4;
+
+       r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->hw_code));
+       inst_count = (prog->hw_code.length / 4) - 1;
+
+       r300VapCntl(rmesa, _mesa_bitcount(prog->key.InputsRead),
+                                _mesa_bitcount(prog->key.OutputsWritten), prog->num_temporaries);
+
+       R300_STATECHANGE(rmesa, pvs);
+       rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
+                               (inst_count << R300_PVS_LAST_INST_SHIFT);
+
+       rmesa->hw.pvs.cmd[R300_PVS_CNTL_2] = (0 << R300_PVS_CONST_BASE_OFFSET_SHIFT) | (param_count << R300_PVS_MAX_CONST_ADDR_SHIFT);
+       rmesa->hw.pvs.cmd[R300_PVS_CNTL_3] = (inst_count << R300_PVS_LAST_VTX_SRC_INST_SHIFT);
+}
index 2f35f02bc848fa42863363c824c2aa500ea9a9dc..44b5f981a9a4c8775042e73a2ef11f0b65000092 100644 (file)
@@ -32,4 +32,7 @@
 
 #endif
 
+void r300SetupVertexProgram(r300ContextPtr rmesa);
+void r300SetupSwtclVertexProgram(r300ContextPtr rmesa);
+
 #endif