zink: use dynamic patch vertices if available
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 31 May 2022 19:42:22 +0000 (15:42 -0400)
committerMarge Bot <emma+marge@anholt.net>
Fri, 3 Jun 2022 01:23:58 +0000 (01:23 +0000)
this one's a little different from other dynamic states in that it
isn't expected to change much, so I've kept it outside of draw handling
since it can be trivially applied elsewhere with no chance of impacting perf

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16838>

src/gallium/drivers/zink/zink_context.c
src/gallium/drivers/zink/zink_draw.cpp
src/gallium/drivers/zink/zink_pipeline.c
src/gallium/drivers/zink/zink_pipeline.h
src/gallium/drivers/zink/zink_program.c

index 193f488..cf16c2a 100644 (file)
@@ -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;
    }
index e4360a2..a03cdf7 100644 (file)
@@ -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);
index 6824fd2..304fae4 100644 (file)
@@ -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;
index f4a5420..330e3c9 100644 (file)
@@ -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];
index 39bdb71..b62c7b9 100644 (file)
@@ -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));