wine-staging/patches/vkd3d-latest/0002-Updated-vkd3d-to-7b4a1fdfbc192cfd02ffb6cf18c0a86b2f6.patch

1025 lines
40 KiB
Diff
Raw Normal View History

2024-05-12 16:30:19 -07:00
From ea3477f55df517065cc716c27e2df7ea68f6760e Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Tue, 23 Apr 2024 08:01:19 +1000
Subject: [PATCH] Updated vkd3d to 7b4a1fdfbc192cfd02ffb6cf18c0a86b2f6eaeb4.
---
libs/vkd3d/include/private/vkd3d_common.h | 70 ++++++
libs/vkd3d/include/vkd3d.h | 115 +++++++++-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 205 ++++++++++++++++--
libs/vkd3d/libs/vkd3d-shader/glsl.c | 1 +
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 2 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 72 ++++--
libs/vkd3d/libs/vkd3d-shader/ir.c | 14 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 5 +
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 84 -------
9 files changed, 430 insertions(+), 138 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
index f9df47d339c..1da73bcfb2e 100644
--- a/libs/vkd3d/include/private/vkd3d_common.h
+++ b/libs/vkd3d/include/private/vkd3d_common.h
@@ -492,6 +492,76 @@ static inline void vkd3d_mutex_destroy(struct vkd3d_mutex *lock)
#endif
}
+struct vkd3d_cond
+{
+#ifdef _WIN32
+ CONDITION_VARIABLE cond;
+#else
+ pthread_cond_t cond;
+#endif
+};
+
+static inline void vkd3d_cond_init(struct vkd3d_cond *cond)
+{
+#ifdef _WIN32
+ InitializeConditionVariable(&cond->cond);
+#else
+ int ret;
+
+ if ((ret = pthread_cond_init(&cond->cond, NULL)))
+ ERR("Failed to initialise the condition variable, ret %d.\n", ret);
+#endif
+}
+
+static inline void vkd3d_cond_signal(struct vkd3d_cond *cond)
+{
+#ifdef _WIN32
+ WakeConditionVariable(&cond->cond);
+#else
+ int ret;
+
+ if ((ret = pthread_cond_signal(&cond->cond)))
+ ERR("Failed to signal the condition variable, ret %d.\n", ret);
+#endif
+}
+
+static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
+{
+#ifdef _WIN32
+ WakeAllConditionVariable(&cond->cond);
+#else
+ int ret;
+
+ if ((ret = pthread_cond_broadcast(&cond->cond)))
+ ERR("Failed to broadcast the condition variable, ret %d.\n", ret);
+#endif
+}
+
+static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
+{
+#ifdef _WIN32
+ if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE))
+ ERR("Failed to wait on the condition variable, error %lu.\n", GetLastError());
+#else
+ int ret;
+
+ if ((ret = pthread_cond_wait(&cond->cond, &lock->lock)))
+ ERR("Failed to wait on the condition variable, ret %d.\n", ret);
+#endif
+}
+
+static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
+{
+#ifdef _WIN32
+ /* Nothing to do. */
+#else
+ int ret;
+
+ if ((ret = pthread_cond_destroy(&cond->cond)))
+ ERR("Failed to destroy the condition variable, ret %d.\n", ret);
+#endif
+}
+
static inline void vkd3d_parse_version(const char *version, int *major, int *minor)
{
*major = atoi(version);
diff --git a/libs/vkd3d/include/vkd3d.h b/libs/vkd3d/include/vkd3d.h
index aa68b70e1bf..71c56331d86 100644
--- a/libs/vkd3d/include/vkd3d.h
+++ b/libs/vkd3d/include/vkd3d.h
@@ -46,21 +46,37 @@ extern "C" {
* \since 1.0
*/
+/** The type of a chained structure. */
enum vkd3d_structure_type
{
- /* 1.0 */
+ /** The structure is a vkd3d_instance_create_info structure. */
VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+ /** The structure is a vkd3d_device_create_info structure. */
VKD3D_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+ /** The structure is a vkd3d_image_resource_create_info structure. */
VKD3D_STRUCTURE_TYPE_IMAGE_RESOURCE_CREATE_INFO,
- /* 1.1 */
+ /**
+ * The structure is a vkd3d_optional_instance_extensions_info structure.
+ * \since 1.1
+ */
VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO,
- /* 1.2 */
+ /**
+ * The structure is a vkd3d_optional_device_extensions_info structure.
+ * \since 1.2
+ */
VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO,
+ /**
+ * The structure is a vkd3d_application_info structure.
+ * \since 1.2
+ */
VKD3D_STRUCTURE_TYPE_APPLICATION_INFO,
- /* 1.3 */
+ /**
+ * The structure is a vkd3d_host_time_domain_info structure.
+ * \since 1.3
+ */
VKD3D_STRUCTURE_TYPE_HOST_TIME_DOMAIN_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE),
@@ -93,54 +109,131 @@ typedef HRESULT (*PFN_vkd3d_join_thread)(void *thread);
struct vkd3d_instance;
+/**
+ * A chained structure containing instance creation parameters.
+ */
struct vkd3d_instance_create_info
{
+ /** Must be set to VKD3D_STRUCTURE_TYPE_INSTANCE_CREATE_INFO. */
enum vkd3d_structure_type type;
+ /** Optional pointer to a structure containing further parameters. */
const void *next;
+ /** An pointer to a function to signal events. */
PFN_vkd3d_signal_event pfn_signal_event;
+ /**
+ * An optional pointer to a function to create threads. If this is NULL vkd3d will use a
+ * function of its choice, depending on the platform. It must be NULL if and only if
+ * pfn_join_thread is NULL.
+ */
PFN_vkd3d_create_thread pfn_create_thread;
+ /**
+ * An optional pointer to a function to join threads. If this is NULL vkd3d will use a
+ * function of its choice, depending on the platform. It must be NULL if and only if
+ * pfn_create_thread is NULL.
+ */
PFN_vkd3d_join_thread pfn_join_thread;
+ /** The size of type WCHAR. It must be 2 or 4 and should normally be set to sizeof(WCHAR). */
size_t wchar_size;
- /* If set to NULL, libvkd3d loads libvulkan. */
+ /**
+ * A pointer to the vkGetInstanceProcAddr Vulkan function, which will be used to load all the
+ * other Vulkan functions. If set to NULL, vkd3d will search and use the Vulkan loader.
+ */
PFN_vkGetInstanceProcAddr pfn_vkGetInstanceProcAddr;
+ /**
+ * A list of Vulkan instance extensions to request. They are intended as required, so instance
+ * creation will fail if any of them is not available.
+ */
const char * const *instance_extensions;
+ /** The number of elements in the instance_extensions array. */
uint32_t instance_extension_count;
};
-/* Extends vkd3d_instance_create_info. Available since 1.1. */
+/**
+ * A chained structure to specify optional instance extensions.
+ *
+ * This structure extends vkd3d_instance_create_info.
+ *
+ * \since 1.1
+ */
struct vkd3d_optional_instance_extensions_info
{
+ /** Must be set to VKD3D_STRUCTURE_TYPE_OPTIONAL_INSTANCE_EXTENSIONS_INFO. */
enum vkd3d_structure_type type;
+ /** Optional pointer to a structure containing further parameters. */
const void *next;
+ /**
+ * A list of optional Vulkan instance extensions to request. Instance creation does not fail if
+ * they are not available.
+ */
const char * const *extensions;
+ /** The number of elements in the extensions array. */
uint32_t extension_count;
};
-/* Extends vkd3d_instance_create_info. Available since 1.2. */
+/**
+ * A chained structure to specify application information.
+ *
+ * This structure extends vkd3d_instance_create_info.
+ *
+ * \since 1.2
+ */
struct vkd3d_application_info
{
+ /** Must be set to VKD3D_STRUCTURE_TYPE_APPLICATION_INFO. */
enum vkd3d_structure_type type;
+ /** Optional pointer to a structure containing further parameters. */
const void *next;
+ /**
+ * The application's name, to be passed to the Vulkan implementation. If it is NULL, a name is
+ * computed from the process executable filename. If that cannot be done, the empty string is
+ * used.
+ */
const char *application_name;
+ /** The application's version, to be passed to the Vulkan implementation. */
uint32_t application_version;
- const char *engine_name; /* "vkd3d" if NULL */
- uint32_t engine_version; /* vkd3d version if engine_name is NULL */
-
+ /**
+ * The engine name, to be passed to the Vulkan implementation. If it is NULL, "vkd3d" is used.
+ */
+ const char *engine_name;
+ /**
+ * The engine version, to be passed to the Vulkan implementation. If it is 0, the version is
+ * computed from the vkd3d library version.
+ */
+ uint32_t engine_version;
+
+ /**
+ * The vkd3d API version to use, to guarantee backward compatibility of the shared library. If
+ * this chained structure is not used then VKD3D_API_VERSION_1_0 is used.
+ */
enum vkd3d_api_version api_version;
};
-/* Extends vkd3d_instance_create_info. Available since 1.3. */
+/**
+ * A chained structure to specify the host time domain.
+ *
+ * This structure extends vkd3d_instance_create_info.
+ *
+ * \since 1.3
+ */
struct vkd3d_host_time_domain_info
{
+ /** Must be set to VKD3D_STRUCTURE_TYPE_HOST_TIME_DOMAIN_INFO. */
enum vkd3d_structure_type type;
+ /** Optional pointer to a structure containing further parameters. */
const void *next;
+ /**
+ * The number of clock ticks per second, used for GetClockCalibration(). It should normally
+ * match the expected result of QueryPerformanceFrequency(). If this chained structure is not
+ * used then 10 millions is used, which means that each tick is a tenth of microsecond, or
+ * equivalently 100 nanoseconds.
+ */
uint64_t ticks_per_second;
};
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index 220ba773887..d07d5adee70 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -419,6 +419,11 @@ enum dx_intrinsic_opcode
DX_FLATTENED_THREAD_ID_IN_GROUP = 96,
DX_MAKE_DOUBLE = 101,
DX_SPLIT_DOUBLE = 102,
+ DX_LOAD_OUTPUT_CONTROL_POINT = 103,
+ DX_LOAD_PATCH_CONSTANT = 104,
+ DX_DOMAIN_LOCATION = 105,
+ DX_STORE_PATCH_CONSTANT = 106,
+ DX_OUTPUT_CONTROL_POINT_ID = 107,
DX_PRIMITIVE_ID = 108,
DX_LEGACY_F32TOF16 = 130,
DX_LEGACY_F16TOF32 = 131,
@@ -799,6 +804,7 @@ struct sm6_parser
struct vkd3d_shader_dst_param *output_params;
struct vkd3d_shader_dst_param *input_params;
+ struct vkd3d_shader_dst_param *patch_constant_params;
uint32_t io_regs_declared[(VKD3DSPR_COUNT + 0x1f) / 0x20];
struct sm6_function *functions;
@@ -2433,10 +2439,12 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx,
if (sm6_value_is_constant(address))
{
idx->offset = sm6_value_get_constant_uint(address);
+ idx->rel_addr = NULL;
}
else if (sm6_value_is_undef(address))
{
idx->offset = 0;
+ idx->rel_addr = NULL;
}
else
{
@@ -2515,7 +2523,7 @@ static size_t sm6_parser_compute_max_value_count(struct sm6_parser *sm6,
* overestimate the value count somewhat, but this should be no problem. */
value_count = size_add_with_overflow_check(value_count, max(block->record_count, 1u) - 1);
sm6->value_capacity = max(sm6->value_capacity, value_count);
- sm6->functions[sm6->function_count].value_count = value_count;
+ sm6->functions[sm6->function_count++].value_count = value_count;
/* The value count returns to its previous value after handling a function. */
if (value_count < SIZE_MAX)
value_count = old_value_count;
@@ -3689,12 +3697,35 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind(
}
static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s,
- enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params)
+ bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params)
{
+ enum vkd3d_shader_type shader_type = sm6->p.program.shader_version.type;
+ bool is_patch_constant, is_control_point;
struct vkd3d_shader_dst_param *param;
const struct signature_element *e;
unsigned int i, count;
+ is_patch_constant = reg_type == VKD3DSPR_PATCHCONST;
+
+ is_control_point = false;
+ if (!is_patch_constant)
+ {
+ switch (shader_type)
+ {
+ case VKD3D_SHADER_TYPE_DOMAIN:
+ case VKD3D_SHADER_TYPE_GEOMETRY:
+ is_control_point = is_input;
+ break;
+
+ case VKD3D_SHADER_TYPE_HULL:
+ is_control_point = true;
+ break;
+
+ default:
+ break;
+ }
+ }
+
for (i = 0; i < s->element_count; ++i)
{
e = &s->elements[i];
@@ -3709,8 +3740,18 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
dst_param_io_init(param, e, reg_type);
count = 0;
- if (e->register_count > 1)
+
+ if (is_control_point)
+ {
+ if (reg_type == VKD3DSPR_OUTPUT)
+ param->reg.idx[count].rel_addr = instruction_array_create_outpointid_param(&sm6->p.program.instructions);
+ param->reg.idx[count++].offset = 0;
+ }
+
+ if (e->register_count > 1 || (is_patch_constant && vsir_sysval_semantic_is_tess_factor(e->sysval_semantic)))
param->reg.idx[count++].offset = 0;
+
+ assert(count < ARRAY_SIZE(param->reg.idx));
param->reg.idx[count++].offset = i;
param->reg.idx_count = count;
}
@@ -3718,12 +3759,21 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature)
{
- sm6_parser_init_signature(sm6, output_signature, VKD3DSPR_OUTPUT, sm6->output_params);
+ sm6_parser_init_signature(sm6, output_signature, false, VKD3DSPR_OUTPUT, sm6->output_params);
}
static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature)
{
- sm6_parser_init_signature(sm6, input_signature, VKD3DSPR_INPUT, sm6->input_params);
+ sm6_parser_init_signature(sm6, input_signature, true, VKD3DSPR_INPUT, sm6->input_params);
+}
+
+static void sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6,
+ const struct shader_signature *patch_constant_signature)
+{
+ bool is_input = sm6->p.program.shader_version.type == VKD3D_SHADER_TYPE_DOMAIN;
+
+ sm6_parser_init_signature(sm6, patch_constant_signature, is_input, VKD3DSPR_PATCHCONST,
+ sm6->patch_constant_params);
}
static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6)
@@ -4752,6 +4802,33 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic
src_param_init_from_value(src_param, operands[0]);
}
+static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ struct vkd3d_shader_instruction *ins = state->ins;
+ struct vkd3d_shader_src_param *src_param;
+ unsigned int component_idx;
+
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
+
+ if ((component_idx = sm6_value_get_constant_uint(operands[0])) >= 3)
+ {
+ WARN("Invalid component index %u.\n", component_idx);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Invalid domain location component index %u.", component_idx);
+ component_idx = 0;
+ }
+
+ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
+ return;
+ sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 3);
+ vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 0);
+ src_param->reg.dimension = VSIR_DIMENSION_VEC4;
+ src_param_init_scalar(src_param, component_idx);
+
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
@@ -4989,18 +5066,43 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi
static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
+ bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT;
+ bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT;
struct vkd3d_shader_instruction *ins = state->ins;
+ unsigned int count, row_index, column_index;
+ const struct vkd3d_shader_dst_param *params;
struct vkd3d_shader_src_param *src_param;
const struct shader_signature *signature;
- unsigned int row_index, column_index;
const struct signature_element *e;
row_index = sm6_value_get_constant_uint(operands[0]);
column_index = sm6_value_get_constant_uint(operands[2]);
+ if (is_control_point && operands[3]->is_undefined)
+ {
+ /* dxcompiler will compile source which does this, so let it pass. */
+ WARN("Control point id is undefined.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND,
+ "The index for a control point load is undefined.");
+ }
+
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
- signature = &sm6->p.program.input_signature;
+ if (is_patch_constant)
+ {
+ signature = &sm6->p.program.patch_constant_signature;
+ params = sm6->patch_constant_params;
+ }
+ else if (is_control_point)
+ {
+ signature = &sm6->p.program.output_signature;
+ params = sm6->output_params;
+ }
+ else
+ {
+ signature = &sm6->p.program.input_signature;
+ params = sm6->input_params;
+ }
if (row_index >= signature->element_count)
{
WARN("Invalid row index %u.\n", row_index);
@@ -5012,10 +5114,18 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6)))
return;
- src_param->reg = sm6->input_params[row_index].reg;
+ src_param->reg = params[row_index].reg;
src_param_init_scalar(src_param, column_index);
+ count = 0;
+
if (e->register_count > 1)
- register_index_address_init(&src_param->reg.idx[0], operands[1], sm6);
+ register_index_address_init(&src_param->reg.idx[count++], operands[1], sm6);
+
+ if (!is_patch_constant && !operands[3]->is_undefined)
+ {
+ assert(src_param->reg.idx_count > count);
+ register_index_address_init(&src_param->reg.idx[count], operands[3], sm6);
+ }
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -5040,6 +5150,12 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
+static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT);
+}
+
static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
@@ -5473,6 +5589,7 @@ static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intr
static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
+ bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT;
struct vkd3d_shader_instruction *ins = state->ins;
struct vkd3d_shader_src_param *src_param;
struct vkd3d_shader_dst_param *dst_param;
@@ -5484,7 +5601,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
row_index = sm6_value_get_constant_uint(operands[0]);
column_index = sm6_value_get_constant_uint(operands[2]);
- signature = &sm6->p.program.output_signature;
+ signature = is_patch_constant ? &sm6->p.program.patch_constant_signature : &sm6->p.program.output_signature;
if (row_index >= signature->element_count)
{
WARN("Invalid row index %u.\n", row_index);
@@ -5516,7 +5633,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6)))
return;
dst_param_init_scalar(dst_param, column_index);
- dst_param->reg = sm6->output_params[row_index].reg;
+ dst_param->reg = is_patch_constant ? sm6->patch_constant_params[row_index].reg : sm6->output_params[row_index].reg;
if (e->register_count > 1)
register_index_address_init(&dst_param->reg.idx[0], operands[1], sm6);
@@ -5736,6 +5853,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_DERIV_FINEX ] = {"e", "R", sm6_parser_emit_dx_unary},
[DX_DERIV_FINEY ] = {"e", "R", sm6_parser_emit_dx_unary},
[DX_DISCARD ] = {"v", "1", sm6_parser_emit_dx_discard},
+ [DX_DOMAIN_LOCATION ] = {"f", "c", sm6_parser_emit_dx_domain_location},
[DX_DOT2 ] = {"g", "RRRR", sm6_parser_emit_dx_dot},
[DX_DOT3 ] = {"g", "RRRRRR", sm6_parser_emit_dx_dot},
[DX_DOT4 ] = {"g", "RRRRRRRR", sm6_parser_emit_dx_dot},
@@ -5765,8 +5883,11 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_LEGACY_F16TOF32 ] = {"f", "i", sm6_parser_emit_dx_unary},
[DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary},
[DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input},
+ [DX_LOAD_OUTPUT_CONTROL_POINT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input},
+ [DX_LOAD_PATCH_CONSTANT ] = {"o", "ii8", sm6_parser_emit_dx_load_input},
[DX_LOG ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_MAKE_DOUBLE ] = {"d", "ii", sm6_parser_emit_dx_make_double},
+ [DX_OUTPUT_CONTROL_POINT_ID ] = {"i", "", sm6_parser_emit_dx_output_control_point_id},
[DX_PRIMITIVE_ID ] = {"i", "", sm6_parser_emit_dx_primitive_id},
[DX_RAW_BUFFER_LOAD ] = {"o", "Hii8i", sm6_parser_emit_dx_raw_buffer_load},
[DX_RAW_BUFFER_STORE ] = {"v", "Hiioooocc", sm6_parser_emit_dx_raw_buffer_store},
@@ -5788,6 +5909,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double},
[DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output},
+ [DX_STORE_PATCH_CONSTANT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output},
[DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_TEX2DMS_GET_SAMPLE_POS ] = {"o", "Hi", sm6_parser_emit_dx_get_sample_pos},
[DX_TEXTURE_GATHER ] = {"o", "HHffffiic", sm6_parser_emit_dx_texture_gather},
@@ -7286,11 +7408,6 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
struct sm6_block *code_block;
struct sm6_value *dst;
- if (sm6->function_count)
- {
- FIXME("Multiple functions are not supported yet.\n");
- return VKD3D_ERROR_INVALID_SHADER;
- }
if (!(function->declaration = sm6_parser_next_function_definition(sm6)))
{
WARN("Failed to find definition to match function body.\n");
@@ -8976,10 +9093,15 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons
{
return ret;
}
- /* TODO: patch constant signature in operand 2. */
+ if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[2],
+ &sm6->p.program.patch_constant_signature, tessellator_domain)) < 0)
+ {
+ return ret;
+ }
sm6_parser_init_input_signature(sm6, &sm6->p.program.input_signature);
sm6_parser_init_output_signature(sm6, &sm6->p.program.output_signature);
+ sm6_parser_init_patch_constant_signature(sm6, &sm6->p.program.patch_constant_signature);
return VKD3D_OK;
}
@@ -9509,9 +9631,10 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6
static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *source_name,
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 shader_signature *patch_constant_signature = &sm6->p.program.patch_constant_signature;
const struct shader_signature *output_signature = &sm6->p.program.output_signature;
const struct shader_signature *input_signature = &sm6->p.program.input_signature;
- size_t count, length, function_count, byte_code_size = dxbc_desc->byte_code_size;
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;
@@ -9674,7 +9797,9 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
}
if (!(sm6->output_params = vsir_program_get_dst_params(&sm6->p.program, output_signature->element_count))
- || !(sm6->input_params = vsir_program_get_dst_params(&sm6->p.program, input_signature->element_count)))
+ || !(sm6->input_params = vsir_program_get_dst_params(&sm6->p.program, input_signature->element_count))
+ || !(sm6->patch_constant_params = vsir_program_get_dst_params(&sm6->p.program,
+ patch_constant_signature->element_count)))
{
ERR("Failed to allocate input/output parameters.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
@@ -9705,6 +9830,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
"Out of memory allocating DXIL value array.");
return VKD3D_ERROR_OUT_OF_MEMORY;
}
+ sm6->function_count = 0;
sm6->ssa_next_id = 1;
if ((ret = sm6_parser_globals_init(sm6)) < 0)
@@ -9754,7 +9880,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
return ret;
}
- if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count))
+ if (!sm6_parser_require_space(sm6, output_signature->element_count + input_signature->element_count
+ + patch_constant_signature->element_count))
{
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
"Out of memory emitting shader signature declarations.");
@@ -9771,9 +9898,41 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const char *sou
return VKD3D_ERROR_INVALID_SHADER;
}
- assert(sm6->function_count == 1);
- if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
- return ret;
+ if (version.type == VKD3D_SHADER_TYPE_HULL)
+ {
+ sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE);
+
+ if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
+ return ret;
+
+ if (!(fn = sm6_parser_get_function(sm6, sm6->patch_constant_function)))
+ {
+ WARN("Failed to find patch constant function '%s'.\n", sm6->patch_constant_function);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
+ "Failed to find the patch constant function '%s' for a hull shader.",
+ sm6->patch_constant_function);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE);
+ if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
+ return ret;
+
+ expected_function_count = 2;
+ }
+ else
+ {
+ if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0)
+ return ret;
+ expected_function_count = 1;
+ }
+
+ if (sm6->function_count > expected_function_count)
+ {
+ FIXME("%zu unhandled functions.\n", sm6->function_count - expected_function_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE,
+ "%zu functions were not emitted.", sm6->function_count - expected_function_count);
+ }
dxil_block_destroy(&sm6->root_block);
diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c
index 3e8dd2c486b..3e482a5fc70 100644
--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c
@@ -79,6 +79,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *generator
case VKD3DSIH_DCL_INPUT:
case VKD3DSIH_DCL_OUTPUT:
case VKD3DSIH_DCL_OUTPUT_SIV:
+ case VKD3DSIH_NOP:
break;
case VKD3DSIH_RET:
shader_glsl_ret(generator, instruction);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 7a8fe4de437..5e3010c4353 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -392,7 +392,7 @@ struct hlsl_attribute
struct hlsl_reg_reservation
{
char reg_type;
- unsigned int reg_index;
+ unsigned int reg_space, reg_index;
char offset_type;
unsigned int offset_index;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index 0c196b77595..f99f322d8d1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -1197,17 +1197,18 @@ static bool add_effect_group(struct hlsl_ctx *ctx, const char *name, struct hlsl
return true;
}
-static struct hlsl_reg_reservation parse_reg_reservation(const char *reg_string)
+static bool parse_reservation_index(const char *string, char *type, uint32_t *index)
{
- struct hlsl_reg_reservation reservation = {0};
+ if (!sscanf(string + 1, "%u", index))
+ return false;
- if (!sscanf(reg_string + 1, "%u", &reservation.reg_index))
- {
- FIXME("Unsupported register reservation syntax.\n");
- return reservation;
- }
- reservation.reg_type = ascii_tolower(reg_string[0]);
- return reservation;
+ *type = ascii_tolower(string[0]);
+ return true;
+}
+
+static bool parse_reservation_space(const char *string, uint32_t *space)
+{
+ return !ascii_strncasecmp(string, "space", 5) && sscanf(string + 5, "%u", space);
}
static struct hlsl_reg_reservation parse_packoffset(struct hlsl_ctx *ctx, const char *reg_string,
@@ -5675,8 +5676,8 @@ static bool state_block_add_entry(struct hlsl_state_block *state_block, struct h
%type <parameters> param_list
%type <parameters> parameters
-%type <reg_reservation> register_opt
-%type <reg_reservation> packoffset_opt
+%type <reg_reservation> register_reservation
+%type <reg_reservation> packoffset_reservation
%type <sampler_dim> texture_type texture_ms_type uav_type rov_type
@@ -6300,12 +6301,12 @@ colon_attribute:
$$.reg_reservation.reg_type = 0;
$$.reg_reservation.offset_type = 0;
}
- | register_opt
+ | register_reservation
{
$$.semantic = (struct hlsl_semantic){0};
$$.reg_reservation = $1;
}
- | packoffset_opt
+ | packoffset_reservation
{
$$.semantic = (struct hlsl_semantic){0};
$$.reg_reservation = $1;
@@ -6327,22 +6328,57 @@ semantic:
}
/* FIXME: Writemasks */
-register_opt:
+register_reservation:
':' KW_REGISTER '(' any_identifier ')'
{
- $$ = parse_reg_reservation($4);
+ memset(&$$, 0, sizeof($$));
+ if (!parse_reservation_index($4, &$$.reg_type, &$$.reg_index))
+ hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register reservation '%s'.", $4);
+
vkd3d_free($4);
}
| ':' KW_REGISTER '(' any_identifier ',' any_identifier ')'
{
- FIXME("Ignoring shader target %s in a register reservation.\n", debugstr_a($4));
+ memset(&$$, 0, sizeof($$));
+ if (parse_reservation_index($6, &$$.reg_type, &$$.reg_index))
+ {
+ hlsl_fixme(ctx, &@4, "Reservation shader target %s.", $4);
+ }
+ else if (parse_reservation_space($6, &$$.reg_space))
+ {
+ if (!parse_reservation_index($4, &$$.reg_type, &$$.reg_index))
+ hlsl_error(ctx, &@4, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register reservation '%s'.", $4);
+ }
+ else
+ {
+ hlsl_error(ctx, &@6, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register or space reservation '%s'.", $6);
+ }
+
vkd3d_free($4);
+ vkd3d_free($6);
+ }
+ | ':' KW_REGISTER '(' any_identifier ',' any_identifier ',' any_identifier ')'
+ {
+ hlsl_fixme(ctx, &@4, "Reservation shader target %s.", $4);
- $$ = parse_reg_reservation($6);
+ memset(&$$, 0, sizeof($$));
+ if (!parse_reservation_index($6, &$$.reg_type, &$$.reg_index))
+ hlsl_error(ctx, &@6, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register reservation '%s'.", $6);
+
+ if (!parse_reservation_space($8, &$$.reg_space))
+ hlsl_error(ctx, &@8, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Invalid register space reservation '%s'.", $8);
+
+ vkd3d_free($4);
vkd3d_free($6);
+ vkd3d_free($8);
}
-packoffset_opt:
+packoffset_reservation:
':' KW_PACKOFFSET '(' any_identifier ')'
{
$$ = parse_packoffset(ctx, $4, NULL, &@$);
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index eca18f4eb28..1f8d60c62ac 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -636,11 +636,14 @@ static bool control_point_normaliser_is_in_control_point_phase(const struct cont
return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE;
}
-static struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
+struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
struct vkd3d_shader_instruction_array *instructions)
{
struct vkd3d_shader_src_param *rel_addr;
+ if (instructions->outpointid_param)
+ return instructions->outpointid_param;
+
if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1)))
return NULL;
@@ -648,6 +651,7 @@ static struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
rel_addr->swizzle = 0;
rel_addr->modifiers = 0;
+ instructions->outpointid_param = rel_addr;
return rel_addr;
}
@@ -3344,6 +3348,14 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
enum vkd3d_result ret;
size_t i;
+ if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL)
+ {
+ FIXME("Hull shaders are not supported.\n");
+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED,
+ "The structurizer does not support hull shaders.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
memset(cfg, 0, sizeof(*cfg));
cfg->message_context = message_context;
cfg->program = program;
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 1f4320968d3..4434e6e98f2 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -202,6 +202,7 @@ enum vkd3d_shader_error
VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307,
VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308,
VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT = 8309,
+ VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND = 8310,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
@@ -1300,6 +1301,8 @@ struct vkd3d_shader_instruction_array
struct vkd3d_shader_immediate_constant_buffer **icbs;
size_t icb_capacity;
size_t icb_count;
+
+ struct vkd3d_shader_src_param *outpointid_param;
};
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
@@ -1310,6 +1313,8 @@ bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *ins
struct vkd3d_shader_immediate_constant_buffer *icb);
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
unsigned int dst, unsigned int src);
+struct vkd3d_shader_src_param *instruction_array_create_outpointid_param(
+ struct vkd3d_shader_instruction_array *instructions);
void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
enum vkd3d_shader_config_flags
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index e0a7acb306d..5f60c8d90ad 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -24,10 +24,6 @@
#define VK_NO_PROTOTYPES
#define CONST_VTABLE
-#ifdef _WIN32
-# define _WIN32_WINNT 0x0600 /* for condition variables */
-#endif
-
#include "vkd3d_common.h"
#include "vkd3d_blob.h"
#include "vkd3d_memory.h"
@@ -205,36 +201,6 @@ union vkd3d_thread_handle
void *handle;
};
-struct vkd3d_cond
-{
- CONDITION_VARIABLE cond;
-};
-
-static inline void vkd3d_cond_init(struct vkd3d_cond *cond)
-{
- InitializeConditionVariable(&cond->cond);
-}
-
-static inline void vkd3d_cond_signal(struct vkd3d_cond *cond)
-{
- WakeConditionVariable(&cond->cond);
-}
-
-static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
-{
- WakeAllConditionVariable(&cond->cond);
-}
-
-static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
-{
- if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE))
- ERR("Could not sleep on the condition variable, error %lu.\n", GetLastError());
-}
-
-static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
-{
-}
-
static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
{
return InterlockedCompareExchange((LONG volatile *)x, xchg, cmp) == cmp;
@@ -265,56 +231,6 @@ union vkd3d_thread_handle
void *handle;
};
-struct vkd3d_cond
-{
- pthread_cond_t cond;
-};
-
-static inline void vkd3d_cond_init(struct vkd3d_cond *cond)
-{
- int ret;
-
- ret = pthread_cond_init(&cond->cond, NULL);
- if (ret)
- ERR("Could not initialize the condition variable, error %d.\n", ret);
-}
-
-static inline void vkd3d_cond_signal(struct vkd3d_cond *cond)
-{
- int ret;
-
- ret = pthread_cond_signal(&cond->cond);
- if (ret)
- ERR("Could not signal the condition variable, error %d.\n", ret);
-}
-
-static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond)
-{
- int ret;
-
- ret = pthread_cond_broadcast(&cond->cond);
- if (ret)
- ERR("Could not broadcast the condition variable, error %d.\n", ret);
-}
-
-static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock)
-{
- int ret;
-
- ret = pthread_cond_wait(&cond->cond, &lock->lock);
- if (ret)
- ERR("Could not wait on the condition variable, error %d.\n", ret);
-}
-
-static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
-{
- int ret;
-
- ret = pthread_cond_destroy(&cond->cond);
- if (ret)
- ERR("Could not destroy the condition variable, error %d.\n", ret);
-}
-
# if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg)
{
--
2.43.0