[PATCH vkd3d 7/8] vkd3d-shader: Add support for OpenGL tessellation shaders.

Józef Kucia joseph.kucia at gmail.com
Thu Feb 14 05:22:33 CST 2019


From: Józef Kucia <jkucia at codeweavers.com>

In DXBC tessellator parameters are specified in hull shaders. In OpenGL,
even in SPIR-V, tessellator parameters must be specified in the
tessellation evaluation shader.

Signed-off-by: Józef Kucia <jkucia at codeweavers.com>
---
 include/vkd3d_shader.h                   | 27 ++++++++++++++++
 libs/vkd3d-shader/spirv.c                | 41 +++++++++++++++++++-----
 libs/vkd3d-shader/vkd3d_shader_private.h | 17 ----------
 3 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h
index 679abfee4061..fef058cb4c97 100644
--- a/include/vkd3d_shader.h
+++ b/include/vkd3d_shader.h
@@ -33,6 +33,7 @@ enum vkd3d_shader_structure_type
     VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_ARGUMENTS,
     VKD3D_SHADER_STRUCTURE_TYPE_SCAN_INFO,
     VKD3D_SHADER_STRUCTURE_TYPE_TRANSFORM_FEEDBACK_INFO,
+    VKD3D_SHADER_STRUCTURE_TYPE_DOMAIN_SHADER_COMPILE_ARGUMENTS,
 
     VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
 };
@@ -195,6 +196,32 @@ struct vkd3d_shader_compile_arguments
     unsigned int output_swizzle_count;
 };
 
+enum vkd3d_tessellator_output_primitive
+{
+    VKD3D_TESSELLATOR_OUTPUT_POINT        = 1,
+    VKD3D_TESSELLATOR_OUTPUT_LINE         = 2,
+    VKD3D_TESSELLATOR_OUTPUT_TRIANGLE_CW  = 3,
+    VKD3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4,
+};
+
+enum vkd3d_tessellator_partitioning
+{
+    VKD3D_TESSELLATOR_PARTITIONING_INTEGER         = 1,
+    VKD3D_TESSELLATOR_PARTITIONING_POW2            = 2,
+    VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD  = 3,
+    VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4,
+};
+
+/* Extends vkd3d_shader_compile_arguments. */
+struct vkd3d_shader_domain_shader_compile_arguments
+{
+    enum vkd3d_shader_structure_type type;
+    const void *next;
+
+    enum vkd3d_tessellator_output_primitive output_primitive;
+    enum vkd3d_tessellator_output_primitive partitioning;
+};
+
 int vkd3d_shader_compile_dxbc(const struct vkd3d_shader_code *dxbc,
         struct vkd3d_shader_code *spirv, unsigned int compiler_options,
         const struct vkd3d_shader_interface_info *shader_interface_info,
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 97963e9a77d9..6ba169f6c6af 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -4856,6 +4856,9 @@ static void vkd3d_dxbc_compiler_emit_dcl_tessellator_domain(struct vkd3d_dxbc_co
     enum vkd3d_tessellator_domain domain = instruction->declaration.tessellator_domain;
     SpvExecutionMode mode;
 
+    if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && vkd3d_dxbc_compiler_is_opengl_target(compiler))
+        return;
+
     switch (domain)
     {
         case VKD3D_TESSELLATOR_DOMAIN_LINE:
@@ -4875,12 +4878,14 @@ static void vkd3d_dxbc_compiler_emit_dcl_tessellator_domain(struct vkd3d_dxbc_co
     vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0);
 }
 
-static void vkd3d_dxbc_compiler_emit_dcl_tessellator_output_primitive(struct vkd3d_dxbc_compiler *compiler,
-        const struct vkd3d_shader_instruction *instruction)
+static void vkd3d_dxbc_compiler_emit_tessellator_output_primitive(struct vkd3d_dxbc_compiler *compiler,
+        enum vkd3d_tessellator_output_primitive primitive)
 {
-    enum vkd3d_tessellator_output_primitive primitive = instruction->declaration.tessellator_output_primitive;
     SpvExecutionMode mode;
 
+    if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && vkd3d_dxbc_compiler_is_opengl_target(compiler))
+        return;
+
     switch (primitive)
     {
         case VKD3D_TESSELLATOR_OUTPUT_POINT:
@@ -4902,12 +4907,14 @@ static void vkd3d_dxbc_compiler_emit_dcl_tessellator_output_primitive(struct vkd
     vkd3d_dxbc_compiler_emit_execution_mode(compiler, mode, NULL, 0);
 }
 
-static void vkd3d_dxbc_compiler_emit_dcl_tessellator_partitioning(struct vkd3d_dxbc_compiler *compiler,
-        const struct vkd3d_shader_instruction *instruction)
+static void vkd3d_dxbc_compiler_emit_tessellator_partitioning(struct vkd3d_dxbc_compiler *compiler,
+        enum vkd3d_tessellator_partitioning partitioning)
 {
-    enum vkd3d_tessellator_partitioning partitioning = instruction->declaration.tessellator_partitioning;
     SpvExecutionMode mode;
 
+    if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL && vkd3d_dxbc_compiler_is_opengl_target(compiler))
+        return;
+
     switch (partitioning)
     {
         case VKD3D_TESSELLATOR_PARTITIONING_INTEGER:
@@ -7426,10 +7433,12 @@ int vkd3d_dxbc_compiler_handle_instruction(struct vkd3d_dxbc_compiler *compiler,
             vkd3d_dxbc_compiler_emit_dcl_tessellator_domain(compiler, instruction);
             break;
         case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE:
-            vkd3d_dxbc_compiler_emit_dcl_tessellator_output_primitive(compiler, instruction);
+            vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler,
+                    instruction->declaration.tessellator_output_primitive);
             break;
         case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING:
-            vkd3d_dxbc_compiler_emit_dcl_tessellator_partitioning(compiler, instruction);
+            vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler,
+                    instruction->declaration.tessellator_partitioning);
             break;
         case VKD3DSIH_DCL_THREAD_GROUP:
             vkd3d_dxbc_compiler_emit_dcl_thread_group(compiler, instruction);
@@ -7775,6 +7784,8 @@ static void vkd3d_dxbc_compiler_emit_shader_epilogue_function(struct vkd3d_dxbc_
 int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
         struct vkd3d_shader_code *spirv)
 {
+    const struct vkd3d_shader_compile_arguments *compile_args = compiler->compile_args;
+    const struct vkd3d_shader_domain_shader_compile_arguments *ds_args;
     struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
 
     vkd3d_spirv_build_op_function_end(builder);
@@ -7782,6 +7793,20 @@ int vkd3d_dxbc_compiler_generate_spirv(struct vkd3d_dxbc_compiler *compiler,
     if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL)
         vkd3d_dxbc_compiler_emit_hull_shader_main(compiler);
 
+    if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN)
+    {
+        if (compile_args && (ds_args = vkd3d_find_struct(compile_args->next, DOMAIN_SHADER_COMPILE_ARGUMENTS)))
+        {
+            vkd3d_dxbc_compiler_emit_tessellator_output_primitive(compiler, ds_args->output_primitive);
+            vkd3d_dxbc_compiler_emit_tessellator_partitioning(compiler, ds_args->partitioning);
+        }
+        else if (vkd3d_dxbc_compiler_is_opengl_target(compiler))
+        {
+            ERR("vkd3d_shader_domain_shader_compile_arguments are required for "
+                    "OpenGL tessellation evaluation shader.\n");
+        }
+    }
+
     if (compiler->epilogue_function_id)
         vkd3d_dxbc_compiler_emit_shader_epilogue_function(compiler);
 
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index ba5875cacaf4..40d46b3b86c1 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -464,23 +464,6 @@ enum vkd3d_tessellator_domain
     VKD3D_TESSELLATOR_DOMAIN_QUAD      = 3,
 };
 
-enum vkd3d_tessellator_output_primitive
-{
-    VKD3D_TESSELLATOR_OUTPUT_POINT        = 1,
-    VKD3D_TESSELLATOR_OUTPUT_LINE         = 2,
-    VKD3D_TESSELLATOR_OUTPUT_TRIANGLE_CW  = 3,
-    VKD3D_TESSELLATOR_OUTPUT_TRIANGLE_CCW = 4,
-};
-
-enum vkd3d_tessellator_partitioning
-{
-    VKD3D_TESSELLATOR_PARTITIONING_INTEGER         = 1,
-    VKD3D_TESSELLATOR_PARTITIONING_POW2            = 2,
-    VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_ODD  = 3,
-    VKD3D_TESSELLATOR_PARTITIONING_FRACTIONAL_EVEN = 4,
-};
-
-
 #define VKD3DSI_NONE                    0x0
 #define VKD3DSI_TEXLD_PROJECT           0x1
 #define VKD3DSI_INDEXED_DYNAMIC         0x4
-- 
2.19.2




More information about the wine-devel mailing list