summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2007-02-05 21:29:25 +0100
committerRoland Scheidegger <[email protected]>2007-02-05 21:29:25 +0100
commit17c13b406f4f8a3e7cf755749aa65448f79f6a84 (patch)
treeac8f8c0af0cf369f1a38ad68dd4d6d0713435db8 /src
parent5b8a50572d3de2b9801be904c7403fc79061d090 (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.c51
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 524472a7772..4c8f967fdff 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] =