From 2d5f21ba650cb85ffea0ed6f41ee0d1e6fe5a29a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 20 Nov 2013 15:22:31 +0000 Subject: [PATCH] gallium: Make TGSI_SEMANTIC_FOG register four-component wide. 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 Reviewed-by: Roland Scheidegger --- src/gallium/auxiliary/draw/draw_llvm.c | 6 ------ src/gallium/auxiliary/draw/draw_vs_exec.c | 7 +------ src/gallium/docs/source/tgsi.rst | 11 ++++------- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 7 +++++++ src/mesa/state_tracker/st_mesa_to_tgsi.c | 7 +++++++ 5 files changed, 19 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..0501aca 100644 --- a/src/gallium/docs/source/tgsi.rst +++ b/src/gallium/docs/source/tgsi.rst @@ -2420,13 +2420,10 @@ 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. But fog coord really is just an ordinary vec4 +register 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 ); -- 2.7.4