zink: set up ntv init for tess shaders
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Fri, 18 Dec 2020 02:24:28 +0000 (21:24 -0500)
committerMarge Bot <eric+marge@anholt.net>
Tue, 22 Dec 2020 13:46:38 +0000 (13:46 +0000)
Reviewed-by: Erik Faye-Lund <kusmabite@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8152>

src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c

index 3e99aba..6a1b530 100644 (file)
@@ -2590,6 +2590,9 @@ nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info,
    case MESA_SHADER_TESS_CTRL:
    case MESA_SHADER_TESS_EVAL:
       spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellation);
+      /* TODO: check features for this */
+      if (s->info.outputs_written & BITFIELD64_BIT(VARYING_SLOT_PSIZ))
+         spirv_builder_emit_cap(&ctx.builder, SpvCapabilityTessellationPointSize);
       break;
 
    case MESA_SHADER_GEOMETRY:
@@ -2630,8 +2633,16 @@ nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info,
    ctx.GLSL_std_450 = spirv_builder_import(&ctx.builder, "GLSL.std.450");
    spirv_builder_emit_source(&ctx.builder, SpvSourceLanguageGLSL, 450);
 
-   spirv_builder_emit_mem_model(&ctx.builder, SpvAddressingModelLogical,
-                                SpvMemoryModelGLSL450);
+   if (s->info.stage == MESA_SHADER_TESS_CTRL) {
+      /* this is required for correct barrier and io semantics */
+      spirv_builder_emit_extension(&ctx.builder, "SPV_KHR_vulkan_memory_model");
+      spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModel);
+      spirv_builder_emit_cap(&ctx.builder, SpvCapabilityVulkanMemoryModelDeviceScope);
+      spirv_builder_emit_mem_model(&ctx.builder, SpvAddressingModelLogical,
+                                   SpvMemoryModelVulkan);
+   } else
+      spirv_builder_emit_mem_model(&ctx.builder, SpvAddressingModelLogical,
+                                   SpvMemoryModelGLSL450);
 
    SpvExecutionModel exec_model;
    switch (s->info.stage) {
@@ -2693,6 +2704,43 @@ nir_to_spirv(struct nir_shader *s, const struct zink_so_info *so_info,
          spirv_builder_emit_exec_mode(&ctx.builder, entry_point,
                                       SpvExecutionModeDepthReplacing);
       break;
+   case MESA_SHADER_TESS_CTRL:
+      spirv_builder_emit_exec_mode_literal(&ctx.builder, entry_point, SpvExecutionModeOutputVertices, s->info.tess.tcs_vertices_out);
+      break;
+   case MESA_SHADER_TESS_EVAL:
+      switch (s->info.tess.primitive_mode) {
+      case GL_TRIANGLES:
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeTriangles);
+         break;
+      case GL_QUADS:
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeQuads);
+         break;
+      case GL_ISOLINES:
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeIsolines);
+         break;
+      default:
+         unreachable("unknown tess prim type!");
+      }
+      if (s->info.tess.ccw)
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeVertexOrderCcw);
+      else
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeVertexOrderCw);
+      switch (s->info.tess.spacing) {
+      case TESS_SPACING_EQUAL:
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSpacingEqual);
+         break;
+      case TESS_SPACING_FRACTIONAL_ODD:
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSpacingFractionalOdd);
+         break;
+      case TESS_SPACING_FRACTIONAL_EVEN:
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModeSpacingFractionalEven);
+         break;
+      default:
+         unreachable("unknown tess spacing!");
+      }
+      if (s->info.tess.point_mode)
+         spirv_builder_emit_exec_mode(&ctx.builder, entry_point, SpvExecutionModePointMode);
+      break;
    case MESA_SHADER_GEOMETRY:
       spirv_builder_emit_exec_mode(&ctx.builder, entry_point, get_input_prim_type_mode(s->info.gs.input_primitive));
       spirv_builder_emit_exec_mode(&ctx.builder, entry_point, get_output_prim_type_mode(s->info.gs.output_primitive));