[Mesa-dev] [PATCH 45/61] radeonsi/gfx9: make sure the 1st shader's main part exists for merged shaders
Marek Olšák
maraeo at gmail.com
Mon Apr 24 08:45:42 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
---
src/gallium/drivers/radeonsi/si_state_shaders.c | 78 +++++++++++++++++++------
1 file changed, 60 insertions(+), 18 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index b35bdfa..6bb3f50 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1428,28 +1428,57 @@ static void si_build_shader_variant(void *job, int thread_index)
&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);
}
+static const struct si_shader_key zeroed;
+
+static bool si_check_missing_main_part(struct si_screen *sscreen,
+ struct si_shader_selector *sel,
+ struct si_compiler_ctx_state *compiler_state,
+ struct si_shader_key *key)
+{
+ struct si_shader **mainp = si_get_main_shader_part(sel, key);
+
+ if (!*mainp) {
+ struct si_shader *main_part = CALLOC_STRUCT(si_shader);
+
+ if (!main_part)
+ return false;
+
+ main_part->selector = sel;
+ main_part->key.as_es = key->as_es;
+ main_part->key.as_ls = key->as_ls;
+
+ if (si_compile_tgsi_shader(sscreen, compiler_state->tm,
+ main_part, false,
+ &compiler_state->debug) != 0) {
+ FREE(main_part);
+ return false;
+ }
+ *mainp = main_part;
+ }
+ return true;
+}
+
/* 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));
}
again:
/* Check if we don't need to change anything.
@@ -1506,47 +1535,60 @@ again:
if (!shader) {
mtx_unlock(&sel->mutex);
return -ENOMEM;
}
shader->selector = sel;
shader->key = *key;
shader->compiler_ctx_state = *compiler_state;
/* Compile the main shader part if it doesn't exist. This can happen
* if the initial guess was wrong. */
- struct si_shader **mainp = si_get_main_shader_part(sel, key);
bool is_pure_monolithic =
sscreen->use_monolithic_shaders ||
memcmp(&key->mono, &zeroed.mono, sizeof(key->mono)) != 0;
- if (!*mainp && !is_pure_monolithic) {
- struct si_shader *main_part = CALLOC_STRUCT(si_shader);
+ if (!is_pure_monolithic) {
+ bool ok;
- if (!main_part) {
- FREE(shader);
- mtx_unlock(&sel->mutex);
- return -ENOMEM; /* skip the draw call */
+ /* Make sure the main shader part is present. This is needed
+ * for shaders that can be compiled as VS, LS, or ES, and only
+ * one of them is compiled at creation.
+ *
+ * For merged shaders, check that the starting shader's main
+ * part is present.
+ */
+ if (sscreen->b.chip_class >= GFX9 &&
+ (sel->type == PIPE_SHADER_TESS_CTRL ||
+ sel->type == PIPE_SHADER_GEOMETRY)) {
+ struct si_shader_selector *shader1 = NULL;
+ struct si_shader_key shader1_key = zeroed;
+
+ if (sel->type == PIPE_SHADER_TESS_CTRL) {
+ shader1 = key->part.tcs.ls;
+ shader1_key.as_ls = 1;
+ } else if (sel->type == PIPE_SHADER_GEOMETRY) {
+ shader1 = key->part.gs.es;
+ shader1_key.as_es = 1;
+ } else
+ assert(0);
+
+ ok = si_check_missing_main_part(sscreen, shader1,
+ compiler_state, &shader1_key);
+ } else {
+ ok = si_check_missing_main_part(sscreen, sel,
+ compiler_state, key);
}
-
- main_part->selector = sel;
- main_part->key.as_es = key->as_es;
- main_part->key.as_ls = key->as_ls;
-
- if (si_compile_tgsi_shader(sscreen, compiler_state->tm,
- main_part, false,
- &compiler_state->debug) != 0) {
- FREE(main_part);
+ if (!ok) {
FREE(shader);
mtx_unlock(&sel->mutex);
return -ENOMEM; /* skip the draw call */
}
- *mainp = main_part;
}
/* Monolithic-only shaders don't make a distinction between optimized
* and unoptimized. */
shader->is_monolithic =
is_pure_monolithic ||
memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;
shader->is_optimized =
!is_pure_monolithic &&
--
2.7.4
More information about the mesa-dev
mailing list