diff options
Diffstat (limited to 'src/gallium/drivers/vc4')
-rw-r--r-- | src/gallium/drivers/vc4/vc4_context.h | 8 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_draw.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_program.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qir.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_qpu_emit.c | 5 | ||||
-rw-r--r-- | src/gallium/drivers/vc4/vc4_register_allocate.c | 5 |
6 files changed, 42 insertions, 9 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..05e2021 100644 --- a/src/gallium/drivers/vc4/vc4_program.c +++ b/src/gallium/drivers/vc4/vc4_program.c @@ -451,6 +451,15 @@ ntq_emit_tex(struct vc4_compile *c, nir_tex_instr *instr) struct qreg u0 = qir_uniform_f(c, 0.0f); struct qreg u1 = qir_uniform_f(c, 1.0f); if (c->key->tex[unit].compare_mode) { + /* From the GL_ARB_shadow spec: + * + * "Let Dt (D subscript t) be the depth texture + * value, in the range [0, 1]. Let R be the + * interpolated texture coordinate clamped to the + * range [0, 1]." + */ + compare = qir_SAT(c, compare); + switch (c->key->tex[unit].compare_func) { case PIPE_FUNC_NEVER: depth_output = qir_uniform_f(c, 0.0f); @@ -2437,9 +2446,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 +2657,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..ab343ee 100644 --- a/src/gallium/drivers/vc4/vc4_register_allocate.c +++ b/src/gallium/drivers/vc4/vc4_register_allocate.c @@ -247,7 +247,7 @@ vc4_register_allocate(struct vc4_context *vc4, struct vc4_compile *c) case QOP_ROT_MUL: assert(inst->src[0].file == QFILE_TEMP); - class_bits[inst->src[0].index] &= ~CLASS_BIT_R0_R3; + class_bits[inst->src[0].index] &= CLASS_BIT_R0_R3; break; default: @@ -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++) { |