[Mesa-dev] [PATCH 06/18] radeonsi: have separate LS and ES main shader parts in the shader selector
Marek Olšák
maraeo at gmail.com
Thu Feb 16 12:52:58 UTC 2017
From: Marek Olšák <marek.olsak at amd.com>
This might reduce the on-demand compilation if the initial VS/LS/ES
determination is wrong.
---
src/gallium/drivers/radeonsi/si_shader.c | 2 +-
src/gallium/drivers/radeonsi/si_shader.h | 16 +++++++++++
src/gallium/drivers/radeonsi/si_state_shaders.c | 36 ++++++++++++++++++++++---
3 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/si_shader.c b/src/gallium/drivers/radeonsi/si_shader.c
index 1829e3e..de42778 100644
--- a/src/gallium/drivers/radeonsi/si_shader.c
+++ b/src/gallium/drivers/radeonsi/si_shader.c
@@ -8233,21 +8233,21 @@ static void si_fix_resource_usage(struct si_screen *sscreen,
si_multiwave_lds_size_workaround(sscreen,
&shader->config.lds_size);
}
}
int si_shader_create(struct si_screen *sscreen, LLVMTargetMachineRef tm,
struct si_shader *shader,
struct pipe_debug_callback *debug)
{
struct si_shader_selector *sel = shader->selector;
- struct si_shader *mainp = sel->main_shader_part;
+ struct si_shader *mainp = *si_get_main_shader_part(sel, &shader->key);
int r;
/* LS, ES, VS are compiled on demand if the main part hasn't been
* compiled for that stage.
*
* Vertex shaders are compiled on demand when a vertex fetch
* workaround must be applied.
*/
if (shader->is_monolithic) {
/* Monolithic shader (compiled as a whole, has many variants,
diff --git a/src/gallium/drivers/radeonsi/si_shader.h b/src/gallium/drivers/radeonsi/si_shader.h
index da88df0..d4b57c9 100644
--- a/src/gallium/drivers/radeonsi/si_shader.h
+++ b/src/gallium/drivers/radeonsi/si_shader.h
@@ -280,20 +280,22 @@ struct si_shader_selector {
struct si_compiler_ctx_state compiler_ctx_state;
pipe_mutex mutex;
struct si_shader *first_variant; /* immutable after the first variant */
struct si_shader *last_variant; /* mutable */
/* The compiled TGSI shader expecting a prolog and/or epilog (not
* uploaded to a buffer).
*/
struct si_shader *main_shader_part;
+ struct si_shader *main_shader_part_ls; /* as_ls is set in the key */
+ struct si_shader *main_shader_part_es; /* as_es is set in the key */
struct si_shader *gs_copy_shader;
struct tgsi_token *tokens;
struct pipe_stream_output_info so;
struct tgsi_shader_info info;
/* PIPE_SHADER_[VERTEX|FRAGMENT|...] */
unsigned type;
@@ -578,11 +580,25 @@ void si_shader_apply_scratch_relocs(struct si_context *sctx,
struct si_shader *shader,
struct si_shader_config *config,
uint64_t scratch_va);
void si_shader_binary_read_config(struct radeon_shader_binary *binary,
struct si_shader_config *conf,
unsigned symbol_offset);
unsigned si_get_spi_shader_z_format(bool writes_z, bool writes_stencil,
bool writes_samplemask);
const char *si_get_shader_name(struct si_shader *shader, unsigned processor);
+/* Inline helpers. */
+
+/* Return the pointer to the main shader part's pointer. */
+static inline struct si_shader **
+si_get_main_shader_part(struct si_shader_selector *sel,
+ struct si_shader_key *key)
+{
+ if (key->as_ls)
+ return &sel->main_shader_part_ls;
+ if (key->as_es)
+ return &sel->main_shader_part_es;
+ return &sel->main_shader_part;
+}
+
#endif
diff --git a/src/gallium/drivers/radeonsi/si_state_shaders.c b/src/gallium/drivers/radeonsi/si_state_shaders.c
index 3630911..179176c 100644
--- a/src/gallium/drivers/radeonsi/si_state_shaders.c
+++ b/src/gallium/drivers/radeonsi/si_state_shaders.c
@@ -1229,29 +1229,53 @@ 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;
+ /* 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 =
memcmp(&key->mono, &zeroed.mono, sizeof(key->mono)) != 0;
+ if (!*mainp && !is_pure_monolithic) {
+ struct si_shader *main_part = CALLOC_STRUCT(si_shader);
+
+ if (!main_part) {
+ FREE(shader);
+ pipe_mutex_unlock(sel->mutex);
+ return -ENOMEM; /* skip the draw call */
+ }
+
+ 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);
+ FREE(shader);
+ pipe_mutex_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 =
- !sel->main_shader_part ||
- sel->main_shader_part->key.as_ls != key->as_ls ||
- sel->main_shader_part->key.as_es != key->as_es ||
is_pure_monolithic ||
memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;
shader->is_optimized =
!sscreen->use_monolithic_shaders &&
memcmp(&key->opt, &zeroed.opt, sizeof(key->opt)) != 0;
if (shader->is_optimized)
util_queue_fence_init(&shader->optimized_ready);
if (!sel->last_variant) {
@@ -1392,21 +1416,21 @@ void si_init_shader_selector_async(void *job, int thread_index)
}
if (tgsi_binary) {
pipe_mutex_lock(sscreen->shader_cache_mutex);
if (!si_shader_cache_insert_shader(sscreen, tgsi_binary, shader))
FREE(tgsi_binary);
pipe_mutex_unlock(sscreen->shader_cache_mutex);
}
}
- sel->main_shader_part = shader;
+ *si_get_main_shader_part(sel, &shader->key) = shader;
/* Unset "outputs_written" flags for outputs converted to
* DEFAULT_VAL, so that later inter-shader optimizations don't
* try to eliminate outputs that don't exist in the final
* shader.
*
* This is only done if non-monolithic shaders are enabled.
*/
if ((sel->type == PIPE_SHADER_VERTEX ||
sel->type == PIPE_SHADER_TESS_EVAL) &&
@@ -1862,20 +1886,24 @@ static void si_delete_shader_selector(struct pipe_context *ctx, void *state)
}
while (p) {
c = p->next_variant;
si_delete_shader(sctx, p);
p = c;
}
if (sel->main_shader_part)
si_delete_shader(sctx, sel->main_shader_part);
+ if (sel->main_shader_part_ls)
+ si_delete_shader(sctx, sel->main_shader_part_ls);
+ if (sel->main_shader_part_es)
+ si_delete_shader(sctx, sel->main_shader_part_es);
if (sel->gs_copy_shader)
si_delete_shader(sctx, sel->gs_copy_shader);
util_queue_fence_destroy(&sel->ready);
pipe_mutex_destroy(sel->mutex);
free(sel->tokens);
free(sel);
}
static unsigned si_get_ps_input_cntl(struct si_context *sctx,
--
2.7.4
More information about the mesa-dev
mailing list