zink: optimize shader recalc
now we only have to loop over the changed shaders that exist for the program, and we can avoid a lot of hashing operations by reusing stored hash values where possible Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11962>
This commit is contained in:
committed by
Marge Bot
parent
785b4728cf
commit
c4702204bc
@@ -274,40 +274,30 @@ destroy_shader_cache(struct zink_screen *screen, struct hash_table *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_SHADER_COUNT], struct zink_gfx_program *prog, bool disallow_reuse)
|
update_shader_modules(struct zink_context *ctx, struct zink_gfx_program *prog)
|
||||||
{
|
{
|
||||||
struct zink_shader *dirty[ZINK_SHADER_COUNT] = {NULL};
|
bool hash_changed = false;
|
||||||
|
bool default_variants = true;
|
||||||
unsigned gfx_bits = u_bit_consecutive(PIPE_SHADER_VERTEX, 5);
|
bool first = !!prog->modules[PIPE_SHADER_VERTEX];
|
||||||
unsigned dirty_shader_stages = ctx->dirty_shader_stages & gfx_bits;
|
u_foreach_bit(pstage, ctx->dirty_shader_stages & prog->stages_present) {
|
||||||
if (!dirty_shader_stages)
|
assert(prog->shaders[pstage]);
|
||||||
return;
|
struct zink_shader_module *zm = get_shader_module_for_stage(ctx, prog->shaders[pstage], prog);
|
||||||
/* we need to map pipe_shader_type -> gl_shader_stage so we can ensure that we're compiling
|
if (prog->modules[pstage] != zm)
|
||||||
* the shaders in pipeline order and have builtin input/output locations match up after being compacted
|
hash_changed = true;
|
||||||
*/
|
default_variants &= zm->default_variant;
|
||||||
while (dirty_shader_stages) {
|
prog->modules[pstage] = zm;
|
||||||
unsigned type = u_bit_scan(&dirty_shader_stages);
|
ctx->gfx_pipeline_state.modules[pstage] = zm->shader;
|
||||||
dirty[tgsi_processor_to_shader_stage(type)] = stages[type];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < ZINK_SHADER_COUNT; ++i) {
|
if (hash_changed) {
|
||||||
/* we need to iterate over the stages in pipeline-order here */
|
if (default_variants && !first)
|
||||||
enum pipe_shader_type type = pipe_shader_type_from_mesa(i);
|
prog->last_variant_hash = prog->default_variant_hash;
|
||||||
assert(type < ZINK_SHADER_COUNT);
|
else
|
||||||
if (dirty[i] || (stages[type] && !prog->modules[type])) {
|
prog->last_variant_hash = _mesa_hash_data(ctx->gfx_pipeline_state.modules, sizeof(ctx->gfx_pipeline_state.modules));
|
||||||
struct zink_shader_module *zm;
|
ctx->gfx_pipeline_state.combined_dirty = true;
|
||||||
zm = get_shader_module_for_stage(ctx, dirty[i] ? dirty[i] : stages[type], prog);
|
|
||||||
prog->modules[type] = zm;
|
|
||||||
ctx->gfx_pipeline_state.combined_dirty |= zm->shader != ctx->gfx_pipeline_state.modules[type];
|
|
||||||
ctx->gfx_pipeline_state.modules[type] = zm->shader;
|
|
||||||
} else if (!stages[type]) {
|
|
||||||
ctx->gfx_pipeline_state.combined_dirty |= ctx->gfx_pipeline_state.modules[type] != VK_NULL_HANDLE;
|
|
||||||
ctx->gfx_pipeline_state.modules[type] = VK_NULL_HANDLE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ctx->gfx_pipeline_state.module_hash = _mesa_hash_data(ctx->gfx_pipeline_state.modules, sizeof(ctx->gfx_pipeline_state.modules));
|
ctx->gfx_pipeline_state.module_hash = prog->last_variant_hash;
|
||||||
unsigned clean = u_bit_consecutive(PIPE_SHADER_VERTEX, 5);
|
ctx->dirty_shader_stages &= ~u_bit_consecutive(PIPE_SHADER_VERTEX, 5);
|
||||||
ctx->dirty_shader_stages &= ~clean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
@@ -350,7 +340,7 @@ equals_gfx_pipeline_state(const void *a, const void *b)
|
|||||||
void
|
void
|
||||||
zink_update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog)
|
zink_update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog)
|
||||||
{
|
{
|
||||||
update_shader_modules(ctx, ctx->gfx_stages, prog, true);
|
update_shader_modules(ctx, prog);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipelineLayout
|
VkPipelineLayout
|
||||||
@@ -446,7 +436,7 @@ zink_create_gfx_program(struct zink_context *ctx,
|
|||||||
ctx->dirty_shader_stages |= prog->stages_present;
|
ctx->dirty_shader_stages |= prog->stages_present;
|
||||||
assign_io(prog, prog->shaders);
|
assign_io(prog, prog->shaders);
|
||||||
|
|
||||||
update_shader_modules(ctx, prog->shaders, prog, false);
|
update_shader_modules(ctx, prog);
|
||||||
prog->default_variant_hash = ctx->gfx_pipeline_state.module_hash;
|
prog->default_variant_hash = ctx->gfx_pipeline_state.module_hash;
|
||||||
|
|
||||||
for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) {
|
for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) {
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ struct zink_gfx_program {
|
|||||||
struct zink_shader *shaders[ZINK_SHADER_COUNT];
|
struct zink_shader *shaders[ZINK_SHADER_COUNT];
|
||||||
struct hash_table *pipelines[11]; // number of draw modes we support
|
struct hash_table *pipelines[11]; // number of draw modes we support
|
||||||
uint32_t default_variant_hash;
|
uint32_t default_variant_hash;
|
||||||
|
uint32_t last_variant_hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct zink_compute_program {
|
struct zink_compute_program {
|
||||||
|
|||||||
Reference in New Issue
Block a user