2024-07-17 17:07:39 -07:00
|
|
|
From c260bdc81c8b805b4ad1772f80c56a2dd9847e55 Mon Sep 17 00:00:00 2001
|
2024-07-14 17:04:33 -07:00
|
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
|
|
Date: Mon, 15 Jul 2024 10:03:30 +1000
|
|
|
|
Subject: [PATCH] Updated vkd3d to 5a53b739959db74e8dcce023a7d49356b9008e92.
|
|
|
|
|
|
|
|
---
|
|
|
|
libs/vkd3d/include/vkd3d_shader.h | 217 ++++++++++++++
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 2 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 11 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 12 +
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 2 +-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 280 +++++++++++++++++-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 99 ++++++-
|
|
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 46 ++-
|
|
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 8 +-
|
|
|
|
9 files changed, 649 insertions(+), 28 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
|
|
index d3afcc11b16..4acb622468a 100644
|
|
|
|
--- a/libs/vkd3d/include/vkd3d_shader.h
|
|
|
|
+++ b/libs/vkd3d/include/vkd3d_shader.h
|
|
|
|
@@ -105,6 +105,11 @@ enum vkd3d_shader_structure_type
|
|
|
|
* \since 1.10
|
|
|
|
*/
|
|
|
|
VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO,
|
|
|
|
+ /**
|
|
|
|
+ * The structure is a vkd3d_shader_parameter_info structure.
|
|
|
|
+ * \since 1.13
|
|
|
|
+ */
|
|
|
|
+ VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO,
|
|
|
|
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE),
|
|
|
|
};
|
|
|
|
@@ -453,44 +458,167 @@ enum vkd3d_shader_binding_flag
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_BINDING_FLAG),
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * The manner in which a parameter value is provided to the shader, used in
|
|
|
|
+ * struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
|
|
|
|
+ */
|
|
|
|
enum vkd3d_shader_parameter_type
|
|
|
|
{
|
|
|
|
VKD3D_SHADER_PARAMETER_TYPE_UNKNOWN,
|
|
|
|
+ /** The parameter value is embedded directly in the shader. */
|
|
|
|
VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT,
|
|
|
|
+ /**
|
|
|
|
+ * The parameter value is provided to the shader via a specialization
|
|
|
|
+ * constant. This value is only supported for the SPIR-V target type.
|
|
|
|
+ */
|
|
|
|
VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT,
|
|
|
|
+ /**
|
|
|
|
+ * The parameter value is provided to the shader as part of a uniform
|
|
|
|
+ * buffer.
|
|
|
|
+ *
|
|
|
|
+ * \since 1.13
|
|
|
|
+ */
|
|
|
|
+ VKD3D_SHADER_PARAMETER_TYPE_BUFFER,
|
|
|
|
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_TYPE),
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * The format of data provided to the shader, used in
|
|
|
|
+ * struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
|
|
|
|
+ */
|
|
|
|
enum vkd3d_shader_parameter_data_type
|
|
|
|
{
|
|
|
|
VKD3D_SHADER_PARAMETER_DATA_TYPE_UNKNOWN,
|
|
|
|
+ /** The parameter is provided as a 32-bit unsigned integer. */
|
|
|
|
VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32,
|
|
|
|
+ /** The parameter is provided as a 32-bit float. \since 1.13 */
|
|
|
|
+ VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32,
|
|
|
|
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_DATA_TYPE),
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Names a specific shader parameter, used in
|
|
|
|
+ * struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
|
|
|
|
+ */
|
|
|
|
enum vkd3d_shader_parameter_name
|
|
|
|
{
|
|
|
|
VKD3D_SHADER_PARAMETER_NAME_UNKNOWN,
|
|
|
|
+ /**
|
|
|
|
+ * The sample count of the framebuffer, as returned by the HLSL function
|
|
|
|
+ * GetRenderTargetSampleCount() or the GLSL builtin gl_NumSamples.
|
|
|
|
+ *
|
|
|
|
+ * This parameter should be specified when compiling to SPIR-V, which
|
|
|
|
+ * provides no builtin ability to query this information from the shader.
|
|
|
|
+ *
|
|
|
|
+ * The default value is 1.
|
|
|
|
+ *
|
|
|
|
+ * The data type for this parameter must be
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32.
|
|
|
|
+ */
|
|
|
|
VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT,
|
|
|
|
+ /**
|
|
|
|
+ * Alpha test comparison function. When this parameter is provided, if the
|
|
|
|
+ * alpha component of the pixel shader colour output at location 0 fails the
|
|
|
|
+ * test, as defined by this function and the reference value provided by
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, the fragment will be
|
|
|
|
+ * discarded.
|
|
|
|
+ *
|
|
|
|
+ * This parameter, along with VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF,
|
|
|
|
+ * can be used to implement fixed function alpha test, as present in
|
|
|
|
+ * Direct3D versions up to 9, if the target environment does not support
|
|
|
|
+ * alpha test as part of its own fixed-function API (as Vulkan and core
|
|
|
|
+ * OpenGL).
|
|
|
|
+ *
|
|
|
|
+ * The default value is VKD3D_SHADER_COMPARISON_FUNC_ALWAYS.
|
|
|
|
+ *
|
|
|
|
+ * The data type for this parameter must be
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32. The value specified must be
|
|
|
|
+ * a member of enum vkd3d_shader_comparison_func.
|
|
|
|
+ *
|
|
|
|
+ * Only VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT is supported in this
|
|
|
|
+ * version of vkd3d-shader.
|
|
|
|
+ *
|
|
|
|
+ * \since 1.13
|
|
|
|
+ */
|
|
|
|
+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC,
|
|
|
|
+ /**
|
|
|
|
+ * Alpha test reference value.
|
|
|
|
+ * See VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC for documentation of
|
|
|
|
+ * alpha test.
|
|
|
|
+ *
|
|
|
|
+ * The default value is zero.
|
|
|
|
+ *
|
|
|
|
+ * \since 1.13
|
|
|
|
+ */
|
|
|
|
+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF,
|
|
|
|
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME),
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * The value of an immediate constant parameter, used in
|
|
|
|
+ * struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
|
|
|
|
+ */
|
|
|
|
struct vkd3d_shader_parameter_immediate_constant
|
|
|
|
{
|
|
|
|
union
|
|
|
|
{
|
|
|
|
+ /**
|
|
|
|
+ * The value if the parameter's data type is
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32.
|
|
|
|
+ */
|
|
|
|
uint32_t u32;
|
|
|
|
+ /**
|
|
|
|
+ * The value if the parameter's data type is
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32.
|
|
|
|
+ *
|
|
|
|
+ * \since 1.13
|
|
|
|
+ */
|
|
|
|
+ float f32;
|
|
|
|
} u;
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * The linkage of a specialization constant parameter, used in
|
|
|
|
+ * struct vkd3d_shader_parameter and struct vkd3d_shader_parameter1.
|
|
|
|
+ */
|
|
|
|
struct vkd3d_shader_parameter_specialization_constant
|
|
|
|
{
|
|
|
|
+ /** The ID of the specialization constant. */
|
|
|
|
uint32_t id;
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * The linkage of a parameter specified through a uniform buffer, used in
|
|
|
|
+ * struct vkd3d_shader_parameter1.
|
|
|
|
+ */
|
|
|
|
+struct vkd3d_shader_parameter_buffer
|
|
|
|
+{
|
|
|
|
+ /**
|
|
|
|
+ * The set of the uniform buffer descriptor. If the target environment does
|
|
|
|
+ * not support descriptor sets, this value must be set to 0.
|
|
|
|
+ */
|
|
|
|
+ unsigned int set;
|
|
|
|
+ /** The binding index of the uniform buffer descriptor. */
|
|
|
|
+ unsigned int binding;
|
|
|
|
+ /** The byte offset of the parameter within the buffer. */
|
|
|
|
+ uint32_t offset;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * An individual shader parameter.
|
|
|
|
+ *
|
|
|
|
+ * This structure is an earlier version of struct vkd3d_shader_parameter1
|
|
|
|
+ * which supports fewer parameter types;
|
|
|
|
+ * refer to that structure for usage information.
|
|
|
|
+ *
|
|
|
|
+ * Only the following types may be used with this structure:
|
|
|
|
+ *
|
|
|
|
+ * - VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT
|
|
|
|
+ * - VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT
|
|
|
|
+ */
|
|
|
|
struct vkd3d_shader_parameter
|
|
|
|
{
|
|
|
|
enum vkd3d_shader_parameter_name name;
|
|
|
|
@@ -503,6 +631,56 @@ struct vkd3d_shader_parameter
|
|
|
|
} u;
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * An individual shader parameter.
|
|
|
|
+ *
|
|
|
|
+ * This structure is used in struct vkd3d_shader_parameter_info; see there for
|
|
|
|
+ * explanation of shader parameters.
|
|
|
|
+ *
|
|
|
|
+ * For example, to specify the rasterizer sample count to the shader via an
|
|
|
|
+ * unsigned integer specialization constant with ID 3,
|
|
|
|
+ * set the following members:
|
|
|
|
+ *
|
|
|
|
+ * - \a name = VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT
|
|
|
|
+ * - \a type = VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT
|
|
|
|
+ * - \a data_type = VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32
|
|
|
|
+ * - \a u.specialization_constant.id = 3
|
|
|
|
+ *
|
|
|
|
+ * This structure is an extended version of struct vkd3d_shader_parameter.
|
|
|
|
+ */
|
|
|
|
+struct vkd3d_shader_parameter1
|
|
|
|
+{
|
|
|
|
+ /** The builtin parameter to be mapped. */
|
|
|
|
+ enum vkd3d_shader_parameter_name name;
|
|
|
|
+ /** How the parameter will be provided to the shader. */
|
|
|
|
+ enum vkd3d_shader_parameter_type type;
|
|
|
|
+ /**
|
|
|
|
+ * The data type of the supplied parameter, which determines how it is to
|
|
|
|
+ * be interpreted.
|
|
|
|
+ */
|
|
|
|
+ enum vkd3d_shader_parameter_data_type data_type;
|
|
|
|
+ union
|
|
|
|
+ {
|
|
|
|
+ /**
|
|
|
|
+ * Additional information if \a type is
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT.
|
|
|
|
+ */
|
|
|
|
+ struct vkd3d_shader_parameter_immediate_constant immediate_constant;
|
|
|
|
+ /**
|
|
|
|
+ * Additional information if \a type is
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT.
|
|
|
|
+ */
|
|
|
|
+ struct vkd3d_shader_parameter_specialization_constant specialization_constant;
|
|
|
|
+ /**
|
|
|
|
+ * Additional information if \a type is
|
|
|
|
+ * VKD3D_SHADER_PARAMETER_TYPE_BUFFER.
|
|
|
|
+ */
|
|
|
|
+ struct vkd3d_shader_parameter_buffer buffer;
|
|
|
|
+ void *_pointer_pad;
|
|
|
|
+ uint32_t _pad[4];
|
|
|
|
+ } u;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
/**
|
|
|
|
* Symbolic register indices for mapping uniform constant register sets in
|
|
|
|
* legacy Direct3D bytecode to constant buffer views in the target environment.
|
|
|
|
@@ -1994,6 +2172,44 @@ struct vkd3d_shader_varying_map_info
|
|
|
|
unsigned int varying_count;
|
|
|
|
};
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * Interface information regarding a builtin shader parameter.
|
|
|
|
+ *
|
|
|
|
+ * Like compile options specified with struct vkd3d_shader_compile_option,
|
|
|
|
+ * parameters are used to specify certain values which are not part of the
|
|
|
|
+ * source shader bytecode but which need to be specified in the shader bytecode
|
|
|
|
+ * in the target format.
|
|
|
|
+ * Unlike struct vkd3d_shader_compile_option, however, this structure allows
|
|
|
|
+ * parameters to be specified in a variety of different ways, as described by
|
|
|
|
+ * enum vkd3d_shader_parameter_type.
|
|
|
|
+ *
|
|
|
|
+ * This structure is an extended version of struct vkd3d_shader_parameter as
|
|
|
|
+ * used in struct vkd3d_shader_spirv_target_info, which allows more parameter
|
|
|
|
+ * types to be used, and also allows specifying parameters when compiling
|
|
|
|
+ * shaders to target types other than SPIR-V. If this structure is chained
|
|
|
|
+ * along with vkd3d_shader_spirv_target_info, any parameters specified in the
|
|
|
|
+ * latter structure are ignored.
|
|
|
|
+ *
|
|
|
|
+ * This structure is passed to vkd3d_shader_compile() and extends
|
|
|
|
+ * vkd3d_shader_compile_info.
|
|
|
|
+ *
|
|
|
|
+ * This structure contains only input parameters.
|
|
|
|
+ *
|
|
|
|
+ * \since 1.13
|
|
|
|
+ */
|
|
|
|
+struct vkd3d_shader_parameter_info
|
|
|
|
+{
|
|
|
|
+ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_PARAMETER_INFO. */
|
|
|
|
+ enum vkd3d_shader_structure_type type;
|
|
|
|
+ /** Optional pointer to a structure containing further parameters. */
|
|
|
|
+ const void *next;
|
|
|
|
+
|
|
|
|
+ /** Pointer to an array of dynamic parameters for this shader instance. */
|
|
|
|
+ const struct vkd3d_shader_parameter1 *parameters;
|
|
|
|
+ /** Size, in elements, of \ref parameters. */
|
|
|
|
+ unsigned int parameter_count;
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
#ifdef LIBVKD3D_SHADER_SOURCE
|
|
|
|
# define VKD3D_SHADER_API VKD3D_EXPORT
|
|
|
|
#else
|
|
|
|
@@ -2077,6 +2293,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported
|
|
|
|
* - vkd3d_shader_descriptor_offset_info
|
|
|
|
* - vkd3d_shader_hlsl_source_info
|
|
|
|
* - vkd3d_shader_interface_info
|
|
|
|
+ * - vkd3d_shader_parameter_info
|
|
|
|
* - vkd3d_shader_preprocess_info
|
|
|
|
* - vkd3d_shader_scan_combined_resource_sampler_info
|
|
|
|
* - vkd3d_shader_scan_descriptor_info
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
|
|
index 4522d56c5c9..abfbd461b33 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
|
|
@@ -1272,7 +1272,7 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st
|
|
|
|
sm1->end = &code[token_count];
|
|
|
|
|
|
|
|
/* Estimate instruction count to avoid reallocation in most shaders. */
|
|
|
|
- if (!vsir_program_init(program, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
|
|
|
|
+ if (!vsir_program_init(program, compile_info, &version, code_size != ~(size_t)0 ? token_count / 4u + 4 : 16))
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
index 2176debc7d2..bf581928a9e 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
|
|
@@ -10206,12 +10206,13 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
-static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program, const char *source_name,
|
|
|
|
+static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_program *program,
|
|
|
|
+ const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
struct vkd3d_shader_message_context *message_context, struct dxbc_shader_desc *dxbc_desc)
|
|
|
|
{
|
|
|
|
size_t count, length, function_count, expected_function_count, byte_code_size = dxbc_desc->byte_code_size;
|
|
|
|
+ const struct vkd3d_shader_location location = {.source_name = compile_info->source_name};
|
|
|
|
struct shader_signature *patch_constant_signature, *output_signature, *input_signature;
|
|
|
|
- const struct vkd3d_shader_location location = {.source_name = source_name};
|
|
|
|
uint32_t version_token, dxil_version, token_count, magic;
|
|
|
|
const uint32_t *byte_code = dxbc_desc->byte_code;
|
|
|
|
unsigned int chunk_offset, chunk_size;
|
|
|
|
@@ -10302,9 +10303,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
|
|
|
|
|
|
|
|
/* Estimate instruction count to avoid reallocation in most shaders. */
|
|
|
|
count = max(token_count, 400) - 400;
|
|
|
|
- if (!vsir_program_init(program, &version, (count + (count >> 2)) / 2u + 10))
|
|
|
|
+ if (!vsir_program_init(program, compile_info, &version, (count + (count >> 2)) / 2u + 10))
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
- vkd3d_shader_parser_init(&sm6->p, program, message_context, source_name);
|
|
|
|
+ vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name);
|
|
|
|
sm6->ptr = &sm6->start[1];
|
|
|
|
sm6->bitpos = 2;
|
|
|
|
|
|
|
|
@@ -10565,7 +10566,7 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co
|
|
|
|
dxbc_desc.byte_code = byte_code;
|
|
|
|
}
|
|
|
|
|
|
|
|
- ret = sm6_parser_init(&sm6, program, compile_info->source_name, message_context, &dxbc_desc);
|
|
|
|
+ ret = sm6_parser_init(&sm6, program, compile_info, message_context, &dxbc_desc);
|
|
|
|
free_dxbc_shader_desc(&dxbc_desc);
|
|
|
|
vkd3d_free(byte_code);
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
|
|
index 7b058a65bc1..56736a65306 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
|
|
@@ -4065,6 +4065,17 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx,
|
|
|
|
return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, rad, loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
+static bool intrinsic_rcp(struct hlsl_ctx *ctx,
|
|
|
|
+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
|
|
+{
|
|
|
|
+ struct hlsl_ir_node *arg;
|
|
|
|
+
|
|
|
|
+ if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc)))
|
|
|
|
+ return false;
|
|
|
|
+
|
|
|
|
+ return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RCP, arg, loc);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static bool intrinsic_reflect(struct hlsl_ctx *ctx,
|
|
|
|
const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
|
|
{
|
|
|
|
@@ -4760,6 +4771,7 @@ intrinsic_functions[] =
|
|
|
|
{"normalize", 1, true, intrinsic_normalize},
|
|
|
|
{"pow", 2, true, intrinsic_pow},
|
|
|
|
{"radians", 1, true, intrinsic_radians},
|
|
|
|
+ {"rcp", 1, true, intrinsic_rcp},
|
|
|
|
{"reflect", 2, true, intrinsic_reflect},
|
|
|
|
{"refract", 3, true, intrinsic_refract},
|
|
|
|
{"round", 1, true, intrinsic_round},
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
|
|
index 7e4f168675e..02884df9d76 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
|
|
@@ -5691,7 +5691,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
|
|
|
|
version.major = ctx->profile->major_version;
|
|
|
|
version.minor = ctx->profile->minor_version;
|
|
|
|
version.type = ctx->profile->type;
|
|
|
|
- if (!vsir_program_init(program, &version, 0))
|
|
|
|
+ if (!vsir_program_init(program, NULL, &version, 0))
|
|
|
|
{
|
|
|
|
ctx->result = VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
return;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
index e5432cb35ce..be9e4219d6a 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
|
|
@@ -19,9 +19,73 @@
|
|
|
|
#include "vkd3d_shader_private.h"
|
|
|
|
#include "vkd3d_types.h"
|
|
|
|
|
|
|
|
-bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve)
|
|
|
|
+static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
+ unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters)
|
|
|
|
+{
|
|
|
|
+ const struct vkd3d_shader_spirv_target_info *spirv_info;
|
|
|
|
+ struct vkd3d_shader_parameter1 *parameters;
|
|
|
|
+
|
|
|
|
+ *ret_count = 0;
|
|
|
|
+ *ret_parameters = NULL;
|
|
|
|
+
|
|
|
|
+ if (!(spirv_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO)) || !spirv_info->parameter_count)
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+
|
|
|
|
+ if (!(parameters = vkd3d_calloc(spirv_info->parameter_count, sizeof(*parameters))))
|
|
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
+
|
|
|
|
+ for (unsigned int i = 0; i < spirv_info->parameter_count; ++i)
|
|
|
|
+ {
|
|
|
|
+ const struct vkd3d_shader_parameter *src = &spirv_info->parameters[i];
|
|
|
|
+ struct vkd3d_shader_parameter1 *dst = ¶meters[i];
|
|
|
|
+
|
|
|
|
+ dst->name = src->name;
|
|
|
|
+ dst->type = src->type;
|
|
|
|
+ dst->data_type = src->data_type;
|
|
|
|
+
|
|
|
|
+ if (src->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
|
|
|
|
+ {
|
|
|
|
+ dst->u.immediate_constant = src->u.immediate_constant;
|
|
|
|
+ }
|
|
|
|
+ else if (src->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT)
|
|
|
|
+ {
|
|
|
|
+ dst->u.specialization_constant = src->u.specialization_constant;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ ERR("Invalid parameter type %#x.\n", src->type);
|
|
|
|
+ return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ *ret_count = spirv_info->parameter_count;
|
|
|
|
+ *ret_parameters = parameters;
|
|
|
|
+
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
+ const struct vkd3d_shader_version *version, unsigned int reserve)
|
|
|
|
{
|
|
|
|
memset(program, 0, sizeof(*program));
|
|
|
|
+
|
|
|
|
+ if (compile_info)
|
|
|
|
+ {
|
|
|
|
+ const struct vkd3d_shader_parameter_info *parameter_info;
|
|
|
|
+
|
|
|
|
+ if ((parameter_info = vkd3d_find_struct(compile_info->next, PARAMETER_INFO)))
|
|
|
|
+ {
|
|
|
|
+ program->parameter_count = parameter_info->parameter_count;
|
|
|
|
+ program->parameters = parameter_info->parameters;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if (convert_parameter_info(compile_info, &program->parameter_count, &program->parameters) < 0)
|
|
|
|
+ return false;
|
|
|
|
+ program->free_parameters = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
program->shader_version = *version;
|
|
|
|
return shader_instruction_array_init(&program->instructions, reserve);
|
|
|
|
}
|
|
|
|
@@ -30,6 +94,8 @@ void vsir_program_cleanup(struct vsir_program *program)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
+ if (program->free_parameters)
|
|
|
|
+ vkd3d_free((void *)program->parameters);
|
|
|
|
for (i = 0; i < program->block_name_count; ++i)
|
|
|
|
vkd3d_free((void *)program->block_names[i]);
|
|
|
|
vkd3d_free(program->block_names);
|
|
|
|
@@ -666,6 +732,12 @@ static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigne
|
|
|
|
dst->write_mask = VKD3DSP_WRITEMASK_0;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx)
|
|
|
|
+{
|
|
|
|
+ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1);
|
|
|
|
+ src->reg.idx[0].offset = idx;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx)
|
|
|
|
{
|
|
|
|
vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
|
|
|
|
@@ -678,6 +750,12 @@ static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32
|
|
|
|
src->reg.u.immconst_u32[0] = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type)
|
|
|
|
+{
|
|
|
|
+ vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1);
|
|
|
|
+ src->reg.idx[0].offset = idx;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
|
|
|
|
enum vkd3d_shader_opcode opcode)
|
|
|
|
{
|
|
|
|
@@ -5282,6 +5360,203 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru
|
|
|
|
return VKD3D_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
+static bool find_colour_signature_idx(const struct shader_signature *signature, uint32_t *index)
|
|
|
|
+{
|
|
|
|
+ for (unsigned int i = 0; i < signature->element_count; ++i)
|
|
|
|
+ {
|
|
|
|
+ if (signature->elements[i].sysval_semantic == VKD3D_SHADER_SV_TARGET
|
|
|
|
+ && !signature->elements[i].register_index)
|
|
|
|
+ {
|
|
|
|
+ *index = i;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program,
|
|
|
|
+ const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func,
|
|
|
|
+ const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx, uint32_t colour_temp, size_t *ret_pos)
|
|
|
|
+{
|
|
|
|
+ struct vkd3d_shader_instruction_array *instructions = &program->instructions;
|
|
|
|
+ size_t pos = ret - instructions->elements;
|
|
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
|
|
+
|
|
|
|
+ static const struct
|
|
|
|
+ {
|
|
|
|
+ enum vkd3d_shader_opcode float_opcode;
|
|
|
|
+ enum vkd3d_shader_opcode uint_opcode;
|
|
|
|
+ bool swap;
|
|
|
|
+ }
|
|
|
|
+ opcodes[] =
|
|
|
|
+ {
|
|
|
|
+ [VKD3D_SHADER_COMPARISON_FUNC_EQUAL] = {VKD3DSIH_EQO, VKD3DSIH_IEQ},
|
|
|
|
+ [VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL] = {VKD3DSIH_NEO, VKD3DSIH_INE},
|
|
|
|
+ [VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE},
|
|
|
|
+ [VKD3D_SHADER_COMPARISON_FUNC_LESS] = {VKD3DSIH_LTO, VKD3DSIH_ULT},
|
|
|
|
+ [VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE, true},
|
|
|
|
+ [VKD3D_SHADER_COMPARISON_FUNC_GREATER] = {VKD3DSIH_LTO, VKD3DSIH_ULT, true},
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER)
|
|
|
|
+ {
|
|
|
|
+ if (!shader_instruction_array_insert_at(&program->instructions, pos, 1))
|
|
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
+ ins = &program->instructions.elements[pos];
|
|
|
|
+
|
|
|
|
+ vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_DISCARD, 0, 1);
|
|
|
|
+ ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
+ src_param_init_const_uint(&ins->src[0], 0);
|
|
|
|
+
|
|
|
|
+ *ret_pos = pos + 1;
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!shader_instruction_array_insert_at(&program->instructions, pos, 3))
|
|
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
+
|
|
|
|
+ ins = &program->instructions.elements[pos];
|
|
|
|
+
|
|
|
|
+ switch (ref->data_type)
|
|
|
|
+ {
|
|
|
|
+ case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32:
|
|
|
|
+ vsir_instruction_init_with_params(program, ins, &ret->location, opcodes[compare_func].float_opcode, 1, 2);
|
|
|
|
+ src_param_init_temp_float(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp);
|
|
|
|
+ src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1],
|
|
|
|
+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_FLOAT);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32:
|
|
|
|
+ vsir_instruction_init_with_params(program, ins, &ret->location, opcodes[compare_func].uint_opcode, 1, 2);
|
|
|
|
+ src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp);
|
|
|
|
+ src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1],
|
|
|
|
+ VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_UINT);
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ FIXME("Unhandled parameter data type %#x.\n", ref->data_type);
|
|
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ dst_param_init_ssa_bool(&ins->dst[0], program->ssa_count);
|
|
|
|
+ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
|
|
|
|
+ ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
|
|
+ ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
|
|
|
|
+
|
|
|
|
+ ++ins;
|
|
|
|
+ vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_DISCARD, 0, 1);
|
|
|
|
+ ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z;
|
|
|
|
+ src_param_init_ssa_bool(&ins->src[0], program->ssa_count);
|
|
|
|
+
|
|
|
|
+ ++program->ssa_count;
|
|
|
|
+
|
|
|
|
+ ++ins;
|
|
|
|
+ vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_MOV, 1, 1);
|
|
|
|
+ vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1);
|
|
|
|
+ ins->dst[0].reg.idx[0].offset = colour_signature_idx;
|
|
|
|
+ ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
|
|
+ ins->dst[0].write_mask = program->output_signature.elements[colour_signature_idx].mask;
|
|
|
|
+ src_param_init_temp_float(&ins->src[0], colour_temp);
|
|
|
|
+ ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4;
|
|
|
|
+ ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
|
|
|
|
+
|
|
|
|
+ *ret_pos = pos + 3;
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *program,
|
|
|
|
+ struct vkd3d_shader_message_context *message_context)
|
|
|
|
+{
|
|
|
|
+ const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL;
|
|
|
|
+ static const struct vkd3d_shader_location no_loc;
|
|
|
|
+ enum vkd3d_shader_comparison_func compare_func;
|
|
|
|
+ uint32_t colour_signature_idx, colour_temp;
|
|
|
|
+ struct vkd3d_shader_instruction *ins;
|
|
|
|
+ size_t new_pos;
|
|
|
|
+ int ret;
|
|
|
|
+
|
|
|
|
+ if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+
|
|
|
|
+ if (!find_colour_signature_idx(&program->output_signature, &colour_signature_idx)
|
|
|
|
+ || !(program->output_signature.elements[colour_signature_idx].mask & VKD3DSP_WRITEMASK_3))
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+
|
|
|
|
+ for (unsigned int i = 0; i < program->parameter_count; ++i)
|
|
|
|
+ {
|
|
|
|
+ const struct vkd3d_shader_parameter1 *parameter = &program->parameters[i];
|
|
|
|
+
|
|
|
|
+ if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_FUNC)
|
|
|
|
+ func = parameter;
|
|
|
|
+ else if (parameter->name == VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF)
|
|
|
|
+ ref = parameter;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!func || !ref)
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+
|
|
|
|
+ if (func->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
|
|
|
|
+ {
|
|
|
|
+ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
|
|
|
|
+ "Unsupported alpha test function parameter type %#x.\n", func->type);
|
|
|
|
+ return VKD3D_ERROR_NOT_IMPLEMENTED;
|
|
|
|
+ }
|
|
|
|
+ if (func->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32)
|
|
|
|
+ {
|
|
|
|
+ vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE,
|
|
|
|
+ "Invalid alpha test function parameter data type %#x.\n", func->data_type);
|
|
|
|
+ return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
|
|
+ }
|
|
|
|
+ compare_func = func->u.immediate_constant.u.u32;
|
|
|
|
+
|
|
|
|
+ if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_ALWAYS)
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+
|
|
|
|
+ /* We're going to be reading from the output, so we need to go
|
|
|
|
+ * through the whole shader and convert it to a temp. */
|
|
|
|
+
|
|
|
|
+ if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER)
|
|
|
|
+ colour_temp = program->temp_count++;
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < program->instructions.count; ++i)
|
|
|
|
+ {
|
|
|
|
+ ins = &program->instructions.elements[i];
|
|
|
|
+
|
|
|
|
+ if (vsir_instruction_is_dcl(ins))
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ if (ins->opcode == VKD3DSIH_RET)
|
|
|
|
+ {
|
|
|
|
+ if ((ret = insert_alpha_test_before_ret(program, ins, compare_func,
|
|
|
|
+ ref, colour_signature_idx, colour_temp, &new_pos)) < 0)
|
|
|
|
+ return ret;
|
|
|
|
+ i = new_pos;
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* No need to convert it if the comparison func is NEVER; we don't
|
|
|
|
+ * read from the output in that case. */
|
|
|
|
+ if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ for (size_t j = 0; j < ins->dst_count; ++j)
|
|
|
|
+ {
|
|
|
|
+ struct vkd3d_shader_dst_param *dst = &ins->dst[j];
|
|
|
|
+
|
|
|
|
+ /* Note we run after I/O normalization. */
|
|
|
|
+ if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx)
|
|
|
|
+ {
|
|
|
|
+ dst->reg.type = VKD3DSPR_TEMP;
|
|
|
|
+ dst->reg.idx[0].offset = colour_temp;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return VKD3D_OK;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
struct validation_context
|
|
|
|
{
|
|
|
|
struct vkd3d_shader_message_context *message_context;
|
|
|
|
@@ -6274,6 +6549,9 @@ enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
+ if ((result = vsir_program_insert_alpha_test(program, message_context)) < 0)
|
|
|
|
+ return result;
|
|
|
|
+
|
|
|
|
if (TRACE_ON())
|
|
|
|
vkd3d_shader_trace(program);
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
index 524fb8e9b1f..72a6f1e60dc 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
|
|
@@ -2418,6 +2418,13 @@ struct spirv_compiler
|
|
|
|
uint32_t *descriptor_offset_ids;
|
|
|
|
struct vkd3d_push_constant_buffer_binding *push_constants;
|
|
|
|
const struct vkd3d_shader_spirv_target_info *spirv_target_info;
|
|
|
|
+ const struct vkd3d_shader_parameter1 *parameters;
|
|
|
|
+ unsigned int parameter_count;
|
|
|
|
+
|
|
|
|
+ struct
|
|
|
|
+ {
|
|
|
|
+ uint32_t buffer_id;
|
|
|
|
+ } *spirv_parameter_info;
|
|
|
|
|
|
|
|
bool prolog_emitted;
|
|
|
|
struct shader_signature input_signature;
|
|
|
|
@@ -3290,16 +3297,15 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil
|
|
|
|
return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static const struct vkd3d_shader_parameter *spirv_compiler_get_shader_parameter(
|
|
|
|
+static const struct vkd3d_shader_parameter1 *spirv_compiler_get_shader_parameter(
|
|
|
|
struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name)
|
|
|
|
{
|
|
|
|
- const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
- for (i = 0; info && i < info->parameter_count; ++i)
|
|
|
|
+ for (i = 0; i < compiler->parameter_count; ++i)
|
|
|
|
{
|
|
|
|
- if (info->parameters[i].name == name)
|
|
|
|
- return &info->parameters[i];
|
|
|
|
+ if (compiler->parameters[i].name == name)
|
|
|
|
+ return &compiler->parameters[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
@@ -3314,6 +3320,7 @@ static const struct vkd3d_spec_constant_info
|
|
|
|
vkd3d_shader_parameters[] =
|
|
|
|
{
|
|
|
|
{VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, 1, "sample_count"},
|
|
|
|
+ {VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, 0, "alpha_test_ref"},
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct vkd3d_spec_constant_info *get_spec_constant_info(enum vkd3d_shader_parameter_name name)
|
|
|
|
@@ -3352,7 +3359,7 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compiler,
|
|
|
|
- enum vkd3d_shader_parameter_name name, uint32_t spec_id)
|
|
|
|
+ enum vkd3d_shader_parameter_name name, uint32_t spec_id, enum vkd3d_data_type type)
|
|
|
|
{
|
|
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
|
|
const struct vkd3d_spec_constant_info *info;
|
|
|
|
@@ -3361,7 +3368,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile
|
|
|
|
info = get_spec_constant_info(name);
|
|
|
|
default_value = info ? info->default_value : 0;
|
|
|
|
|
|
|
|
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
+ type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1);
|
|
|
|
id = vkd3d_spirv_build_op_spec_constant(builder, type_id, default_value);
|
|
|
|
vkd3d_spirv_build_op_decorate1(builder, id, SpvDecorationSpecId, spec_id);
|
|
|
|
|
|
|
|
@@ -3380,7 +3387,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler,
|
|
|
|
- enum vkd3d_shader_parameter_name name, uint32_t spec_id)
|
|
|
|
+ enum vkd3d_shader_parameter_name name, uint32_t spec_id, enum vkd3d_data_type type)
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
@@ -3390,13 +3397,29 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler
|
|
|
|
return compiler->spec_constants[i].id;
|
|
|
|
}
|
|
|
|
|
|
|
|
- return spirv_compiler_emit_spec_constant(compiler, name, spec_id);
|
|
|
|
+ return spirv_compiler_emit_spec_constant(compiler, name, spec_id, type);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compiler,
|
|
|
|
+ const struct vkd3d_shader_parameter1 *parameter, enum vkd3d_data_type type)
|
|
|
|
+{
|
|
|
|
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
|
|
+ unsigned int index = parameter - compiler->parameters;
|
|
|
|
+ uint32_t type_id, ptr_id, ptr_type_id;
|
|
|
|
+
|
|
|
|
+ type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1);
|
|
|
|
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id);
|
|
|
|
+ ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id,
|
|
|
|
+ compiler->spirv_parameter_info[index].buffer_id,
|
|
|
|
+ spirv_compiler_get_constant_uint(compiler, 0));
|
|
|
|
+ return vkd3d_spirv_build_op_load(builder, type_id, ptr_id, SpvMemoryAccessMaskNone);
|
|
|
|
}
|
|
|
|
|
|
|
|
-static uint32_t spirv_compiler_emit_uint_shader_parameter(struct spirv_compiler *compiler,
|
|
|
|
+static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *compiler,
|
|
|
|
enum vkd3d_shader_parameter_name name)
|
|
|
|
{
|
|
|
|
- const struct vkd3d_shader_parameter *parameter;
|
|
|
|
+ const struct vkd3d_shader_parameter1 *parameter;
|
|
|
|
+ enum vkd3d_data_type type = VKD3D_DATA_UINT;
|
|
|
|
|
|
|
|
if (!(parameter = spirv_compiler_get_shader_parameter(compiler, name)))
|
|
|
|
{
|
|
|
|
@@ -3405,15 +3428,28 @@ static uint32_t spirv_compiler_emit_uint_shader_parameter(struct spirv_compiler
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT)
|
|
|
|
- return spirv_compiler_get_constant_uint(compiler, parameter->u.immediate_constant.u.u32);
|
|
|
|
+ {
|
|
|
|
+ if (parameter->data_type == VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32)
|
|
|
|
+ return spirv_compiler_get_constant_float(compiler, parameter->u.immediate_constant.u.f32);
|
|
|
|
+ else
|
|
|
|
+ return spirv_compiler_get_constant_uint(compiler, parameter->u.immediate_constant.u.u32);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (parameter->data_type == VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32)
|
|
|
|
+ type = VKD3D_DATA_FLOAT;
|
|
|
|
+ else
|
|
|
|
+ type = VKD3D_DATA_UINT;
|
|
|
|
+
|
|
|
|
if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_SPECIALIZATION_CONSTANT)
|
|
|
|
- return spirv_compiler_get_spec_constant(compiler, name, parameter->u.specialization_constant.id);
|
|
|
|
+ return spirv_compiler_get_spec_constant(compiler, name, parameter->u.specialization_constant.id, type);
|
|
|
|
+ if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_BUFFER)
|
|
|
|
+ return spirv_compiler_get_buffer_parameter(compiler, parameter, type);
|
|
|
|
|
|
|
|
FIXME("Unhandled parameter type %#x.\n", parameter->type);
|
|
|
|
|
|
|
|
default_parameter:
|
|
|
|
return spirv_compiler_get_spec_constant(compiler,
|
|
|
|
- name, spirv_compiler_alloc_spec_constant_id(compiler));
|
|
|
|
+ name, spirv_compiler_alloc_spec_constant_id(compiler), type);
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *compiler,
|
|
|
|
@@ -4188,6 +4224,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
|
|
return spirv_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask);
|
|
|
|
else if (reg->type == VKD3DSPR_UNDEF)
|
|
|
|
return spirv_compiler_emit_load_undef(compiler, reg, write_mask);
|
|
|
|
+ else if (reg->type == VKD3DSPR_PARAMETER)
|
|
|
|
+ return spirv_compiler_emit_shader_parameter(compiler, reg->idx[0].offset);
|
|
|
|
|
|
|
|
component_count = vsir_write_mask_component_count(write_mask);
|
|
|
|
component_type = vkd3d_component_type_from_data_type(reg->data_type);
|
|
|
|
@@ -8129,6 +8167,8 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler,
|
|
|
|
if (src->reg.data_type != VKD3D_DATA_BOOL)
|
|
|
|
condition_id = spirv_compiler_emit_int_to_bool(compiler,
|
|
|
|
instruction->flags, src->reg.data_type, 1, condition_id);
|
|
|
|
+ else if (instruction->flags & VKD3D_SHADER_CONDITIONAL_OP_Z)
|
|
|
|
+ condition_id = vkd3d_spirv_build_op_logical_not(builder, vkd3d_spirv_get_op_type_bool(builder), condition_id);
|
|
|
|
void_id = vkd3d_spirv_get_op_type_void(builder);
|
|
|
|
vkd3d_spirv_build_op_function_call(builder, void_id, spirv_compiler_get_discard_function_id(compiler),
|
|
|
|
&condition_id, 1);
|
|
|
|
@@ -9525,7 +9565,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co
|
|
|
|
|
|
|
|
if (src->reg.type == VKD3DSPR_RASTERIZER)
|
|
|
|
{
|
|
|
|
- val_id = spirv_compiler_emit_uint_shader_parameter(compiler,
|
|
|
|
+ val_id = spirv_compiler_emit_shader_parameter(compiler,
|
|
|
|
VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
@@ -10570,6 +10610,35 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct
|
|
|
|
|
|
|
|
spirv_compiler_emit_descriptor_declarations(compiler);
|
|
|
|
|
|
|
|
+ compiler->parameter_count = program->parameter_count;
|
|
|
|
+ compiler->parameters = program->parameters;
|
|
|
|
+ compiler->spirv_parameter_info = vkd3d_calloc(compiler->parameter_count, sizeof(*compiler->spirv_parameter_info));
|
|
|
|
+ for (i = 0; i < compiler->parameter_count; ++i)
|
|
|
|
+ {
|
|
|
|
+ const struct vkd3d_shader_parameter1 *parameter = &compiler->parameters[i];
|
|
|
|
+
|
|
|
|
+ if (parameter->type == VKD3D_SHADER_PARAMETER_TYPE_BUFFER)
|
|
|
|
+ {
|
|
|
|
+ uint32_t type_id, struct_id, ptr_type_id, var_id;
|
|
|
|
+
|
|
|
|
+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1);
|
|
|
|
+
|
|
|
|
+ struct_id = vkd3d_spirv_build_op_type_struct(builder, &type_id, 1);
|
|
|
|
+ vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBlock, NULL, 0);
|
|
|
|
+ vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0,
|
|
|
|
+ SpvDecorationOffset, parameter->u.buffer.offset);
|
|
|
|
+
|
|
|
|
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, struct_id);
|
|
|
|
+ var_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
|
|
|
|
+ ptr_type_id, SpvStorageClassUniform, 0);
|
|
|
|
+
|
|
|
|
+ vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationDescriptorSet, parameter->u.buffer.set);
|
|
|
|
+ vkd3d_spirv_build_op_decorate1(builder, var_id, SpvDecorationBinding, parameter->u.buffer.binding);
|
|
|
|
+
|
|
|
|
+ compiler->spirv_parameter_info[i].buffer_id = var_id;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count))
|
|
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
index a7c37215e5e..3a9a402e8e2 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
|
|
@@ -2493,7 +2493,7 @@ fail:
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_program *program,
|
|
|
|
- const uint32_t *byte_code, size_t byte_code_size, const char *source_name,
|
|
|
|
+ const uint32_t *byte_code, size_t byte_code_size, const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
struct vkd3d_shader_message_context *message_context)
|
|
|
|
{
|
|
|
|
struct vkd3d_shader_version version;
|
|
|
|
@@ -2552,9 +2552,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro
|
|
|
|
version.minor = VKD3D_SM4_VERSION_MINOR(version_token);
|
|
|
|
|
|
|
|
/* Estimate instruction count to avoid reallocation in most shaders. */
|
|
|
|
- if (!vsir_program_init(program, &version, token_count / 7u + 20))
|
|
|
|
+ if (!vsir_program_init(program, compile_info, &version, token_count / 7u + 20))
|
|
|
|
return false;
|
|
|
|
- vkd3d_shader_parser_init(&sm4->p, program, message_context, source_name);
|
|
|
|
+ vkd3d_shader_parser_init(&sm4->p, program, message_context, compile_info->source_name);
|
|
|
|
sm4->ptr = sm4->start;
|
|
|
|
|
|
|
|
init_sm4_lookup_tables(&sm4->lookup);
|
|
|
|
@@ -2651,7 +2651,7 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!shader_sm4_init(&sm4, program, dxbc_desc.byte_code, dxbc_desc.byte_code_size,
|
|
|
|
- compile_info->source_name, message_context))
|
|
|
|
+ compile_info, message_context))
|
|
|
|
{
|
|
|
|
WARN("Failed to initialise shader parser.\n");
|
|
|
|
free_dxbc_shader_desc(&dxbc_desc);
|
|
|
|
@@ -5189,6 +5189,44 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
+ case HLSL_OP1_RCP:
|
|
|
|
+ switch (dst_type->e.numeric.type)
|
|
|
|
+ {
|
|
|
|
+ case HLSL_TYPE_FLOAT:
|
|
|
|
+ /* SM5 comes with a RCP opcode */
|
|
|
|
+ if (tpf->ctx->profile->major_version >= 5)
|
|
|
|
+ {
|
|
|
|
+ write_sm4_unary_op(tpf, VKD3D_SM5_OP_RCP, &expr->node, arg1, 0);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ /* For SM4, implement as DIV dst, 1.0, src */
|
|
|
|
+ struct sm4_instruction instr;
|
|
|
|
+ struct hlsl_constant_value one;
|
|
|
|
+
|
|
|
|
+ assert(type_is_float(dst_type));
|
|
|
|
+
|
|
|
|
+ memset(&instr, 0, sizeof(instr));
|
|
|
|
+ instr.opcode = VKD3D_SM4_OP_DIV;
|
|
|
|
+
|
|
|
|
+ sm4_dst_from_node(&instr.dsts[0], &expr->node);
|
|
|
|
+ instr.dst_count = 1;
|
|
|
|
+
|
|
|
|
+ for (unsigned int i = 0; i < 4; i++)
|
|
|
|
+ one.u[i].f = 1.0f;
|
|
|
|
+ sm4_src_from_constant_value(&instr.srcs[0], &one, dst_type->dimx, instr.dsts[0].write_mask);
|
|
|
|
+ sm4_src_from_node(tpf, &instr.srcs[1], arg1, instr.dsts[0].write_mask);
|
|
|
|
+ instr.src_count = 2;
|
|
|
|
+
|
|
|
|
+ write_sm4_instruction(tpf, &instr);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ default:
|
|
|
|
+ hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s rcp expression.", dst_type_string->buffer);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
case HLSL_OP1_REINTERPRET:
|
|
|
|
write_sm4_unary_op(tpf, VKD3D_SM4_OP_MOV, &expr->node, arg1, 0);
|
|
|
|
break;
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
index 96e613669a6..bf9759ebbbf 100644
|
|
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
|
|
@@ -619,6 +619,7 @@ enum vkd3d_shader_register_type
|
|
|
|
VKD3DSPR_SSA,
|
|
|
|
VKD3DSPR_WAVELANECOUNT,
|
|
|
|
VKD3DSPR_WAVELANEINDEX,
|
|
|
|
+ VKD3DSPR_PARAMETER,
|
|
|
|
|
|
|
|
VKD3DSPR_COUNT,
|
|
|
|
|
|
|
|
@@ -1362,6 +1363,10 @@ struct vsir_program
|
|
|
|
struct shader_signature output_signature;
|
|
|
|
struct shader_signature patch_constant_signature;
|
|
|
|
|
|
|
|
+ unsigned int parameter_count;
|
|
|
|
+ const struct vkd3d_shader_parameter1 *parameters;
|
|
|
|
+ bool free_parameters;
|
|
|
|
+
|
|
|
|
unsigned int input_control_point_count, output_control_point_count;
|
|
|
|
unsigned int flat_constant_count[3];
|
|
|
|
unsigned int block_count;
|
|
|
|
@@ -1377,7 +1382,8 @@ void vsir_program_cleanup(struct vsir_program *program);
|
|
|
|
int vsir_program_compile(struct vsir_program *program, uint64_t config_flags,
|
|
|
|
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out,
|
|
|
|
struct vkd3d_shader_message_context *message_context);
|
|
|
|
-bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve);
|
|
|
|
+bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info,
|
|
|
|
+ const struct vkd3d_shader_version *version, unsigned int reserve);
|
|
|
|
enum vkd3d_result vsir_program_normalise(struct vsir_program *program, uint64_t config_flags,
|
|
|
|
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context);
|
|
|
|
enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t config_flags,
|
|
|
|
--
|
|
|
|
2.43.0
|
|
|
|
|