From 941d6b008fbfef4f98a98198fe270e2f5e53ee9e Mon Sep 17 00:00:00 2001 From: Aapo Tahkola Date: Sat, 29 Jan 2005 17:57:07 +0000 Subject: Beginings of program generation. This code havent been tested nor hooked up. --- src/mesa/drivers/dri/r300/r300_context.h | 8 + src/mesa/drivers/dri/r300/r300_state.c | 51 ++++++ src/mesa/drivers/dri/r300/r300_vertexprog.c | 246 +++++++++++++++++++++++++++- 3 files changed, 304 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index fd076a38ec..57a258487e 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -519,9 +519,15 @@ struct r300_vertex_shader_state { int unknown_ptr3; /* pointer within program space */ }; +/* 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 { struct vertex_program mesa_program; /* Must be first */ int translated; + + struct r300_vertex_shader_fragment program; + struct r300_vertex_shader_fragment params; }; @@ -660,6 +666,8 @@ struct r300_context { GLuint TexGenInputs; GLuint TexGenCompSel; GLmatrix tmpmat; + + struct r300_vertex_program *current_vp; }; #define R300_CONTEXT(ctx) ((r300ContextPtr)(ctx->DriverCtx)) diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index 1592961d45..dedc5df0a8 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -1297,6 +1297,57 @@ void r300SetupVertexShader(r300ContextPtr rmesa) #endif } +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; + +#if 0 +/* This needs to be replaced by vertex shader generation code */ + + + /* textures enabled ? */ + if(rmesa->state.texture.tc_count>0){ + rmesa->state.vertex_shader=SINGLE_TEXTURE_VERTEX_SHADER; + } else { + rmesa->state.vertex_shader=FLAT_COLOR_VERTEX_SHADER; + } + + + rmesa->state.vertex_shader.matrix[0].length=16; + memcpy(rmesa->state.vertex_shader.matrix[0].body.f, ctx->_ModelProjectMatrix.m, 16*4); +#endif + + setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->current_vp->program)); + + setup_vertex_shader_fragment(rmesa, VSF_DEST_MATRIX0, &(rmesa->current_vp->params)); + + #if 0 + setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN1, &(rmesa->state.vertex_shader.unknown1)); + setup_vertex_shader_fragment(rmesa, VSF_DEST_UNKNOWN2, &(rmesa->state.vertex_shader.unknown2)); + #endif + + R300_STATECHANGE(rmesa, pvs); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_1]=(0 << R300_PVS_CNTL_1_PROGRAM_START_SHIFT) + | (rmesa->state.vertex_shader.unknown_ptr1 << R300_PVS_CNTL_1_UNKNOWN_SHIFT) + | (rmesa->current_vp->program.length/4 << R300_PVS_CNTL_1_PROGRAM_END_SHIFT); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_2]=(0 << R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT) + | (rmesa->current_vp->params.length/4 << R300_PVS_CNTL_2_PARAM_COUNT_SHIFT); + rmesa->hw.pvs.cmd[R300_PVS_CNTL_3]=(0/*rmesa->state.vertex_shader.unknown_ptr2*/ << R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT) + | (rmesa->current_vp->program.length/4/*rmesa->state.vertex_shader.unknown_ptr3*/ << 0); + + /* This is done for vertex shader fragments, but also needs to be done for vap_pvs, + so I leave it as a reminder */ + #if 0 + reg_start(R300_VAP_PVS_WAITIDLE,0); + e32(0x00000000); + #endif +} + void r300SetupPixelShader(r300ContextPtr rmesa) { int i,k; diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c index 5c555015e3..50a816c6d4 100644 --- a/src/mesa/drivers/dri/r300/r300_vertexprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c @@ -110,13 +110,14 @@ void dump_program_params(struct vertex_program *vp) fprintf(stderr, "NumAttributes=%d\n", vp->Base.NumAttributes); fprintf(stderr, "NumAddressRegs=%d\n", vp->Base.NumAddressRegs); +#if 0 for(pi=0; pi < vp->Base.NumParameters; pi++){ fprintf(stderr, "{ "); for(i=0; i < 4; i++) fprintf(stderr, "%f ", vp->Base.LocalParams[pi][i]); fprintf(stderr, "}\n"); } - +#endif for(pi=0; pi < vp->Parameters->NumParameters; pi++){ fprintf(stderr, "param %02d:", pi); @@ -208,6 +209,249 @@ static void debug_vp(struct vertex_program *vp) } +void update_params(struct r300_vertex_program *vp) +{ + int pi; + struct vertex_program *mesa_vp=(void *)vp; + + vp->params.length=0; + + /* Temporary solution */ + + for(pi=0; pi < mesa_vp->Parameters->NumParameters; pi++){ + switch(mesa_vp->Parameters->Parameters[pi].Type){ + + case NAMED_PARAMETER: + //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name); + case CONSTANT: + vp->params.body.f[pi*4+0]=mesa_vp->Parameters->Parameters[pi].Values[0]; + vp->params.body.f[pi*4+1]=mesa_vp->Parameters->Parameters[pi].Values[1]; + vp->params.body.f[pi*4+2]=mesa_vp->Parameters->Parameters[pi].Values[2]; + vp->params.body.f[pi*4+3]=mesa_vp->Parameters->Parameters[pi].Values[3]; + vp->params.length+=4; + break; + + case STATE: + fprintf(stderr, "State found! bailing out.\n"); + exit(0); + /* fetch state info */ + continue; + break; + default: _mesa_problem(NULL, "Bad param type in %s", __FUNCTION__); + } + + } + +} + +unsigned long translate_dst_mask(GLboolean *mask) +{ + unsigned long flags=0; + + if(mask[0]) flags |= VSF_FLAG_X; + if(mask[1]) flags |= VSF_FLAG_Y; + if(mask[2]) flags |= VSF_FLAG_Z; + if(mask[3]) flags |= VSF_FLAG_W; + + return flags; +} + +unsigned long translate_dst_class(enum register_file file) +{ + + switch(file){ + case PROGRAM_TEMPORARY: + return R300_VPI_OUT_REG_CLASS_TEMPORARY; + case PROGRAM_OUTPUT: + return R300_VPI_OUT_REG_CLASS_RESULT; + /* + case PROGRAM_INPUT: + case PROGRAM_LOCAL_PARAM: + case PROGRAM_ENV_PARAM: + case PROGRAM_NAMED_PARAM: + case PROGRAM_STATE_VAR: + case PROGRAM_WRITE_ONLY: + case PROGRAM_ADDRESS: + */ + default: + fprintf(stderr, "problem in %s", __FUNCTION__); + exit(0); + } +} + +unsigned long translate_src_class(enum register_file file) +{ + + switch(file){ + case PROGRAM_TEMPORARY: + return R300_VPI_IN_REG_CLASS_TEMPORARY; + + + case PROGRAM_INPUT: + case PROGRAM_LOCAL_PARAM: + case PROGRAM_ENV_PARAM: + case PROGRAM_NAMED_PARAM: + case PROGRAM_STATE_VAR: + return R300_VPI_IN_REG_CLASS_PARAMETER; + /* + case PROGRAM_OUTPUT: + case PROGRAM_WRITE_ONLY: + case PROGRAM_ADDRESS: + */ + default: + fprintf(stderr, "problem in %s", __FUNCTION__); + exit(0); + } +} + +unsigned long translate_swizzle(GLubyte swizzle) +{ + switch(swizzle){ + case 0: return VSF_IN_COMPONENT_X; + case 1: return VSF_IN_COMPONENT_Y; + case 2: return VSF_IN_COMPONENT_Z; + case 3: return VSF_IN_COMPONENT_W; + + case SWIZZLE_ZERO: + case SWIZZLE_ONE: + default: + fprintf(stderr, "problem in %s", __FUNCTION__); + exit(0); + } +} + +unsigned long translate_src(struct vp_src_register *src) +{ + return MAKE_VSF_SOURCE(src->Index, + translate_swizzle(src->Swizzle[0]), + translate_swizzle(src->Swizzle[1]), + translate_swizzle(src->Swizzle[2]), + translate_swizzle(src->Swizzle[3]), + translate_src_class(src->File), + src->Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE); +} + +unsigned long translate_opcode(enum vp_opcode opcode) +{ + + switch(opcode){ + case VP_OPCODE_ADD: return R300_VPI_OUT_OP_ADD; + case VP_OPCODE_DST: return R300_VPI_OUT_OP_DST; + case VP_OPCODE_EX2: return R300_VPI_OUT_OP_EX2; + case VP_OPCODE_EXP: return R300_VPI_OUT_OP_EXP; + case VP_OPCODE_FRC: return R300_VPI_OUT_OP_FRC; + case VP_OPCODE_LG2: return R300_VPI_OUT_OP_LG2; + case VP_OPCODE_LIT: return R300_VPI_OUT_OP_LIT; + case VP_OPCODE_LOG: return R300_VPI_OUT_OP_LOG; + case VP_OPCODE_MAD: return R300_VPI_OUT_OP_MAD; + case VP_OPCODE_MAX: return R300_VPI_OUT_OP_MAX; + case VP_OPCODE_MIN: return R300_VPI_OUT_OP_MIN; + case VP_OPCODE_MUL: return R300_VPI_OUT_OP_MUL; + case VP_OPCODE_POW: return R300_VPI_OUT_OP_POW; + case VP_OPCODE_RCP: return R300_VPI_OUT_OP_RCP; + case VP_OPCODE_RSQ: return R300_VPI_OUT_OP_RSQ; + case VP_OPCODE_SGE: return R300_VPI_OUT_OP_SGE; + case VP_OPCODE_SLT: return R300_VPI_OUT_OP_SLT; + /* these ops need special handling */ + case VP_OPCODE_ABS: + case VP_OPCODE_ARL: + case VP_OPCODE_DP3: + case VP_OPCODE_DP4: + case VP_OPCODE_DPH: + case VP_OPCODE_FLR: + case VP_OPCODE_MOV: + case VP_OPCODE_SUB: + case VP_OPCODE_SWZ: + case VP_OPCODE_XPD: + case VP_OPCODE_RCC: + case VP_OPCODE_PRINT: + case VP_OPCODE_END: + fprintf(stderr, "%s should not be called with opcode %d", __FUNCTION__, opcode); + break; + default: + fprintf(stderr, "%s unknown opcode %d", __FUNCTION__, opcode); + } + exit(-1); + return 0; +} + +static void translate_program(struct r300_vertex_program *vp) +{ + struct vertex_program *mesa_vp=(void *)vp; + struct vp_instruction *vpi; + int inst_index=0; + int operand_index, i; + int op_found; + update_params(vp); + + vp->program.length=0; + + for(vpi=mesa_vp->Instructions; vpi->Opcode != VP_OPCODE_END; vpi++, inst_index++){ + switch(vpi->Opcode){ + case VP_OPCODE_ABS: + case VP_OPCODE_ARL: + case VP_OPCODE_DP3: + case VP_OPCODE_DP4: + case VP_OPCODE_DPH: + case VP_OPCODE_DST: + case VP_OPCODE_FLR: + case VP_OPCODE_MOV: + case VP_OPCODE_SUB: + case VP_OPCODE_SWZ: + case VP_OPCODE_XPD: + case VP_OPCODE_RCC: + case VP_OPCODE_PRINT: + fprintf(stderr, "Dont know how to handle op %d yet\n", vpi->Opcode); + exit(-1); + break; + case VP_OPCODE_END: + break; + default: + break; + } + vp->program.body.i[inst_index].op=MAKE_VSF_OP(translate_opcode(vpi->Opcode), vpi->DstReg.Index, + translate_dst_mask(vpi->DstReg.WriteMask), translate_dst_class(vpi->DstReg.File)); + + op_found=0; + for(i=0; i < sizeof(op_names) / sizeof(*op_names); i++) + if(op_names[i].opcode == vpi->Opcode){ + op_found=1; + break; + } + if(!op_found){ + fprintf(stderr, "op %d not found in op_names\n", vpi->Opcode); + exit(-1); + } + + switch(op_names[i].ip){ + case 1: + vp->program.body.i[inst_index].src1=translate_src(&vpi->SrcReg[0]); + vp->program.body.i[inst_index].src2=0; + vp->program.body.i[inst_index].src3=0; + break; + + case 2: + vp->program.body.i[inst_index].src1=translate_src(&vpi->SrcReg[0]); + vp->program.body.i[inst_index].src2=translate_src(&vpi->SrcReg[1]); + vp->program.body.i[inst_index].src3=0; + break; + + case 3: + vp->program.body.i[inst_index].src1=translate_src(&vpi->SrcReg[0]); + vp->program.body.i[inst_index].src2=translate_src(&vpi->SrcReg[1]); + vp->program.body.i[inst_index].src3=translate_src(&vpi->SrcReg[2]); + break; + + default: + fprintf(stderr, "scalars and op RCC not handled yet"); + exit(-1); + break; + } + } + vp->program.length=inst_index*4; + +} + static void r300BindProgram(GLcontext *ctx, GLenum target, struct program *prog) { fprintf(stderr, "r300BindProgram\n"); -- cgit v1.2.3