mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
zink: split vertex state pipeline hashing into its own value
by creating a separate hash value for vertex state, changes to the vbos and bindings requires massively less overhead as it doesn't require the rest of the pipeline state to be rehashed Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10508>
This commit is contained in:
parent
7ca64c1c4d
commit
ff1941aa08
5 changed files with 34 additions and 34 deletions
|
|
@ -339,17 +339,6 @@ zink_draw_vbo(struct pipe_context *pctx,
|
|||
ctx->gfx_pipeline_state.dirty = true;
|
||||
ctx->gfx_pipeline_state.primitive_restart = !!dinfo->primitive_restart;
|
||||
|
||||
if (!zink_screen(pctx->screen)->info.have_EXT_extended_dynamic_state) {
|
||||
for (unsigned i = 0; i < ctx->element_state->hw_state.num_bindings; i++) {
|
||||
unsigned binding = ctx->element_state->binding_map[i];
|
||||
const struct pipe_vertex_buffer *vb = ctx->vertex_buffers + binding;
|
||||
if (ctx->gfx_pipeline_state.vertex_strides[i] != vb->stride) {
|
||||
ctx->gfx_pipeline_state.vertex_strides[i] = vb->stride;
|
||||
ctx->gfx_pipeline_state.dirty = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum pipe_prim_type reduced_prim = u_reduced_prim(dinfo->mode);
|
||||
|
||||
bool depth_bias = false;
|
||||
|
|
@ -488,7 +477,7 @@ zink_draw_vbo(struct pipe_context *pctx,
|
|||
vkCmdSetBlendConstants(batch->state->cmdbuf, ctx->blend_constants);
|
||||
|
||||
|
||||
VkPipeline pipeline = zink_get_gfx_pipeline(screen, gfx_program,
|
||||
VkPipeline pipeline = zink_get_gfx_pipeline(ctx, gfx_program,
|
||||
&ctx->gfx_pipeline_state,
|
||||
dinfo->mode);
|
||||
vkCmdBindPipeline(batch->state->cmdbuf, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@ struct zink_vertex_elements_state;
|
|||
struct zink_gfx_pipeline_state {
|
||||
struct zink_render_pass *render_pass;
|
||||
|
||||
struct zink_vertex_elements_hw_state *element_state;
|
||||
|
||||
uint32_t num_attachments;
|
||||
struct zink_blend_state *blend_state;
|
||||
|
||||
|
|
@ -68,6 +66,11 @@ struct zink_gfx_pipeline_state {
|
|||
uint32_t combined_hash;
|
||||
bool combined_dirty;
|
||||
|
||||
struct zink_vertex_elements_hw_state *element_state;
|
||||
bool vertex_state_dirty;
|
||||
|
||||
uint32_t final_hash;
|
||||
|
||||
uint32_t vertex_buffers_enabled_mask;
|
||||
uint32_t vertex_strides[PIPE_MAX_ATTRIBS];
|
||||
bool have_EXT_extended_dynamic_state;
|
||||
|
|
|
|||
|
|
@ -371,17 +371,6 @@ update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_
|
|||
static uint32_t
|
||||
hash_gfx_pipeline_state(const void *key)
|
||||
{
|
||||
const struct zink_gfx_pipeline_state *state = key;
|
||||
uint32_t hash = 0;
|
||||
if (!state->have_EXT_extended_dynamic_state) {
|
||||
/* if we don't have dynamic states, we have to hash the enabled vertex buffer bindings */
|
||||
uint32_t vertex_buffers_enabled_mask = state->vertex_buffers_enabled_mask;
|
||||
hash = XXH32(&vertex_buffers_enabled_mask, sizeof(uint32_t), hash);
|
||||
while (vertex_buffers_enabled_mask) {
|
||||
unsigned idx = u_bit_scan(&vertex_buffers_enabled_mask);
|
||||
hash = XXH32(&state->vertex_strides[idx], sizeof(uint32_t), hash);
|
||||
}
|
||||
}
|
||||
return _mesa_hash_data(key, offsetof(struct zink_gfx_pipeline_state, hash));
|
||||
}
|
||||
|
||||
|
|
@ -390,9 +379,9 @@ equals_gfx_pipeline_state(const void *a, const void *b)
|
|||
{
|
||||
const struct zink_gfx_pipeline_state *sa = a;
|
||||
const struct zink_gfx_pipeline_state *sb = b;
|
||||
if (sa->vertex_buffers_enabled_mask != sb->vertex_buffers_enabled_mask)
|
||||
return false;
|
||||
if (!sa->have_EXT_extended_dynamic_state) {
|
||||
if (sa->vertex_buffers_enabled_mask != sb->vertex_buffers_enabled_mask)
|
||||
return false;
|
||||
/* if we don't have dynamic states, we have to hash the enabled vertex buffer bindings */
|
||||
uint32_t mask_a = sa->vertex_buffers_enabled_mask;
|
||||
uint32_t mask_b = sb->vertex_buffers_enabled_mask;
|
||||
|
|
@ -890,26 +879,44 @@ primitive_topology(enum pipe_prim_type mode)
|
|||
}
|
||||
|
||||
VkPipeline
|
||||
zink_get_gfx_pipeline(struct zink_screen *screen,
|
||||
zink_get_gfx_pipeline(struct zink_context *ctx,
|
||||
struct zink_gfx_program *prog,
|
||||
struct zink_gfx_pipeline_state *state,
|
||||
enum pipe_prim_type mode)
|
||||
{
|
||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||
VkPrimitiveTopology vkmode = primitive_topology(mode);
|
||||
assert(vkmode <= ARRAY_SIZE(prog->pipelines));
|
||||
|
||||
struct hash_entry *entry = NULL;
|
||||
|
||||
|
||||
if (state->dirty) {
|
||||
state->combined_dirty = true;
|
||||
state->vertex_state_dirty = state->combined_dirty = true;
|
||||
state->hash = hash_gfx_pipeline_state(state);
|
||||
state->dirty = false;
|
||||
}
|
||||
if (state->combined_dirty) {
|
||||
state->vertex_state_dirty = true;
|
||||
state->combined_hash = XXH32(&state->module_hash, sizeof(uint32_t), state->hash);
|
||||
state->combined_dirty = false;
|
||||
}
|
||||
entry = _mesa_hash_table_search_pre_hashed(prog->pipelines[vkmode], state->combined_hash, state);
|
||||
if (state->vertex_state_dirty) {
|
||||
uint32_t hash = state->combined_hash;
|
||||
if (!state->have_EXT_extended_dynamic_state) {
|
||||
/* if we don't have dynamic states, we have to hash the enabled vertex buffer bindings */
|
||||
uint32_t vertex_buffers_enabled_mask = state->vertex_buffers_enabled_mask;
|
||||
hash = XXH32(&vertex_buffers_enabled_mask, sizeof(uint32_t), hash);
|
||||
|
||||
for (unsigned i = 0; i < state->element_state->num_bindings; i++) {
|
||||
struct pipe_vertex_buffer *vb = ctx->vertex_buffers + ctx->element_state->binding_map[i];
|
||||
state->vertex_strides[i] = vb->buffer.resource ? vb->stride : 0;
|
||||
hash = XXH32(&state->vertex_strides[i], sizeof(uint32_t), hash);
|
||||
}
|
||||
}
|
||||
state->final_hash = XXH32(&state->element_state, sizeof(void*), hash);
|
||||
state->vertex_state_dirty = false;
|
||||
}
|
||||
entry = _mesa_hash_table_search_pre_hashed(prog->pipelines[vkmode], state->final_hash, state);
|
||||
|
||||
if (!entry) {
|
||||
VkPipeline pipeline = zink_create_gfx_pipeline(screen, prog,
|
||||
|
|
@ -924,7 +931,7 @@ zink_get_gfx_pipeline(struct zink_screen *screen,
|
|||
memcpy(&pc_entry->state, state, sizeof(*state));
|
||||
pc_entry->pipeline = pipeline;
|
||||
|
||||
entry = _mesa_hash_table_insert_pre_hashed(prog->pipelines[vkmode], state->combined_hash, state, pc_entry);
|
||||
entry = _mesa_hash_table_insert_pre_hashed(prog->pipelines[vkmode], state->final_hash, state, pc_entry);
|
||||
assert(entry);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ zink_destroy_gfx_program(struct zink_screen *screen,
|
|||
struct zink_gfx_program *prog);
|
||||
|
||||
VkPipeline
|
||||
zink_get_gfx_pipeline(struct zink_screen *screen,
|
||||
zink_get_gfx_pipeline(struct zink_context *ctx,
|
||||
struct zink_gfx_program *prog,
|
||||
struct zink_gfx_pipeline_state *state,
|
||||
enum pipe_prim_type mode);
|
||||
|
|
|
|||
|
|
@ -95,8 +95,9 @@ zink_bind_vertex_elements_state(struct pipe_context *pctx,
|
|||
struct zink_context *ctx = zink_context(pctx);
|
||||
struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
|
||||
ctx->element_state = cso;
|
||||
state->dirty = true;
|
||||
if (cso) {
|
||||
if (state->element_state != &ctx->element_state->hw_state)
|
||||
state->vertex_state_dirty = true;
|
||||
state->element_state = &ctx->element_state->hw_state;
|
||||
} else
|
||||
state->element_state = NULL;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue