commit 81d4ca188f7d77fb133a41a9fbd6b29318b211e1 Author: Michel Dänzer Date: Wed Oct 29 11:30:05 2014 +0900 radeonsi: If compiling the vertex or geometry shader fails, skip the draw diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 030d6e9..79529ed 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -2280,8 +2280,6 @@ int si_shader_select(struct pipe_context *ctx, if (unlikely(r)) { R600_ERR("Failed to build shader variant (type=%u) %d\n", sel->type, r); - sel->current = NULL; - FREE(shader); return r; } si_shader_init_pm4_state(shader); diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 708e42a..59d2620 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -601,7 +601,7 @@ static void si_init_gs_rings(struct si_context *sctx) false, false, 0, 0); } -static void si_update_derived_state(struct si_context *sctx) +static bool si_update_derived_state(struct si_context *sctx) { struct pipe_context * ctx = (struct pipe_context*)sctx; @@ -619,12 +619,17 @@ static void si_update_derived_state(struct si_context *sctx) if (sctx->gs_shader) { si_shader_select(ctx, sctx->gs_shader); + if (!sctx->gs_shader->current->pm4 || + !sctx->gs_shader->current->gs_copy_shader->pm4) + return false; si_pm4_bind_state(sctx, gs, sctx->gs_shader->current->pm4); si_pm4_bind_state(sctx, vs, sctx->gs_shader->current->gs_copy_shader->pm4); sctx->b.streamout.stride_in_dw = sctx->gs_shader->so.stride; si_shader_select(ctx, sctx->vs_shader); + if (!sctx->vs_shader->current->pm4) + return false; si_pm4_bind_state(sctx, es, sctx->vs_shader->current->pm4); if (!sctx->gs_rings) @@ -650,6 +655,8 @@ static void si_update_derived_state(struct si_context *sctx) si_pm4_bind_state(sctx, gs_onoff, sctx->gs_on); } else { si_shader_select(ctx, sctx->vs_shader); + if (!sctx->vs_shader->current->pm4) + return false; si_pm4_bind_state(sctx, vs, sctx->vs_shader->current->pm4); sctx->b.streamout.stride_in_dw = sctx->vs_shader->so.stride; @@ -668,13 +675,14 @@ static void si_update_derived_state(struct si_context *sctx) si_shader_select(ctx, sctx->ps_shader); - if (!sctx->ps_shader->current) { + if (!sctx->ps_shader->current->pm4) { struct si_shader_selector *sel; /* use a dummy shader if compiling the shader (variant) failed */ si_make_dummy_ps(sctx); sel = sctx->dummy_pixel_shader; si_shader_select(ctx, sel); + FREE(sctx->ps_shader->current); sctx->ps_shader->current = sel->current; } @@ -687,6 +695,8 @@ static void si_update_derived_state(struct si_context *sctx) sctx->ps_db_shader_control = sctx->ps_shader->current->db_shader_control; sctx->db_render_state.dirty = true; } + + return true; } static void si_state_draw(struct si_context *sctx, @@ -916,7 +926,8 @@ void si_draw_vbo(struct pipe_context *ctx, const struct pipe_draw_info *info) if (!sctx->ps_shader || !sctx->vs_shader) return; - si_update_derived_state(sctx); + if (!si_update_derived_state(sctx)) + return; if (sctx->vertex_buffers_dirty) { si_update_vertex_buffers(sctx);