[Mesa-dev] [PATCH] st/mesa: add a fallback for clear_with_quad when no vs_layer

Jose Fonseca jfonseca at vmware.com
Sun Nov 16 05:57:04 PST 2014


> Fun fact -- llvmpipe also needs this.

I think this is because this functionality was developed with D3D10 in mind, and  

http://msdn.microsoft.com/en-gb/library/windows/desktop/bb509647.aspx

states that SV_RenderTargetArrayIndex "an be written from the geometry shader and read by the pixel shader."


BTW, coding these helper shaders as text is not a great idea IMO:

- The tgsi_parse thing was written for debugging purposes mainly.

- Whenever there are TGSI interface changes, any breakage with ureg will cause compile errors, where as it will only be detected at runtime with TGSI

- ureg module makes it really easy to write shaders.  It's not really much more work.


Jose

________________________________________
From: mesa-dev <mesa-dev-bounces at lists.freedesktop.org> on behalf of Ilia Mirkin <imirkin at alum.mit.edu>
Sent: 15 November 2014 21:20
To: mesa-dev at lists.freedesktop.org
Cc: 10.3 10.4
Subject: Re: [Mesa-dev] [PATCH] st/mesa: add a fallback for clear_with_quad     when no vs_layer

On Sat, Nov 15, 2014 at 1:38 PM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> Not all drivers can set gl_Layer from VS. Add a fallback that passes the
> instance id from VS to GS, and then uses the GS to set the layer.
>
> Tested by adding
>
>   quad_buffers |= clear_buffers;
>   clear_buffers = 0;
>
> to the st_Clear logic, and forcing set_vertex_shader_layered in all
> cases. No piglit regressions (on piglits with 'clear' in the name).
>
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> Cc: "10.3 10.4" <mesa-stable at lists.freedesktop.org>
> ---
>
> No explicit piglit test hits this path without the above hacks, so it went
> under the radar for a long time. I tested this on nvc0 with the above hacks,
> and double-checked that without them, things still worked.

Fun fact -- llvmpipe also needs this.

>
>  src/gallium/auxiliary/util/u_simple_shaders.c | 70 +++++++++++++++++++++++++++
>  src/gallium/auxiliary/util/u_simple_shaders.h |  6 +++
>  src/mesa/state_tracker/st_cb_clear.c          | 25 ++++++++--
>  src/mesa/state_tracker/st_context.h           |  1 +
>  4 files changed, 97 insertions(+), 5 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
> index adf4887..2cf528b 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.c
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.c
> @@ -124,6 +124,76 @@ void *util_make_layered_clear_vertex_shader(struct pipe_context *pipe)
>     return pipe->create_vs_state(pipe, &state);
>  }
>
> +/**
> + * Takes position and color, and outputs position, color, and instance id.
> + */
> +void *util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe)
> +{
> +   static const char text[] =
> +         "VERT\n"
> +         "DCL IN[0]\n"
> +         "DCL IN[1]\n"
> +         "DCL SV[0], INSTANCEID\n"
> +         "DCL OUT[0], POSITION\n"
> +         "DCL OUT[1], GENERIC[0]\n"
> +         "DCL OUT[2], GENERIC[1]\n"
> +
> +         "MOV OUT[0], IN[0]\n"
> +         "MOV OUT[1], IN[1]\n"
> +         "MOV OUT[2].x, SV[0].xxxx\n"
> +         "END\n";
> +   struct tgsi_token tokens[1000];
> +   struct pipe_shader_state state = {tokens};
> +
> +   if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
> +      assert(0);
> +      return NULL;
> +   }
> +   return pipe->create_vs_state(pipe, &state);
> +}
> +
> +/**
> + * Takes position, color, and target layer, and emits vertices on that target
> + * layer, with the specified color.
> + */
> +void *util_make_layered_clear_geometry_shader(struct pipe_context *pipe)
> +{
> +   static const char text[] =
> +      "GEOM\n"
> +      "PROPERTY GS_INPUT_PRIMITIVE TRIANGLES\n"
> +      "PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP\n"
> +      "PROPERTY GS_MAX_OUTPUT_VERTICES 3\n"
> +      "PROPERTY GS_INVOCATIONS 1\n"
> +      "DCL IN[][0], POSITION\n" /* position */
> +      "DCL IN[][1], GENERIC[0]\n" /* color */
> +      "DCL IN[][2], GENERIC[1]\n" /* vs invocation */
> +      "DCL OUT[0], POSITION\n"
> +      "DCL OUT[1], GENERIC[0]\n"
> +      "DCL OUT[2], LAYER\n"
> +      "IMM[0] INT32 {0, 0, 0, 0}\n"
> +
> +      "MOV OUT[0], IN[0][0]\n"
> +      "MOV OUT[1], IN[0][1]\n"
> +      "MOV OUT[2].x, IN[0][2].xxxx\n"
> +      "EMIT IMM[0].xxxx\n"
> +      "MOV OUT[0], IN[1][0]\n"
> +      "MOV OUT[1], IN[1][1]\n"
> +      "MOV OUT[2].x, IN[1][2].xxxx\n"
> +      "EMIT IMM[0].xxxx\n"
> +      "MOV OUT[0], IN[2][0]\n"
> +      "MOV OUT[1], IN[2][1]\n"
> +      "MOV OUT[2].x, IN[2][2].xxxx\n"
> +      "EMIT IMM[0].xxxx\n"
> +      "END\n";
> +   struct tgsi_token tokens[1000];
> +   struct pipe_shader_state state = {tokens};
> +
> +   if (!tgsi_text_translate(text, tokens, Elements(tokens))) {
> +      assert(0);
> +      return NULL;
> +   }
> +   return pipe->create_gs_state(pipe, &state);
> +}
>
>  /**
>   * Make simple fragment texture shader:
> diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
> index c1d14aa..b467b9f5 100644
> --- a/src/gallium/auxiliary/util/u_simple_shaders.h
> +++ b/src/gallium/auxiliary/util/u_simple_shaders.h
> @@ -60,6 +60,12 @@ extern void *
>  util_make_layered_clear_vertex_shader(struct pipe_context *pipe);
>
>  extern void *
> +util_make_layered_clear_helper_vertex_shader(struct pipe_context *pipe);
> +
> +extern void *
> +util_make_layered_clear_geometry_shader(struct pipe_context *pipe);
> +
> +extern void *
>  util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
>                                          unsigned tex_target,
>                                          unsigned interp_mode,
> diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
> index 2c1414e..e778556 100644
> --- a/src/mesa/state_tracker/st_cb_clear.c
> +++ b/src/mesa/state_tracker/st_cb_clear.c
> @@ -88,6 +88,14 @@ st_destroy_clear(struct st_context *st)
>        cso_delete_vertex_shader(st->cso_context, st->clear.vs);
>        st->clear.vs = NULL;
>     }
> +   if (st->clear.vs_layered) {
> +      cso_delete_vertex_shader(st->cso_context, st->clear.vs_layered);
> +      st->clear.vs_layered = NULL;
> +   }
> +   if (st->clear.gs_layered) {
> +      cso_delete_geometry_shader(st->cso_context, st->clear.gs_layered);
> +      st->clear.gs_layered = NULL;
> +   }
>  }
>
>
> @@ -127,6 +135,7 @@ set_vertex_shader(struct st_context *st)
>     }
>
>     cso_set_vertex_shader_handle(st->cso_context, st->clear.vs);
> +   cso_set_geometry_shader_handle(st->cso_context, NULL);
>  }
>
>
> @@ -135,18 +144,25 @@ set_vertex_shader_layered(struct st_context *st)
>  {
>     struct pipe_context *pipe = st->pipe;
>
> -   if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID) ||
> -       !pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT)) {
> -      assert(!"Got layered clear, but the VS layer output is unsupported");
> +   if (!pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_INSTANCEID)) {
> +      assert(!"Got layered clear, but VS instancing is unsupported");
>        set_vertex_shader(st);
>        return;
>     }
>
>     if (!st->clear.vs_layered) {
> -      st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
> +      bool vs_layer =
> +         pipe->screen->get_param(pipe->screen, PIPE_CAP_TGSI_VS_LAYER_VIEWPORT);
> +      if (vs_layer) {
> +         st->clear.vs_layered = util_make_layered_clear_vertex_shader(pipe);
> +      } else {
> +         st->clear.vs_layered = util_make_layered_clear_helper_vertex_shader(pipe);
> +         st->clear.gs_layered = util_make_layered_clear_geometry_shader(pipe);
> +      }
>     }
>
>     cso_set_vertex_shader_handle(st->cso_context, st->clear.vs_layered);
> +   cso_set_geometry_shader_handle(st->cso_context, st->clear.gs_layered);
>  }
>
>
> @@ -332,7 +348,6 @@ clear_with_quad(struct gl_context *ctx, unsigned clear_buffers)
>     }
>
>     set_fragment_shader(st);
> -   cso_set_geometry_shader_handle(st->cso_context, NULL);
>
>     if (num_layers > 1)
>        set_vertex_shader_layered(st);
> diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h
> index 58f14f9..15f9df4 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -181,6 +181,7 @@ struct st_context
>        void *vs;
>        void *fs;
>        void *vs_layered;
> +      void *gs_layered;
>     } clear;
>
>     /** used for anything using util_draw_vertex_buffer */
> --
> 2.0.4
>
_______________________________________________
mesa-dev mailing list
mesa-dev at lists.freedesktop.org
https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.freedesktop.org_mailman_listinfo_mesa-2Ddev&d=AAIGaQ&c=Sqcl0Ez6M0X8aeM67LKIiDJAXVeAw-YihVMNtXt-uEs&r=zfmBZnnVGHeYde45pMKNnVyzeaZbdIqVLprmZCM2zzE&m=AJkgmCtbrAQbFW1WS2D4G8ejAN60xUfyuKCpIA2w3tM&s=bP5XakeSwHBChJ-RRWrGo-6Ksrm8fRkJcHIkuDy0Vds&e=


More information about the mesa-dev mailing list