_mesa_enable_extension( ctx, "GL_NV_vertex_program");
#endif
/* currently bogus data */
- ctx->Const.MaxVertexProgramInstructions=128;
- ctx->Const.MaxVertexProgramAttribs=64;
- ctx->Const.MaxVertexProgramTemps=64;
- ctx->Const.MaxVertexProgramLocalParams=64;
- ctx->Const.MaxVertexProgramEnvParams=64;
- ctx->Const.MaxVertexProgramAddressRegs=8;
+ ctx->Const.MaxVertexProgramInstructions=VSF_MAX_FRAGMENT_LENGTH;
+ ctx->Const.MaxVertexProgramAttribs=16; // r420
+ ctx->Const.MaxVertexProgramTemps=VSF_MAX_FRAGMENT_TEMPS;
+ ctx->Const.MaxVertexProgramLocalParams=256; // r420
+ ctx->Const.MaxVertexProgramEnvParams=256; // r420
+ ctx->Const.MaxVertexProgramAddressRegs=1;
driInitExtensions(ctx, card_extensions, GL_TRUE);
void r300SetupVertexShader(r300ContextPtr rmesa)
{
GLcontext* ctx = rmesa->radeon.glCtx;
+ struct r300_vertex_shader_fragment unk4={
+ length: 4,
+ body: { f: {
+ /*0.0*/(rand()%100)/10.0,
+ /*0.0*/(rand()%100)/10.0,
+ /*1.0*/(rand()%100)/10.0,
+ /*0.0*/(rand()%100)/10.0
+ } }
+ };
LOCAL_VARS
- if(rmesa->current_vp != NULL){
- r300SetupVertexProgram(rmesa);
- return ;
- }
-
/* 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->current_vp != NULL){
+ r300SetupVertexProgram(rmesa);
+ return ;
+ }
/* This needs to be replaced by vertex shader generation code */
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;
VERTEX_SHADER_INSTRUCTION t2rs[1024];
VERTEX_SHADER_INSTRUCTION *o_inst;
unsigned long operands;
- int u_temp_i=63; /* Initial value should be last tmp reg that hw supports */
+ /* Initial value should be last tmp reg that hw supports.
+ Strangely enough r300 doesnt mind even though these would be out of range.
+ Smart enough to realize that it doesnt need it? */
+ int u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1;
#ifdef SRCS_WRITABLE
struct vp_src_register src[3];
#else
o_inst->src1=MAKE_VSF_SOURCE(t_src_index(vp, &src[2]),
SWIZZLE_X, SWIZZLE_Y,
SWIZZLE_Z, SWIZZLE_W,
- t_src_class(src[0].File), VSF_FLAG_NONE);
+ t_src_class(src[2].File), VSF_FLAG_NONE);
o_inst->src2=MAKE_VSF_SOURCE(t_src_index(vp, &src[2]),
SWIZZLE_ZERO, SWIZZLE_ZERO,
SWIZZLE_ZERO, SWIZZLE_ZERO,
- t_src_class(src[0].File), VSF_FLAG_NONE);
+ t_src_class(src[2].File), VSF_FLAG_NONE);
o_inst->src3=0;
o_inst++;
#ifdef SRCS_WRITABLE
vpi->Opcode=VP_OPCODE_MAX;
src[1]=src[0];
- src[1].Negate=GL_TRUE;
+ src[1].Negate=!src[0].Negate;
+ operands=op_operands(vpi->Opcode);
break;
#else
o_inst->op=MAKE_VSF_OP(R300_VPI_OUT_OP_MAX, vpi->DstReg.Index,
u_temp_i--;
goto next;
+ case VP_OPCODE_LIT://LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
+ o_inst->op=MAKE_VSF_OP(R300_VPI_OUT_OP_LIT, vpi->DstReg.Index,
+ t_dst_mask(vpi->DstReg.WriteMask), t_dst_class(vpi->DstReg.File));
+ /* NOTE: Users swizzling might not work. */
+ o_inst->src1=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(src[0].Swizzle[0]), // x
+ t_swizzle(src[0].Swizzle[3]), // w
+ t_swizzle(src[0].Swizzle[2]), // z
+ t_swizzle(src[0].Swizzle[1]), // y
+ t_src_class(src[0].File),
+ src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE);
+ o_inst->src2=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(src[0].Swizzle[1]), // y
+ t_swizzle(src[0].Swizzle[3]), // w
+ t_swizzle(src[0].Swizzle[2]), // z
+ t_swizzle(src[0].Swizzle[0]), // x
+ t_src_class(src[0].File),
+ src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE);
+ o_inst->src3=MAKE_VSF_SOURCE(t_src_index(vp, &src[0]),
+ t_swizzle(src[0].Swizzle[1]), // y
+ t_swizzle(src[0].Swizzle[0]), // x
+ t_swizzle(src[0].Swizzle[2]), // z
+ t_swizzle(src[0].Swizzle[3]), // w
+ t_src_class(src[0].File),
+ src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE);
+ goto next;
+
case VP_OPCODE_DPH://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
o_inst->op=MAKE_VSF_OP(R300_VPI_OUT_OP_DOT, vpi->DstReg.Index,
t_dst_mask(vpi->DstReg.WriteMask), t_dst_class(vpi->DstReg.File));
o_inst->src3=0;
goto next;
- case VP_OPCODE_XPD:
+ case VP_OPCODE_XPD: /* Broken due to swizzling */
/* ADD TMP 0.X Y Z PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
MUL TMP 1.X Y Z W TMP 0{} {Z X Y ZERO} PARAM 1{} {Y Z X ZERO}
MAD RESULT 1.X Y Z W TMP 0{} {Y Z X ONE} PARAM 1{} {Z X Y ONE} TMP 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W*/