From 029d18cd3d79ff956c50b3486078d968d15bf0fb Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Fri, 3 Nov 2006 12:48:18 +0000 Subject: enable generic arrays for r200 hw vertex programs by assigning unused color and texture inputs to them. Not widely tested yet. This should eliminate all fallbacks due to vertex programs, except writes to back facing colors, or when exceeding a hw limit (12 temps, 12 attribs etc.). --- src/mesa/drivers/dri/r200/r200_maos_arrays.c | 63 +++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 5 deletions(-) (limited to 'src/mesa/drivers/dri/r200/r200_maos_arrays.c') diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 92348c90ca..f6ab2f0074 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -385,8 +385,8 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) GLuint vfmt0 = 0, vfmt1 = 0; GLuint count = VB->Count; GLuint i; - - if (1) { + + if (inputs & VERT_BIT_POS) { if (!rmesa->tcl.obj.buf) emit_vector( ctx, &rmesa->tcl.obj, @@ -404,7 +404,6 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) } component[nr++] = &rmesa->tcl.obj; } - if (inputs & VERT_BIT_NORMAL) { if (!rmesa->tcl.norm.buf) @@ -481,7 +480,7 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT; component[nr++] = &rmesa->tcl.spec; } - + for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { if (inputs & (VERT_BIT_TEX0 << i)) { if (!rmesa->tcl.tex[i].buf) @@ -497,6 +496,50 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) } } + if (ctx->VertexProgram._Enabled) { + int *vp_inputs = rmesa->curr_vp_hw->inputs; + for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) { + if (inputs & (1 << i)) { + int geninput = i - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[i]->data, + 4, + VB->AttribPtr[i]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + switch (vp_inputs[i]) { + case 0: + vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + break; + case 2: + case 3: + case 4: + case 5: + vfmt0 |= R200_VTX_FP_RGBA << (R200_VTX_COLOR_0_SHIFT + (vp_inputs[i] - 2) * 2); + break; + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (vp_inputs[i] - 6) * 3); + break; + case 13: + vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; + break; + case 1: + case 12: + default: + assert(0); + } + } + } + } + if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { R200_STATECHANGE( rmesa, vtx ); @@ -522,7 +565,7 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) if (newinputs & VERT_BIT_NORMAL) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); - + if (newinputs & VERT_BIT_FOG) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.fog, __FUNCTION__ ); @@ -536,4 +579,14 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) if (newinputs & VERT_BIT_TEX(unit)) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.tex[unit], __FUNCTION__ ); } + + if (ctx->VertexProgram._Enabled) { + int i; + for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { + if (newinputs & (1 << i)) + r200ReleaseDmaRegion( rmesa, + &rmesa->tcl.generic[i - VERT_ATTRIB_GENERIC0], __FUNCTION__ ); + } + } + } -- cgit v1.2.3 From 21cf414489af84b8bb374f76c36db8f0f1919733 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 30 Nov 2006 00:52:54 +0000 Subject: fix mixed conventional / generic vertex arrays which caused a wrong array order leading to very bogus rendering (for instance WoW intro screen mentioned in #8250). --- src/mesa/drivers/dri/r200/r200_context.h | 2 + src/mesa/drivers/dri/r200/r200_maos_arrays.c | 111 ++++++++++++++++++++++++++- src/mesa/drivers/dri/r200/r200_vertprog.c | 4 + 3 files changed, 116 insertions(+), 1 deletion(-) (limited to 'src/mesa/drivers/dri/r200/r200_maos_arrays.c') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 9f109e07ff..fa38a78e26 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -107,6 +107,8 @@ struct r200_vertex_program { VERTEX_SHADER_INSTRUCTION instr[R200_VSF_MAX_INST + 6]; int pos_end; int inputs[VERT_ATTRIB_MAX]; + int rev_inputs[16]; + int gen_inputs_mapped; int native; int fogpidx; int fogmode; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index f6ab2f0074..39c1f68911 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -385,6 +385,14 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) GLuint vfmt0 = 0, vfmt1 = 0; GLuint count = VB->Count; GLuint i; + GLuint generic_in_mapped = 0; + struct r200_vertex_program *vp = NULL; + + /* this looks way more complicated than necessary... */ + if (ctx->VertexProgram._Enabled) { + vp = rmesa->curr_vp_hw; + generic_in_mapped = vp->gen_inputs_mapped; + } if (inputs & VERT_BIT_POS) { if (!rmesa->tcl.obj.buf) @@ -404,6 +412,19 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) } component[nr++] = &rmesa->tcl.obj; } + else if (generic_in_mapped & (1 << 0)) { + int geninput = vp->rev_inputs[0] - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, + 4, + VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + } if (inputs & VERT_BIT_NORMAL) { if (!rmesa->tcl.norm.buf) @@ -463,6 +484,23 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) component[nr++] = &rmesa->tcl.rgba; } +/* vfmt0 |= R200_VTX_PK_RGBA << R200_VTX_COLOR_0_SHIFT; + emit_ubyte_rgba( ctx, &rmesa->tcl.rgba, + (char *)VB->ColorPtr[0]->data, 4, + VB->ColorPtr[0]->stride, count);*/ + else if (generic_in_mapped & (1 << 2)) { + int geninput = vp->rev_inputs[2] - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, + 4, + VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_0_SHIFT; + } if (inputs & VERT_BIT_COLOR1) { @@ -480,8 +518,49 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) vfmt0 |= R200_VTX_FP_RGB << R200_VTX_COLOR_1_SHIFT; component[nr++] = &rmesa->tcl.spec; } + else if (generic_in_mapped & (1 << 3)) { + int geninput = vp->rev_inputs[3] - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, + 4, + VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_1_SHIFT; + } - for ( i = 0 ; i < ctx->Const.MaxTextureUnits ; i++ ) { + if (generic_in_mapped & (1 << 4)) { + int geninput = vp->rev_inputs[4] - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, + 4, + VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_2_SHIFT; + } + + if (generic_in_mapped & (1 << 5)) { + int geninput = vp->rev_inputs[5] - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, + 4, + VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + vfmt0 |= R200_VTX_FP_RGBA << R200_VTX_COLOR_3_SHIFT; + } + + for ( i = 0 ; i < 6 ; i++ ) { if (inputs & (VERT_BIT_TEX0 << i)) { if (!rmesa->tcl.tex[i].buf) emit_vector( ctx, @@ -494,8 +573,37 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) vfmt1 |= VB->TexCoordPtr[i]->size << (i * 3); component[nr++] = &rmesa->tcl.tex[i]; } + else if (generic_in_mapped & (1 << (i + 6))) { + int geninput = vp->rev_inputs[i + 6] - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, + 4, + VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + vfmt1 |= 4 << (R200_VTX_TEX0_COMP_CNT_SHIFT + (i * 3)); + } } + if (generic_in_mapped & (1 << 13)) { + int geninput = vp->rev_inputs[13] - VERT_ATTRIB_GENERIC0; + if (!rmesa->tcl.generic[geninput].buf) { + emit_vector( ctx, + &(rmesa->tcl.generic[geninput]), + (char *)VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->data, + 4, + VB->AttribPtr[geninput + VERT_ATTRIB_GENERIC0]->stride, + count ); + } + component[nr++] = &rmesa->tcl.generic[geninput]; + vfmt0 |= R200_VTX_XY1 | R200_VTX_Z1 | R200_VTX_W1; + } + +/* doesn't work. Wrong order with mixed generic & conventional! */ +/* if (ctx->VertexProgram._Enabled) { int *vp_inputs = rmesa->curr_vp_hw->inputs; for ( i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++ ) { @@ -539,6 +647,7 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) } } } +*/ if (vfmt0 != rmesa->hw.vtx.cmd[VTX_VTXFMT_0] || vfmt1 != rmesa->hw.vtx.cmd[VTX_VTXFMT_1]) { diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index ce14c617c8..899e84caa0 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -405,6 +405,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte int dofogfix = 0; int fog_temp_i = 0; int free_inputs; + int free_inputs_conv; int array_count = 0; vp->native = GL_FALSE; @@ -530,6 +531,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte array_count++; } } + free_inputs_conv = free_inputs; /* using VERT_ATTRIB_TEX6/7 would be illegal */ /* completely ignore aliasing? */ for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { @@ -548,11 +550,13 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte if (free_inputs & (1 << j)) { free_inputs &= ~(1 << j); vp->inputs[i] = j; + vp->rev_inputs[j] = i; break; } } } } + vp->gen_inputs_mapped = free_inputs ^ free_inputs_conv; if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) { if (R200_DEBUG & DEBUG_FALLBACKS) { -- cgit v1.2.3 From 2956a0c8a8395e4d9ae00888aeb88ea5c38b89ad Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Thu, 14 Dec 2006 00:34:44 +0100 Subject: submit vertex weights to make World of Warcraft maybe happy (bug 8250) submit the vertex weights to hw, which will enable broken vertex programs errorneously using them to work. Note however that this will only work if glWeight is used, there is no code in mesa at all to deal with weight vertex array (glWeightPointerARB). --- src/mesa/drivers/dri/r200/r200_context.h | 1 + src/mesa/drivers/dri/r200/r200_maos_arrays.c | 19 ++++++++++++++++++- src/mesa/drivers/dri/r200/r200_vertprog.c | 1 - 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'src/mesa/drivers/dri/r200/r200_maos_arrays.c') diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index fa38a78e26..44c67b68cb 100644 --- a/src/mesa/drivers/dri/r200/r200_context.h +++ b/src/mesa/drivers/dri/r200/r200_context.h @@ -735,6 +735,7 @@ struct r200_tcl_info { GLuint *Elts; struct r200_dma_region indexed_verts; + struct r200_dma_region weight; struct r200_dma_region obj; struct r200_dma_region rgba; struct r200_dma_region spec; diff --git a/src/mesa/drivers/dri/r200/r200_maos_arrays.c b/src/mesa/drivers/dri/r200/r200_maos_arrays.c index 39c1f68911..270dc35a46 100644 --- a/src/mesa/drivers/dri/r200/r200_maos_arrays.c +++ b/src/mesa/drivers/dri/r200/r200_maos_arrays.c @@ -423,7 +423,21 @@ void r200EmitArrays( GLcontext *ctx, GLuint inputs ) count ); } component[nr++] = &rmesa->tcl.generic[geninput]; - vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + vfmt0 |= R200_VTX_W0 | R200_VTX_Z0; + } + + if (inputs & VERT_BIT_WEIGHT) { + if (!rmesa->tcl.weight.buf) + emit_vector( ctx, + &rmesa->tcl.weight, + (char *)VB->AttribPtr[VERT_ATTRIB_WEIGHT]->data, + VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size, + VB->AttribPtr[VERT_ATTRIB_WEIGHT]->stride, + count); + + assert(VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size <= 4); + vfmt0 |= VB->AttribPtr[VERT_ATTRIB_WEIGHT]->size << R200_VTX_WEIGHT_COUNT_SHIFT; + component[nr++] = &rmesa->tcl.weight; } if (inputs & VERT_BIT_NORMAL) { @@ -672,6 +686,9 @@ void r200ReleaseArrays( GLcontext *ctx, GLuint newinputs ) if (newinputs & VERT_BIT_POS) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.obj, __FUNCTION__ ); + if (newinputs & VERT_BIT_WEIGHT) + r200ReleaseDmaRegion( rmesa, &rmesa->tcl.weight, __FUNCTION__ ); + if (newinputs & VERT_BIT_NORMAL) r200ReleaseDmaRegion( rmesa, &rmesa->tcl.norm, __FUNCTION__ ); diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c index 899e84caa0..491701b796 100644 --- a/src/mesa/drivers/dri/r200/r200_vertprog.c +++ b/src/mesa/drivers/dri/r200/r200_vertprog.c @@ -503,7 +503,6 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte array_count++; } if (mesa_vp->Base.InputsRead & VERT_BIT_WEIGHT) { - /* we don't actually handle that later. Then again, we don't have to... */ vp->inputs[VERT_ATTRIB_WEIGHT] = 12; array_count++; } -- cgit v1.2.3