zink: move pipeline state comparison to c++ template

the other part of the pipeline update hotpath

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18135>
This commit is contained in:
Mike Blumenkrantz 2022-08-04 15:54:19 -04:00 committed by Marge Bot
parent c886a7a423
commit d862871682
4 changed files with 79 additions and 45 deletions

View file

@ -223,50 +223,6 @@ equals_pipeline_lib(const void *a, const void *b)
return !memcmp(a, b, offsetof(struct zink_gfx_library_key, pipeline));
}
static bool
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->uses_dynamic_stride != sb->uses_dynamic_stride)
return false;
/* dynamic vs rp */
if (!!sa->render_pass != !!sb->render_pass)
return false;
if (!sa->have_EXT_extended_dynamic_state || !sa->uses_dynamic_stride) {
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;
while (mask_a || mask_b) {
unsigned idx_a = u_bit_scan(&mask_a);
unsigned idx_b = u_bit_scan(&mask_b);
if (sa->vertex_strides[idx_a] != sb->vertex_strides[idx_b])
return false;
}
}
if (!sa->have_EXT_extended_dynamic_state) {
if (memcmp(&sa->dyn_state1, &sb->dyn_state1, offsetof(struct zink_pipeline_dynamic_state1, depth_stencil_alpha_state)))
return false;
if (!!sa->dyn_state1.depth_stencil_alpha_state != !!sb->dyn_state1.depth_stencil_alpha_state ||
(sa->dyn_state1.depth_stencil_alpha_state &&
memcmp(sa->dyn_state1.depth_stencil_alpha_state, sb->dyn_state1.depth_stencil_alpha_state,
sizeof(struct zink_depth_stencil_alpha_hw_state))))
return false;
}
if (!sa->have_EXT_extended_dynamic_state2) {
if (memcmp(&sa->dyn_state2, &sb->dyn_state2, sizeof(sa->dyn_state2)))
return false;
} else if (!sa->extendedDynamicState2PatchControlPoints) {
if (sa->dyn_state2.vertices_per_patch != sb->dyn_state2.vertices_per_patch)
return false;
}
return !memcmp(sa->modules, sb->modules, sizeof(sa->modules)) &&
!memcmp(a, b, offsetof(struct zink_gfx_pipeline_state, hash));
}
uint32_t
hash_gfx_input_dynamic(const void *key)
{
@ -564,7 +520,7 @@ zink_create_gfx_program(struct zink_context *ctx,
prog->last_vertex_stage = stages[MESA_SHADER_VERTEX];
for (int i = 0; i < ARRAY_SIZE(prog->pipelines); ++i) {
_mesa_hash_table_init(&prog->pipelines[i], prog, NULL, equals_gfx_pipeline_state);
_mesa_hash_table_init(&prog->pipelines[i], prog, NULL, zink_get_gfx_pipeline_eq_func(screen));
/* only need first 3/4 for point/line/tri/patch */
if (screen->info.have_EXT_extended_dynamic_state &&
i == (prog->last_vertex_stage->nir->info.stage == MESA_SHADER_TESS_EVAL ? 4 : 3))

View file

@ -297,6 +297,8 @@ zink_set_fs_point_coord_key(struct zink_context *ctx)
bool
zink_set_rasterizer_discard(struct zink_context *ctx, bool disable);
equals_gfx_pipeline_state_func
zink_get_gfx_pipeline_eq_func(struct zink_screen *screen);
#ifdef __cplusplus
}
#endif

View file

@ -260,3 +260,69 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
state->pipeline = cache_entry->pipeline;
return state->pipeline;
}
template <zink_pipeline_dynamic_state DYNAMIC_STATE>
static bool
equals_gfx_pipeline_state(const void *a, const void *b)
{
const struct zink_gfx_pipeline_state *sa = (const struct zink_gfx_pipeline_state *)a;
const struct zink_gfx_pipeline_state *sb = (const struct zink_gfx_pipeline_state *)b;
if (sa->uses_dynamic_stride != sb->uses_dynamic_stride)
return false;
/* dynamic vs rp */
if (!!sa->render_pass != !!sb->render_pass)
return false;
if (DYNAMIC_STATE == ZINK_PIPELINE_NO_DYNAMIC_STATE || !sa->uses_dynamic_stride) {
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;
while (mask_a || mask_b) {
unsigned idx_a = u_bit_scan(&mask_a);
unsigned idx_b = u_bit_scan(&mask_b);
if (sa->vertex_strides[idx_a] != sb->vertex_strides[idx_b])
return false;
}
}
if (DYNAMIC_STATE == ZINK_PIPELINE_NO_DYNAMIC_STATE) {
if (memcmp(&sa->dyn_state1, &sb->dyn_state1, offsetof(struct zink_pipeline_dynamic_state1, depth_stencil_alpha_state)))
return false;
if (!!sa->dyn_state1.depth_stencil_alpha_state != !!sb->dyn_state1.depth_stencil_alpha_state ||
(sa->dyn_state1.depth_stencil_alpha_state &&
memcmp(sa->dyn_state1.depth_stencil_alpha_state, sb->dyn_state1.depth_stencil_alpha_state,
sizeof(struct zink_depth_stencil_alpha_hw_state))))
return false;
}
if (DYNAMIC_STATE < ZINK_PIPELINE_DYNAMIC_STATE2) {
if (memcmp(&sa->dyn_state2, &sb->dyn_state2, sizeof(sa->dyn_state2)))
return false;
} else if (DYNAMIC_STATE != ZINK_PIPELINE_DYNAMIC_STATE2_PCP && DYNAMIC_STATE != ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT_PCP) {
if (sa->dyn_state2.vertices_per_patch != sb->dyn_state2.vertices_per_patch)
return false;
}
return !memcmp(sa->modules, sb->modules, sizeof(sa->modules)) &&
!memcmp(a, b, offsetof(struct zink_gfx_pipeline_state, hash));
}
equals_gfx_pipeline_state_func
zink_get_gfx_pipeline_eq_func(struct zink_screen *screen)
{
if (screen->info.have_EXT_extended_dynamic_state) {
if (screen->info.have_EXT_extended_dynamic_state2) {
if (screen->info.have_EXT_vertex_input_dynamic_state) {
if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT_PCP>;
else
return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT>;
} else {
if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_STATE2_PCP>;
else
return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_STATE2>;
}
}
return equals_gfx_pipeline_state<ZINK_PIPELINE_DYNAMIC_STATE>;
}
return equals_gfx_pipeline_state<ZINK_PIPELINE_NO_DYNAMIC_STATE>;
}

View file

@ -100,6 +100,15 @@ typedef enum {
ZINK_DYNAMIC_VERTEX_INPUT,
} zink_dynamic_state;
typedef enum {
ZINK_PIPELINE_NO_DYNAMIC_STATE,
ZINK_PIPELINE_DYNAMIC_STATE,
ZINK_PIPELINE_DYNAMIC_STATE2,
ZINK_PIPELINE_DYNAMIC_STATE2_PCP,
ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT,
ZINK_PIPELINE_DYNAMIC_VERTEX_INPUT_PCP,
} zink_pipeline_dynamic_state;
enum zink_blit_flags {
ZINK_BLIT_NORMAL = 1 << 0,
ZINK_BLIT_SAVE_FS = 1 << 1,
@ -739,6 +748,7 @@ struct zink_program {
bool removed;
};
typedef bool (*equals_gfx_pipeline_state_func)(const void *a, const void *b);
struct zink_gfx_library_key {
uint32_t hw_rast_state;