gallium: Make TGSI_SEMANTIC_FOG register four-component wide.
authorJosé Fonseca <jfonseca@vmware.com>
Wed, 20 Nov 2013 15:22:31 +0000 (15:22 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Thu, 21 Nov 2013 14:00:05 +0000 (14:00 +0000)
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 <sroland@vmware.com>
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/draw/draw_vs_exec.c
src/gallium/docs/source/tgsi.rst
src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/mesa/state_tracker/st_mesa_to_tgsi.c

index fe49b8687ab6d256a6e1ea5ce7f2807d9fc9a9d4..71cc45f1f6817bd639913b26ffbc13af9edd172b 100644 (file)
@@ -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;
                }
             }
          }
index 610039498a335635aec94ba2b395ea4d83d51a3c..83cc5fda5a7c786d36098969a8b585dd1c308d07 100644 (file)
@@ -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];
index f80c08d31759b506e6363a909d1d24971c29c0a9..0501aca54fc56797a09d3addb7e0badd7e240edd 100644 (file)
@@ -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
index 6319079d524e2ddbf1d69625a39b1150abc4badc..74b3e5b58d9533e0238ba2480e9590d1db6e23af 100644 (file)
@@ -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);
index 921b0f9b89448932dce272b4e9a13d01cb13b896..7d79c62354074ec4477db6065bee08e6090875ec 100644 (file)
@@ -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 );