From: Marek Olšák <marek.ol...@amd.com> If the shader selector is created with a different context than the shader variant, we should use the calling context's target machine for the shader variant.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=99419 --- src/gallium/drivers/radeonsi/si_shader.h | 2 ++ src/gallium/drivers/radeonsi/si_state_shaders.c | 41 ++++++++++++++++--------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h index 5a24318..cf4da85 100644 --- a/src/gallium/drivers/radeonsi/si_shader.h +++ b/src/gallium/drivers/radeonsi/si_shader.h @@ -491,20 +491,22 @@ struct si_shader_info { ubyte vs_output_param_offset[SI_MAX_VS_OUTPUTS]; ubyte num_input_sgprs; ubyte num_input_vgprs; char face_vgpr_index; bool uses_instanceid; ubyte nr_pos_exports; ubyte nr_param_exports; }; struct si_shader { + struct si_compiler_ctx_state compiler_ctx_state; + struct si_shader_selector *selector; struct si_shader *next_variant; struct si_shader_part *prolog; struct si_shader_part *epilog; struct si_pm4_state *pm4; struct r600_resource *bo; struct r600_resource *scratch_bo; struct si_shader_key key; diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c index eaba19a..010ce15 100644 --- a/src/gallium/drivers/radeonsi/si_state_shaders.c +++ b/src/gallium/drivers/radeonsi/si_state_shaders.c @@ -1079,55 +1079,56 @@ static inline void si_shader_selector_key(struct pipe_context *ctx, assert(0); } } static void si_build_shader_variant(void *job, int thread_index) { struct si_shader *shader = (struct si_shader *)job; struct si_shader_selector *sel = shader->selector; struct si_screen *sscreen = sel->screen; LLVMTargetMachineRef tm; - struct pipe_debug_callback *debug = &sel->compiler_ctx_state.debug; + struct pipe_debug_callback *debug = &shader->compiler_ctx_state.debug; int r; if (thread_index >= 0) { assert(thread_index < ARRAY_SIZE(sscreen->tm)); tm = sscreen->tm[thread_index]; if (!debug->async) debug = NULL; } else { - tm = sel->compiler_ctx_state.tm; + tm = shader->compiler_ctx_state.tm; } r = si_shader_create(sscreen, tm, shader, debug); if (unlikely(r)) { R600_ERR("Failed to build shader variant (type=%u) %d\n", sel->type, r); shader->compilation_failed = true; return; } - if (sel->compiler_ctx_state.is_debug_context) { + if (shader->compiler_ctx_state.is_debug_context) { FILE *f = open_memstream(&shader->shader_log, &shader->shader_log_size); if (f) { si_shader_dump(sscreen, shader, NULL, sel->type, f, false); fclose(f); } } si_shader_init_pm4_state(sscreen, shader); } /* Select the hw shader variant depending on the current state. */ static int si_shader_select_with_key(struct si_screen *sscreen, struct si_shader_ctx_state *state, + struct si_compiler_ctx_state *compiler_state, struct si_shader_key *key, int thread_index) { static const struct si_shader_key zeroed; struct si_shader_selector *sel = state->cso; struct si_shader *current = state->current; struct si_shader *iter, *shader = NULL; if (unlikely(sscreen->b.debug_flags & DBG_NO_OPT_VARIANT)) { memset(&key->opt, 0, sizeof(key->opt)); @@ -1184,20 +1185,21 @@ again: } /* Build a new shader. */ shader = CALLOC_STRUCT(si_shader); if (!shader) { pipe_mutex_unlock(sel->mutex); return -ENOMEM; } shader->selector = sel; shader->key = *key; + shader->compiler_ctx_state = *compiler_state; /* Monolithic-only shaders don't make a distinction between optimized * and unoptimized. */ shader->is_monolithic = !sel->main_shader_part || sel->main_shader_part->key.as_ls != key->as_ls || sel->main_shader_part->key.as_es != key->as_es || memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0 || memcmp(&key->mono, &zeroed.mono, sizeof(key->mono)) != 0; @@ -1233,27 +1235,29 @@ again: si_build_shader_variant(shader, thread_index); if (!shader->compilation_failed) state->current = shader; pipe_mutex_unlock(sel->mutex); return shader->compilation_failed ? -1 : 0; } static int si_shader_select(struct pipe_context *ctx, - struct si_shader_ctx_state *state) + struct si_shader_ctx_state *state, + struct si_compiler_ctx_state *compiler_state) { struct si_context *sctx = (struct si_context *)ctx; struct si_shader_key key; si_shader_selector_key(ctx, state->cso, &key); - return si_shader_select_with_key(sctx->screen, state, &key, -1); + return si_shader_select_with_key(sctx->screen, state, compiler_state, + &key, -1); } static void si_parse_next_shader_property(const struct tgsi_shader_info *info, struct si_shader_key *key) { unsigned next_shader = info->properties[TGSI_PROPERTY_NEXT_SHADER]; switch (info->processor) { case PIPE_SHADER_VERTEX: switch (next_shader) { @@ -1420,21 +1424,23 @@ void si_init_shader_selector_async(void *job, int thread_index) sel->info.uses_linear_center && sel->info.uses_linear_centroid; key.part.ps.epilog.alpha_func = PIPE_FUNC_ALWAYS; for (i = 0; i < 8; i++) if (sel->info.colors_written & (1 << i)) key.part.ps.epilog.spi_shader_col_format |= V_028710_SPI_SHADER_FP16_ABGR << (i * 4); break; } - if (si_shader_select_with_key(sscreen, &state, &key, thread_index)) + if (si_shader_select_with_key(sscreen, &state, + &sel->compiler_ctx_state, &key, + thread_index)) fprintf(stderr, "radeonsi: can't create a monolithic shader\n"); } /* The GS copy shader is always pre-compiled. */ if (sel->type == PIPE_SHADER_GEOMETRY) { sel->gs_copy_shader = si_generate_gs_copy_shader(sscreen, tm, sel, debug); if (!sel->gs_copy_shader) { fprintf(stderr, "radeonsi: can't create GS copy shader\n"); return; } @@ -2363,88 +2369,95 @@ static void si_update_so(struct si_context *sctx, struct si_shader_selector *sha for (i = 0; i < so->num_outputs; i++) enabled_stream_buffers_mask |= (1 << so->output[i].output_buffer) << (so->output[i].stream * 4); sctx->b.streamout.enabled_stream_buffers_mask = enabled_stream_buffers_mask; sctx->b.streamout.stride_in_dw = shader->so.stride; } bool si_update_shaders(struct si_context *sctx) { struct pipe_context *ctx = (struct pipe_context*)sctx; + struct si_compiler_ctx_state compiler_state; struct si_state_rasterizer *rs = sctx->queued.named.rasterizer; struct si_shader *old_vs = si_get_vs_state(sctx); bool old_clip_disable = old_vs ? old_vs->key.opt.hw_vs.clip_disable : false; int r; + compiler_state.tm = sctx->tm; + compiler_state.debug = sctx->b.debug; + compiler_state.is_debug_context = sctx->is_debug; + /* Update stages before GS. */ if (sctx->tes_shader.cso) { if (!sctx->tf_ring) { si_init_tess_factor_ring(sctx); if (!sctx->tf_ring) return false; } /* VS as LS */ - r = si_shader_select(ctx, &sctx->vs_shader); + r = si_shader_select(ctx, &sctx->vs_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, ls, sctx->vs_shader.current->pm4); if (sctx->tcs_shader.cso) { - r = si_shader_select(ctx, &sctx->tcs_shader); + r = si_shader_select(ctx, &sctx->tcs_shader, + &compiler_state); if (r) return false; si_pm4_bind_state(sctx, hs, sctx->tcs_shader.current->pm4); } else { if (!sctx->fixed_func_tcs_shader.cso) { si_generate_fixed_func_tcs(sctx); if (!sctx->fixed_func_tcs_shader.cso) return false; } - r = si_shader_select(ctx, &sctx->fixed_func_tcs_shader); + r = si_shader_select(ctx, &sctx->fixed_func_tcs_shader, + &compiler_state); if (r) return false; si_pm4_bind_state(sctx, hs, sctx->fixed_func_tcs_shader.current->pm4); } - r = si_shader_select(ctx, &sctx->tes_shader); + r = si_shader_select(ctx, &sctx->tes_shader, &compiler_state); if (r) return false; if (sctx->gs_shader.cso) { /* TES as ES */ si_pm4_bind_state(sctx, es, sctx->tes_shader.current->pm4); } else { /* TES as VS */ si_pm4_bind_state(sctx, vs, sctx->tes_shader.current->pm4); si_update_so(sctx, sctx->tes_shader.cso); } } else if (sctx->gs_shader.cso) { /* VS as ES */ - r = si_shader_select(ctx, &sctx->vs_shader); + r = si_shader_select(ctx, &sctx->vs_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, es, sctx->vs_shader.current->pm4); } else { /* VS as VS */ - r = si_shader_select(ctx, &sctx->vs_shader); + r = si_shader_select(ctx, &sctx->vs_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, vs, sctx->vs_shader.current->pm4); si_update_so(sctx, sctx->vs_shader.cso); } /* Update GS. */ if (sctx->gs_shader.cso) { - r = si_shader_select(ctx, &sctx->gs_shader); + r = si_shader_select(ctx, &sctx->gs_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, gs, sctx->gs_shader.current->pm4); si_pm4_bind_state(sctx, vs, sctx->gs_shader.cso->gs_copy_shader->pm4); si_update_so(sctx, sctx->gs_shader.cso); if (!si_update_gs_ring_buffers(sctx)) return false; } else { si_pm4_bind_state(sctx, gs, NULL); @@ -2452,21 +2465,21 @@ bool si_update_shaders(struct si_context *sctx) } si_update_vgt_shader_config(sctx); if (old_clip_disable != si_get_vs_state(sctx)->key.opt.hw_vs.clip_disable) si_mark_atom_dirty(sctx, &sctx->clip_regs); if (sctx->ps_shader.cso) { unsigned db_shader_control; - r = si_shader_select(ctx, &sctx->ps_shader); + r = si_shader_select(ctx, &sctx->ps_shader, &compiler_state); if (r) return false; si_pm4_bind_state(sctx, ps, sctx->ps_shader.current->pm4); db_shader_control = sctx->ps_shader.cso->db_shader_control | S_02880C_KILL_ENABLE(si_get_alpha_test_func(sctx) != PIPE_FUNC_ALWAYS); if (si_pm4_state_changed(sctx, ps) || si_pm4_state_changed(sctx, vs) || sctx->sprite_coord_enable != rs->sprite_coord_enable || -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev