mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-22 00:30:13 +01:00
radeonsi: separate the compilation chunk of si_create_shader_selector
The function interface is ready to be used by util_queue. Also, si_shader_select_with_key can no longer accept si_context. Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
This commit is contained in:
parent
6781a2a994
commit
850cd953b1
3 changed files with 111 additions and 81 deletions
|
|
@ -233,6 +233,13 @@ struct si_shader;
|
||||||
* binaries for one TGSI program. This can be shared by multiple contexts.
|
* binaries for one TGSI program. This can be shared by multiple contexts.
|
||||||
*/
|
*/
|
||||||
struct si_shader_selector {
|
struct si_shader_selector {
|
||||||
|
struct si_screen *screen;
|
||||||
|
|
||||||
|
/* Should only be used by si_init_shader_selector_async
|
||||||
|
* if thread_index == -1 (non-threaded). */
|
||||||
|
LLVMTargetMachineRef tm;
|
||||||
|
struct pipe_debug_callback debug;
|
||||||
|
|
||||||
pipe_mutex mutex;
|
pipe_mutex mutex;
|
||||||
struct si_shader *first_variant; /* immutable after the first variant */
|
struct si_shader *first_variant; /* immutable after the first variant */
|
||||||
struct si_shader *last_variant; /* mutable */
|
struct si_shader *last_variant; /* mutable */
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,7 @@ bool si_update_shaders(struct si_context *sctx);
|
||||||
void si_init_shader_functions(struct si_context *sctx);
|
void si_init_shader_functions(struct si_context *sctx);
|
||||||
bool si_init_shader_cache(struct si_screen *sscreen);
|
bool si_init_shader_cache(struct si_screen *sscreen);
|
||||||
void si_destroy_shader_cache(struct si_screen *sscreen);
|
void si_destroy_shader_cache(struct si_screen *sscreen);
|
||||||
|
void si_init_shader_selector_async(void *job, int thread_index);
|
||||||
|
|
||||||
/* si_state_draw.c */
|
/* si_state_draw.c */
|
||||||
void si_emit_cache_flush(struct si_context *sctx, struct r600_atom *atom);
|
void si_emit_cache_flush(struct si_context *sctx, struct r600_atom *atom);
|
||||||
|
|
|
||||||
|
|
@ -981,11 +981,12 @@ static inline void si_shader_selector_key(struct pipe_context *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Select the hw shader variant depending on the current state. */
|
/* Select the hw shader variant depending on the current state. */
|
||||||
static int si_shader_select_with_key(struct pipe_context *ctx,
|
static int si_shader_select_with_key(struct si_screen *sscreen,
|
||||||
struct si_shader_ctx_state *state,
|
struct si_shader_ctx_state *state,
|
||||||
union si_shader_key *key)
|
union si_shader_key *key,
|
||||||
|
LLVMTargetMachineRef tm,
|
||||||
|
struct pipe_debug_callback *debug)
|
||||||
{
|
{
|
||||||
struct si_context *sctx = (struct si_context *)ctx;
|
|
||||||
struct si_shader_selector *sel = state->cso;
|
struct si_shader_selector *sel = state->cso;
|
||||||
struct si_shader *current = state->current;
|
struct si_shader *current = state->current;
|
||||||
struct si_shader *iter, *shader = NULL;
|
struct si_shader *iter, *shader = NULL;
|
||||||
|
|
@ -1020,7 +1021,7 @@ static int si_shader_select_with_key(struct pipe_context *ctx,
|
||||||
shader->selector = sel;
|
shader->selector = sel;
|
||||||
shader->key = *key;
|
shader->key = *key;
|
||||||
|
|
||||||
r = si_shader_create(sctx->screen, sctx->tm, shader, &sctx->b.debug);
|
r = si_shader_create(sscreen, tm, shader, debug);
|
||||||
if (unlikely(r)) {
|
if (unlikely(r)) {
|
||||||
R600_ERR("Failed to build shader variant (type=%u) %d\n",
|
R600_ERR("Failed to build shader variant (type=%u) %d\n",
|
||||||
sel->type, r);
|
sel->type, r);
|
||||||
|
|
@ -1028,7 +1029,7 @@ static int si_shader_select_with_key(struct pipe_context *ctx,
|
||||||
pipe_mutex_unlock(sel->mutex);
|
pipe_mutex_unlock(sel->mutex);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
si_shader_init_pm4_state(sctx->screen, shader);
|
si_shader_init_pm4_state(sscreen, shader);
|
||||||
|
|
||||||
if (!sel->last_variant) {
|
if (!sel->last_variant) {
|
||||||
sel->first_variant = shader;
|
sel->first_variant = shader;
|
||||||
|
|
@ -1045,10 +1046,12 @@ static int si_shader_select_with_key(struct pipe_context *ctx,
|
||||||
static int si_shader_select(struct pipe_context *ctx,
|
static int si_shader_select(struct pipe_context *ctx,
|
||||||
struct si_shader_ctx_state *state)
|
struct si_shader_ctx_state *state)
|
||||||
{
|
{
|
||||||
|
struct si_context *sctx = (struct si_context *)ctx;
|
||||||
union si_shader_key key;
|
union si_shader_key key;
|
||||||
|
|
||||||
si_shader_selector_key(ctx, state->cso, &key);
|
si_shader_selector_key(ctx, state->cso, &key);
|
||||||
return si_shader_select_with_key(ctx, state, &key);
|
return si_shader_select_with_key(sctx->screen, state, &key,
|
||||||
|
sctx->tm, &sctx->b.debug);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void si_parse_next_shader_property(const struct tgsi_shader_info *info,
|
static void si_parse_next_shader_property(const struct tgsi_shader_info *info,
|
||||||
|
|
@ -1076,6 +1079,94 @@ static void si_parse_next_shader_property(const struct tgsi_shader_info *info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile the main shader part or the monolithic shader as part of
|
||||||
|
* si_shader_selector initialization. Since it can be done asynchronously,
|
||||||
|
* there is no way to report compile failures to applications.
|
||||||
|
*/
|
||||||
|
void si_init_shader_selector_async(void *job, int thread_index)
|
||||||
|
{
|
||||||
|
struct si_shader_selector *sel = (struct si_shader_selector *)job;
|
||||||
|
struct si_screen *sscreen = sel->screen;
|
||||||
|
LLVMTargetMachineRef tm = sel->tm;
|
||||||
|
struct pipe_debug_callback *debug = &sel->debug;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
/* Compile the main shader part for use with a prolog and/or epilog.
|
||||||
|
* If this fails, the driver will try to compile a monolithic shader
|
||||||
|
* on demand.
|
||||||
|
*/
|
||||||
|
if (sel->type != PIPE_SHADER_GEOMETRY &&
|
||||||
|
!sscreen->use_monolithic_shaders) {
|
||||||
|
struct si_shader *shader = CALLOC_STRUCT(si_shader);
|
||||||
|
void *tgsi_binary;
|
||||||
|
|
||||||
|
if (!shader) {
|
||||||
|
fprintf(stderr, "radeonsi: can't allocate a main shader part\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shader->selector = sel;
|
||||||
|
si_parse_next_shader_property(&sel->info, &shader->key);
|
||||||
|
|
||||||
|
tgsi_binary = si_get_tgsi_binary(sel);
|
||||||
|
|
||||||
|
/* Try to load the shader from the shader cache. */
|
||||||
|
pipe_mutex_lock(sscreen->shader_cache_mutex);
|
||||||
|
|
||||||
|
if (tgsi_binary &&
|
||||||
|
si_shader_cache_load_shader(sscreen, tgsi_binary, shader)) {
|
||||||
|
FREE(tgsi_binary);
|
||||||
|
} else {
|
||||||
|
/* Compile the shader if it hasn't been loaded from the cache. */
|
||||||
|
if (si_compile_tgsi_shader(sscreen, tm, shader, false,
|
||||||
|
debug) != 0) {
|
||||||
|
FREE(shader);
|
||||||
|
FREE(tgsi_binary);
|
||||||
|
pipe_mutex_unlock(sscreen->shader_cache_mutex);
|
||||||
|
fprintf(stderr, "radeonsi: can't compile a main shader part\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgsi_binary &&
|
||||||
|
!si_shader_cache_insert_shader(sscreen, tgsi_binary, shader))
|
||||||
|
FREE(tgsi_binary);
|
||||||
|
}
|
||||||
|
pipe_mutex_unlock(sscreen->shader_cache_mutex);
|
||||||
|
|
||||||
|
sel->main_shader_part = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pre-compilation. */
|
||||||
|
if (sel->type == PIPE_SHADER_GEOMETRY ||
|
||||||
|
sscreen->b.debug_flags & DBG_PRECOMPILE) {
|
||||||
|
struct si_shader_ctx_state state = {sel};
|
||||||
|
union si_shader_key key;
|
||||||
|
|
||||||
|
memset(&key, 0, sizeof(key));
|
||||||
|
si_parse_next_shader_property(&sel->info, &key);
|
||||||
|
|
||||||
|
/* Set reasonable defaults, so that the shader key doesn't
|
||||||
|
* cause any code to be eliminated.
|
||||||
|
*/
|
||||||
|
switch (sel->type) {
|
||||||
|
case PIPE_SHADER_TESS_CTRL:
|
||||||
|
key.tcs.epilog.prim_mode = PIPE_PRIM_TRIANGLES;
|
||||||
|
break;
|
||||||
|
case PIPE_SHADER_FRAGMENT:
|
||||||
|
key.ps.epilog.alpha_func = PIPE_FUNC_ALWAYS;
|
||||||
|
for (i = 0; i < 8; i++)
|
||||||
|
if (sel->info.colors_written & (1 << i))
|
||||||
|
key.ps.epilog.spi_shader_col_format |=
|
||||||
|
V_028710_SPI_SHADER_FP16_ABGR << (i * 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (si_shader_select_with_key(sscreen, &state, &key, tm, debug))
|
||||||
|
fprintf(stderr, "radeonsi: can't create a monolithic shader\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void *si_create_shader_selector(struct pipe_context *ctx,
|
static void *si_create_shader_selector(struct pipe_context *ctx,
|
||||||
const struct pipe_shader_state *state)
|
const struct pipe_shader_state *state)
|
||||||
{
|
{
|
||||||
|
|
@ -1087,6 +1178,9 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
|
||||||
if (!sel)
|
if (!sel)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
sel->screen = sscreen;
|
||||||
|
sel->tm = sctx->tm;
|
||||||
|
sel->debug = sctx->b.debug;
|
||||||
sel->tokens = tgsi_dup_tokens(state->tokens);
|
sel->tokens = tgsi_dup_tokens(state->tokens);
|
||||||
if (!sel->tokens) {
|
if (!sel->tokens) {
|
||||||
FREE(sel);
|
FREE(sel);
|
||||||
|
|
@ -1199,83 +1293,11 @@ static void *si_create_shader_selector(struct pipe_context *ctx,
|
||||||
if (sel->info.writes_memory)
|
if (sel->info.writes_memory)
|
||||||
sel->db_shader_control |= S_02880C_EXEC_ON_HIER_FAIL(1) |
|
sel->db_shader_control |= S_02880C_EXEC_ON_HIER_FAIL(1) |
|
||||||
S_02880C_EXEC_ON_NOOP(1);
|
S_02880C_EXEC_ON_NOOP(1);
|
||||||
|
|
||||||
/* Compile the main shader part for use with a prolog and/or epilog. */
|
|
||||||
if (sel->type != PIPE_SHADER_GEOMETRY &&
|
|
||||||
!sscreen->use_monolithic_shaders) {
|
|
||||||
struct si_shader *shader = CALLOC_STRUCT(si_shader);
|
|
||||||
void *tgsi_binary;
|
|
||||||
|
|
||||||
if (!shader)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
shader->selector = sel;
|
|
||||||
si_parse_next_shader_property(&sel->info, &shader->key);
|
|
||||||
|
|
||||||
tgsi_binary = si_get_tgsi_binary(sel);
|
|
||||||
|
|
||||||
/* Try to load the shader from the shader cache. */
|
|
||||||
pipe_mutex_lock(sscreen->shader_cache_mutex);
|
|
||||||
|
|
||||||
if (tgsi_binary &&
|
|
||||||
si_shader_cache_load_shader(sscreen, tgsi_binary, shader)) {
|
|
||||||
FREE(tgsi_binary);
|
|
||||||
} else {
|
|
||||||
/* Compile the shader if it hasn't been loaded from the cache. */
|
|
||||||
if (si_compile_tgsi_shader(sscreen, sctx->tm, shader, false,
|
|
||||||
&sctx->b.debug) != 0) {
|
|
||||||
FREE(shader);
|
|
||||||
FREE(tgsi_binary);
|
|
||||||
pipe_mutex_unlock(sscreen->shader_cache_mutex);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tgsi_binary &&
|
|
||||||
!si_shader_cache_insert_shader(sscreen, tgsi_binary, shader))
|
|
||||||
FREE(tgsi_binary);
|
|
||||||
}
|
|
||||||
pipe_mutex_unlock(sscreen->shader_cache_mutex);
|
|
||||||
|
|
||||||
sel->main_shader_part = shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Pre-compilation. */
|
|
||||||
if (sel->type == PIPE_SHADER_GEOMETRY ||
|
|
||||||
sscreen->b.debug_flags & DBG_PRECOMPILE) {
|
|
||||||
struct si_shader_ctx_state state = {sel};
|
|
||||||
union si_shader_key key;
|
|
||||||
|
|
||||||
memset(&key, 0, sizeof(key));
|
|
||||||
si_parse_next_shader_property(&sel->info, &key);
|
|
||||||
|
|
||||||
/* Set reasonable defaults, so that the shader key doesn't
|
|
||||||
* cause any code to be eliminated.
|
|
||||||
*/
|
|
||||||
switch (sel->type) {
|
|
||||||
case PIPE_SHADER_TESS_CTRL:
|
|
||||||
key.tcs.epilog.prim_mode = PIPE_PRIM_TRIANGLES;
|
|
||||||
break;
|
|
||||||
case PIPE_SHADER_FRAGMENT:
|
|
||||||
key.ps.epilog.alpha_func = PIPE_FUNC_ALWAYS;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
if (sel->info.colors_written & (1 << i))
|
|
||||||
key.ps.epilog.spi_shader_col_format |=
|
|
||||||
V_028710_SPI_SHADER_FP16_ABGR << (i * 4);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (si_shader_select_with_key(ctx, &state, &key))
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
pipe_mutex_init(sel->mutex);
|
pipe_mutex_init(sel->mutex);
|
||||||
return sel;
|
|
||||||
|
|
||||||
error:
|
si_init_shader_selector_async(sel, -1);
|
||||||
fprintf(stderr, "radeonsi: can't create a shader\n");
|
|
||||||
tgsi_free_tokens(sel->tokens);
|
return sel;
|
||||||
FREE(sel);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
|
static void si_bind_vs_shader(struct pipe_context *ctx, void *state)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue