iris: Add the variant to the list as early as possible
I tried to find a way to break this into some smaller commits, but everything is very intertwined. :( When searching the variants list in the iris_uncompiled_shader, add the new variant if it is not found. This will be necessary for threaded shader compilation. This conceptually simple change had a bunch of fallout. Much of this was at least conceptually borrowed from radeonsi. - Other threads might find a variant in the list before the variant has been compiled. To accomdate this, add a fence. Each thread will wait on the fence in the variant when searching the list. - A variant in the list may fail compilation. To accomodate this, add a flag. All paths will examine iris_compiled_shader::compilation_failed before trying to use the variant. - The race condition between multiple threads trying to create the same variant at the same time is handled *before* both thread spend the effort to compile the shader. The means that iris_upload_shader cannot change shaders on the caller, so it does not need to return anything. v2: Change "found" parameter of find_or_add_variant to "added." This inverts the values returned, and it probably makes uses of the returned value more easily understood. Always set the value in the called function. Suggested by Ken. v3: Move shader->compilation_failed check to avoid shader != NULL test. Rearrange some logic and add a comment in iris_update_compiled_tcs. Suggested by Ken. Don't call find_or_add_variant in iris_create_shader_state. See https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11229#note_1000843 for more details. Noticed by Ken. Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11229>
This commit is contained in:
@@ -1107,13 +1107,22 @@ last_vue_stage(struct iris_context *ice)
|
||||
return MESA_SHADER_VERTEX;
|
||||
}
|
||||
|
||||
/**
|
||||
* \param added Set to \c true if the variant was added to the list (i.e., a
|
||||
* variant matching \c key was not found). Set to \c false
|
||||
* otherwise.
|
||||
*/
|
||||
static inline struct iris_compiled_shader *
|
||||
find_variant(const struct iris_screen *screen,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
const void *key, unsigned key_size)
|
||||
find_or_add_variant(const struct iris_screen *screen,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
enum iris_program_cache_id cache_id,
|
||||
const void *key, unsigned key_size,
|
||||
bool *added)
|
||||
{
|
||||
struct list_head *start = ish->variants.next;
|
||||
|
||||
*added = false;
|
||||
|
||||
if (screen->precompile) {
|
||||
/* Check the first list entry. There will always be at least one
|
||||
* variant in the list (most likely the precompile variant), and
|
||||
@@ -1123,8 +1132,10 @@ find_variant(const struct iris_screen *screen,
|
||||
struct iris_compiled_shader *first =
|
||||
list_first_entry(&ish->variants, struct iris_compiled_shader, link);
|
||||
|
||||
if (memcmp(&first->key, key, key_size) == 0)
|
||||
if (memcmp(&first->key, key, key_size) == 0) {
|
||||
util_queue_fence_wait(&first->ready);
|
||||
return first;
|
||||
}
|
||||
|
||||
/* Skip this one in the loop below */
|
||||
start = first->link.next;
|
||||
@@ -1145,7 +1156,20 @@ find_variant(const struct iris_screen *screen,
|
||||
}
|
||||
}
|
||||
|
||||
simple_mtx_unlock(&ish->lock);
|
||||
if (variant == NULL) {
|
||||
variant = iris_create_shader_variant(screen, NULL, cache_id,
|
||||
key_size, key);
|
||||
|
||||
/* Append our new variant to the shader's variant list. */
|
||||
list_addtail(&variant->link, &ish->variants);
|
||||
*added = true;
|
||||
|
||||
simple_mtx_unlock(&ish->lock);
|
||||
} else {
|
||||
simple_mtx_unlock(&ish->lock);
|
||||
|
||||
util_queue_fence_wait(&variant->ready);
|
||||
}
|
||||
|
||||
return variant;
|
||||
}
|
||||
@@ -1153,11 +1177,12 @@ find_variant(const struct iris_screen *screen,
|
||||
/**
|
||||
* Compile a vertex shader, and upload the assembly.
|
||||
*/
|
||||
static struct iris_compiled_shader *
|
||||
static void
|
||||
iris_compile_vs(struct iris_screen *screen,
|
||||
struct u_upload_mgr *uploader,
|
||||
struct pipe_debug_callback *dbg,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
struct iris_compiled_shader *shader,
|
||||
const struct iris_vs_prog_key *key)
|
||||
{
|
||||
const struct brw_compiler *compiler = screen->compiler;
|
||||
@@ -1211,27 +1236,28 @@ iris_compile_vs(struct iris_screen *screen,
|
||||
if (program == NULL) {
|
||||
dbg_printf("Failed to compile vertex shader: %s\n", params.error_str);
|
||||
ralloc_free(mem_ctx);
|
||||
return NULL;
|
||||
|
||||
shader->compilation_failed = true;
|
||||
util_queue_fence_signal(&shader->ready);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
shader->compilation_failed = false;
|
||||
|
||||
iris_debug_recompile(screen, dbg, ish, &brw_key.base);
|
||||
|
||||
uint32_t *so_decls =
|
||||
screen->vtbl.create_so_decl_list(&ish->stream_output,
|
||||
&vue_prog_data->vue_map);
|
||||
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, NULL, IRIS_CACHE_VS, sizeof(*key), key);
|
||||
|
||||
shader = iris_upload_shader(screen, ish, shader, NULL, uploader,
|
||||
IRIS_CACHE_VS, sizeof(*key), key, program,
|
||||
prog_data, so_decls, system_values, num_system_values,
|
||||
0, num_cbufs, &bt);
|
||||
iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_VS,
|
||||
sizeof(*key), key, program, prog_data, so_decls,
|
||||
system_values, num_system_values, 0, num_cbufs, &bt);
|
||||
|
||||
iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1252,16 +1278,17 @@ iris_update_compiled_vs(struct iris_context *ice)
|
||||
screen->vtbl.populate_vs_key(ice, &ish->nir->info, last_vue_stage(ice), &key);
|
||||
|
||||
struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_VS];
|
||||
bool added;
|
||||
struct iris_compiled_shader *shader =
|
||||
find_variant(screen, ish, &key, sizeof(key));
|
||||
find_or_add_variant(screen, ish, IRIS_CACHE_VS, &key, sizeof(key), &added);
|
||||
|
||||
if (!shader) {
|
||||
shader = iris_disk_cache_retrieve(screen, uploader, ish,
|
||||
&key, sizeof(key));
|
||||
if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
|
||||
&key, sizeof(key))) {
|
||||
iris_compile_vs(screen, uploader, &ice->dbg, ish, shader, &key);
|
||||
}
|
||||
|
||||
if (!shader)
|
||||
shader = iris_compile_vs(screen, uploader, &ice->dbg, ish, &key);
|
||||
if (shader->compilation_failed)
|
||||
shader = NULL;
|
||||
|
||||
if (old != shader) {
|
||||
iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_VERTEX],
|
||||
@@ -1327,12 +1354,13 @@ get_unified_tess_slots(const struct iris_context *ice,
|
||||
/**
|
||||
* Compile a tessellation control shader, and upload the assembly.
|
||||
*/
|
||||
static struct iris_compiled_shader *
|
||||
static void
|
||||
iris_compile_tcs(struct iris_screen *screen,
|
||||
struct hash_table *passthrough_ht,
|
||||
struct u_upload_mgr *uploader,
|
||||
struct pipe_debug_callback *dbg,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
struct iris_compiled_shader *shader,
|
||||
const struct iris_tcs_prog_key *key)
|
||||
{
|
||||
const struct brw_compiler *compiler = screen->compiler;
|
||||
@@ -1407,27 +1435,26 @@ iris_compile_tcs(struct iris_screen *screen,
|
||||
if (program == NULL) {
|
||||
dbg_printf("Failed to compile control shader: %s\n", error_str);
|
||||
ralloc_free(mem_ctx);
|
||||
return NULL;
|
||||
|
||||
shader->compilation_failed = true;
|
||||
util_queue_fence_signal(&shader->ready);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
shader->compilation_failed = false;
|
||||
|
||||
iris_debug_recompile(screen, dbg, ish, &brw_key.base);
|
||||
|
||||
void *passthrough_mem_ctx = (ish != NULL) ? NULL : passthrough_ht;
|
||||
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, passthrough_mem_ctx, IRIS_CACHE_TCS,
|
||||
sizeof(*key), key);
|
||||
|
||||
shader = iris_upload_shader(screen, ish, shader, passthrough_ht, uploader,
|
||||
IRIS_CACHE_TCS, sizeof(*key), key, program,
|
||||
prog_data, NULL, system_values, num_system_values,
|
||||
0, num_cbufs, &bt);
|
||||
iris_upload_shader(screen, ish, shader, passthrough_ht, uploader,
|
||||
IRIS_CACHE_TCS, sizeof(*key), key, program, prog_data,
|
||||
NULL, system_values, num_system_values, 0, num_cbufs,
|
||||
&bt);
|
||||
|
||||
if (ish)
|
||||
iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1462,20 +1489,39 @@ iris_update_compiled_tcs(struct iris_context *ice)
|
||||
screen->vtbl.populate_tcs_key(ice, &key);
|
||||
|
||||
struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_TCS];
|
||||
struct iris_compiled_shader *shader =
|
||||
tcs ? find_variant(screen, tcs, &key, sizeof(key)) :
|
||||
iris_find_cached_shader(ice, IRIS_CACHE_TCS, sizeof(key), &key);
|
||||
struct iris_compiled_shader *shader;
|
||||
bool added = false;
|
||||
|
||||
if (tcs != NULL) {
|
||||
shader = find_or_add_variant(screen, tcs, IRIS_CACHE_TCS, &key,
|
||||
sizeof(key), &added);
|
||||
} else {
|
||||
/* Look for and possibly create a passthrough TCS */
|
||||
shader = iris_find_cached_shader(ice, IRIS_CACHE_TCS, sizeof(key), &key);
|
||||
|
||||
|
||||
if (shader == NULL) {
|
||||
shader = iris_create_shader_variant(screen, ice->shaders.cache,
|
||||
IRIS_CACHE_TCS, sizeof(key), &key);
|
||||
added = true;
|
||||
}
|
||||
|
||||
if (tcs && !shader) {
|
||||
shader = iris_disk_cache_retrieve(screen, uploader, tcs,
|
||||
&key, sizeof(key));
|
||||
}
|
||||
|
||||
if (!shader) {
|
||||
shader = iris_compile_tcs(screen, ice->shaders.cache,
|
||||
uploader, &ice->dbg, tcs, &key);
|
||||
/* If the shader was not found in (whichever cache), call iris_compile_tcs
|
||||
* if either ish is NULL or the shader could not be found in the disk
|
||||
* cache.
|
||||
*/
|
||||
if (added &&
|
||||
(tcs == NULL || !iris_disk_cache_retrieve(screen, uploader, tcs, shader,
|
||||
&key, sizeof(key)))) {
|
||||
iris_compile_tcs(screen, ice->shaders.cache, uploader, &ice->dbg, tcs,
|
||||
shader, &key);
|
||||
}
|
||||
|
||||
if (shader->compilation_failed)
|
||||
shader = NULL;
|
||||
|
||||
if (old != shader) {
|
||||
iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_CTRL],
|
||||
shader);
|
||||
@@ -1492,11 +1538,12 @@ iris_update_compiled_tcs(struct iris_context *ice)
|
||||
/**
|
||||
* Compile a tessellation evaluation shader, and upload the assembly.
|
||||
*/
|
||||
static struct iris_compiled_shader *
|
||||
static void
|
||||
iris_compile_tes(struct iris_screen *screen,
|
||||
struct u_upload_mgr *uploader,
|
||||
struct pipe_debug_callback *dbg,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
struct iris_compiled_shader *shader,
|
||||
const struct iris_tes_prog_key *key)
|
||||
{
|
||||
const struct brw_compiler *compiler = screen->compiler;
|
||||
@@ -1544,27 +1591,28 @@ iris_compile_tes(struct iris_screen *screen,
|
||||
if (program == NULL) {
|
||||
dbg_printf("Failed to compile evaluation shader: %s\n", error_str);
|
||||
ralloc_free(mem_ctx);
|
||||
return NULL;
|
||||
|
||||
shader->compilation_failed = true;
|
||||
util_queue_fence_signal(&shader->ready);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
shader->compilation_failed = false;
|
||||
|
||||
iris_debug_recompile(screen, dbg, ish, &brw_key.base);
|
||||
|
||||
uint32_t *so_decls =
|
||||
screen->vtbl.create_so_decl_list(&ish->stream_output,
|
||||
&vue_prog_data->vue_map);
|
||||
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, NULL, IRIS_CACHE_TES, sizeof(*key), key);
|
||||
|
||||
shader = iris_upload_shader(screen, ish, shader, NULL, uploader,
|
||||
IRIS_CACHE_TES, sizeof(*key), key, program,
|
||||
prog_data, so_decls, system_values, num_system_values,
|
||||
0, num_cbufs, &bt);
|
||||
iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_TES,
|
||||
sizeof(*key), key, program, prog_data, so_decls,
|
||||
system_values, num_system_values, 0, num_cbufs, &bt);
|
||||
|
||||
iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1586,16 +1634,17 @@ iris_update_compiled_tes(struct iris_context *ice)
|
||||
screen->vtbl.populate_tes_key(ice, &ish->nir->info, last_vue_stage(ice), &key);
|
||||
|
||||
struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_TES];
|
||||
bool added;
|
||||
struct iris_compiled_shader *shader =
|
||||
find_variant(screen, ish, &key, sizeof(key));
|
||||
find_or_add_variant(screen, ish, IRIS_CACHE_TES, &key, sizeof(key), &added);
|
||||
|
||||
if (!shader) {
|
||||
shader = iris_disk_cache_retrieve(screen, uploader, ish,
|
||||
&key, sizeof(key));
|
||||
if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
|
||||
&key, sizeof(key))) {
|
||||
iris_compile_tes(screen, uploader, &ice->dbg, ish, shader, &key);
|
||||
}
|
||||
|
||||
if (!shader)
|
||||
shader = iris_compile_tes(screen, uploader, &ice->dbg, ish, &key);
|
||||
if (shader->compilation_failed)
|
||||
shader = NULL;
|
||||
|
||||
if (old != shader) {
|
||||
iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_TESS_EVAL],
|
||||
@@ -1620,11 +1669,12 @@ iris_update_compiled_tes(struct iris_context *ice)
|
||||
/**
|
||||
* Compile a geometry shader, and upload the assembly.
|
||||
*/
|
||||
static struct iris_compiled_shader *
|
||||
static void
|
||||
iris_compile_gs(struct iris_screen *screen,
|
||||
struct u_upload_mgr *uploader,
|
||||
struct pipe_debug_callback *dbg,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
struct iris_compiled_shader *shader,
|
||||
const struct iris_gs_prog_key *key)
|
||||
{
|
||||
const struct brw_compiler *compiler = screen->compiler;
|
||||
@@ -1672,27 +1722,28 @@ iris_compile_gs(struct iris_screen *screen,
|
||||
if (program == NULL) {
|
||||
dbg_printf("Failed to compile geometry shader: %s\n", error_str);
|
||||
ralloc_free(mem_ctx);
|
||||
return NULL;
|
||||
|
||||
shader->compilation_failed = true;
|
||||
util_queue_fence_signal(&shader->ready);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
shader->compilation_failed = false;
|
||||
|
||||
iris_debug_recompile(screen, dbg, ish, &brw_key.base);
|
||||
|
||||
uint32_t *so_decls =
|
||||
screen->vtbl.create_so_decl_list(&ish->stream_output,
|
||||
&vue_prog_data->vue_map);
|
||||
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, NULL, IRIS_CACHE_GS, sizeof(*key), key);
|
||||
|
||||
shader = iris_upload_shader(screen, ish, shader, NULL, uploader,
|
||||
IRIS_CACHE_GS, sizeof(*key), key, program,
|
||||
prog_data, so_decls, system_values, num_system_values,
|
||||
0, num_cbufs, &bt);
|
||||
iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_GS,
|
||||
sizeof(*key), key, program, prog_data, so_decls,
|
||||
system_values, num_system_values, 0, num_cbufs, &bt);
|
||||
|
||||
iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1715,15 +1766,18 @@ iris_update_compiled_gs(struct iris_context *ice)
|
||||
struct iris_gs_prog_key key = { KEY_ID(vue.base) };
|
||||
screen->vtbl.populate_gs_key(ice, &ish->nir->info, last_vue_stage(ice), &key);
|
||||
|
||||
shader = find_variant(screen, ish, &key, sizeof(key));
|
||||
bool added;
|
||||
|
||||
if (!shader) {
|
||||
shader = iris_disk_cache_retrieve(screen, uploader, ish,
|
||||
&key, sizeof(key));
|
||||
shader = find_or_add_variant(screen, ish, IRIS_CACHE_GS, &key,
|
||||
sizeof(key), &added);
|
||||
|
||||
if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
|
||||
&key, sizeof(key))) {
|
||||
iris_compile_gs(screen, uploader, &ice->dbg, ish, shader, &key);
|
||||
}
|
||||
|
||||
if (!shader)
|
||||
shader = iris_compile_gs(screen, uploader, &ice->dbg, ish, &key);
|
||||
if (shader->compilation_failed)
|
||||
shader = NULL;
|
||||
}
|
||||
|
||||
if (old != shader) {
|
||||
@@ -1743,11 +1797,12 @@ iris_update_compiled_gs(struct iris_context *ice)
|
||||
/**
|
||||
* Compile a fragment (pixel) shader, and upload the assembly.
|
||||
*/
|
||||
static struct iris_compiled_shader *
|
||||
static void
|
||||
iris_compile_fs(struct iris_screen *screen,
|
||||
struct u_upload_mgr *uploader,
|
||||
struct pipe_debug_callback *dbg,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
struct iris_compiled_shader *shader,
|
||||
const struct iris_fs_prog_key *key,
|
||||
struct brw_vue_map *vue_map)
|
||||
{
|
||||
@@ -1805,23 +1860,24 @@ iris_compile_fs(struct iris_screen *screen,
|
||||
if (program == NULL) {
|
||||
dbg_printf("Failed to compile fragment shader: %s\n", params.error_str);
|
||||
ralloc_free(mem_ctx);
|
||||
return NULL;
|
||||
|
||||
shader->compilation_failed = true;
|
||||
util_queue_fence_signal(&shader->ready);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
shader->compilation_failed = false;
|
||||
|
||||
iris_debug_recompile(screen, dbg, ish, &brw_key.base);
|
||||
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, NULL, IRIS_CACHE_FS, sizeof(*key), key);
|
||||
|
||||
shader = iris_upload_shader(screen, ish, shader, NULL, uploader,
|
||||
IRIS_CACHE_FS, sizeof(*key), key, program,
|
||||
prog_data, NULL, system_values, num_system_values,
|
||||
0, num_cbufs, &bt);
|
||||
iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_FS,
|
||||
sizeof(*key), key, program, prog_data, NULL,
|
||||
system_values, num_system_values, 0, num_cbufs, &bt);
|
||||
|
||||
iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
return shader;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1847,18 +1903,19 @@ iris_update_compiled_fs(struct iris_context *ice)
|
||||
key.input_slots_valid = last_vue_map->slots_valid;
|
||||
|
||||
struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_FS];
|
||||
bool added;
|
||||
struct iris_compiled_shader *shader =
|
||||
find_variant(screen, ish, &key, sizeof(key));
|
||||
find_or_add_variant(screen, ish, IRIS_CACHE_FS, &key,
|
||||
sizeof(key), &added);
|
||||
|
||||
if (!shader) {
|
||||
shader = iris_disk_cache_retrieve(screen, uploader, ish,
|
||||
&key, sizeof(key));
|
||||
if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
|
||||
&key, sizeof(key))) {
|
||||
iris_compile_fs(screen, uploader, &ice->dbg, ish, shader, &key,
|
||||
last_vue_map);
|
||||
}
|
||||
|
||||
if (!shader) {
|
||||
shader = iris_compile_fs(screen, uploader, &ice->dbg,
|
||||
ish, &key, last_vue_map);
|
||||
}
|
||||
if (shader->compilation_failed)
|
||||
shader = NULL;
|
||||
|
||||
if (old != shader) {
|
||||
// XXX: only need to flag CLIP if barycentric has NONPERSPECTIVE
|
||||
@@ -2032,11 +2089,12 @@ iris_update_compiled_shaders(struct iris_context *ice)
|
||||
}
|
||||
}
|
||||
|
||||
static struct iris_compiled_shader *
|
||||
static void
|
||||
iris_compile_cs(struct iris_screen *screen,
|
||||
struct u_upload_mgr *uploader,
|
||||
struct pipe_debug_callback *dbg,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
struct iris_compiled_shader *shader,
|
||||
const struct iris_cs_prog_key *key)
|
||||
{
|
||||
const struct brw_compiler *compiler = screen->compiler;
|
||||
@@ -2073,24 +2131,25 @@ iris_compile_cs(struct iris_screen *screen,
|
||||
const unsigned *program = brw_compile_cs(compiler, mem_ctx, ¶ms);
|
||||
if (program == NULL) {
|
||||
dbg_printf("Failed to compile compute shader: %s\n", params.error_str);
|
||||
ralloc_free(mem_ctx);
|
||||
return false;
|
||||
|
||||
shader->compilation_failed = true;
|
||||
util_queue_fence_signal(&shader->ready);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
shader->compilation_failed = false;
|
||||
|
||||
iris_debug_recompile(screen, dbg, ish, &brw_key.base);
|
||||
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, NULL, IRIS_CACHE_CS, sizeof(*key), key);
|
||||
|
||||
shader = iris_upload_shader(screen, ish, shader, NULL, uploader,
|
||||
IRIS_CACHE_CS, sizeof(*key), key, program,
|
||||
prog_data, NULL, system_values, num_system_values,
|
||||
ish->kernel_input_size, num_cbufs, &bt);
|
||||
iris_upload_shader(screen, ish, shader, NULL, uploader, IRIS_CACHE_CS,
|
||||
sizeof(*key), key, program, prog_data, NULL,
|
||||
system_values, num_system_values, ish->kernel_input_size,
|
||||
num_cbufs, &bt);
|
||||
|
||||
iris_disk_cache_store(screen->disk_cache, ish, shader, key, sizeof(*key));
|
||||
|
||||
ralloc_free(mem_ctx);
|
||||
return shader;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -2106,16 +2165,18 @@ iris_update_compiled_cs(struct iris_context *ice)
|
||||
screen->vtbl.populate_cs_key(ice, &key);
|
||||
|
||||
struct iris_compiled_shader *old = ice->shaders.prog[IRIS_CACHE_CS];
|
||||
bool added;
|
||||
struct iris_compiled_shader *shader =
|
||||
find_variant(screen, ish, &key, sizeof(key));
|
||||
find_or_add_variant(screen, ish, IRIS_CACHE_CS, &key,
|
||||
sizeof(key), &added);
|
||||
|
||||
if (!shader) {
|
||||
shader = iris_disk_cache_retrieve(screen, uploader, ish,
|
||||
&key, sizeof(key));
|
||||
if (added && !iris_disk_cache_retrieve(screen, uploader, ish, shader,
|
||||
&key, sizeof(key))) {
|
||||
iris_compile_cs(screen, uploader, &ice->dbg, ish, shader, &key);
|
||||
}
|
||||
|
||||
if (!shader)
|
||||
shader = iris_compile_cs(screen, uploader, &ice->dbg, ish, &key);
|
||||
if (shader->compilation_failed)
|
||||
shader = NULL;
|
||||
|
||||
if (old != shader) {
|
||||
iris_shader_variant_reference(&ice->shaders.prog[MESA_SHADER_COMPUTE],
|
||||
@@ -2383,8 +2444,14 @@ iris_create_compute_state(struct pipe_context *ctx,
|
||||
if (screen->precompile) {
|
||||
struct iris_cs_prog_key key = { KEY_ID(base) };
|
||||
|
||||
if (!iris_disk_cache_retrieve(screen, uploader, ish, &key, sizeof(key)))
|
||||
iris_compile_cs(screen, uploader, &ice->dbg, ish, &key);
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, NULL, IRIS_CACHE_CS,
|
||||
sizeof(key), &key);
|
||||
|
||||
if (!iris_disk_cache_retrieve(screen, uploader, ish, shader,
|
||||
&key, sizeof(key))) {
|
||||
iris_compile_cs(screen, uploader, &ice->dbg, ish, shader, &key);
|
||||
}
|
||||
}
|
||||
|
||||
return ish;
|
||||
@@ -2395,28 +2462,28 @@ iris_compile_shader(struct iris_screen *screen,
|
||||
struct u_upload_mgr *uploader,
|
||||
struct pipe_debug_callback *dbg,
|
||||
struct iris_uncompiled_shader *ish,
|
||||
const void *key)
|
||||
struct iris_compiled_shader *shader)
|
||||
{
|
||||
switch (ish->nir->info.stage) {
|
||||
case MESA_SHADER_VERTEX:
|
||||
iris_compile_vs(screen, uploader, dbg, ish,
|
||||
(const struct iris_vs_prog_key *) key);
|
||||
iris_compile_vs(screen, uploader, dbg, ish, shader,
|
||||
&shader->key.vs);
|
||||
break;
|
||||
case MESA_SHADER_TESS_CTRL:
|
||||
iris_compile_tcs(screen, NULL, uploader, dbg, ish,
|
||||
(const struct iris_tcs_prog_key *) key);
|
||||
iris_compile_tcs(screen, NULL, uploader, dbg, ish, shader,
|
||||
&shader->key.tcs);
|
||||
break;
|
||||
case MESA_SHADER_TESS_EVAL:
|
||||
iris_compile_tes(screen, uploader, dbg, ish,
|
||||
(const struct iris_tes_prog_key *) key);
|
||||
iris_compile_tes(screen, uploader, dbg, ish, shader,
|
||||
&shader->key.tes);
|
||||
break;
|
||||
case MESA_SHADER_GEOMETRY:
|
||||
iris_compile_gs(screen, uploader, dbg, ish,
|
||||
(const struct iris_gs_prog_key *) key);
|
||||
iris_compile_gs(screen, uploader, dbg, ish, shader,
|
||||
&shader->key.gs);
|
||||
break;
|
||||
case MESA_SHADER_FRAGMENT:
|
||||
iris_compile_fs(screen, uploader, dbg, ish,
|
||||
(const struct iris_fs_prog_key *) key, NULL);
|
||||
iris_compile_fs(screen, uploader, dbg, ish, shader,
|
||||
&shader->key.fs, NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2544,8 +2611,18 @@ iris_create_shader_state(struct pipe_context *ctx,
|
||||
if (screen->precompile) {
|
||||
struct u_upload_mgr *uploader = ice->shaders.uploader_unsync;
|
||||
|
||||
if (!iris_disk_cache_retrieve(screen, uploader, ish, &key, key_size))
|
||||
iris_compile_shader(screen, uploader, &ice->dbg, ish, &key);
|
||||
struct iris_compiled_shader *shader =
|
||||
iris_create_shader_variant(screen, NULL,
|
||||
(enum iris_program_cache_id) info->stage,
|
||||
key_size, &key);
|
||||
|
||||
/* Append our new variant to the shader's variant list. */
|
||||
list_addtail(&shader->link, &ish->variants);
|
||||
|
||||
if (!iris_disk_cache_retrieve(screen, uploader, ish, shader,
|
||||
&key, key_size)) {
|
||||
iris_compile_shader(screen, uploader, &ice->dbg, ish, shader);
|
||||
}
|
||||
}
|
||||
|
||||
return ish;
|
||||
|
Reference in New Issue
Block a user