From: Józef Kucia Subject: [PATCH vkd3d 7/8] vkd3d-shader: Add support for OpenGL tessellation shaders. Message-Id: <20190214112234.3572-7-joseph.kucia@gmail.com> Date: Thu, 14 Feb 2019 12:22:33 +0100 From: Józef Kucia 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 --- 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