summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2011-11-17 16:40:02 -0700
committerBrian Paul <[email protected]>2012-02-23 07:49:06 -0700
commit8a9cad6384c61670e96165ad8c5f6ade927c6fa0 (patch)
treed5c789f4187773517897fcb6950e9fd49a9fe1de /src/gallium
parent4516fcc57f8f45fc0e2e4d8681fd5d74e4f31d7d (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/svga/svga_state_fs.c50
-rw-r--r--src/gallium/drivers/svga/svga_state_vs.c49
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 c95d82fc00e..8503b03eed4 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 b82e68556e4..3cb0cdb9697 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);