[Mesa-dev] [PATCH 2/2] svga: check shader size against max command buffer size

Jose Fonseca jfonseca at vmware.com
Mon Feb 3 20:23:07 CET 2014


Looks good AFAICT.

Jose

----- Original Message -----
> If the shader is too large, plug in a dummy shader.  This patch also
> reworks the existing dummy shader code.
> ---
>  src/gallium/drivers/svga/include/svga_reg.h |    1 +
>  src/gallium/drivers/svga/svga_state_fs.c    |   60
>  +++++++++++++++++++++------
>  2 files changed, 49 insertions(+), 12 deletions(-)
> 
> diff --git a/src/gallium/drivers/svga/include/svga_reg.h
> b/src/gallium/drivers/svga/include/svga_reg.h
> index 1b96c2e..dee719d 100644
> --- a/src/gallium/drivers/svga/include/svga_reg.h
> +++ b/src/gallium/drivers/svga/include/svga_reg.h
> @@ -889,6 +889,7 @@ typedef enum {
>  } SVGAFifoCmdId;
>  
>  #define SVGA_CMD_MAX_ARGS           64
> +#define SVGA_CB_MAX_COMMAND_SIZE (32 * 1024) // 32 KB
>  
>  
>  /*
> diff --git a/src/gallium/drivers/svga/svga_state_fs.c
> b/src/gallium/drivers/svga/svga_state_fs.c
> index 860a0c8..7119a19 100644
> --- a/src/gallium/drivers/svga/svga_state_fs.c
> +++ b/src/gallium/drivers/svga/svga_state_fs.c
> @@ -76,12 +76,18 @@ search_fs_key(const struct svga_fragment_shader *fs,
>  /**
>   * If we fail to compile a fragment shader (because it uses too many
>   * registers, for example) we'll use a dummy/fallback shader that
> - * simply emits a constant color.
> + * simply emits a constant color (red for debug, black for release).
> + * We hit this with the Unigine/Heaven demo when Shaders = High.
> + * With black, the demo still looks good.
>   */
>  static const struct tgsi_token *
>  get_dummy_fragment_shader(void)
>  {
> -   static const float red[4] = { 1.0, 0.0, 0.0, 0.0 };
> +#ifdef DEBUG
> +   static const float color[4] = { 1.0, 0.0, 0.0, 0.0 }; /* red */
> +#else
> +   static const float color[4] = { 0.0, 0.0, 0.0, 0.0 }; /* black */
> +#endif
>     struct ureg_program *ureg;
>     const struct tgsi_token *tokens;
>     struct ureg_src src;
> @@ -93,7 +99,7 @@ get_dummy_fragment_shader(void)
>        return NULL;
>  
>     dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
> -   src = ureg_DECL_immediate(ureg, red, 4);
> +   src = ureg_DECL_immediate(ureg, color, 4);
>     ureg_MOV(ureg, dst, src);
>     ureg_END(ureg);
>  
> @@ -106,6 +112,29 @@ get_dummy_fragment_shader(void)
>  
>  
>  /**
> + * Replace the given shader's instruction with a simple constant-color
> + * shader.  We use this when normal shader translation fails.
> + */
> +static struct svga_shader_variant *
> +get_compiled_dummy_shader(struct svga_fragment_shader *fs,
> +                          const struct svga_fs_compile_key *key)
> +{
> +   const struct tgsi_token *dummy = get_dummy_fragment_shader();
> +   struct svga_shader_variant *variant;
> +
> +   if (!dummy) {
> +      return NULL;
> +   }
> +
> +   FREE((void *) fs->base.tokens);
> +   fs->base.tokens = dummy;
> +
> +   variant = svga_translate_fragment_program(fs, key);
> +   return variant;
> +}
> +
> +
> +/**
>   * Translate TGSI shader into an svga shader variant.
>   */
>  static enum pipe_error
> @@ -119,17 +148,24 @@ compile_fs(struct svga_context *svga,
>  
>     variant = svga_translate_fragment_program( fs, key );
>     if (variant == NULL) {
> -      /* some problem during translation, try the dummy shader */
> -      const struct tgsi_token *dummy = get_dummy_fragment_shader();
> -      if (!dummy) {
> -         ret = PIPE_ERROR_OUT_OF_MEMORY;
> +      debug_printf("Failed to compile fragment shader,"
> +                   " using dummy shader instead.\n");
> +      variant = get_compiled_dummy_shader(fs, key);
> +      if (!variant) {
> +         ret = PIPE_ERROR;
>           goto fail;
>        }
> -      debug_printf("Failed to compile fragment shader, using dummy shader
> instead.\n");
> -      FREE((void *) fs->base.tokens);
> -      fs->base.tokens = dummy;
> -      variant = svga_translate_fragment_program(fs, key);
> -      if (variant == NULL) {
> +   }
> +
> +   if (variant->nr_tokens * sizeof(variant->tokens[0])
> +       + sizeof(SVGA3dCmdDefineShader) + sizeof(SVGA3dCmdHeader)
> +       >= SVGA_CB_MAX_COMMAND_SIZE) {
> +      /* too big, use dummy shader */
> +      debug_printf("Shader too large (%lu bytes),"
> +                   " using dummy shader instead.\n",
> +                   (unsigned long ) variant->nr_tokens *
> sizeof(variant->tokens[0]));
> +      variant = get_compiled_dummy_shader(fs, key);
> +      if (!variant) {
>           ret = PIPE_ERROR;
>           goto fail;
>        }
> --
> 1.7.10.4
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://urldefense.proofpoint.com/v1/url?u=http://lists.freedesktop.org/mailman/listinfo/mesa-dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=NMr9uy2iTjWVixC0wOcYCWEIYhfo80qKwRgdodpoDzA%3D%0A&m=D6Q9%2Bo%2FJoK7IQSw%2BN8R2qpRcyU4Ejo41GMF0kxJRxeI%3D%0A&s=725f477afcd6dfa8da7adbf9b89b6405506a4888f384392732f367b7249261da
> 


More information about the mesa-dev mailing list