diff options
author | Roland Scheidegger <sroland@tungstengraphics.com> | 2007-02-05 21:29:25 +0100 |
---|---|---|
committer | Roland Scheidegger <sroland@tungstengraphics.com> | 2007-02-05 21:29:25 +0100 |
commit | 17c13b406f4f8a3e7cf755749aa65448f79f6a84 (patch) | |
tree | ac8f8c0af0cf369f1a38ad68dd4d6d0713435db8 /src | |
parent | 5b8a50572d3de2b9801be904c7403fc79061d090 (diff) |
fix issues when using mixed-mode pos-invariant vp and ff tnl (bug #9856)
ARB_vp requires vertex transformation to be invariant to fixed function tnl
if the position_invariant option is used. So the same function needs to be
used, otherwise z-fighting artifacts may happen with applications which rely
on the results being really the same due to precision issues when dealing with
floating point values (may not be a problem when using a non-optimizing
compiler strictly following IEEE rules).
Diffstat (limited to 'src')
-rw-r--r-- | src/mesa/tnl/t_vb_arbprogram.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 524472a777..4c8f967fdf 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -1249,8 +1249,7 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) m->nr_inputs = m->nr_outputs = 0; for (i = 0; i < VERT_ATTRIB_MAX; i++) { - if (program->Base.InputsRead & (1<<i) || - (i == VERT_ATTRIB_POS && program->IsPositionInvariant)) { + if (program->Base.InputsRead & (1<<i)) { GLuint j = m->nr_inputs++; m->input[j].idx = i; m->input[j].data = (GLfloat *)m->VB->AttribPtr[i]->data; @@ -1258,16 +1257,15 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) m->input[j].size = m->VB->AttribPtr[i]->size; ASSIGN_4V(m->File[0][REG_IN0 + i], 0, 0, 0, 1); } - } + } for (i = 0; i < VERT_RESULT_MAX; i++) { - if (program->Base.OutputsWritten & (1 << i) || - (i == VERT_RESULT_HPOS && program->IsPositionInvariant)) { + if (program->Base.OutputsWritten & (1 << i)) { GLuint j = m->nr_outputs++; m->output[j].idx = i; m->output[j].data = (GLfloat *)m->attribs[i].data; } - } + } /* Run the actual program: @@ -1297,15 +1295,6 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) } } - /* If the program is position invariant, multiply the input position - * by the MVP matrix and store in the vertex position result register. - */ - if (program->IsPositionInvariant) { - TRANSFORM_POINT( m->File[0][REG_OUT0+0], - ctx->_ModelProjectMatrix.m, - m->File[0][REG_IN0+0]); - } - for (j = 0; j < m->nr_outputs; j++) { GLuint idx = REG_OUT0 + m->output[j].idx; m->output[j].data[0] = m->File[0][idx][0]; @@ -1327,15 +1316,39 @@ run_arb_vertex_program(GLcontext *ctx, struct tnl_pipeline_stage *stage) * TODO: 2) Integrate t_vertex.c so that we just go straight ahead * and build machine vertices here. */ - VB->ClipPtr = &m->attribs[VERT_RESULT_HPOS]; - VB->ClipPtr->count = VB->Count; /* XXX There seems to be confusion between using the VERT_ATTRIB_* * values vs _TNL_ATTRIB_* tokens here: */ outputs = program->Base.OutputsWritten; - if (program->IsPositionInvariant) - outputs |= (1<<VERT_RESULT_HPOS); + + if (program->IsPositionInvariant) { + /* We need the exact same transform as in the fixed function path here + to guarantee invariance, depending on compiler optimization flags results + could be different otherwise */ + VB->ClipPtr = TransformRaw( &m->attribs[0], + &ctx->_ModelProjectMatrix, + m->VB->AttribPtr[0] ); + + /* Drivers expect this to be clean to element 4... + */ + switch (VB->ClipPtr->size) { + case 1: + /* impossible */ + case 2: + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 2 ); + /* fall-through */ + case 3: + _mesa_vector4f_clean_elem( VB->ClipPtr, VB->Count, 3 ); + /* fall-through */ + case 4: + break; + } + } + else { + VB->ClipPtr = &m->attribs[VERT_RESULT_HPOS]; + VB->ClipPtr->count = VB->Count; + } if (outputs & (1<<VERT_RESULT_COL0)) { VB->ColorPtr[0] = |