From 8fc8d34ea006d298a29032b140a363b0a3faddbb Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Thu, 26 Jan 2023 14:28:18 -0600 Subject: [PATCH] vkd3d-shader/spirv: Introduce an option to control whether point size is written. --- include/vkd3d_shader.h | 12 ++++++++++++ libs/vkd3d-shader/spirv.c | 22 ++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/include/vkd3d_shader.h b/include/vkd3d_shader.h index 7b9c0ff7..86ffb9d5 100644 --- a/include/vkd3d_shader.h +++ b/include/vkd3d_shader.h @@ -150,6 +150,18 @@ enum vkd3d_shader_compile_option_name VKD3D_SHADER_COMPILE_OPTION_API_VERSION = 0x00000004, /** \a value is a member of enum vkd3d_shader_compile_option_typed_uav. \since 1.5 */ VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV = 0x00000005, + /** + * If \a value is nonzero, write the point size for Vulkan tessellation and + * geometry shaders. This option should be enabled if and only if the + * shaderTessellationAndGeometryPointSize feature is enabled. The default + * value is nonzero, i.e. write the point size. + * + * This option is supported by vkd3d_shader_compile() for the SPIR-V target + * type and Vulkan targets; it should not be enabled otherwise. + * + * \since 1.6 + */ + VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE = 0x00000006, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), }; diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c index 417cdc92..f0cfee47 100644 --- a/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d-shader/spirv.c @@ -2285,6 +2285,7 @@ struct spirv_compiler struct vkd3d_shader_spec_constant *spec_constants; size_t spec_constants_size; enum vkd3d_shader_compile_option_formatting_flags formatting; + bool write_tess_geom_point_size; struct vkd3d_string_buffer_cache string_buffers; }; @@ -2351,6 +2352,7 @@ struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version * compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; + compiler->write_tess_geom_point_size = true; for (i = 0; i < compile_info->option_count; ++i) { @@ -2389,6 +2391,10 @@ struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version * else WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name); break; + + case VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE: + compiler->write_tess_geom_point_size = option->value; + break; } } @@ -6348,10 +6354,18 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) /* Set the point size. Point sprites are not supported in d3d10+, but * point primitives can still be used with e.g. stream output. Vulkan * requires the point size to always be explicitly defined when outputting - * points. */ - vkd3d_spirv_build_op_store(&compiler->spirv_builder, - spirv_compiler_emit_builtin_variable(compiler, &point_size, SpvStorageClassOutput, 0), - spirv_compiler_get_constant_float(compiler, 1.0f), SpvMemoryAccessMaskNone); + * points. + * + * If shaderTessellationAndGeometryPointSize is disabled, we must not write + * PointSize for tessellation and geometry shaders. In that case the point + * size defaults to 1.0. */ + if (spirv_compiler_is_opengl_target(compiler) || compiler->shader_type == VKD3D_SHADER_TYPE_VERTEX + || compiler->write_tess_geom_point_size) + { + vkd3d_spirv_build_op_store(&compiler->spirv_builder, + spirv_compiler_emit_builtin_variable(compiler, &point_size, SpvStorageClassOutput, 0), + spirv_compiler_get_constant_float(compiler, 1.0f), SpvMemoryAccessMaskNone); + } } static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compiler,