mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-04 07:38:10 +02:00
Beginings of program generation. This code havent been tested nor hooked up.
This commit is contained in:
parent
3bde211549
commit
941d6b008f
3 changed files with 304 additions and 1 deletions
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue