sprintf(buf, "zink_shader_module");
}
-static void
-debug_describe_zink_shader_cache(char* buf, const struct zink_shader_cache *ptr)
-{
- sprintf(buf, "zink_shader_cache");
-}
-
/* copied from iris */
struct keybox {
uint16_t size;
find_cached_shader(struct zink_gfx_program *prog, gl_shader_stage stage, uint32_t key_size, const void *key)
{
struct keybox *keybox = make_keybox(NULL, stage, key, key_size);
- struct hash_entry *entry = _mesa_hash_table_search(prog->shader_cache->shader_cache, keybox);
+ struct hash_entry *entry =
+ _mesa_hash_table_search(prog->shader_cache, keybox);
ralloc_free(keybox);
}
zm->shader = mod;
- _mesa_hash_table_insert(prog->shader_cache->shader_cache, keybox, zm);
+ _mesa_hash_table_insert(prog->shader_cache, keybox, zm);
ralloc_free(keybox);
}
}
static void
-zink_destroy_shader_cache(struct zink_screen *screen, struct zink_shader_cache *sc)
-{
- hash_table_foreach(sc->shader_cache, entry) {
- struct zink_shader_module *zm = entry->data;
- zink_shader_module_reference(screen, &zm, NULL);
- }
- _mesa_hash_table_destroy(sc->shader_cache, NULL);
- free(sc);
-}
-
-static inline void
-zink_shader_cache_reference(struct zink_screen *screen,
- struct zink_shader_cache **dst,
- struct zink_shader_cache *src)
-{
- struct zink_shader_cache *old_dst = dst ? *dst : NULL;
-
- if (pipe_reference_described(old_dst ? &old_dst->reference : NULL, &src->reference,
- (debug_reference_descriptor)debug_describe_zink_shader_cache))
- zink_destroy_shader_cache(screen, old_dst);
- if (dst) *dst = src;
-}
-
-static void
update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_SHADER_COUNT], struct zink_gfx_program *prog)
{
struct zink_shader *dirty[ZINK_SHADER_COUNT] = {NULL};
existing_shaders |= 1 << i;
}
}
- if (ctx->dirty_shader_stages == existing_shaders || !existing_shaders) {
+ if (ctx->dirty_shader_stages == existing_shaders || !existing_shaders)
/* all shaders are being recompiled: new slot map */
memset(prog->shader_slot_map, -1, sizeof(prog->shader_slot_map));
- /* we need the slot map to match up, so we can't reuse the previous cache if we can't guarantee
- * the slots match up
- * TOOD: if we compact the slot map table, we can store it on the shader keys and reuse the cache
- */
- prog->shader_cache = CALLOC_STRUCT(zink_shader_cache);
- pipe_reference_init(&prog->shader_cache->reference, 1);
- prog->shader_cache->shader_cache = _mesa_hash_table_create(NULL, keybox_hash, keybox_equals);
- } else {
+ else {
/* at least some shaders are being reused: use existing slot map so locations match up */
memcpy(prog->shader_slot_map, ctx->curr_program->shader_slot_map, sizeof(prog->shader_slot_map));
prog->shader_slots_reserved = ctx->curr_program->shader_slots_reserved;
- /* and then we can also reuse the shader cache since we know the slots are the same */
- zink_shader_cache_reference(zink_screen(ctx->base.screen), &prog->shader_cache, ctx->curr_program->shader_cache);
}
}
goto fail;
pipe_reference_init(&prog->reference, 1);
+ /* we need the slot map to match up, so shaders are only cached for a given program */
+ prog->shader_cache = _mesa_hash_table_create(NULL, keybox_hash, keybox_equals);
init_slot_map(ctx, prog);
}
_mesa_hash_table_destroy(prog->pipelines[i], NULL);
}
- zink_shader_cache_reference(screen, &prog->shader_cache, NULL);
+ hash_table_foreach(prog->shader_cache, entry) {
+ struct zink_shader_module *zm = entry->data;
+ zink_shader_module_reference(screen, &zm, NULL);
+ }
+ _mesa_hash_table_destroy(prog->shader_cache, NULL);
FREE(prog);
}
struct hash_table;
struct set;
-/* a shader module is used for directly reusing a shader module between programs,
- * e.g., in the case where we're swapping out only one shader,
- * allowing us to skip going through shader keys
- */
struct zink_shader_module {
struct pipe_reference reference;
VkShaderModule shader;
//bool flat_shade;
};
-/* a shader key is used for swapping out shader modules based on pipeline states,
- * e.g., if sampleCount changes, we must verify that the fs doesn't need a recompile
- * to account for GL ignoring gl_SampleMask in some cases when VK will not
- * which allows us to avoid recompiling shaders when the pipeline state changes repeatedly
- */
+
struct zink_shader_key {
union {
struct zink_fs_key fs;
uint32_t size;
};
-/* the shader cache stores a mapping of zink_shader_key::VkShaderModule */
-struct zink_shader_cache {
- struct pipe_reference reference;
- struct hash_table *shader_cache;
-};
-
struct zink_gfx_program {
struct pipe_reference reference;
struct zink_shader_module *modules[ZINK_SHADER_COUNT]; // compute stage doesn't belong here
struct zink_shader *shaders[ZINK_SHADER_COUNT];
- struct zink_shader_cache *shader_cache;
unsigned char shader_slot_map[VARYING_SLOT_MAX];
unsigned char shader_slots_reserved;
VkDescriptorSetLayout dsl;
unsigned num_descriptors;
struct hash_table *pipelines[10]; // number of draw modes we support
struct set *render_passes;
+ struct hash_table *shader_cache;
};
struct zink_gfx_program *