mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 20:10:14 +01:00
zink: selectively disable dynamic vertex stride
if the vertex state doesn't meet the requirements to use this feature, fall back to fully-baked pipelines instead of violating spec Reviewed-by: Dave Airlie <airlied@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16018>
This commit is contained in:
parent
d46774f8e6
commit
1eada1b02d
5 changed files with 44 additions and 7 deletions
|
|
@ -4205,6 +4205,8 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||||
|
|
||||||
ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
|
ctx->pipeline_changed[0] = ctx->pipeline_changed[1] = true;
|
||||||
ctx->gfx_pipeline_state.dirty = true;
|
ctx->gfx_pipeline_state.dirty = true;
|
||||||
|
ctx->gfx_pipeline_state.uses_dynamic_stride = screen->info.have_EXT_extended_dynamic_state ||
|
||||||
|
screen->info.have_EXT_vertex_input_dynamic_state;
|
||||||
ctx->compute_pipeline_state.dirty = true;
|
ctx->compute_pipeline_state.dirty = true;
|
||||||
ctx->fb_changed = ctx->rp_changed = true;
|
ctx->fb_changed = ctx->rp_changed = true;
|
||||||
ctx->gfx_pipeline_state.gfx_prim_mode = PIPE_PRIM_MAX;
|
ctx->gfx_pipeline_state.gfx_prim_mode = PIPE_PRIM_MAX;
|
||||||
|
|
|
||||||
|
|
@ -749,8 +749,12 @@ zink_draw(struct pipe_context *pctx,
|
||||||
|
|
||||||
if (DRAW_STATE)
|
if (DRAW_STATE)
|
||||||
zink_bind_vertex_state(batch, ctx, vstate, partial_velem_mask);
|
zink_bind_vertex_state(batch, ctx, vstate, partial_velem_mask);
|
||||||
else if (BATCH_CHANGED || ctx->vertex_buffers_dirty)
|
else if (BATCH_CHANGED || ctx->vertex_buffers_dirty) {
|
||||||
zink_bind_vertex_buffers<DYNAMIC_STATE>(batch, ctx);
|
if (DYNAMIC_STATE == ZINK_DYNAMIC_VERTEX_INPUT || ctx->gfx_pipeline_state.uses_dynamic_stride)
|
||||||
|
zink_bind_vertex_buffers<DYNAMIC_STATE>(batch, ctx);
|
||||||
|
else
|
||||||
|
zink_bind_vertex_buffers<ZINK_NO_DYNAMIC_STATE>(batch, ctx);
|
||||||
|
}
|
||||||
|
|
||||||
if (BATCH_CHANGED) {
|
if (BATCH_CHANGED) {
|
||||||
ctx->pipeline_changed[0] = false;
|
ctx->pipeline_changed[0] = false;
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
|
||||||
vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
|
vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
|
||||||
vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
|
vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
|
||||||
vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
|
vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
|
||||||
if (!screen->info.have_EXT_extended_dynamic_state) {
|
if (!screen->info.have_EXT_extended_dynamic_state || !state->uses_dynamic_stride) {
|
||||||
for (int i = 0; i < state->element_state->num_bindings; ++i) {
|
for (int i = 0; i < state->element_state->num_bindings; ++i) {
|
||||||
const unsigned buffer_id = binding_map[i];
|
const unsigned buffer_id = binding_map[i];
|
||||||
VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
|
VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
|
||||||
|
|
@ -232,7 +232,7 @@ zink_create_gfx_pipeline(struct zink_screen *screen,
|
||||||
if (state->element_state->num_attribs) {
|
if (state->element_state->num_attribs) {
|
||||||
if (screen->info.have_EXT_vertex_input_dynamic_state)
|
if (screen->info.have_EXT_vertex_input_dynamic_state)
|
||||||
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
|
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
|
||||||
else if (screen->info.have_EXT_extended_dynamic_state)
|
else if (screen->info.have_EXT_extended_dynamic_state && state->uses_dynamic_stride)
|
||||||
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
|
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
|
||||||
}
|
}
|
||||||
if (screen->info.have_EXT_extended_dynamic_state2) {
|
if (screen->info.have_EXT_extended_dynamic_state2) {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ struct zink_gfx_pipeline_state {
|
||||||
uint32_t vertex_buffers_enabled_mask;
|
uint32_t vertex_buffers_enabled_mask;
|
||||||
uint32_t vertex_strides[PIPE_MAX_ATTRIBS];
|
uint32_t vertex_strides[PIPE_MAX_ATTRIBS];
|
||||||
bool sample_locations_enabled;
|
bool sample_locations_enabled;
|
||||||
|
bool uses_dynamic_stride;
|
||||||
bool have_EXT_extended_dynamic_state;
|
bool have_EXT_extended_dynamic_state;
|
||||||
bool have_EXT_extended_dynamic_state2;
|
bool have_EXT_extended_dynamic_state2;
|
||||||
uint8_t has_points; //either gs outputs points or prim type is points
|
uint8_t has_points; //either gs outputs points or prim type is points
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,9 @@ equals_gfx_pipeline_state(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
const struct zink_gfx_pipeline_state *sa = a;
|
const struct zink_gfx_pipeline_state *sa = a;
|
||||||
const struct zink_gfx_pipeline_state *sb = b;
|
const struct zink_gfx_pipeline_state *sb = b;
|
||||||
if (!sa->have_EXT_extended_dynamic_state) {
|
if (sa->uses_dynamic_stride != sb->uses_dynamic_stride)
|
||||||
|
return false;
|
||||||
|
if (!sa->have_EXT_extended_dynamic_state || !sa->uses_dynamic_stride) {
|
||||||
if (sa->vertex_buffers_enabled_mask != sb->vertex_buffers_enabled_mask)
|
if (sa->vertex_buffers_enabled_mask != sb->vertex_buffers_enabled_mask)
|
||||||
return false;
|
return false;
|
||||||
/* if we don't have dynamic states, we have to hash the enabled vertex buffer bindings */
|
/* if we don't have dynamic states, we have to hash the enabled vertex buffer bindings */
|
||||||
|
|
@ -252,6 +254,8 @@ equals_gfx_pipeline_state(const void *a, const void *b)
|
||||||
if (sa->vertex_strides[idx_a] != sb->vertex_strides[idx_b])
|
if (sa->vertex_strides[idx_a] != sb->vertex_strides[idx_b])
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!sa->have_EXT_extended_dynamic_state) {
|
||||||
if (sa->dyn_state1.front_face != sb->dyn_state1.front_face)
|
if (sa->dyn_state1.front_face != sb->dyn_state1.front_face)
|
||||||
return false;
|
return false;
|
||||||
if (!!sa->dyn_state1.depth_stencil_alpha_state != !!sb->dyn_state1.depth_stencil_alpha_state ||
|
if (!!sa->dyn_state1.depth_stencil_alpha_state != !!sb->dyn_state1.depth_stencil_alpha_state ||
|
||||||
|
|
@ -765,7 +769,29 @@ get_pipeline_idx(bool have_EXT_extended_dynamic_state, enum pipe_prim_type mode,
|
||||||
}
|
}
|
||||||
return vkmode;
|
return vkmode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
VUID-vkCmdBindVertexBuffers2-pStrides-06209
|
||||||
|
If pStrides is not NULL each element of pStrides must be either 0 or greater than or equal
|
||||||
|
to the maximum extent of all vertex input attributes fetched from the corresponding
|
||||||
|
binding, where the extent is calculated as the VkVertexInputAttributeDescription::offset
|
||||||
|
plus VkVertexInputAttributeDescription::format size
|
||||||
|
|
||||||
|
* thus, if the stride doesn't meet the minimum requirement for a binding,
|
||||||
|
* disable the dynamic state here and use a fully-baked pipeline
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
check_vertex_strides(struct zink_context *ctx)
|
||||||
|
{
|
||||||
|
const struct zink_vertex_elements_state *ves = ctx->element_state;
|
||||||
|
for (unsigned i = 0; i < ves->hw_state.num_bindings; i++) {
|
||||||
|
const struct pipe_vertex_buffer *vb = ctx->vertex_buffers + ves->binding_map[i];
|
||||||
|
unsigned stride = vb->buffer.resource ? vb->stride : 0;
|
||||||
|
if (stride < ves->min_stride[i])
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
VkPipeline
|
VkPipeline
|
||||||
zink_get_gfx_pipeline(struct zink_context *ctx,
|
zink_get_gfx_pipeline(struct zink_context *ctx,
|
||||||
|
|
@ -776,6 +802,7 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
|
||||||
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
struct zink_screen *screen = zink_screen(ctx->base.screen);
|
||||||
const bool have_EXT_vertex_input_dynamic_state = screen->info.have_EXT_vertex_input_dynamic_state;
|
const bool have_EXT_vertex_input_dynamic_state = screen->info.have_EXT_vertex_input_dynamic_state;
|
||||||
const bool have_EXT_extended_dynamic_state = screen->info.have_EXT_extended_dynamic_state;
|
const bool have_EXT_extended_dynamic_state = screen->info.have_EXT_extended_dynamic_state;
|
||||||
|
bool uses_dynamic_stride = state->uses_dynamic_stride;
|
||||||
|
|
||||||
VkPrimitiveTopology vkmode = zink_primitive_topology(mode);
|
VkPrimitiveTopology vkmode = zink_primitive_topology(mode);
|
||||||
const unsigned idx = get_pipeline_idx(screen->info.have_EXT_extended_dynamic_state, mode, vkmode);
|
const unsigned idx = get_pipeline_idx(screen->info.have_EXT_extended_dynamic_state, mode, vkmode);
|
||||||
|
|
@ -797,7 +824,9 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
|
||||||
if (!have_EXT_vertex_input_dynamic_state && ctx->vertex_state_changed) {
|
if (!have_EXT_vertex_input_dynamic_state && ctx->vertex_state_changed) {
|
||||||
if (state->pipeline)
|
if (state->pipeline)
|
||||||
state->final_hash ^= state->vertex_hash;
|
state->final_hash ^= state->vertex_hash;
|
||||||
if (!have_EXT_extended_dynamic_state) {
|
if (have_EXT_extended_dynamic_state)
|
||||||
|
uses_dynamic_stride = check_vertex_strides(ctx);
|
||||||
|
if (!uses_dynamic_stride) {
|
||||||
uint32_t hash = 0;
|
uint32_t hash = 0;
|
||||||
/* if we don't have dynamic states, we have to hash the enabled vertex buffer bindings */
|
/* if we don't have dynamic states, we have to hash the enabled vertex buffer bindings */
|
||||||
uint32_t vertex_buffers_enabled_mask = state->vertex_buffers_enabled_mask;
|
uint32_t vertex_buffers_enabled_mask = state->vertex_buffers_enabled_mask;
|
||||||
|
|
@ -815,6 +844,7 @@ zink_get_gfx_pipeline(struct zink_context *ctx,
|
||||||
state->final_hash ^= state->vertex_hash;
|
state->final_hash ^= state->vertex_hash;
|
||||||
}
|
}
|
||||||
state->modules_changed = false;
|
state->modules_changed = false;
|
||||||
|
state->uses_dynamic_stride = uses_dynamic_stride;
|
||||||
ctx->vertex_state_changed = false;
|
ctx->vertex_state_changed = false;
|
||||||
|
|
||||||
entry = _mesa_hash_table_search_pre_hashed(&prog->pipelines[idx], state->final_hash, state);
|
entry = _mesa_hash_table_search_pre_hashed(&prog->pipelines[idx], state->final_hash, state);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue