Module: Mesa
Branch: main
Commit: 55c8f5e288ea18683f0438c115fb9561b72a9a87
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=55c8f5e288ea18683f0438c115fb9561b72a9a87

Author: George Ouzounoudis <[email protected]>
Date:   Thu Aug 24 22:54:37 2023 +0300

nvk: Support extended dynamic state for tessellation domain origin

The tessellation domain origin, type, prims and spacing are all pushed
together in SET_TESSELLATION_PARAMETERS. So to support domain origin as
dynamic we need to push all these together when the state is dynamically
changed or when a new tessellation shader is bound.
This is also needed for EXT_shader_object.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/24872>

---

 src/nouveau/vulkan/nvk_cmd_draw.c          | 34 +++++++++++++++++++++++++++++-
 src/nouveau/vulkan/nvk_graphics_pipeline.c | 34 ++++--------------------------
 src/nouveau/vulkan/nvk_physical_device.c   |  2 +-
 src/nouveau/vulkan/nvk_shader.h            |  6 ++++++
 4 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/src/nouveau/vulkan/nvk_cmd_draw.c 
b/src/nouveau/vulkan/nvk_cmd_draw.c
index 1188f79b2cd..22b2b760d2f 100644
--- a/src/nouveau/vulkan/nvk_cmd_draw.c
+++ b/src/nouveau/vulkan/nvk_cmd_draw.c
@@ -930,6 +930,15 @@ nvk_cmd_bind_graphics_pipeline(struct nvk_cmd_buffer *cmd,
    cmd->state.gfx.pipeline = pipeline;
    vk_cmd_set_dynamic_graphics_state(&cmd->vk, &pipeline->dynamic);
 
+   /* When a pipeline with tess shaders is bound we need to re-upload the
+    * tessellation parameters at flush_ts_state, as the domain origin can be
+    * dynamic.
+    */
+   if (nvk_shader_is_enabled(&pipeline->base.shaders[MESA_SHADER_TESS_EVAL])) {
+      BITSET_SET(cmd->vk.dynamic_graphics_state.dirty,
+                 MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN);
+   }
+
    struct nv_push *p = nvk_cmd_buffer_push(cmd, pipeline->push_dw_count);
    nv_push_raw(p, pipeline->push_data, pipeline->push_dw_count);
 }
@@ -999,11 +1008,34 @@ nvk_flush_ts_state(struct nvk_cmd_buffer *cmd)
 {
    const struct vk_dynamic_graphics_state *dyn =
       &cmd->vk.dynamic_graphics_state;
+   struct nv_push *p = nvk_cmd_buffer_push(cmd, 4);
 
    if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_TS_PATCH_CONTROL_POINTS)) {
-      struct nv_push *p = nvk_cmd_buffer_push(cmd, 2);
       P_IMMD(p, NV9097, SET_PATCH, dyn->ts.patch_control_points);
    }
+
+   if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_TS_DOMAIN_ORIGIN)) {
+      const struct nvk_graphics_pipeline *pipeline= cmd->state.gfx.pipeline;
+      const struct nvk_shader *shader =
+         &pipeline->base.shaders[MESA_SHADER_TESS_EVAL];
+
+      if (nvk_shader_is_enabled(shader)) {
+         enum nak_ts_prims prims = shader->info.ts.prims;
+         /* When the origin is lower-left, we have to flip the winding order */
+         if (dyn->ts.domain_origin == 
VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT) {
+            if (prims == NAK_TS_PRIMS_TRIANGLES_CW)
+               prims = NAK_TS_PRIMS_TRIANGLES_CCW;
+            else if (prims == NAK_TS_PRIMS_TRIANGLES_CCW)
+               prims = NAK_TS_PRIMS_TRIANGLES_CW;
+         }
+         P_MTHD(p, NV9097, SET_TESSELLATION_PARAMETERS);
+         P_NV9097_SET_TESSELLATION_PARAMETERS(p, {
+            shader->info.ts.domain,
+            shader->info.ts.spacing,
+            prims
+         });
+      }
+   }
 }
 
 static void
diff --git a/src/nouveau/vulkan/nvk_graphics_pipeline.c 
b/src/nouveau/vulkan/nvk_graphics_pipeline.c
index dfb0d0ad4b9..8485818fcd3 100644
--- a/src/nouveau/vulkan/nvk_graphics_pipeline.c
+++ b/src/nouveau/vulkan/nvk_graphics_pipeline.c
@@ -113,27 +113,6 @@ static const uint32_t mesa_to_nv9097_shader_type[] = {
    [MESA_SHADER_FRAGMENT]  = NV9097_SET_PIPELINE_SHADER_TYPE_PIXEL,
 };
 
-static void
-emit_tessellation_paramaters(struct nv_push *p,
-                             const struct nvk_shader *shader,
-                             const struct vk_tessellation_state *state)
-{
-   enum nak_ts_prims prims = shader->info.ts.prims;
-   /* When the origin is lower-left, we have to flip the winding order */
-   if (state->domain_origin == VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT) {
-      if (prims == NAK_TS_PRIMS_TRIANGLES_CW)
-         prims = NAK_TS_PRIMS_TRIANGLES_CCW;
-      else if (prims == NAK_TS_PRIMS_TRIANGLES_CCW)
-         prims = NAK_TS_PRIMS_TRIANGLES_CW;
-   }
-   P_MTHD(p, NV9097, SET_TESSELLATION_PARAMETERS);
-   P_NV9097_SET_TESSELLATION_PARAMETERS(p, {
-      shader->info.ts.domain,
-      shader->info.ts.spacing,
-      prims
-   });
-}
-
 static void
 merge_tess_info(struct shader_info *tes_info, struct shader_info *tcs_info)
 {
@@ -267,11 +246,11 @@ nvk_graphics_pipeline_create(struct nvk_device *dev,
       uint32_t idx = mesa_to_nv9097_shader_type[stage];
 
       P_IMMD(p, NV9097, SET_PIPELINE_SHADER(idx), {
-         .enable  = shader->upload_size > 0,
+         .enable  = nvk_shader_is_enabled(shader),
          .type    = mesa_to_nv9097_shader_type[stage],
       });
 
-      if (shader->upload_size == 0)
+      if (!nvk_shader_is_enabled(shader))
          continue;
 
       if (stage != MESA_SHADER_FRAGMENT)
@@ -294,6 +273,8 @@ nvk_graphics_pipeline_create(struct nvk_device *dev,
       switch (stage) {
       case MESA_SHADER_VERTEX:
       case MESA_SHADER_GEOMETRY:
+      case MESA_SHADER_TESS_CTRL:
+      case MESA_SHADER_TESS_EVAL:
          break;
 
       case MESA_SHADER_FRAGMENT:
@@ -329,13 +310,6 @@ nvk_graphics_pipeline_create(struct nvk_device *dev,
                              shader->info.fs.uses_sample_shading;
          break;
 
-      case MESA_SHADER_TESS_CTRL:
-         break;
-
-      case MESA_SHADER_TESS_EVAL:
-         emit_tessellation_paramaters(p, shader, state.ts);
-         break;
-
       default:
          unreachable("Unsupported shader stage");
       }
diff --git a/src/nouveau/vulkan/nvk_physical_device.c 
b/src/nouveau/vulkan/nvk_physical_device.c
index aead8a93c72..8e9bab843a0 100644
--- a/src/nouveau/vulkan/nvk_physical_device.c
+++ b/src/nouveau/vulkan/nvk_physical_device.c
@@ -389,7 +389,7 @@ nvk_get_device_features(const struct nv_device_info *info,
       .extendedDynamicState2PatchControlPoints = true,
 
       /* VK_EXT_extended_dynamic_state3 */
-      .extendedDynamicState3TessellationDomainOrigin = false,
+      .extendedDynamicState3TessellationDomainOrigin = true,
       .extendedDynamicState3DepthClampEnable = true,
       .extendedDynamicState3PolygonMode = true,
       .extendedDynamicState3RasterizationSamples = false,
diff --git a/src/nouveau/vulkan/nvk_shader.h b/src/nouveau/vulkan/nvk_shader.h
index 0644b4e4e7a..dea5cdf0bd6 100644
--- a/src/nouveau/vulkan/nvk_shader.h
+++ b/src/nouveau/vulkan/nvk_shader.h
@@ -64,6 +64,12 @@ nvk_shader_address(const struct nvk_shader *shader)
    return shader->upload_addr + shader->upload_padding;
 }
 
+static inline bool
+nvk_shader_is_enabled(const struct nvk_shader *shader)
+{
+   return shader->upload_size > 0;
+}
+
 VkShaderStageFlags nvk_nak_stages(const struct nv_device_info *info);
 
 uint64_t

Reply via email to