{
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;
}
}
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);
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);
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;
}
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);
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;
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;
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;
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];
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));