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:
@@ -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.rast_samples = MAX2(state->samples, 1);
|
||||||
ctx->gfx_pipeline_state.num_attachments = state->nr_cbufs;
|
ctx->gfx_pipeline_state.num_attachments = state->nr_cbufs;
|
||||||
|
ctx->gfx_pipeline_state.hash = 0;
|
||||||
|
|
||||||
struct zink_batch *batch = zink_batch_no_rp(ctx);
|
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)
|
if (!ctx)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
ctx->gfx_pipeline_state.hash = 0;
|
||||||
|
|
||||||
ctx->base.screen = pscreen;
|
ctx->base.screen = pscreen;
|
||||||
ctx->base.priv = priv;
|
ctx->base.priv = priv;
|
||||||
|
|
||||||
|
@@ -53,6 +53,10 @@ struct zink_gfx_pipeline_state {
|
|||||||
uint8_t rast_samples;
|
uint8_t rast_samples;
|
||||||
|
|
||||||
bool primitive_restart;
|
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
|
VkPipeline
|
||||||
|
@@ -163,13 +163,13 @@ update_shader_modules(struct zink_context *ctx, struct zink_shader *stages[ZINK_
|
|||||||
static uint32_t
|
static uint32_t
|
||||||
hash_gfx_pipeline_state(const void *key)
|
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
|
static bool
|
||||||
equals_gfx_pipeline_state(const void *a, const void *b)
|
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 *
|
struct zink_gfx_program *
|
||||||
@@ -319,9 +319,16 @@ zink_get_gfx_pipeline(struct zink_screen *screen,
|
|||||||
{
|
{
|
||||||
assert(mode <= ARRAY_SIZE(prog->pipelines));
|
assert(mode <= ARRAY_SIZE(prog->pipelines));
|
||||||
|
|
||||||
/* TODO: use pre-hashed versions to save some time (can re-hash only when
|
struct hash_entry *entry = NULL;
|
||||||
state changes) */
|
|
||||||
struct hash_entry *entry = _mesa_hash_table_search(prog->pipelines[mode], state);
|
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) {
|
if (!entry) {
|
||||||
VkPrimitiveTopology vkmode = primitive_topology(mode);
|
VkPrimitiveTopology vkmode = primitive_topology(mode);
|
||||||
VkPipeline pipeline = zink_create_gfx_pipeline(screen, prog,
|
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));
|
memcpy(&pc_entry->state, state, sizeof(*state));
|
||||||
pc_entry->pipeline = pipeline;
|
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);
|
assert(entry);
|
||||||
|
|
||||||
reference_render_pass(screen, prog, state->render_pass);
|
reference_render_pass(screen, prog, state->render_pass);
|
||||||
|
@@ -81,6 +81,7 @@ zink_bind_vertex_elements_state(struct pipe_context *pctx,
|
|||||||
struct zink_context *ctx = zink_context(pctx);
|
struct zink_context *ctx = zink_context(pctx);
|
||||||
struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
|
struct zink_gfx_pipeline_state *state = &ctx->gfx_pipeline_state;
|
||||||
ctx->element_state = cso;
|
ctx->element_state = cso;
|
||||||
|
state->hash = 0;
|
||||||
if (cso) {
|
if (cso) {
|
||||||
state->element_state = &ctx->element_state->hw_state;
|
state->element_state = &ctx->element_state->hw_state;
|
||||||
struct zink_vertex_elements_state *ves = cso;
|
struct zink_vertex_elements_state *ves = cso;
|
||||||
@@ -256,7 +257,12 @@ zink_create_blend_state(struct pipe_context *pctx,
|
|||||||
static void
|
static void
|
||||||
zink_bind_blend_state(struct pipe_context *pctx, void *cso)
|
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
|
static void
|
||||||
@@ -348,7 +354,12 @@ zink_create_depth_stencil_alpha_state(struct pipe_context *pctx,
|
|||||||
static void
|
static void
|
||||||
zink_bind_depth_stencil_alpha_state(struct pipe_context *pctx, void *cso)
|
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
|
static void
|
||||||
@@ -423,8 +434,15 @@ zink_bind_rasterizer_state(struct pipe_context *pctx, void *cso)
|
|||||||
ctx->rast_state = cso;
|
ctx->rast_state = cso;
|
||||||
|
|
||||||
if (ctx->rast_state) {
|
if (ctx->rast_state) {
|
||||||
ctx->gfx_pipeline_state.rast_state = &ctx->rast_state->hw_state;
|
if (ctx->gfx_pipeline_state.rast_state != &ctx->rast_state->hw_state) {
|
||||||
ctx->line_width = ctx->rast_state->line_width;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user