On 11/20/2013 03:23 PM, jfons...@vmware.com wrote:
From: José Fonseca <jfons...@vmware.com>
D3D9 Shader Model 2 restricted the fog register to one component,
http://msdn.microsoft.com/en-us/library/windows/desktop/bb172945.aspx ,
but that restriction no longer exists in Shader Model 3, and several
WHCK tests enforce that.
So this change:
- lifts the single-component restriction TGSI_SEMANTIC_FOG
from Gallium interface
- updates the Mesa state tracker to enforce output fog has (f, 0, 0, 1)
- draw module was updated to leave TGSI_SEMANTIC_FOG output registers
alone
Several gallium drivers that are going out of their way to clear
TGSI_SEMANTIC_FOG components could be simplified in the future.
Thanks to Si Chen and Michal Krol for identifying the problem.
Testing done: piglit fogcoord-*.vpfp tests
---
src/gallium/auxiliary/draw/draw_llvm.c | 6 ------
src/gallium/auxiliary/draw/draw_vs_exec.c | 7 +------
src/gallium/docs/source/tgsi.rst | 10 +++-------
src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 7 +++++++
src/mesa/state_tracker/st_mesa_to_tgsi.c | 7 +++++++
5 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c
b/src/gallium/auxiliary/draw/draw_llvm.c
index fe49b86..71cc45f 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -659,12 +659,6 @@ generate_vs(struct draw_llvm_variant *variant,
LLVMBuildStore(builder, out, outputs[attrib][chan]);
}
break;
- case TGSI_SEMANTIC_FOG:
- if (chan == 1 || chan == 2)
- LLVMBuildStore(builder, bld.zero, outputs[attrib][chan]);
- else if (chan == 3)
- LLVMBuildStore(builder, bld.one, outputs[attrib][chan]);
- break;
}
}
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c
b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 6100394..83cc5fd 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -167,12 +167,7 @@ vs_exec_run_linear( struct draw_vertex_shader *shader,
output[slot][2] = CLAMP(machine->Outputs[slot].xyzw[2].f[j],
0.0f, 1.0f);
output[slot][3] = CLAMP(machine->Outputs[slot].xyzw[3].f[j],
0.0f, 1.0f);
}
- else if (name == TGSI_SEMANTIC_FOG) {
- output[slot][0] = machine->Outputs[slot].xyzw[0].f[j];
- output[slot][1] = 0;
- output[slot][2] = 0;
- output[slot][3] = 1;
- } else
+ else
{
output[slot][0] = machine->Outputs[slot].xyzw[0].f[j];
output[slot][1] = machine->Outputs[slot].xyzw[1].f[j];
diff --git a/src/gallium/docs/source/tgsi.rst b/src/gallium/docs/source/tgsi.rst
index f80c08d..1070619 100644
--- a/src/gallium/docs/source/tgsi.rst
+++ b/src/gallium/docs/source/tgsi.rst
@@ -2420,13 +2420,9 @@ TGSI_SEMANTIC_FOG
Vertex shader inputs and outputs and fragment shader inputs may be
labeled with TGSI_SEMANTIC_FOG to indicate that the register contains
-a fog coordinate in the form (F, 0, 0, 1). Typically, the fragment
-shader will use the fog coordinate to compute a fog blend factor which
-is used to blend the normal fragment color with a constant fog color.
-
-Only the first component matters when writing from the vertex shader;
-the driver will ensure that the coordinate is in this format when used
-as a fragment shader input.
+a fog coordinate. Typically, the fragment shader will use the fog coordinate
+to compute a fog blend factor which is used to blend the normal fragment color
+with a constant fog color.
Maybe add some text that the "fog coord" really is just an ordinary vec4
reg like regular semantics?
TGSI_SEMANTIC_PSIZE
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 6319079..74b3e5b 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -4889,6 +4889,13 @@ st_translate_program(
t->outputs[i] = ureg_DECL_output(ureg,
outputSemanticName[i],
outputSemanticIndex[i]);
+ if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) {
+ /* force register to contain a fog coordinate in the form (F, 0,
0, 1). */
+ ureg_MOV(ureg,
+ ureg_writemask(t->outputs[i], TGSI_WRITEMASK_XYZW &
~TGSI_WRITEMASK_X),
+ ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f));
+ t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X);
+ }
}
if (passthrough_edgeflags)
emit_edgeflags(t);
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c
b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 921b0f9..7d79c62 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -1121,6 +1121,13 @@ st_translate_mesa_program(
t->outputs[i] = ureg_DECL_output( ureg,
outputSemanticName[i],
outputSemanticIndex[i] );
+ if (outputSemanticName[i] == TGSI_SEMANTIC_FOG) {
+ /* force register to contain a fog coordinate in the form (F, 0,
0, 1). */
+ ureg_MOV(ureg,
+ ureg_writemask(t->outputs[i], TGSI_WRITEMASK_XYZW &
~TGSI_WRITEMASK_X),
+ ureg_imm4f(ureg, 0.0f, 0.0f, 0.0f, 1.0f));
+ t->outputs[i] = ureg_writemask(t->outputs[i], TGSI_WRITEMASK_X);
+ }
}
if (passthrough_edgeflags)
emit_edgeflags( t, program );
Otherwise looks good to me. Can't say I'm a big fan of our half-baked
d3d10-bolted-on-d3d9 semantics style, but this just changes a weirdo
semantic into one which doesn't really have much meaning which is fine
by me - I think you get lucky because there aren't any drivers which
can't actually do this, even r300 which can't do SM3 looks like it
treats fog interpolation like any other generic semantic (though that
was just a very quick glance).
Roland
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev