mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-04-27 02:20:38 +02:00
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:
parent
c886a7a423
commit
d862871682
4 changed files with 79 additions and 45 deletions
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue