Mesa (master): svga: use dummy shaders when translation fails

Brian Paul brianp at kemper.freedesktop.org
Thu Feb 23 14:54:38 UTC 2012


Module: Mesa
Branch: master
Commit: 8a9cad6384c61670e96165ad8c5f6ade927c6fa0
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=8a9cad6384c61670e96165ad8c5f6ade927c6fa0

Author: Brian Paul <brianp at vmware.com>
Date:   Thu Nov 17 16:40:02 2011 -0700

svga: use dummy shaders when translation fails

Before, if shader translation failed for any reason we'd keep trying
to translate the shader over and over again during state validation.
The dummy fragment shader emits solid red so that might be visual
clue that translation is failing.

Reviewed-by: Jose Fonseca <jfonseca at vmware.com>

---

 src/gallium/drivers/svga/svga_state_fs.c |   50 ++++++++++++++++++++++++++++-
 src/gallium/drivers/svga/svga_state_vs.c |   49 ++++++++++++++++++++++++++++-
 2 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/svga/svga_state_fs.c b/src/gallium/drivers/svga/svga_state_fs.c
index c95d82f..8503b03 100644
--- a/src/gallium/drivers/svga/svga_state_fs.c
+++ b/src/gallium/drivers/svga/svga_state_fs.c
@@ -26,7 +26,9 @@
 #include "util/u_inlines.h"
 #include "pipe/p_defines.h"
 #include "util/u_math.h"
+#include "util/u_memory.h"
 #include "util/u_bitmask.h"
+#include "tgsi/tgsi_ureg.h"
 
 #include "svga_context.h"
 #include "svga_state.h"
@@ -66,6 +68,38 @@ static struct svga_shader_result *search_fs_key( 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.
+ */
+static const struct tgsi_token *
+get_dummy_fragment_shader(void)
+{
+   static const float red[4] = { 1.0, 0.0, 0.0, 0.0 };
+   struct ureg_program *ureg;
+   const struct tgsi_token *tokens;
+   struct ureg_src src;
+   struct ureg_dst dst;
+   unsigned num_tokens;
+
+   ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+   if (!ureg)
+      return NULL;
+
+   dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
+   src = ureg_DECL_immediate(ureg, red, 4);
+   ureg_MOV(ureg, dst, src);
+   ureg_END(ureg);
+
+   tokens = ureg_get_tokens(ureg, &num_tokens);
+
+   ureg_destroy(ureg);
+
+   return tokens;
+}
+
+
 static enum pipe_error compile_fs( struct svga_context *svga,
                                    struct svga_fragment_shader *fs,
                                    const struct svga_fs_compile_key *key,
@@ -76,8 +110,20 @@ static enum pipe_error compile_fs( struct svga_context *svga,
 
    result = svga_translate_fragment_program( fs, key );
    if (result == NULL) {
-      ret = PIPE_ERROR;  /* some problem during translation */
-      goto fail;
+      /* 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;
+         goto fail;
+      }
+      debug_printf("Failed to compile fragment shader, using dummy shader instead.\n");
+      FREE((void *) fs->base.tokens);
+      fs->base.tokens = dummy;
+      result = svga_translate_fragment_program(fs, key);
+      if (result == NULL) {
+         ret = PIPE_ERROR;
+         goto fail;
+      }
    }
 
    result->id = util_bitmask_add(svga->fs_bm);
diff --git a/src/gallium/drivers/svga/svga_state_vs.c b/src/gallium/drivers/svga/svga_state_vs.c
index b82e685..3cb0cdb 100644
--- a/src/gallium/drivers/svga/svga_state_vs.c
+++ b/src/gallium/drivers/svga/svga_state_vs.c
@@ -27,8 +27,10 @@
 #include "pipe/p_defines.h"
 #include "util/u_format.h"
 #include "util/u_math.h"
+#include "util/u_memory.h"
 #include "util/u_bitmask.h"
 #include "translate/translate.h"
+#include "tgsi/tgsi_ureg.h"
 
 #include "svga_context.h"
 #include "svga_state.h"
@@ -65,6 +67,37 @@ static struct svga_shader_result *search_vs_key( struct svga_vertex_shader *vs,
 }
 
 
+/**
+ * If we fail to compile a vertex shader we'll use a dummy/fallback shader
+ * that simply emits a (0,0,0,1) vertex position.
+ */
+static const struct tgsi_token *
+get_dummy_vertex_shader(void)
+{
+   static const float zero[4] = { 0.0, 0.0, 0.0, 1.0 };
+   struct ureg_program *ureg;
+   const struct tgsi_token *tokens;
+   struct ureg_src src;
+   struct ureg_dst dst;
+   unsigned num_tokens;
+
+   ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
+   if (!ureg)
+      return NULL;
+
+   dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
+   src = ureg_DECL_immediate(ureg, zero, 4);
+   ureg_MOV(ureg, dst, src);
+   ureg_END(ureg);
+
+   tokens = ureg_get_tokens(ureg, &num_tokens);
+
+   ureg_destroy(ureg);
+
+   return tokens;
+}
+
+
 static enum pipe_error compile_vs( struct svga_context *svga,
                                    struct svga_vertex_shader *vs,
                                    const struct svga_vs_compile_key *key,
@@ -75,8 +108,20 @@ static enum pipe_error compile_vs( struct svga_context *svga,
 
    result = svga_translate_vertex_program( vs, key );
    if (result == NULL) {
-      ret = PIPE_ERROR_OUT_OF_MEMORY;
-      goto fail;
+      /* some problem during translation, try the dummy shader */
+      const struct tgsi_token *dummy = get_dummy_vertex_shader();
+      if (!dummy) {
+         ret = PIPE_ERROR_OUT_OF_MEMORY;
+         goto fail;
+      }
+      debug_printf("Failed to compile vertex shader, using dummy shader instead.\n");
+      FREE((void *) vs->base.tokens);
+      vs->base.tokens = dummy;
+      result = svga_translate_vertex_program(vs, key);
+      if (result == NULL) {
+         ret = PIPE_ERROR;
+         goto fail;
+      }
    }
 
    result->id = util_bitmask_add(svga->vs_bm);




More information about the mesa-commit mailing list