zink: pre-hash gfx-pipeline-state

Store a hash in `zink_gfx_pipeline_state` to keep track of state
changes and avoid to recompute it when the state has not changed.

Signed-off-by: Antonio Caggiano <antonio.caggiano@collabora.com>
Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Reviewed-by: Erik Faye-Lund <erik.faye-lund@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6061>
This commit is contained in:
Antonio Caggiano
2020-07-24 16:50:15 +02:00
parent 7be12df5e6
commit 1185b3f32d
4 changed files with 43 additions and 10 deletions

View File

@@ -612,6 +612,7 @@ zink_set_framebuffer_state(struct pipe_context *pctx,
ctx->gfx_pipeline_state.rast_samples = MAX2(state->samples, 1);
ctx->gfx_pipeline_state.num_attachments = state->nr_cbufs;
ctx->gfx_pipeline_state.hash = 0;
struct zink_batch *batch = zink_batch_no_rp(ctx);
@@ -1050,6 +1051,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
if (!ctx)
goto fail;
ctx->gfx_pipeline_state.hash = 0;
ctx->base.screen = pscreen;
ctx->base.priv = priv;

View File

@@ -53,6 +53,10 @@ struct zink_gfx_pipeline_state {
uint8_t rast_samples;
bool primitive_restart;
/* Pre-hashed value for table lookup, invalid when zero.
* Members after this point are not included in pipeline state hash key */
uint32_t hash;
};
VkPipeline

View File

@@ -163,13 +163,13 @@ update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_
static uint32_t
hash_gfx_pipeline_state(const void *key)
{
return _mesa_hash_data(key, sizeof(struct zink_gfx_pipeline_state));
return _mesa_hash_data(key, offsetof(struct zink_gfx_pipeline_state, hash));
}
static bool
equals_gfx_pipeline_state(const void *a, const void *b)
{
return memcmp(a, b, sizeof(struct zink_gfx_pipeline_state)) == 0;
return memcmp(a, b, offsetof(struct zink_gfx_pipeline_state, hash)) == 0;
}
struct zink_gfx_program *
@@ -319,9 +319,16 @@ zink_get_gfx_pipeline(struct zink_screen *screen,
{
assert(mode <= ARRAY_SIZE(prog->pipelines));
/* TODO: use pre-hashed versions to save some time (can re-hash only when
state changes) */
struct hash_entry *entry = _mesa_hash_table_search(prog->pipelines[mode], state);
struct hash_entry *entry = NULL;
if (!state->hash) {
state->hash = hash_gfx_pipeline_state(state);
/* make sure the hash is not zero, as we take it as invalid.
* TODO: rework this using a separate dirty-bit */
assert(state->hash != 0);
}
entry = _mesa_hash_table_search_pre_hashed(prog->pipelines[mode], state->hash, state);
if (!entry) {
VkPrimitiveTopology vkmode = primitive_topology(mode);
VkPipeline pipeline = zink_create_gfx_pipeline(screen, prog,
@@ -336,7 +343,8 @@ zink_get_gfx_pipeline(struct zink_screen *screen,
memcpy(&pc_entry->state, state, sizeof(*state));
pc_entry->pipeline = pipeline;
entry = _mesa_hash_table_insert(prog->pipelines[mode], &pc_entry->state, pc_entry);
assert(state->hash);
entry = _mesa_hash_table_insert_pre_hashed(prog->pipelines[mode], state->hash, state, pc_entry);
assert(entry);
reference_render_pass(screen, prog, state->render_pass);

View File

@@ -81,6 +81,7 @@ 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->hash = 0;
if (cso) {
state->element_state = &ctx->element_state->hw_state;
struct zink_vertex_elements_state *ves = cso;
@@ -256,7 +257,12 @@ zink_create_blend_state(struct pipe_context *pctx,
static void
zink_bind_blend_state(struct pipe_context *pctx, void *cso)
{
zink_context(pctx)->gfx_pipeline_state.blend_state = cso;
struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
if (state->blend_state != cso) {
state->blend_state = cso;
state->hash = 0;
}
}
static void
@@ -348,7 +354,12 @@ zink_create_depth_stencil_alpha_state(struct pipe_context *pctx,
static void
zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
{
zink_context(pctx)->gfx_pipeline_state.depth_stencil_alpha_state = cso;
struct zink_gfx_pipeline_state* state = &zink_context(pctx)->gfx_pipeline_state;
if (state->depth_stencil_alpha_state != cso) {
state->depth_stencil_alpha_state = cso;
state->hash = 0;
}
}
static void
@@ -423,8 +434,15 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
ctx->rast_state = cso;
if (ctx->rast_state) {
if (ctx->gfx_pipeline_state.rast_state != &ctx->rast_state->hw_state) {
ctx->gfx_pipeline_state.rast_state = &ctx->rast_state->hw_state;
ctx->gfx_pipeline_state.hash = 0;
}
if (ctx->line_width != ctx->rast_state->line_width) {
ctx->line_width = ctx->rast_state->line_width;
ctx->gfx_pipeline_state.hash = 0;
}
}
}