summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAapo Tahkola <aet@rasterburn.org>2005-02-01 16:56:52 +0000
committerAapo Tahkola <aet@rasterburn.org>2005-02-01 16:56:52 +0000
commit7bccfa10269f228844d65ee198414970ad8cc881 (patch)
tree14f17796403860b5f3f74173f139b8f517ae66cf /src
parent5dd4030e761d1c880e0860ba0d5173e8272da8d0 (diff)
Vertex programs work now with some restrictions. I expect arbvptorus to work
correctly when normals are delivered. Please note that some programs only start in vb mode as there is something wrong in immediate mode vb code.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h7
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c1
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c100
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertexprog.c351
4 files changed, 320 insertions, 139 deletions
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index 0e0aa665a5..14f06fba4c 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -538,7 +538,10 @@ struct r300_vertex_program {
struct r300_vertex_shader_fragment program;
struct r300_vertex_shader_fragment params;
-
+
+ int t2rs;
+ unsigned long num_temporaries; /* Number of temp vars used by program */
+ int inputs[VERT_ATTRIB_MAX];
};
/* 64 appears to be the maximum */
@@ -686,6 +689,8 @@ extern void r300DestroyContext(__DRIcontextPrivate * driContextPriv);
extern GLboolean r300CreateContext(const __GLcontextModes * glVisual,
__DRIcontextPrivate * driContextPriv,
void *sharedContextPrivate);
+
extern void r300InitVertexProgFuncs(struct dd_function_table *functions);
+extern void r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp);
#endif /* __R300_CONTEXT_H__ */
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 75ef2bfacc..1e4db5e1d3 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -626,7 +626,6 @@ static void r300_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
for (i = 1; i < ctx->Const.MaxTextureUnits; i++)
FALLBACK_IF(ctx->Texture.Unit[i].Enabled);
-
/* let r300_run_render do its job */
#if 0
stage->active = GL_FALSE;
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index c75f2154e1..e17cb8fe4d 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -844,28 +844,80 @@ void r300_setup_routing(GLcontext *ctx, GLboolean immediate)
/* All offsets are 0 - for use by immediate mode.
Should change later to handle vertex buffers */
+ if(r300->current_vp){
+
+ /* VERT_ATTRIB_WEIGHT, VERT_ATTRIB_SIX, VERT_ATTRIB_SEVEN, VERT_ATTRIB_GENERIC0,
+ VERT_ATTRIB_GENERIC1, VERT_ATTRIB_GENERIC2, VERT_ATTRIB_GENERIC3 */
+
+ if(r300->current_vp->inputs[VERT_ATTRIB_POS] != -1){
+ if(tnl->render_inputs & _TNL_BIT_POS){
+ reg=r300->current_vp->inputs[VERT_ATTRIB_POS];
+ CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
+ }else fprintf(stderr, "vp expects pos but none was given\n");
+ }
+ if(r300->current_vp->inputs[VERT_ATTRIB_NORMAL] != -1){
+ if(tnl->render_inputs & _TNL_BIT_NORMAL){
+ reg=r300->current_vp->inputs[VERT_ATTRIB_NORMAL];
+ CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT);
+ }else fprintf(stderr, "vp expects normal but none was given\n");
+ }
+ if(r300->current_vp->inputs[VERT_ATTRIB_COLOR0] != -1){
+ if(tnl->render_inputs & _TNL_BIT_COLOR0){
+ reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR0];
+ CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
+ }else fprintf(stderr, "vp expects primary color but none was given\n");
+ }
+ if(r300->current_vp->inputs[VERT_ATTRIB_COLOR1] != -1){
+ if(tnl->render_inputs & _TNL_BIT_COLOR1){
+ reg=r300->current_vp->inputs[VERT_ATTRIB_COLOR1];
+ CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR);
+ }else fprintf(stderr, "vp expects secondary color but none was given\n");
+ }
+ if(r300->current_vp->inputs[VERT_ATTRIB_FOG] != -1){
+ if(tnl->render_inputs & _TNL_BIT_FOG){
+ reg=r300->current_vp->inputs[VERT_ATTRIB_FOG];
+ CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);
+ }else fprintf(stderr, "vp expects fog but none was given\n");
+ }
+ for(i=0;i < ctx->Const.MaxTextureUnits;i++) // tex 7 is last
+ if(r300->current_vp->inputs[VERT_ATTRIB_TEX0+i] != -1){
+ if(tnl->render_inputs & (_TNL_BIT_TEX0<<i)){
+ reg=r300->current_vp->inputs[VERT_ATTRIB_TEX0+i];
+ CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
+ }else fprintf(stderr, "vp expects tex%d but none was given\n", i);
+ }
+#if 0
+ if((tnl->render_inputs & _TNL_BIT_INDEX))
+ CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT);
+
+ if((tnl->render_inputs & _TNL_BIT_POINTSIZE))
+ CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT);
+#endif
+ }else{
+
if(tnl->render_inputs & _TNL_BIT_POS)
CONFIGURE_AOS(VB->ObjPtr, 0, i_coords, AOS_FORMAT_FLOAT);
if(tnl->render_inputs & _TNL_BIT_NORMAL)
CONFIGURE_AOS(VB->NormalPtr, 0, i_normal, AOS_FORMAT_FLOAT);
-
+
if(tnl->render_inputs & _TNL_BIT_COLOR0)
CONFIGURE_AOS(VB->ColorPtr[0], 0, i_color[0], AOS_FORMAT_FLOAT_COLOR);
if(tnl->render_inputs & _TNL_BIT_COLOR1)
CONFIGURE_AOS(VB->SecondaryColorPtr[0], 0, i_color[1], AOS_FORMAT_FLOAT_COLOR);
-
+
if(tnl->render_inputs & _TNL_BIT_FOG)
CONFIGURE_AOS(VB->FogCoordPtr, 0, i_fog, AOS_FORMAT_FLOAT);
-
+
for(i=0;i < ctx->Const.MaxTextureUnits;i++)
if(tnl->render_inputs & (_TNL_BIT_TEX0<<i))
CONFIGURE_AOS(VB->TexCoordPtr[i], 0, i_tex[i], AOS_FORMAT_FLOAT);
-
+
if(tnl->render_inputs & _TNL_BIT_INDEX)
CONFIGURE_AOS(VB->IndexPtr[0], 0, i_index, AOS_FORMAT_FLOAT);
if(tnl->render_inputs & _TNL_BIT_POINTSIZE)
CONFIGURE_AOS(VB->PointSizePtr, 0, i_pointsize, AOS_FORMAT_FLOAT);
-
+ }
+
r300->state.aos_count=count;
if (RADEON_DEBUG & DEBUG_STATE)
@@ -1245,11 +1297,16 @@ void static inline setup_vertex_shader_fragment(r300ContextPtr r300, int dest, s
}
}
+void r300SetupVertexProgram(r300ContextPtr rmesa);
void r300SetupVertexShader(r300ContextPtr rmesa)
{
GLcontext* ctx = rmesa->radeon.glCtx;
-
+
+ if(rmesa->current_vp){
+ 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;
@@ -1306,27 +1363,15 @@ void r300SetupVertexShader(r300ContextPtr rmesa)
void r300SetupVertexProgram(r300ContextPtr rmesa)
{
GLcontext* ctx = rmesa->radeon.glCtx;
+ int inst_count;
+ int param_count;
/* 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
+ r300VertexProgUpdateParams(ctx, rmesa->current_vp);
setup_vertex_shader_fragment(rmesa, VSF_DEST_PROGRAM, &(rmesa->current_vp->program));
@@ -1336,15 +1381,18 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
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
-
+
+ inst_count=rmesa->current_vp->program.length/4 - 1;
+ param_count=rmesa->current_vp->params.length/4;
+
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);
+ | (inst_count/*0*/ << R300_PVS_CNTL_1_UNKNOWN_SHIFT)
+ | (inst_count << 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);
+ | (param_count << 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);
+ | ((inst_count-rmesa->current_vp->t2rs) /*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 */
diff --git a/src/mesa/drivers/dri/r300/r300_vertexprog.c b/src/mesa/drivers/dri/r300/r300_vertexprog.c
index 50a816c6d4..c137c84764 100644
--- a/src/mesa/drivers/dri/r300/r300_vertexprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertexprog.c
@@ -1,3 +1,34 @@
+/**************************************************************************
+
+Copyright (C) 2005 Aapo Tahkola.
+
+All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+on the rights to use, copy, modify, merge, publish, distribute, sub
+license, and/or sell copies of the Software, and to permit persons to whom
+the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice (including the next
+paragraph) shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Aapo Tahkola <aet@rasterburn.org>
+ */
#include "glheader.h"
#include "macros.h"
#include "enums.h"
@@ -99,7 +130,7 @@ char *dst_mask_names[4]={ "X", "Y", "Z", "W" };
XPD v,v v cross product
*/
-void dump_program_params(struct vertex_program *vp)
+void dump_program_params(GLcontext *ctx, struct vertex_program *vp)
{
int i;
int pi;
@@ -110,6 +141,8 @@ void dump_program_params(struct vertex_program *vp)
fprintf(stderr, "NumAttributes=%d\n", vp->Base.NumAttributes);
fprintf(stderr, "NumAddressRegs=%d\n", vp->Base.NumAddressRegs);
+ _mesa_load_state_parameters(ctx, vp->Parameters);
+
#if 0
for(pi=0; pi < vp->Base.NumParameters; pi++){
fprintf(stderr, "{ ");
@@ -134,8 +167,6 @@ void dump_program_params(struct vertex_program *vp)
case STATE:
fprintf(stderr, "(STATE)\n");
- /* fetch state info */
- continue;
break;
}
@@ -148,13 +179,13 @@ void dump_program_params(struct vertex_program *vp)
}
}
-static void debug_vp(struct vertex_program *vp)
+static void debug_vp(GLcontext *ctx, struct vertex_program *vp)
{
struct vp_instruction *vpi;
int i, operand_index;
int operator_index;
- dump_program_params(vp);
+ dump_program_params(ctx, vp);
vpi=vp->Instructions;
@@ -209,42 +240,39 @@ static void debug_vp(struct vertex_program *vp)
}
-void update_params(struct r300_vertex_program *vp)
+void r300VertexProgUpdateParams(GLcontext *ctx, struct r300_vertex_program *vp)
{
int pi;
struct vertex_program *mesa_vp=(void *)vp;
+ int dst_index;
- vp->params.length=0;
+ _mesa_load_state_parameters(ctx, mesa_vp->Parameters);
- /* Temporary solution */
+ //debug_vp(ctx, mesa_vp);
+ dst_index=0;
for(pi=0; pi < mesa_vp->Parameters->NumParameters; pi++){
switch(mesa_vp->Parameters->Parameters[pi].Type){
+ case STATE:
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;
+ vp->params.body.f[dst_index++]=mesa_vp->Parameters->Parameters[pi].Values[0];
+ vp->params.body.f[dst_index++]=mesa_vp->Parameters->Parameters[pi].Values[1];
+ vp->params.body.f[dst_index++]=mesa_vp->Parameters->Parameters[pi].Values[2];
+ vp->params.body.f[dst_index++]=mesa_vp->Parameters->Parameters[pi].Values[3];
break;
+
default: _mesa_problem(NULL, "Bad param type in %s", __FUNCTION__);
}
}
+ vp->params.length=dst_index;
}
-unsigned long translate_dst_mask(GLboolean *mask)
+static unsigned long t_dst_mask(GLboolean *mask)
{
unsigned long flags=0;
@@ -256,14 +284,14 @@ unsigned long translate_dst_mask(GLboolean *mask)
return flags;
}
-unsigned long translate_dst_class(enum register_file file)
+static unsigned long t_dst_class(enum register_file file)
{
switch(file){
case PROGRAM_TEMPORARY:
- return R300_VPI_OUT_REG_CLASS_TEMPORARY;
+ return VSF_OUT_CLASS_TMP;
case PROGRAM_OUTPUT:
- return R300_VPI_OUT_REG_CLASS_RESULT;
+ return VSF_OUT_CLASS_RESULT;
/*
case PROGRAM_INPUT:
case PROGRAM_LOCAL_PARAM:
@@ -279,20 +307,21 @@ unsigned long translate_dst_class(enum register_file file)
}
}
-unsigned long translate_src_class(enum register_file file)
+static unsigned long t_src_class(enum register_file file)
{
switch(file){
case PROGRAM_TEMPORARY:
- return R300_VPI_IN_REG_CLASS_TEMPORARY;
-
+ return VSF_IN_CLASS_TMP;
case PROGRAM_INPUT:
+ return VSF_IN_CLASS_ATTR;
+
case PROGRAM_LOCAL_PARAM:
case PROGRAM_ENV_PARAM:
case PROGRAM_NAMED_PARAM:
case PROGRAM_STATE_VAR:
- return R300_VPI_IN_REG_CLASS_PARAMETER;
+ return VSF_IN_CLASS_PARAM;
/*
case PROGRAM_OUTPUT:
case PROGRAM_WRITE_ONLY:
@@ -304,7 +333,7 @@ unsigned long translate_src_class(enum register_file file)
}
}
-unsigned long translate_swizzle(GLubyte swizzle)
+static unsigned long t_swizzle(GLubyte swizzle)
{
switch(swizzle){
case 0: return VSF_IN_COMPONENT_X;
@@ -319,19 +348,52 @@ unsigned long translate_swizzle(GLubyte swizzle)
exit(0);
}
}
+
+static unsigned long t_src_index(struct r300_vertex_program *vp, struct vp_src_register *src)
+{
+ int i;
+ int max_reg=-1;
+
+ if(src->File == PROGRAM_INPUT){
+ /*
+ switch(src->Index){
+ case 0: return 0;
+ case 3: return 1;
+
+ case 2: return 2;
+ case 8: return 8;
+
+ default: printf("unknown input index %d\n", src->Index); exit(0); break;
+ }*/
+
+ if(vp->inputs[src->Index] != -1)
+ return vp->inputs[src->Index];
+
+ for(i=0; i < VERT_ATTRIB_MAX; i++)
+ if(vp->inputs[i] > max_reg)
+ max_reg=vp->inputs[i];
+
+ vp->inputs[src->Index]=max_reg+1;
+
+ return vp->inputs[src->Index];
+ }else{
+ return src->Index;
+ }
+}
-unsigned long translate_src(struct vp_src_register *src)
+static unsigned long t_src(struct r300_vertex_program *vp, 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),
+
+ return MAKE_VSF_SOURCE(t_src_index(vp, src),
+ t_swizzle(src->Swizzle[0]),
+ t_swizzle(src->Swizzle[1]),
+ t_swizzle(src->Swizzle[2]),
+ t_swizzle(src->Swizzle[3]),
+ t_src_class(src->File),
src->Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE);
}
-unsigned long translate_opcode(enum vp_opcode opcode)
+static unsigned long t_opcode(enum vp_opcode opcode)
{
switch(opcode){
@@ -352,55 +414,105 @@ unsigned long translate_opcode(enum vp_opcode opcode)
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;
+ case VP_OPCODE_DP4: return R300_VPI_OUT_OP_DOT;
+
default:
- fprintf(stderr, "%s unknown opcode %d", __FUNCTION__, opcode);
+ fprintf(stderr, "%s: Should not be called with opcode %d!", __FUNCTION__, opcode);
}
exit(-1);
return 0;
}
-
+
+static unsigned long op_operands(enum vp_opcode opcode)
+{
+ int i;
+
+ /* Can we trust mesas opcodes to be in order ? */
+ for(i=0; i < sizeof(op_names) / sizeof(*op_names); i++)
+ if(op_names[i].opcode == opcode)
+ return op_names[i].ip;
+
+ fprintf(stderr, "op %d not found in op_names\n", 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);
+ VERTEX_SHADER_INSTRUCTION t2rs[1024];
+ VERTEX_SHADER_INSTRUCTION *o_inst;
+ unsigned long operands;
+ vp->t2rs=0;
vp->program.length=0;
+ vp->num_temporaries=mesa_vp->Base.NumTemporaries;
+
+ for(i=0; i < VERT_ATTRIB_MAX; i++)
+ vp->inputs[i]=-1;
- for(vpi=mesa_vp->Instructions; vpi->Opcode != VP_OPCODE_END; vpi++, inst_index++){
+ o_inst=vp->program.body.i;
+ for(vpi=mesa_vp->Instructions; vpi->Opcode != VP_OPCODE_END; vpi++, o_inst++){
+
+ operands=op_operands(vpi->Opcode);
+
+ /* these ops need special handling.
+ Ops that need temp vars should probably be given reg indexes starting at the end of tmp area. */
switch(vpi->Opcode){
- case VP_OPCODE_ABS:
+ case VP_OPCODE_MOV://ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
+ o_inst->op=MAKE_VSF_OP(R300_VPI_OUT_OP_ADD, vpi->DstReg.Index,
+ t_dst_mask(vpi->DstReg.WriteMask), t_dst_class(vpi->DstReg.File));
+ o_inst->src1=t_src(vp, &vpi->SrcReg[0]);
+ o_inst->src2=MAKE_VSF_SOURCE(t_src_index(vp, &vpi->SrcReg[0]),
+ SWIZZLE_ZERO, SWIZZLE_ZERO,
+ SWIZZLE_ZERO, SWIZZLE_ZERO,
+ t_src_class(vpi->SrcReg[0].File), VSF_FLAG_NONE);
+
+ o_inst->src3=0;
+ goto next;
+
+ case VP_OPCODE_DP3://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO}
+ 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->src1=MAKE_VSF_SOURCE(t_src_index(vp, &vpi->SrcReg[0]),
+ t_swizzle(vpi->SrcReg[0].Swizzle[0]),
+ t_swizzle(vpi->SrcReg[0].Swizzle[1]),
+ t_swizzle(vpi->SrcReg[0].Swizzle[2]),
+ SWIZZLE_ZERO,
+ t_src_class(vpi->SrcReg[0].File),
+ vpi->SrcReg[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE);
+
+ o_inst->src2=MAKE_VSF_SOURCE(t_src_index(vp, &vpi->SrcReg[1]),
+ t_swizzle(vpi->SrcReg[1].Swizzle[0]),
+ t_swizzle(vpi->SrcReg[1].Swizzle[1]),
+ t_swizzle(vpi->SrcReg[1].Swizzle[2]),
+ SWIZZLE_ZERO,
+ t_src_class(vpi->SrcReg[1].File),
+ vpi->SrcReg[1].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE);
+
+ o_inst->src3=0;
+ goto next;
+
+ case VP_OPCODE_ABS://MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
case VP_OPCODE_ARL:
- case VP_OPCODE_DP3:
- case VP_OPCODE_DP4:
- case VP_OPCODE_DPH:
- case VP_OPCODE_DST:
+ case VP_OPCODE_DPH://DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
case VP_OPCODE_FLR:
- case VP_OPCODE_MOV:
- case VP_OPCODE_SUB:
+ /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W}
+ ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */
+
+ case VP_OPCODE_SUB://ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
case VP_OPCODE_SWZ:
case VP_OPCODE_XPD:
+ /* 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*/
+
case VP_OPCODE_RCC:
case VP_OPCODE_PRINT:
+ //vp->num_temporaries++;
fprintf(stderr, "Dont know how to handle op %d yet\n", vpi->Opcode);
exit(-1);
break;
@@ -409,37 +521,27 @@ static void translate_program(struct r300_vertex_program *vp)
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){
+
+ o_inst->op=MAKE_VSF_OP(t_opcode(vpi->Opcode), vpi->DstReg.Index,
+ t_dst_mask(vpi->DstReg.WriteMask), t_dst_class(vpi->DstReg.File));
+
+ switch(operands){
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;
+ o_inst->src1=t_src(vp, &vpi->SrcReg[0]);
+ o_inst->src2=0;
+ o_inst->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;
+ o_inst->src1=t_src(vp, &vpi->SrcReg[0]);
+ o_inst->src2=t_src(vp, &vpi->SrcReg[1]);
+ o_inst->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]);
+ o_inst->src1=t_src(vp, &vpi->SrcReg[0]);
+ o_inst->src2=t_src(vp, &vpi->SrcReg[1]);
+ o_inst->src3=t_src(vp, &vpi->SrcReg[2]);
break;
default:
@@ -447,14 +549,38 @@ static void translate_program(struct r300_vertex_program *vp)
exit(-1);
break;
}
+ next:
+
+ /* If instruction writes to result and one of the inputs is tmp, we move it at the end of program */
+ if(vpi->DstReg.File == PROGRAM_OUTPUT){
+ for(operand_index=0; operand_index < operands; operand_index++)
+ if(vpi->SrcReg[operand_index].File == PROGRAM_TEMPORARY){
+ t2rs[vp->t2rs++]=*o_inst;
+ o_inst--; /* FIXME */
+ break;
+ }
+ }
+
}
- vp->program.length=inst_index*4;
-
+ /* Put "tmp to result" instructions in */
+ for(i=0; i < vp->t2rs; i++, o_inst++)
+ *o_inst=t2rs[i];
+
+ vp->program.length=(o_inst - vp->program.body.i) * 4;
+ vp->translated=GL_TRUE;
}
static void r300BindProgram(GLcontext *ctx, GLenum target, struct program *prog)
{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ struct r300_vertex_program *vp=(void *)prog;
+#if 0
fprintf(stderr, "r300BindProgram\n");
+#endif
+ if(rmesa->current_vp == vp)
+ return ;
+
+ rmesa->current_vp = vp;
}
/* Mesa doesnt seem to have prototype for this */
@@ -464,34 +590,26 @@ _mesa_init_ati_fragment_shader( GLcontext *ctx, struct ati_fragment_shader *prog
static struct program *r300NewProgram(GLcontext *ctx, GLenum target, GLuint id)
{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_vertex_program *vp;
struct fragment_program *fp;
struct ati_fragment_shader *afs;
-
+#if 0
fprintf(stderr, "r300NewProgram, target=%d, id=%d\n", target, id);
-
+#endif
switch(target){
case GL_VERTEX_PROGRAM_ARB:
- fprintf(stderr, "vertex prog\n");
vp=CALLOC_STRUCT(r300_vertex_program);
-
- /* note that vp points to mesa_program since its first on the struct
- */
return _mesa_init_vertex_program(ctx, &vp->mesa_program, target, id);
case GL_FRAGMENT_PROGRAM_ARB:
- fprintf(stderr, "fragment prog\n");
fp=CALLOC_STRUCT(fragment_program);
return _mesa_init_fragment_program(ctx, fp, target, id);
case GL_FRAGMENT_PROGRAM_NV:
- fprintf(stderr, "nv fragment prog\n");
fp=CALLOC_STRUCT(fragment_program);
return _mesa_init_fragment_program(ctx, fp, target, id);
case GL_FRAGMENT_SHADER_ATI:
- fprintf(stderr, "ati fragment prog\n");
afs=CALLOC_STRUCT(ati_fragment_shader);
return _mesa_init_ati_fragment_shader(ctx, afs, target, id);
}
@@ -502,9 +620,14 @@ static struct program *r300NewProgram(GLcontext *ctx, GLenum target, GLuint id)
static void r300DeleteProgram(GLcontext *ctx, struct program *prog)
{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ struct r300_vertex_program *vp=(void *)prog;
+#if 0
fprintf(stderr, "r300DeleteProgram\n");
+#endif
+ if(rmesa->current_vp == vp)
+ rmesa->current_vp = NULL;
- /* check that not active */
_mesa_delete_program(ctx, prog);
}
@@ -515,38 +638,44 @@ static void r300ProgramStringNotify(GLcontext *ctx, GLenum target,
struct program *prog)
{
struct r300_vertex_program *vp=(void *)prog;
-
+#if 0
fprintf(stderr, "r300ProgramStringNotify\n");
- /* XXX: There is still something wrong as mesa doesnt call r300IsProgramNative at all */
- (void)r300IsProgramNative(ctx, target, prog);
-
+#endif
+
switch(target) {
case GL_VERTEX_PROGRAM_ARB:
vp->translated=GL_FALSE;
break;
}
+ /* XXX: There is still something wrong as mesa doesnt call r300IsProgramNative at all */
+ (void)r300IsProgramNative(ctx, target, prog);
+
}
static GLboolean r300IsProgramNative(GLcontext *ctx, GLenum target,
struct program *prog)
{
+ struct r300_vertex_program *vp=(void *)prog;
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+#if 0
fprintf(stderr, "r300IsProgramNative\n");
//exit(0);
- debug_vp((struct vertex_program *)prog);
-
+ debug_vp(ctx, vp);
+#endif
+ translate_program(vp);
+ //r300VertexProgUpdateParams(ctx, vp);
+
return 1;
}
/* This is misnamed and shouldnt be here since fragment programs use these functions too */
void r300InitVertexProgFuncs(struct dd_function_table *functions)
{
-#if 1
functions->NewProgram=r300NewProgram;
functions->BindProgram=r300BindProgram;
functions->DeleteProgram=r300DeleteProgram;
functions->ProgramStringNotify=r300ProgramStringNotify;
functions->IsProgramNative=r300IsProgramNative;
-#endif
}