From: Józef Kucia <jkucia(a)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(a)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