[Mesa-dev] [PATCH] gallium: Make TGSI_SEMANTIC_FOG register four-component wide.

Roland Scheidegger sroland at vmware.com
Wed Nov 20 08:28:42 PST 2013


On 11/20/2013 03:23 PM, jfonseca at vmware.com wrote:
> From: José Fonseca <jfonseca at 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


More information about the mesa-dev mailing list