summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2016-11-07 09:05:59 -0800
committerEmil Velikov <emil.l.velikov@gmail.com>2016-11-23 13:07:00 +0000
commit9a4206379b0e36d440481ae89b98467ed53dc86b (patch)
tree6d9b1420beb64122d90d2e73b77c154dd9e97add /src/gallium
parent4685a724f5894a3426419b9b3d4f0ec129493ad1 (diff)
downloadexternal_mesa3d-9a4206379b0e36d440481ae89b98467ed53dc86b.zip
external_mesa3d-9a4206379b0e36d440481ae89b98467ed53dc86b.tar.gz
external_mesa3d-9a4206379b0e36d440481ae89b98467ed53dc86b.tar.bz2
vc4: Don't abort when a shader compile fails.
It's much better to just skip the draw call entirely. Getting this information out of register allocation will also be useful for implementing threaded fragment shaders, which will need to retry non-threaded if RA fails. Cc: <mesa-stable@lists.freedesktop.org> (cherry picked from commit 4d019bd703e7c20d56d5b858577607115b4926a3)
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/vc4/vc4_context.h8
-rw-r--r--src/gallium/drivers/vc4/vc4_draw.c5
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c18
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h1
-rw-r--r--src/gallium/drivers/vc4/vc4_qpu_emit.c5
-rw-r--r--src/gallium/drivers/vc4/vc4_register_allocate.c3
6 files changed, 32 insertions, 8 deletions
diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h
index 313630a..c164eba 100644
--- a/src/gallium/drivers/vc4/vc4_context.h
+++ b/src/gallium/drivers/vc4/vc4_context.h
@@ -156,6 +156,12 @@ struct vc4_compiled_shader {
bool disable_early_z;
+ /* Set if the compile failed, likely due to register allocation
+ * failure. In this case, we have no shader to run and should not try
+ * to do any draws.
+ */
+ bool failed;
+
uint8_t num_inputs;
/* Byte offsets for the start of the vertex attributes 0-7, and the
@@ -449,7 +455,7 @@ void vc4_flush_jobs_reading_resource(struct vc4_context *vc4,
void vc4_emit_state(struct pipe_context *pctx);
void vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c);
struct qpu_reg *vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c);
-void vc4_update_compiled_shaders(struct vc4_context *vc4, uint8_t prim_mode);
+bool vc4_update_compiled_shaders(struct vc4_context *vc4, uint8_t prim_mode);
bool vc4_rt_format_supported(enum pipe_format f);
bool vc4_rt_format_is_565(enum pipe_format f);
diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c
index 61c5842..c5afc0c 100644
--- a/src/gallium/drivers/vc4/vc4_draw.c
+++ b/src/gallium/drivers/vc4/vc4_draw.c
@@ -307,7 +307,10 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
}
vc4_start_draw(vc4);
- vc4_update_compiled_shaders(vc4, info->mode);
+ if (!vc4_update_compiled_shaders(vc4, info->mode)) {
+ debug_warn_once("shader compile failed, skipping draw call.\n");
+ return;
+ }
vc4_emit_state(pctx);
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 0145488..fe07d91 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -2437,9 +2437,15 @@ vc4_get_compiled_shader(struct vc4_context *vc4, enum qstage stage,
}
}
- copy_uniform_state_to_shader(shader, c);
- shader->bo = vc4_bo_alloc_shader(vc4->screen, c->qpu_insts,
- c->qpu_inst_count * sizeof(uint64_t));
+ shader->failed = c->failed;
+ if (c->failed) {
+ shader->failed = true;
+ } else {
+ copy_uniform_state_to_shader(shader, c);
+ shader->bo = vc4_bo_alloc_shader(vc4->screen, c->qpu_insts,
+ c->qpu_inst_count *
+ sizeof(uint64_t));
+ }
/* Copy the compiler UBO range state to the compiled shader, dropping
* out arrays that were never referenced by an indirect load.
@@ -2642,11 +2648,15 @@ vc4_update_compiled_vs(struct vc4_context *vc4, uint8_t prim_mode)
}
}
-void
+bool
vc4_update_compiled_shaders(struct vc4_context *vc4, uint8_t prim_mode)
{
vc4_update_compiled_fs(vc4, prim_mode);
vc4_update_compiled_vs(vc4, prim_mode);
+
+ return !(vc4->prog.cs->failed ||
+ vc4->prog.vs->failed ||
+ vc4->prog.fs->failed);
}
static uint32_t
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index 4d41c42..c76aeb2 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -523,6 +523,7 @@ struct vc4_compile {
uint32_t program_id;
uint32_t variant_id;
+ bool failed;
};
/* Special nir_load_input intrinsic index for loading the current TLB
diff --git a/src/gallium/drivers/vc4/vc4_qpu_emit.c b/src/gallium/drivers/vc4/vc4_qpu_emit.c
index 4d371c0..eedee55 100644
--- a/src/gallium/drivers/vc4/vc4_qpu_emit.c
+++ b/src/gallium/drivers/vc4/vc4_qpu_emit.c
@@ -565,10 +565,13 @@ vc4_generate_code_block(struct vc4_compile *c,
void
vc4_generate_code(struct vc4_context *vc4, struct vc4_compile *c)
{
- struct qpu_reg *temp_registers = vc4_register_allocate(vc4, c);
struct qblock *start_block = list_first_entry(&c->blocks,
struct qblock, link);
+ struct qpu_reg *temp_registers = vc4_register_allocate(vc4, c);
+ if (!temp_registers)
+ return;
+
switch (c->stage) {
case QSTAGE_VERT:
case QSTAGE_COORD:
diff --git a/src/gallium/drivers/vc4/vc4_register_allocate.c b/src/gallium/drivers/vc4/vc4_register_allocate.c
index fc44764..6c99b05 100644
--- a/src/gallium/drivers/vc4/vc4_register_allocate.c
+++ b/src/gallium/drivers/vc4/vc4_register_allocate.c
@@ -323,7 +323,8 @@ vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c)
if (!ok) {
fprintf(stderr, "Failed to register allocate:\n");
qir_dump(c);
- abort();
+ c->failed = true;
+ return NULL;
}
for (uint32_t i = 0; i < c->num_temps; i++) {