nvk: Compile geometry shaders
authorGeorge Ouzounoudis <geothrock@gmail.com>
Tue, 18 Oct 2022 18:51:37 +0000 (21:51 +0300)
committerMarge Bot <emma+marge@anholt.net>
Fri, 4 Aug 2023 21:32:03 +0000 (21:32 +0000)
This enables compiling geometry shaders.  Based primarily on gallium
nvc0/nvc0_program.c.

We need to enable/disable user clip planes based on the last geometry
stage.  Some asserts in codegen need to be changed too because the
compacted clip distance inputs are arrayed in the geometry shader. So we
have an array of clip distances for each input vertex.

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

src/nouveau/vulkan/nvk_graphics_pipeline.c
src/nouveau/vulkan/nvk_shader.c

index 0ec183a..4895f8e 100644 (file)
@@ -282,30 +282,9 @@ nvk_graphics_pipeline_create(struct nvk_device *device,
       P_IMMD(p, NV9097, SET_PIPELINE_REGISTER_COUNT(idx), shader->num_gprs);
 
       switch (stage) {
-      case MESA_SHADER_VERTEX: {
-         uint8_t clip_cull = shader->vs.clip_enable | shader->vs.cull_enable;
-         P_IMMD(p, NV9097, SET_USER_CLIP_ENABLE, {
-            .plane0 = (clip_cull >> 0) & 1,
-            .plane1 = (clip_cull >> 1) & 1,
-            .plane2 = (clip_cull >> 2) & 1,
-            .plane3 = (clip_cull >> 3) & 1,
-            .plane4 = (clip_cull >> 4) & 1,
-            .plane5 = (clip_cull >> 5) & 1,
-            .plane6 = (clip_cull >> 6) & 1,
-            .plane7 = (clip_cull >> 7) & 1,
-         });
-         P_IMMD(p, NV9097, SET_USER_CLIP_OP, {
-            .plane0 = (shader->vs.cull_enable >> 0) & 1,
-            .plane1 = (shader->vs.cull_enable >> 1) & 1,
-            .plane2 = (shader->vs.cull_enable >> 2) & 1,
-            .plane3 = (shader->vs.cull_enable >> 3) & 1,
-            .plane4 = (shader->vs.cull_enable >> 4) & 1,
-            .plane5 = (shader->vs.cull_enable >> 5) & 1,
-            .plane6 = (shader->vs.cull_enable >> 6) & 1,
-            .plane7 = (shader->vs.cull_enable >> 7) & 1,
-         });
+      case MESA_SHADER_VERTEX:
+      case MESA_SHADER_GEOMETRY:
          break;
-      }
 
       case MESA_SHADER_FRAGMENT:
          P_IMMD(p, NV9097, SET_SUBTILING_PERF_KNOB_A, {
@@ -342,6 +321,31 @@ nvk_graphics_pipeline_create(struct nvk_device *device,
       }
    }
 
+   const uint8_t clip_cull = last_geom->vs.clip_enable |
+                             last_geom->vs.cull_enable;
+   if (clip_cull) {
+      P_IMMD(p, NV9097, SET_USER_CLIP_ENABLE, {
+         .plane0 = (clip_cull >> 0) & 1,
+         .plane1 = (clip_cull >> 1) & 1,
+         .plane2 = (clip_cull >> 2) & 1,
+         .plane3 = (clip_cull >> 3) & 1,
+         .plane4 = (clip_cull >> 4) & 1,
+         .plane5 = (clip_cull >> 5) & 1,
+         .plane6 = (clip_cull >> 6) & 1,
+         .plane7 = (clip_cull >> 7) & 1,
+      });
+      P_IMMD(p, NV9097, SET_USER_CLIP_OP, {
+         .plane0 = (last_geom->vs.cull_enable >> 0) & 1,
+         .plane1 = (last_geom->vs.cull_enable >> 1) & 1,
+         .plane2 = (last_geom->vs.cull_enable >> 2) & 1,
+         .plane3 = (last_geom->vs.cull_enable >> 3) & 1,
+         .plane4 = (last_geom->vs.cull_enable >> 4) & 1,
+         .plane5 = (last_geom->vs.cull_enable >> 5) & 1,
+         .plane6 = (last_geom->vs.cull_enable >> 6) & 1,
+         .plane7 = (last_geom->vs.cull_enable >> 7) & 1,
+      });
+   }
+
    /* TODO: prog_selects_layer */
    P_IMMD(p, NV9097, SET_RT_LAYER, {
       .v       = 0,
index 936aaf7..a4afdc6 100644 (file)
@@ -603,6 +603,37 @@ nvk_vs_gen_header(struct nvk_shader *vs, struct nv50_ir_prog_info_out *info)
    return nvk_vtgp_gen_header(vs, info);
 }
 
+static int
+nvk_gs_gen_header(struct nvk_shader *gs, struct nv50_ir_prog_info_out *info)
+{
+   gs->hdr[0] = 0x20061 | (4 << 10);
+
+   gs->hdr[2] = MIN2(info->prop.gp.instanceCount, 32) << 24;
+
+   switch (info->prop.gp.outputPrim) {
+   case MESA_PRIM_POINTS:
+      gs->hdr[3] = 0x01000000;
+      gs->hdr[0] |= 0xf0000000;
+      break;
+   case MESA_PRIM_LINE_STRIP:
+      gs->hdr[3] = 0x06000000;
+      gs->hdr[0] |= 0x10000000;
+      break;
+   case MESA_PRIM_TRIANGLE_STRIP:
+      gs->hdr[3] = 0x07000000;
+      gs->hdr[0] |= 0x10000000;
+      break;
+   default:
+      assert(0);
+      break;
+   }
+
+   gs->hdr[4] = CLAMP(info->prop.gp.maxVertices, 1, 1024);
+
+   return nvk_vtgp_gen_header(gs, info);
+}
+
+
 #define NVC0_INTERP_FLAT          (1 << 0)
 #define NVC0_INTERP_PERSPECTIVE   (2 << 0)
 #define NVC0_INTERP_LINEAR        (3 << 0)
@@ -757,6 +788,9 @@ nvk_compile_nir(struct nvk_physical_device *device, nir_shader *nir,
       ret = nvk_fs_gen_header(shader, &info_out);
       shader->fs.uses_sample_shading = nir->info.fs.uses_sample_shading;
       break;
+   case PIPE_SHADER_GEOMETRY:
+      ret = nvk_gs_gen_header(shader, &info_out);
+      break;
    case PIPE_SHADER_COMPUTE:
       break;
    default: