[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