diff --git a/src/gallium/drivers/zink/zink_context.c b/src/gallium/drivers/zink/zink_context.c index 193f4881028..cf16c2af807 100644 --- a/src/gallium/drivers/zink/zink_context.c +++ b/src/gallium/drivers/zink/zink_context.c @@ -1930,8 +1930,11 @@ zink_set_patch_vertices(struct pipe_context *pctx, uint8_t patch_vertices) { struct zink_context *ctx = zink_context(pctx); if (zink_set_tcs_key_patches(ctx, patch_vertices)) { - ctx->gfx_pipeline_state.vertices_per_patch = patch_vertices ? patch_vertices - 1 : 0; - ctx->gfx_pipeline_state.dirty = true; + ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch = patch_vertices ? patch_vertices - 1 : 0; + if (zink_screen(ctx->base.screen)->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) + VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, patch_vertices); + else + ctx->gfx_pipeline_state.dirty = true; } } @@ -2456,6 +2459,8 @@ flush_batch(struct zink_context *ctx, bool sync) ctx->dd->bindless_bound = false; ctx->di.bindless_refs_dirty = true; ctx->sample_locations_changed = ctx->gfx_pipeline_state.sample_locations_enabled; + if (zink_screen(ctx->base.screen)->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) + VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch + 1); if (conditional_render_active) zink_start_conditional_render(ctx); reapply_color_write(ctx); @@ -4177,6 +4182,7 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) ctx->gfx_pipeline_state.have_EXT_extended_dynamic_state = screen->info.have_EXT_extended_dynamic_state; ctx->gfx_pipeline_state.have_EXT_extended_dynamic_state2 = screen->info.have_EXT_extended_dynamic_state2; + ctx->gfx_pipeline_state.extendedDynamicState2PatchControlPoints = screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints; slab_create_child(&ctx->transfer_pool, &screen->transfer_pool); slab_create_child(&ctx->transfer_pool_unsync, &screen->transfer_pool); @@ -4295,6 +4301,12 @@ zink_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags) zink_select_draw_vbo(ctx); zink_select_launch_grid(ctx); + /* set on startup just to avoid validation errors if a draw comes through without + * a tess shader later + */ + if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) + VKCTX(CmdSetPatchControlPointsEXT)(ctx->batch.state->cmdbuf, 1); + if (!(flags & PIPE_CONTEXT_PREFER_THREADED) || flags & PIPE_CONTEXT_COMPUTE_ONLY) { return &ctx->base; } diff --git a/src/gallium/drivers/zink/zink_draw.cpp b/src/gallium/drivers/zink/zink_draw.cpp index e4360a29a7b..a03cdf760fc 100644 --- a/src/gallium/drivers/zink/zink_draw.cpp +++ b/src/gallium/drivers/zink/zink_draw.cpp @@ -200,7 +200,7 @@ update_gfx_program(struct zink_context *ctx) ctx->dirty_shader_stages |= prog->stages_present; } else { ctx->dirty_shader_stages |= bits; - prog = zink_create_gfx_program(ctx, ctx->gfx_stages, ctx->gfx_pipeline_state.vertices_per_patch + 1); + prog = zink_create_gfx_program(ctx, ctx->gfx_stages, ctx->gfx_pipeline_state.dyn_state2.vertices_per_patch + 1); _mesa_hash_table_insert_pre_hashed(ht, hash, prog->shaders, prog); } zink_update_gfx_program(ctx, prog); diff --git a/src/gallium/drivers/zink/zink_pipeline.c b/src/gallium/drivers/zink/zink_pipeline.c index 6824fd26a99..304fae43ba1 100644 --- a/src/gallium/drivers/zink/zink_pipeline.c +++ b/src/gallium/drivers/zink/zink_pipeline.c @@ -241,6 +241,8 @@ zink_create_gfx_pipeline(struct zink_screen *screen, if (screen->info.have_EXT_extended_dynamic_state2) { dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT; dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT; + if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) + dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT; } if (!screen->driver_workarounds.color_write_missing) dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT; @@ -336,7 +338,7 @@ zink_create_gfx_pipeline(struct zink_screen *screen, VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0}; if (prog->shaders[PIPE_SHADER_TESS_CTRL] && prog->shaders[PIPE_SHADER_TESS_EVAL]) { tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO; - tci.patchControlPoints = state->vertices_per_patch + 1; + tci.patchControlPoints = state->dyn_state2.vertices_per_patch + 1; pci.pTessellationState = &tci; tci.pNext = &tdci; tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO; diff --git a/src/gallium/drivers/zink/zink_pipeline.h b/src/gallium/drivers/zink/zink_pipeline.h index f4a54203fb7..330e3c97f92 100644 --- a/src/gallium/drivers/zink/zink_pipeline.h +++ b/src/gallium/drivers/zink/zink_pipeline.h @@ -49,12 +49,12 @@ struct zink_pipeline_dynamic_state1 { struct zink_pipeline_dynamic_state2 { bool primitive_restart; bool rasterizer_discard; + uint32_t vertices_per_patch:5; }; struct zink_gfx_pipeline_state { uint32_t rast_state : ZINK_RAST_HW_STATE_SIZE; //zink_rasterizer_hw_state - uint32_t vertices_per_patch:5; - uint32_t rast_samples:10; //4 extra bits + uint32_t rast_samples:15; //9 extra bits uint32_t void_alpha_attachments:PIPE_MAX_COLOR_BUFS; VkSampleMask sample_mask; @@ -84,6 +84,7 @@ struct zink_gfx_pipeline_state { bool uses_dynamic_stride; bool have_EXT_extended_dynamic_state; bool have_EXT_extended_dynamic_state2; + bool extendedDynamicState2PatchControlPoints; uint8_t has_points; //either gs outputs points or prim type is points struct { struct zink_shader_key key[5]; diff --git a/src/gallium/drivers/zink/zink_program.c b/src/gallium/drivers/zink/zink_program.c index 39bdb71fdc4..b62c7b90f47 100644 --- a/src/gallium/drivers/zink/zink_program.c +++ b/src/gallium/drivers/zink/zink_program.c @@ -270,6 +270,9 @@ equals_gfx_pipeline_state(const void *a, const void *b) 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));