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 *
{
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,
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);
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;
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
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
ctx->rast_state = cso;
if (ctx->rast_state) {
- ctx->gfx_pipeline_state.rast_state = &ctx->rast_state->hw_state;
- ctx->line_width = ctx->rast_state->line_width;
+ 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;
+ }
}
}