diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index ecefb6fdd3d..6d494f91d3c 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -2111,25 +2111,27 @@ zink_shader_compile(struct zink_screen *screen, struct zink_shader *zs, nir_shad /* TODO: use a separate mem ctx here for ralloc */ switch (zs->nir->info.stage) { case MESA_SHADER_VERTEX: { - uint32_t decomposed_attrs = 0, decomposed_attrs_without_w = 0; - const struct zink_vs_key *vs_key = zink_vs_key(key); - switch (vs_key->size) { - case 4: - decomposed_attrs = vs_key->u32.decomposed_attrs; - decomposed_attrs_without_w = vs_key->u32.decomposed_attrs_without_w; - break; - case 2: - decomposed_attrs = vs_key->u16.decomposed_attrs; - decomposed_attrs_without_w = vs_key->u16.decomposed_attrs_without_w; - break; - case 1: - decomposed_attrs = vs_key->u8.decomposed_attrs; - decomposed_attrs_without_w = vs_key->u8.decomposed_attrs_without_w; - break; - default: break; + if (!screen->optimal_keys) { + uint32_t decomposed_attrs = 0, decomposed_attrs_without_w = 0; + const struct zink_vs_key *vs_key = zink_vs_key(key); + switch (vs_key->size) { + case 4: + decomposed_attrs = vs_key->u32.decomposed_attrs; + decomposed_attrs_without_w = vs_key->u32.decomposed_attrs_without_w; + break; + case 2: + decomposed_attrs = vs_key->u16.decomposed_attrs; + decomposed_attrs_without_w = vs_key->u16.decomposed_attrs_without_w; + break; + case 1: + decomposed_attrs = vs_key->u8.decomposed_attrs; + decomposed_attrs_without_w = vs_key->u8.decomposed_attrs_without_w; + break; + default: break; + } + if (decomposed_attrs || decomposed_attrs_without_w) + NIR_PASS_V(nir, decompose_attribs, decomposed_attrs, decomposed_attrs_without_w); } - if (decomposed_attrs || decomposed_attrs_without_w) - NIR_PASS_V(nir, decompose_attribs, decomposed_attrs, decomposed_attrs_without_w); FALLTHROUGH; } case MESA_SHADER_TESS_EVAL: diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index b89db31b247..6d2535ef7a6 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1303,6 +1303,7 @@ zink_set_inlinable_constants(struct pipe_context *pctx, if (shader == MESA_SHADER_COMPUTE) { key = &ctx->compute_pipeline_state.key; } else { + assert(!zink_screen(pctx->screen)->optimal_keys); key = &ctx->gfx_pipeline_state.shader_keys.key[shader]; } inlinable_uniforms = key->base.inlined_uniform_values; @@ -1353,6 +1354,7 @@ invalidate_inlined_uniforms(struct zink_context *ctx, gl_shader_stage pstage) if (pstage == MESA_SHADER_COMPUTE) return; + assert(!zink_screen(ctx->base.screen)->optimal_keys); struct zink_shader_key *key = &ctx->gfx_pipeline_state.shader_keys.key[pstage]; key->inline_uniforms = false; } @@ -4678,14 +4680,15 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) goto fail; } - ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base.last_vertex_stage = true; - ctx->last_vertex_stage_dirty = true; - ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].key.tcs.patch_vertices = 1; - ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].size = sizeof(struct zink_vs_key_base); - ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_EVAL].size = sizeof(struct zink_vs_key_base); - ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].size = sizeof(struct zink_tcs_key); - ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_GEOMETRY].size = sizeof(struct zink_vs_key_base); - ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].size = sizeof(struct zink_fs_key); + zink_set_last_vertex_key(ctx)->last_vertex_stage = true; + zink_set_tcs_key_patches(ctx, 1); + if (!screen->optimal_keys) { + ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].size = sizeof(struct zink_vs_key_base); + ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_EVAL].size = sizeof(struct zink_vs_key_base); + ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].size = sizeof(struct zink_tcs_key); + ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_GEOMETRY].size = sizeof(struct zink_vs_key_base); + ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].size = sizeof(struct zink_fs_key); + } _mesa_hash_table_init(&ctx->framebuffer_cache, ctx, hash_framebuffer_imageless, equals_framebuffer_imageless); if (!zink_init_render_pass(ctx)) goto fail; diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 42cd6d990d8..39e20ab4834 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -210,6 +210,98 @@ get_shader_module_for_stage(struct zink_context *ctx, struct zink_screen *screen return NULL; } +ALWAYS_INLINE static struct zink_shader_module * +create_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_screen *screen, + struct zink_shader *zs, struct zink_gfx_program *prog, + gl_shader_stage stage, + struct zink_gfx_pipeline_state *state) +{ + VkShaderModule mod; + struct zink_shader_module *zm; + uint16_t *key; + unsigned mask = stage == MESA_SHADER_FRAGMENT ? BITFIELD_MASK(16) : BITFIELD_MASK(8); + if (zs == prog->last_vertex_stage) { + key = (uint16_t*)&state->shader_keys_optimal.key.vs_base; + } else if (stage == MESA_SHADER_FRAGMENT) { + key = (uint16_t*)&state->shader_keys_optimal.key.fs; + } else if (stage == MESA_SHADER_TESS_CTRL && zs->is_generated) { + key = (uint16_t*)&state->shader_keys_optimal.key.tcs; + } else { + key = NULL; + } + size_t key_size = sizeof(uint16_t); + zm = calloc(1, sizeof(struct zink_shader_module) + (key ? key_size : 0)); + if (!zm) { + return NULL; + } + if (stage == MESA_SHADER_TESS_CTRL && zs->is_generated && zs->spirv) { + assert(ctx); //TODO async + struct zink_tcs_key *tcs = (struct zink_tcs_key*)key; + mod = zink_shader_tcs_compile(screen, zs, tcs->patch_vertices); + } else { + mod = zink_shader_compile(screen, zs, prog->nir[stage], (struct zink_shader_key*)key); + } + if (!mod) { + FREE(zm); + return NULL; + } + zm->shader = mod; + /* non-generated tcs won't use the shader key */ + const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->is_generated; + if (key && !is_nongenerated_tcs) { + zm->key_size = key_size; + uint16_t *data = (uint16_t*)zm->key; + /* sanitize actual key bits */ + *data = (*key) & mask; + } + zm->default_variant = !util_dynarray_contains(&prog->shader_cache[stage][0][0], void*); + util_dynarray_append(&prog->shader_cache[stage][0][0], void*, zm); + return zm; +} + +ALWAYS_INLINE static struct zink_shader_module * +get_shader_module_for_stage_optimal(struct zink_context *ctx, struct zink_screen *screen, + struct zink_shader *zs, struct zink_gfx_program *prog, + gl_shader_stage stage, + struct zink_gfx_pipeline_state *state) +{ + /* non-generated tcs won't use the shader key */ + const bool is_nongenerated_tcs = stage == MESA_SHADER_TESS_CTRL && !zs->is_generated; + uint16_t *key; + unsigned mask = stage == MESA_SHADER_FRAGMENT ? BITFIELD_MASK(16) : BITFIELD_MASK(8); + if (zs == prog->last_vertex_stage) { + key = (uint16_t*)&ctx->gfx_pipeline_state.shader_keys_optimal.key.vs_base; + } else if (stage == MESA_SHADER_FRAGMENT) { + key = (uint16_t*)&ctx->gfx_pipeline_state.shader_keys_optimal.key.fs; + } else if (stage == MESA_SHADER_TESS_CTRL && zs->is_generated) { + key = (uint16_t*)&ctx->gfx_pipeline_state.shader_keys_optimal.key.tcs; + } else { + key = NULL; + } + struct util_dynarray *shader_cache = &prog->shader_cache[stage][0][0]; + unsigned count = util_dynarray_num_elements(shader_cache, struct zink_shader_module *); + struct zink_shader_module **pzm = shader_cache->data; + for (unsigned i = 0; i < count; i++) { + struct zink_shader_module *iter = pzm[i]; + if (is_nongenerated_tcs) { + /* always match */ + } else if (key) { + uint16_t val = (*key) & mask; + /* no key is bigger than uint16_t */ + if (memcmp(iter->key, &val, sizeof(uint16_t))) + continue; + } + if (i > 0) { + struct zink_shader_module *zero = pzm[0]; + pzm[0] = iter; + pzm[i] = zero; + } + return iter; + } + + return NULL; +} + static void zink_destroy_shader_module(struct zink_screen *screen, struct zink_shader_module *zm) { @@ -278,6 +370,32 @@ update_gfx_shader_modules(struct zink_context *ctx, } } +ALWAYS_INLINE static void +update_gfx_shader_modules_optimal(struct zink_context *ctx, + struct zink_screen *screen, + struct zink_gfx_program *prog, uint32_t mask, + struct zink_gfx_pipeline_state *state) +{ + assert(prog->modules[MESA_SHADER_VERTEX]); + for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) { + if (!(mask & BITFIELD_BIT(i))) + continue; + + assert(prog->shaders[i]); + + struct zink_shader_module *zm = get_shader_module_for_stage_optimal(ctx, screen, prog->shaders[i], prog, i, state); + if (!zm) + zm = create_shader_module_for_stage_optimal(ctx, screen, prog->shaders[i], prog, i, state); + state->modules[i] = zm->shader; + if (prog->modules[i] == zm->shader) + continue; + state->modules_changed = true; + prog->modules[i] = zm->shader; + } + + prog->last_variant_hash = state->shader_keys_optimal.key.val; +} + static void generate_gfx_program_modules(struct zink_context *ctx, struct zink_screen *screen, struct zink_gfx_program *prog, struct zink_gfx_pipeline_state *state) { @@ -306,12 +424,32 @@ generate_gfx_program_modules(struct zink_context *ctx, struct zink_screen *scree variant_hash ^= prog->module_hash[i]; } - prog->last_variant_hash = variant_hash; p_atomic_dec(&prog->base.reference.count); + state->modules_changed = true; + + prog->last_variant_hash = variant_hash; if (default_variants) prog->default_variant_hash = prog->last_variant_hash; +} +static void +generate_gfx_program_modules_optimal(struct zink_context *ctx, struct zink_screen *screen, struct zink_gfx_program *prog, struct zink_gfx_pipeline_state *state) +{ + assert(!prog->modules[MESA_SHADER_VERTEX]); + for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) { + if (!(prog->stages_present & BITFIELD_BIT(i))) + continue; + + assert(prog->shaders[i]); + + struct zink_shader_module *zm = zm = create_shader_module_for_stage_optimal(ctx, screen, prog->shaders[i], prog, i, state); + state->modules[i] = zm->shader; + prog->modules[i] = zm->shader; + } + + p_atomic_dec(&prog->base.reference.count); state->modules_changed = true; + prog->last_variant_hash = state->shader_keys_optimal.key.val; } static uint32_t @@ -397,10 +535,16 @@ static void update_gfx_program(struct zink_context *ctx, struct zink_gfx_program *prog) { struct zink_screen *screen = zink_screen(ctx->base.screen); - if (screen->info.have_EXT_non_seamless_cube_map) - update_gfx_program_nonseamless(ctx, prog, true); - else - update_gfx_program_nonseamless(ctx, prog, false); + if (screen->optimal_keys) { + update_gfx_shader_modules_optimal(ctx, screen, prog, + ctx->dirty_shader_stages & prog->stages_present, + &ctx->gfx_pipeline_state); + } else { + if (screen->info.have_EXT_non_seamless_cube_map) + update_gfx_program_nonseamless(ctx, prog, true); + else + update_gfx_program_nonseamless(ctx, prog, false); + } } void @@ -409,9 +553,11 @@ zink_gfx_program_update(struct zink_context *ctx) if (ctx->last_vertex_stage_dirty) { gl_shader_stage pstage = ctx->last_vertex_stage->nir->info.stage; ctx->dirty_shader_stages |= BITFIELD_BIT(pstage); - memcpy(&ctx->gfx_pipeline_state.shader_keys.key[pstage].key.vs_base, - &ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base, - sizeof(struct zink_vs_key_base)); + if (!zink_screen(ctx->base.screen)->optimal_keys) { + memcpy(&ctx->gfx_pipeline_state.shader_keys.key[pstage].key.vs_base, + &ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base, + sizeof(struct zink_vs_key_base)); + } ctx->last_vertex_stage_dirty = false; } unsigned bits = BITFIELD_MASK(MESA_SHADER_COMPUTE); @@ -435,7 +581,10 @@ zink_gfx_program_update(struct zink_context *ctx) ctx->dirty_shader_stages |= bits; prog = zink_create_gfx_program(ctx, ctx->gfx_stages, ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch); _mesa_hash_table_insert_pre_hashed(ht, hash, prog->shaders, prog); - generate_gfx_program_modules(ctx, zink_screen(ctx->base.screen), prog, &ctx->gfx_pipeline_state); + if (zink_screen(ctx->base.screen)->optimal_keys) + generate_gfx_program_modules_optimal(ctx, zink_screen(ctx->base.screen), prog, &ctx->gfx_pipeline_state); + else + generate_gfx_program_modules(ctx, zink_screen(ctx->base.screen), prog, &ctx->gfx_pipeline_state); } simple_mtx_unlock(&ctx->program_lock[zink_program_cache_stages(ctx->shader_stages)]); if (prog && prog != ctx->curr_program) @@ -1085,12 +1234,14 @@ bind_last_vertex_stage(struct zink_context *ctx) ctx->last_vertex_stage = ctx->gfx_stages[MESA_SHADER_VERTEX]; gl_shader_stage current = ctx->last_vertex_stage ? ctx->last_vertex_stage->nir->info.stage : MESA_SHADER_VERTEX; if (old != current) { - if (old != MESA_SHADER_STAGES) { - memset(&ctx->gfx_pipeline_state.shader_keys.key[old].key.vs_base, 0, sizeof(struct zink_vs_key_base)); - ctx->dirty_shader_stages |= BITFIELD_BIT(old); - } else { - /* always unset vertex shader values when changing to a non-vs last stage */ - memset(&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].key.vs_base, 0, sizeof(struct zink_vs_key_base)); + if (!zink_screen(ctx->base.screen)->optimal_keys) { + if (old != MESA_SHADER_STAGES) { + memset(&ctx->gfx_pipeline_state.shader_keys.key[old].key.vs_base, 0, sizeof(struct zink_vs_key_base)); + ctx->dirty_shader_stages |= BITFIELD_BIT(old); + } else { + /* always unset vertex shader values when changing to a non-vs last stage */ + memset(&ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].key.vs_base, 0, sizeof(struct zink_vs_key_base)); + } } unsigned num_viewports = ctx->vp_state.num_viewports; @@ -1349,6 +1500,8 @@ zink_program_init(struct zink_context *ctx) STATIC_ASSERT(offsetof(struct zink_gfx_pipeline_state, modules) - offsetof(struct zink_gfx_pipeline_state, gkey) == offsetof(struct zink_gfx_library_key, modules) - offsetof(struct zink_gfx_library_key, hw_rast_state)); + + STATIC_ASSERT(sizeof(union zink_shader_key_optimal) == sizeof(uint32_t)); } bool diff --git a/src/gallium/drivers/zink/zink_program.h b/src/gallium/drivers/zink/zink_program.h index c693707940b..c24ed4cc1fd 100644 --- a/src/gallium/drivers/zink/zink_program.h +++ b/src/gallium/drivers/zink/zink_program.h @@ -224,19 +224,25 @@ static inline struct zink_fs_key * zink_set_fs_key(struct zink_context *ctx) { ctx->dirty_shader_stages |= BITFIELD_BIT(MESA_SHADER_FRAGMENT); - return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs; + return zink_screen(ctx->base.screen)->optimal_keys ? + &ctx->gfx_pipeline_state.shader_keys_optimal.key.fs : + &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs; } static inline const struct zink_fs_key * zink_get_fs_key(struct zink_context *ctx) { - return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs; + return zink_screen(ctx->base.screen)->optimal_keys ? + &ctx->gfx_pipeline_state.shader_keys_optimal.key.fs : + &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_FRAGMENT].key.fs; } static inline bool zink_set_tcs_key_patches(struct zink_context *ctx, uint8_t patch_vertices) { - struct zink_tcs_key *tcs = &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].key.tcs; + struct zink_tcs_key *tcs = zink_screen(ctx->base.screen)->optimal_keys ? + &ctx->gfx_pipeline_state.shader_keys_optimal.key.tcs : + &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].key.tcs; if (tcs->patch_vertices == patch_vertices) return false; ctx->dirty_shader_stages |= BITFIELD_BIT(MESA_SHADER_TESS_CTRL); @@ -247,7 +253,9 @@ zink_set_tcs_key_patches(struct zink_context *ctx, uint8_t patch_vertices) static inline const struct zink_tcs_key * zink_get_tcs_key(struct zink_context *ctx) { - return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].key.tcs; + return zink_screen(ctx->base.screen)->optimal_keys ? + &ctx->gfx_pipeline_state.shader_keys_optimal.key.tcs : + &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_TESS_CTRL].key.tcs; } void @@ -257,12 +265,14 @@ static inline struct zink_vs_key * zink_set_vs_key(struct zink_context *ctx) { ctx->dirty_shader_stages |= BITFIELD_BIT(MESA_SHADER_VERTEX); + assert(!zink_screen(ctx->base.screen)->optimal_keys); return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].key.vs; } static inline const struct zink_vs_key * zink_get_vs_key(struct zink_context *ctx) { + assert(!zink_screen(ctx->base.screen)->optimal_keys); return &ctx->gfx_pipeline_state.shader_keys.key[MESA_SHADER_VERTEX].key.vs; } @@ -270,13 +280,17 @@ static inline struct zink_vs_key_base * zink_set_last_vertex_key(struct zink_context *ctx) { ctx->last_vertex_stage_dirty = true; - return &ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base; + return zink_screen(ctx->base.screen)->optimal_keys ? + &ctx->gfx_pipeline_state.shader_keys_optimal.key.vs_base : + &ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base; } static inline const struct zink_vs_key_base * zink_get_last_vertex_key(struct zink_context *ctx) { - return &ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base; + return zink_screen(ctx->base.screen)->optimal_keys ? + &ctx->gfx_pipeline_state.shader_keys_optimal.key.vs_base : + &ctx->gfx_pipeline_state.shader_keys.last_vertex.key.vs_base; } static inline void @@ -295,6 +309,7 @@ zink_set_fs_point_coord_key(struct zink_context *ctx) static inline const struct zink_shader_key_base * zink_get_shader_key_base(struct zink_context *ctx, gl_shader_stage pstage) { + assert(!zink_screen(ctx->base.screen)->optimal_keys); return &ctx->gfx_pipeline_state.shader_keys.key[pstage].base; } @@ -302,6 +317,7 @@ static inline struct zink_shader_key_base * zink_set_shader_key_base(struct zink_context *ctx, gl_shader_stage pstage) { ctx->dirty_shader_stages |= BITFIELD_BIT(pstage); + assert(!zink_screen(ctx->base.screen)->optimal_keys); return &ctx->gfx_pipeline_state.shader_keys.key[pstage].base; } diff --git a/src/gallium/drivers/zink/zink_screen.c b/src/gallium/drivers/zink/zink_screen.c index b4676691060..a8dd0814906 100644 --- a/src/gallium/drivers/zink/zink_screen.c +++ b/src/gallium/drivers/zink/zink_screen.c @@ -2534,6 +2534,11 @@ zink_internal_create_screen(const struct pipe_screen_config *config) goto fail; } + if (!screen->driver_workarounds.force_pipeline_library) + screen->optimal_keys = !screen->need_decompose_attrs && screen->info.have_EXT_non_seamless_cube_map && !screen->driconf.inline_uniforms; + if (screen->optimal_keys) + screen->driver_workarounds.force_pipeline_library = false; + return screen; fail: diff --git a/src/gallium/drivers/zink/zink_shader_keys.h b/src/gallium/drivers/zink/zink_shader_keys.h index 151e5b163e3..4ca013901ed 100644 --- a/src/gallium/drivers/zink/zink_shader_keys.h +++ b/src/gallium/drivers/zink/zink_shader_keys.h @@ -93,6 +93,15 @@ struct zink_shader_key { uint32_t size; }; +union zink_shader_key_optimal { + struct { + struct zink_vs_key_base vs_base; + struct zink_tcs_key tcs; + struct zink_fs_key fs; + }; + uint32_t val; +}; + static inline const struct zink_fs_key * zink_fs_key(const struct zink_shader_key *key) { diff --git a/src/gallium/drivers/zink/zink_state.c b/src/gallium/drivers/zink/zink_state.c index f31604c90e6..a22e9b2cc81 100644 --- a/src/gallium/drivers/zink/zink_state.c +++ b/src/gallium/drivers/zink/zink_state.c @@ -185,6 +185,9 @@ zink_bind_vertex_elements_state(struct pipe_context *pctx, ctx->vertex_state_changed = !zink_screen(pctx->screen)->info.have_EXT_vertex_input_dynamic_state; ctx->vertex_buffers_dirty = ctx->element_state->hw_state.num_bindings > 0; } + state->element_state = &ctx->element_state->hw_state; + if (zink_screen(pctx->screen)->optimal_keys) + return; const struct zink_vs_key *vs = zink_get_vs_key(ctx); uint32_t decomposed_attrs = 0, decomposed_attrs_without_w = 0; switch (vs->size) { @@ -224,7 +227,6 @@ zink_bind_vertex_elements_state(struct pipe_context *pctx, key->key.vs.size = size; key->size += 2 * size; } - state->element_state = &ctx->element_state->hw_state; } else { state->element_state = NULL; ctx->vertex_buffers_dirty = false; diff --git a/src/gallium/drivers/zink/zink_types.h b/src/gallium/drivers/zink/zink_types.h index 79906d9a3da..b8efed1f3e8 100644 --- a/src/gallium/drivers/zink/zink_types.h +++ b/src/gallium/drivers/zink/zink_types.h @@ -683,10 +683,15 @@ struct zink_gfx_pipeline_state { struct zink_vertex_elements_hw_state *element_state; bool sample_locations_enabled; uint8_t has_points; //either gs outputs points or prim type is points - struct { - struct zink_shader_key key[5]; - struct zink_shader_key last_vertex; - } shader_keys; + union { + struct { + struct zink_shader_key key[5]; + struct zink_shader_key last_vertex; + } shader_keys; + struct { + union zink_shader_key_optimal key; + } shader_keys_optimal; + }; struct zink_blend_state *blend_state; struct zink_render_pass *render_pass; struct zink_render_pass *next_render_pass; //will be used next time rp is begun @@ -1108,6 +1113,7 @@ struct zink_screen { struct zink_device_info info; struct nir_shader_compiler_options nir_options; + bool optimal_keys; bool have_X8_D24_UNORM_PACK32; bool have_D24_UNORM_S8_UINT; bool have_D32_SFLOAT_S8_UINT;