diff options
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_context.h | 49 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_emit.c | 3 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_state.c | 179 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_state.h | 1 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_vertprog.c | 145 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r300/r300_vertprog.h | 3 |
6 files changed, 164 insertions, 216 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index 4111fa2d81..2ea064ed45 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -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 diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c index 45e7074002..1e79a76b47 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.c +++ b/src/mesa/drivers/dri/r300/r300_emit.c @@ -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; diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index af9e553eb5..91f9acd5bf 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -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); + } } /** diff --git a/src/mesa/drivers/dri/r300/r300_state.h b/src/mesa/drivers/dri/r300/r300_state.h index 3921efa8e3..cac639d7c6 100644 --- a/src/mesa/drivers/dri/r300/r300_state.h +++ b/src/mesa/drivers/dri/r300/r300_state.h @@ -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__ */ diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 146daa367c..949c0b499c 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -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); +} diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h index 2f35f02bc8..44b5f981a9 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.h +++ b/src/mesa/drivers/dri/r300/r300_vertprog.h @@ -32,4 +32,7 @@ #endif +void r300SetupVertexProgram(r300ContextPtr rmesa); +void r300SetupSwtclVertexProgram(r300ContextPtr rmesa); + #endif |