wine-staging/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch
2024-02-07 14:12:01 +11:00

1766 lines
78 KiB
Diff

From 68e2bce0d09d84419126651774b5a08b22b30c48 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Thu, 1 Feb 2024 12:20:04 +1100
Subject: [PATCH] Updated vkd3d to 6dea3d08b1e9453bfc51dfec827cf1a25c2729df.
---
libs/vkd3d/include/private/vkd3d_debug.h | 4 +
libs/vkd3d/include/vkd3d_d3dcompiler.h | 4 +
libs/vkd3d/include/vkd3d_shader.h | 8 +-
libs/vkd3d/include/vkd3d_utils.h | 2 +
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 17 +-
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 15 +-
libs/vkd3d/libs/vkd3d-shader/dxil.c | 170 ++++++++-
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 137 +++++--
libs/vkd3d/libs/vkd3d-shader/ir.c | 334 +++++++++++++++++-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 56 ++-
libs/vkd3d/libs/vkd3d-shader/tpf.c | 10 +-
.../libs/vkd3d-shader/vkd3d_shader_main.c | 4 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 108 ++++--
libs/vkd3d/libs/vkd3d/device.c | 12 +-
libs/vkd3d/libs/vkd3d/resource.c | 24 +-
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 16 +-
16 files changed, 767 insertions(+), 154 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_debug.h b/libs/vkd3d/include/private/vkd3d_debug.h
index 663fc311adf..c5b6ccedf81 100644
--- a/libs/vkd3d/include/private/vkd3d_debug.h
+++ b/libs/vkd3d/include/private/vkd3d_debug.h
@@ -89,6 +89,10 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size);
#define TRACE_ON() (vkd3d_dbg_get_level() == VKD3D_DBG_LEVEL_TRACE)
#endif
+#ifndef WARN_ON
+#define WARN_ON() (vkd3d_dbg_get_level() >= VKD3D_DBG_LEVEL_WARN)
+#endif
+
#define FIXME_ONCE VKD3D_DBG_LOG_ONCE(FIXME, WARN)
#define VKD3D_DEBUG_ENV_NAME(name) const char *const vkd3d_dbg_env_name = name
diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler.h b/libs/vkd3d/include/vkd3d_d3dcompiler.h
index 1975f4f980a..872a90bbc4b 100644
--- a/libs/vkd3d/include/vkd3d_d3dcompiler.h
+++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h
@@ -79,6 +79,7 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader,
ID3DBlob **error_messages);
HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob);
+HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob);
HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob);
HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
@@ -89,5 +90,8 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename
HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection);
HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
+typedef HRESULT (WINAPI *pD3DDisassemble)(const void *data, SIZE_T data_size,
+ UINT flags, const char *comments, ID3DBlob **blob);
+
#endif /* __D3DCOMPILER_H__ */
#endif /* __VKD3D_D3DCOMPILER_H */
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index a8cc3a336a3..2f4478a7983 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -1777,10 +1777,10 @@ struct vkd3d_shader_dxbc_desc
* \endcode
*/
#define VKD3D_SHADER_SWIZZLE(x, y, z, w) \
- vkd3d_shader_create_swizzle(VKD3D_SHADER_SWIZZLE_ ## x, \
- VKD3D_SHADER_SWIZZLE_ ## y, \
- VKD3D_SHADER_SWIZZLE_ ## z, \
- VKD3D_SHADER_SWIZZLE_ ## w)
+ (VKD3D_SHADER_SWIZZLE_ ## x << VKD3D_SHADER_SWIZZLE_SHIFT(0) \
+ | VKD3D_SHADER_SWIZZLE_ ## y << VKD3D_SHADER_SWIZZLE_SHIFT(1) \
+ | VKD3D_SHADER_SWIZZLE_ ## z << VKD3D_SHADER_SWIZZLE_SHIFT(2) \
+ | VKD3D_SHADER_SWIZZLE_ ## w << VKD3D_SHADER_SWIZZLE_SHIFT(3))
/** The identity swizzle ".xyzw". */
#define VKD3D_SHADER_NO_SWIZZLE VKD3D_SHADER_SWIZZLE(X, Y, Z, W)
diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h
index adcac5fcf64..7616a3f3c46 100644
--- a/libs/vkd3d/include/vkd3d_utils.h
+++ b/libs/vkd3d/include/vkd3d_utils.h
@@ -117,6 +117,8 @@ VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_
VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
/** \since 1.11 */
+VKD3D_UTILS_API HRESULT WINAPI D3DDisassemble(const void *data,
+ SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob);
VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection);
#ifdef __cplusplus
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index af939396a08..dd96b7fa50b 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -1389,7 +1389,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler,
{
static const char write_mask_chars[] = "xyzw";
- if (param->reg.data_type == VKD3D_DATA_DOUBLE)
+ if (data_type_is_64_bit(param->reg.data_type))
write_mask = vsir_write_mask_32_from_64(write_mask);
shader_addline(buffer, ".%s", compiler->colours.write_mask);
@@ -1454,13 +1454,18 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler,
if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64
&& param->reg.dimension == VSIR_DIMENSION_VEC4)
{
- unsigned int swizzle_x = vsir_swizzle_get_component(swizzle, 0);
- unsigned int swizzle_y = vsir_swizzle_get_component(swizzle, 1);
- unsigned int swizzle_z = vsir_swizzle_get_component(swizzle, 2);
- unsigned int swizzle_w = vsir_swizzle_get_component(swizzle, 3);
-
static const char swizzle_chars[] = "xyzw";
+ unsigned int swizzle_x, swizzle_y, swizzle_z, swizzle_w;
+
+ if (data_type_is_64_bit(param->reg.data_type))
+ swizzle = vsir_swizzle_32_from_64(swizzle);
+
+ swizzle_x = vsir_swizzle_get_component(swizzle, 0);
+ swizzle_y = vsir_swizzle_get_component(swizzle, 1);
+ swizzle_z = vsir_swizzle_get_component(swizzle, 2);
+ swizzle_w = vsir_swizzle_get_component(swizzle, 3);
+
if (swizzle_x == swizzle_y
&& swizzle_x == swizzle_z
&& swizzle_x == swizzle_w)
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 4ba001ea4cd..9ad9f735dd1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -587,7 +587,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output,
if (!(element = find_signature_element_by_register_index(signature, register_index)))
{
- vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC,
+ vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC,
"%s register %u was used without being declared.", output ? "Output" : "Input", register_index);
return;
}
@@ -899,7 +899,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const
shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token))
{
- if (!(src_rel_addr = shader_parser_get_src_params(&sm1->p, 1)))
+ if (!(src_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1)))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory.");
@@ -920,7 +920,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const
shader_sm1_read_param(sm1, ptr, &token, &addr_token);
if (has_relative_address(token))
{
- if (!(dst_rel_addr = shader_parser_get_src_params(&sm1->p, 1)))
+ if (!(dst_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1)))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY,
"Out of memory.");
@@ -1089,6 +1089,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
{
struct vkd3d_shader_src_param *src_params, *predicate;
const struct vkd3d_sm1_opcode_info *opcode_info;
+ struct vsir_program *program = &sm1->p.program;
struct vkd3d_shader_dst_param *dst_param;
const uint32_t **ptr = &sm1->ptr;
uint32_t opcode_token;
@@ -1111,7 +1112,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE,
"Invalid opcode %#x (token 0x%08x, shader version %u.%u).",
opcode_token & VKD3D_SM1_OPCODE_MASK, opcode_token,
- sm1->p.program.shader_version.major, sm1->p.program.shader_version.minor);
+ program->shader_version.major, program->shader_version.minor);
goto fail;
}
@@ -1121,11 +1122,11 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
ins->raw = false;
ins->structured = false;
predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED);
- ins->predicate = predicate = predicated ? shader_parser_get_src_params(&sm1->p, 1) : NULL;
+ ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL;
ins->dst_count = opcode_info->dst_count;
- ins->dst = dst_param = shader_parser_get_dst_params(&sm1->p, ins->dst_count);
+ ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count);
ins->src_count = opcode_info->src_count;
- ins->src = src_params = shader_parser_get_src_params(&sm1->p, ins->src_count);
+ ins->src = src_params = vsir_program_get_src_params(program, ins->src_count);
if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count))
{
vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory.");
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index 8a31d03c531..0358dbb6e06 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -36,6 +36,10 @@ static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4;
static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
+#define VKD3D_SHADER_SWIZZLE_64_MASK \
+ (VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(0) \
+ | VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(1))
+
enum bitcode_block_id
{
BLOCKINFO_BLOCK = 0,
@@ -354,6 +358,8 @@ enum dx_intrinsic_opcode
DX_IMIN = 38,
DX_UMAX = 39,
DX_UMIN = 40,
+ DX_IBFE = 51,
+ DX_UBFE = 52,
DX_CREATE_HANDLE = 57,
DX_CBUFFER_LOAD_LEGACY = 59,
DX_BUFFER_LOAD = 68,
@@ -363,6 +369,7 @@ enum dx_intrinsic_opcode
DX_DERIV_FINEY = 86,
DX_LEGACY_F32TOF16 = 130,
DX_LEGACY_F16TOF32 = 131,
+ DX_RAW_BUFFER_LOAD = 139,
};
enum dxil_cast_code
@@ -2078,13 +2085,16 @@ static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins,
{
vsir_instruction_init(ins, &sm6->p.location, handler_idx);
ins->resource_type = resource->u.handle.d->resource_type;
+ ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
+ ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER;
}
static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins,
unsigned int count, struct sm6_parser *sm6)
{
- struct vkd3d_shader_src_param *params = shader_parser_get_src_params(&sm6->p, count);
- if (!params)
+ struct vkd3d_shader_src_param *params;
+
+ if (!(params = vsir_program_get_src_params(&sm6->p.program, count)))
{
ERR("Failed to allocate src params.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
@@ -2099,8 +2109,9 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_
static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_shader_instruction *ins,
unsigned int count, struct sm6_parser *sm6)
{
- struct vkd3d_shader_dst_param *params = shader_parser_get_dst_params(&sm6->p, count);
- if (!params)
+ struct vkd3d_shader_dst_param *params;
+
+ if (!(params = vsir_program_get_dst_params(&sm6->p.program, count)))
{
ERR("Failed to allocate dst params.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
@@ -2211,6 +2222,8 @@ static inline void src_param_init(struct vkd3d_shader_src_param *param)
static void src_param_init_scalar(struct vkd3d_shader_src_param *param, unsigned int component_idx)
{
param->swizzle = vkd3d_shader_create_swizzle(component_idx, component_idx, component_idx, component_idx);
+ if (data_type_is_64_bit(param->reg.data_type))
+ param->swizzle &= VKD3D_SHADER_SWIZZLE_64_MASK;
param->modifiers = VKD3DSPSM_NONE;
}
@@ -2241,7 +2254,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx,
}
else
{
- struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&sm6->p, 1);
+ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&sm6->p.program, 1);
if (rel_addr)
src_param_init_from_value(rel_addr, address);
idx->offset = 0;
@@ -3100,6 +3113,15 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param,
param->reg.dimension = VSIR_DIMENSION_VEC4;
}
+static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params,
+ const struct sm6_value **operands, unsigned int count)
+{
+ unsigned int i;
+
+ for (i = 0; i < count; ++i)
+ src_param_init_from_value(&src_params[i], operands[i]);
+}
+
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)
{
@@ -3624,6 +3646,8 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr
type = sm6_type_get_scalar_type(dst->type, 0);
assert(type);
src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type);
+ if (data_type_is_64_bit(src_param->reg.data_type))
+ src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle);
instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6);
}
@@ -3689,6 +3713,34 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int
ins->handler_idx = VKD3DSIH_NOP;
}
+static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode op)
+{
+ switch (op)
+ {
+ case DX_IBFE:
+ return VKD3DSIH_IBFE;
+ case DX_UBFE:
+ return VKD3DSIH_UBFE;
+ default:
+ vkd3d_unreachable();
+ }
+}
+
+static void sm6_parser_emit_dx_tertiary(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_params;
+ unsigned int i;
+
+ vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_tertiary_op(op));
+ src_params = instruction_src_params_alloc(ins, 3, sm6);
+ for (i = 0; i < 3; ++i)
+ src_param_init_from_value(&src_params[i], operands[i]);
+
+ instruction_dst_param_init_ssa_scalar(ins, sm6);
+}
+
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)
{
@@ -3722,6 +3774,49 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
+static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
+ const struct sm6_value **operands, struct function_emission_state *state)
+{
+ unsigned int operand_count, write_mask, component_count = VKD3D_VEC4_SIZE;
+ struct vkd3d_shader_instruction *ins = state->ins;
+ struct vkd3d_shader_src_param *src_params;
+ const struct sm6_value *resource;
+ bool raw;
+
+ resource = operands[0];
+ if (!sm6_value_validate_is_handle(resource, sm6))
+ return;
+ raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
+
+ if (op == DX_RAW_BUFFER_LOAD)
+ {
+ write_mask = sm6_value_get_constant_uint(operands[3]);
+ if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL)
+ {
+ WARN("Invalid write mask %#x.\n", write_mask);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Write mask %#x for a raw/structured buffer load operation is invalid.", write_mask);
+ return;
+ }
+ else if (write_mask & (write_mask + 1))
+ {
+ FIXME("Unhandled write mask %#x.\n", write_mask);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Write mask %#x for a raw/structured buffer load operation is unhandled.", write_mask);
+ }
+ component_count = vsir_write_mask_component_count(write_mask);
+ }
+
+ instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6);
+ operand_count = 2 + !raw;
+ if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6)))
+ return;
+ src_params_init_from_operands(src_params, &operands[1], operand_count - 1);
+ src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg);
+
+ instruction_dst_param_init_ssa_vector(ins, component_count, sm6);
+}
+
static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op,
const struct sm6_value **operands, struct function_emission_state *state)
{
@@ -3733,6 +3828,12 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri
if (!sm6_value_validate_is_handle(resource, sm6))
return;
+ if (resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER
+ || resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER)
+ {
+ return sm6_parser_emit_dx_raw_buffer_load(sm6, op, operands, state);
+ }
+
if (resource->u.handle.d->kind != RESOURCE_KIND_TYPEDBUFFER)
{
WARN("Resource is not a typed buffer.\n");
@@ -3875,6 +3976,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary},
[DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary},
[DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary},
+ [DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary},
[DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
[DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
[DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary},
@@ -3884,6 +3986,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary},
[DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input},
[DX_LOG ] = {"g", "R", sm6_parser_emit_dx_unary},
+ [DX_RAW_BUFFER_LOAD ] = {"o", "Hii8i", sm6_parser_emit_dx_raw_buffer_load},
[DX_ROUND_NE ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_ROUND_NI ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary},
@@ -3893,6 +3996,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] =
[DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary},
[DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output},
[DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary},
+ [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary},
[DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary},
[DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary},
};
@@ -4444,8 +4548,8 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil
vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV);
src_param = instruction_src_params_alloc(ins, 1, sm6);
- src_param_init_from_value(src_param, src);
- src_param->swizzle = vkd3d_shader_create_swizzle(elem_idx, elem_idx, elem_idx, elem_idx);
+ src_param_init_scalar(src_param, elem_idx);
+ src_param->reg = src->u.reg;
instruction_dst_param_init_ssa_scalar(ins, sm6);
}
@@ -5975,6 +6079,8 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k
switch (kind)
{
case RESOURCE_KIND_TYPEDBUFFER:
+ case RESOURCE_KIND_RAWBUFFER:
+ case RESOURCE_KIND_STRUCTUREDBUFFER:
return VKD3D_SHADER_RESOURCE_BUFFER;
default:
return VKD3D_SHADER_RESOURCE_NONE;
@@ -6039,6 +6145,13 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
}
ins->resource_type = resource_type;
+ if (!m)
+ {
+ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
+ ins->declaration.raw_resource.resource.reg.write_mask = 0;
+ return &ins->declaration.raw_resource.resource;
+ }
+
if (!sm6_metadata_value_is_node(m))
{
WARN("Resource metadata list is not a node.\n");
@@ -6093,6 +6206,39 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
return &ins->declaration.semantic.resource;
}
+ else if (dxil_resource_type == RESOURCE_TYPE_RAW_STRUCTURED)
+ {
+ if (kind == RESOURCE_KIND_RAWBUFFER)
+ {
+ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW;
+ ins->declaration.raw_resource.resource.reg.write_mask = 0;
+
+ return &ins->declaration.raw_resource.resource;
+ }
+
+ if (kind != RESOURCE_KIND_STRUCTUREDBUFFER)
+ {
+ WARN("Unhandled resource kind %u.\n", kind);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Resource kind %u for a raw or structured buffer is unhandled.", kind);
+ return NULL;
+ }
+
+ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED;
+ ins->declaration.structured_resource.byte_stride = values[1];
+ ins->declaration.structured_resource.resource.reg.write_mask = 0;
+
+ /* TODO: 16-bit resources. */
+ if (ins->declaration.structured_resource.byte_stride % 4u)
+ {
+ WARN("Byte stride %u is not a multiple of 4.\n", ins->declaration.structured_resource.byte_stride);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Structured resource byte stride %u is not a multiple of 4.",
+ ins->declaration.structured_resource.byte_stride);
+ }
+
+ return &ins->declaration.structured_resource.resource;
+ }
else
{
FIXME("Unhandled resource type %u.\n", dxil_resource_type);
@@ -6159,7 +6305,8 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6,
d->kind = kind;
d->reg_type = VKD3DSPR_RESOURCE;
d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_RESOURCE;
- d->resource_data_type = ins->declaration.semantic.resource_data_type[0];
+ d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL)
+ ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range);
@@ -6232,7 +6379,8 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6,
d->kind = values[0];
d->reg_type = VKD3DSPR_UAV;
d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_UAV;
- d->resource_data_type = ins->declaration.semantic.resource_data_type[0];
+ d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL_UAV_TYPED)
+ ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range);
@@ -7165,8 +7313,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
return ret;
}
- if (!(sm6->output_params = shader_parser_get_dst_params(&sm6->p, output_signature->element_count))
- || !(sm6->input_params = shader_parser_get_dst_params(&sm6->p, input_signature->element_count)))
+ 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)))
{
ERR("Failed to allocate input/output parameters.\n");
vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 1fe141a346a..6ad60e4c6c2 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -4123,13 +4123,46 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
- if (var->is_uniform && var->last_read)
+ unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
+
+ if (!var->is_uniform || !var->last_read || reg_size == 0)
+ continue;
+
+ if (var->reg_reservation.reg_type == 'c')
{
- unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
+ unsigned int reg_idx = var->reg_reservation.reg_index;
+ unsigned int i;
- if (reg_size == 0)
- continue;
+ assert(reg_size % 4 == 0);
+ for (i = 0; i < reg_size / 4; ++i)
+ {
+ if (get_available_writemask(&allocator, 1, UINT_MAX, reg_idx + i) != VKD3DSP_WRITEMASK_ALL)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "Overlapping register() reservations on 'c%u'.", reg_idx + i);
+ }
+
+ record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX);
+ }
+
+ var->regs[HLSL_REGSET_NUMERIC].id = reg_idx;
+ var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4;
+ var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL;
+ var->regs[HLSL_REGSET_NUMERIC].allocated = true;
+ TRACE("Allocated reserved %s to %s.\n", var->name,
+ debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type));
+ }
+ }
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
+ if (!var->is_uniform || !var->last_read || reg_size == 0)
+ continue;
+
+ if (!var->regs[HLSL_REGSET_NUMERIC].allocated)
+ {
var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, &allocator,
1, UINT_MAX, var->data_type);
TRACE("Allocated %s to %s.\n", var->name,
@@ -4269,45 +4302,52 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3
return NULL;
}
-static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var)
+static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, bool register_reservation)
{
unsigned int var_reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC];
enum hlsl_type_class var_class = var->data_type->class;
struct hlsl_buffer *buffer = var->buffer;
- if (var->reg_reservation.offset_type == 'c')
+ if (register_reservation)
{
- if (var->reg_reservation.offset_index % 4)
+ var->buffer_offset = 4 * var->reg_reservation.reg_index;
+ }
+ else
+ {
+ if (var->reg_reservation.offset_type == 'c')
{
- if (var_class == HLSL_CLASS_MATRIX)
+ if (var->reg_reservation.offset_index % 4)
{
- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
- "packoffset() reservations with matrix types must be aligned with the beginning of a register.");
- }
- else if (var_class == HLSL_CLASS_ARRAY)
- {
- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
- "packoffset() reservations with array types must be aligned with the beginning of a register.");
- }
- else if (var_class == HLSL_CLASS_STRUCT)
- {
- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
- "packoffset() reservations with struct types must be aligned with the beginning of a register.");
- }
- else if (var_class == HLSL_CLASS_VECTOR)
- {
- unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index);
-
- if (var->reg_reservation.offset_index != aligned_offset)
+ if (var_class == HLSL_CLASS_MATRIX)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "packoffset() reservations with matrix types must be aligned with the beginning of a register.");
+ }
+ else if (var_class == HLSL_CLASS_ARRAY)
+ {
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "packoffset() reservations with array types must be aligned with the beginning of a register.");
+ }
+ else if (var_class == HLSL_CLASS_STRUCT)
+ {
hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
- "packoffset() reservations with vector types cannot span multiple registers.");
+ "packoffset() reservations with struct types must be aligned with the beginning of a register.");
+ }
+ else if (var_class == HLSL_CLASS_VECTOR)
+ {
+ unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index);
+
+ if (var->reg_reservation.offset_index != aligned_offset)
+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION,
+ "packoffset() reservations with vector types cannot span multiple registers.");
+ }
}
+ var->buffer_offset = var->reg_reservation.offset_index;
+ }
+ else
+ {
+ var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size);
}
- var->buffer_offset = var->reg_reservation.offset_index;
- }
- else
- {
- var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size);
}
TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name);
@@ -4376,6 +4416,11 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx)
}
}
+static bool var_has_buffer_offset_register_reservation(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var)
+{
+ return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer;
+}
+
static void allocate_buffers(struct hlsl_ctx *ctx)
{
struct hlsl_buffer *buffer;
@@ -4384,13 +4429,29 @@ static void allocate_buffers(struct hlsl_ctx *ctx)
LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
{
- if (var->is_uniform && !hlsl_type_is_resource(var->data_type))
- {
- if (var->is_param)
- var->buffer = ctx->params_buffer;
+ if (!var->is_uniform || hlsl_type_is_resource(var->data_type))
+ continue;
- calculate_buffer_offset(ctx, var);
- }
+ if (var->is_param)
+ var->buffer = ctx->params_buffer;
+ }
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (!var->is_uniform || hlsl_type_is_resource(var->data_type))
+ continue;
+
+ if (var_has_buffer_offset_register_reservation(ctx, var))
+ calculate_buffer_offset(ctx, var, true);
+ }
+
+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry)
+ {
+ if (!var->is_uniform || hlsl_type_is_resource(var->data_type))
+ continue;
+
+ if (!var_has_buffer_offset_register_reservation(ctx, var))
+ calculate_buffer_offset(ctx, var, false);
}
validate_buffer_offsets(ctx);
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
index 9079be48b4f..a0d6212cbf5 100644
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
@@ -66,7 +66,7 @@ static void remove_dcl_temps(struct vsir_program *program)
}
}
-static bool vsir_instruction_init_with_params(struct vkd3d_shader_parser *parser,
+static bool vsir_instruction_init_with_params(struct vsir_program *program,
struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
enum vkd3d_shader_opcode handler_idx, unsigned int dst_count, unsigned int src_count)
{
@@ -74,13 +74,13 @@ static bool vsir_instruction_init_with_params(struct vkd3d_shader_parser *parser
ins->dst_count = dst_count;
ins->src_count = src_count;
- if (!(ins->dst = shader_parser_get_dst_params(parser, ins->dst_count)))
+ if (!(ins->dst = vsir_program_get_dst_params(program, ins->dst_count)))
{
ERR("Failed to allocate %u destination parameters.\n", dst_count);
return false;
}
- if (!(ins->src = shader_parser_get_src_params(parser, ins->src_count)))
+ if (!(ins->src = vsir_program_get_src_params(program, ins->src_count)))
{
ERR("Failed to allocate %u source parameters.\n", src_count);
return false;
@@ -116,7 +116,7 @@ static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_pa
/* tmp = ins->dst[0] < 0 */
ins = &instructions->elements[i + 1];
- if (!vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2))
+ if (!vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2))
return VKD3D_ERROR_OUT_OF_MEMORY;
vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
@@ -139,7 +139,7 @@ static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_pa
for (k = 1; k < components_read; ++k)
{
ins = &instructions->elements[i + 1 + k];
- if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2)))
+ if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2)))
return VKD3D_ERROR_OUT_OF_MEMORY;
vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1);
@@ -160,7 +160,7 @@ static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_pa
/* discard_nz tmp.x */
ins = &instructions->elements[i + 1 + components_read];
- if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1)))
+ if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1)))
return VKD3D_ERROR_OUT_OF_MEMORY;
ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
@@ -442,6 +442,15 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader
param->modifiers = VKD3DSPSM_NONE;
}
+void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type,
+ enum vkd3d_data_type data_type, unsigned int idx_count)
+{
+ vsir_register_init(&param->reg, reg_type, data_type, idx_count);
+ param->write_mask = VKD3DSP_WRITEMASK_0;
+ param->modifiers = VKD3DSPDM_NONE;
+ param->shift = 0;
+}
+
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id)
{
vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UINT, 1);
@@ -449,6 +458,18 @@ void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned in
param->reg.idx[0].offset = label_id;
}
+static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx)
+{
+ vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
+ src->reg.idx[0].offset = idx;
+}
+
+static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx)
+{
+ vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1);
+ dst->reg.idx[0].offset = idx;
+}
+
void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
enum vkd3d_shader_opcode handler_idx)
{
@@ -457,12 +478,12 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk
ins->handler_idx = handler_idx;
}
-static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location,
- unsigned int label_id, void *parser)
+static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins,
+ const struct vkd3d_shader_location *location, unsigned int label_id, struct vsir_program *program)
{
struct vkd3d_shader_src_param *src_param;
- if (!(src_param = shader_parser_get_src_params(parser, 1)))
+ if (!(src_param = vsir_program_get_src_params(program, 1)))
return false;
vsir_src_param_init_label(src_param, label_id);
@@ -1808,8 +1829,9 @@ static unsigned int cf_flattener_alloc_block_id(struct cf_flattener *flattener)
static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins,
unsigned int count, struct cf_flattener *flattener)
{
- struct vkd3d_shader_src_param *params = shader_parser_get_src_params(flattener->parser, count);
- if (!params)
+ struct vkd3d_shader_src_param *params;
+
+ if (!(params = vsir_program_get_src_params(&flattener->parser->program, count)))
{
flattener->allocation_failed = true;
return NULL;
@@ -1825,7 +1847,7 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int
if (!(ins = cf_flattener_require_space(flattener, 1)))
return;
- if (vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->parser))
+ if (vsir_instruction_init_label(ins, &flattener->location, label_id, &flattener->parser->program))
++flattener->instruction_count;
else
flattener->allocation_failed = true;
@@ -2350,6 +2372,271 @@ static enum vkd3d_result flatten_control_flow_constructs(struct vkd3d_shader_par
return result;
}
+static unsigned int label_from_src_param(const struct vkd3d_shader_src_param *param)
+{
+ assert(param->reg.type == VKD3DSPR_LABEL);
+ return param->reg.idx[0].offset;
+}
+
+static bool reserve_instructions(struct vkd3d_shader_instruction **instructions, size_t *capacity, size_t count)
+{
+ if (!vkd3d_array_reserve((void **)instructions, capacity, count, sizeof(**instructions)))
+ {
+ ERR("Failed to allocate instructions.\n");
+ return false;
+ }
+
+ return true;
+}
+
+/* A record represents replacing a jump from block `switch_label' to
+ * block `target_label' with a jump from block `if_label' to block
+ * `target_label'. */
+struct lower_switch_to_if_ladder_block_mapping
+{
+ unsigned int switch_label;
+ unsigned int if_label;
+ unsigned int target_label;
+};
+
+static bool lower_switch_to_if_ladder_add_block_mapping(struct lower_switch_to_if_ladder_block_mapping **block_map,
+ size_t *map_capacity, size_t *map_count, unsigned int switch_label, unsigned int if_label, unsigned int target_label)
+{
+ if (!vkd3d_array_reserve((void **)block_map, map_capacity, *map_count + 1, sizeof(**block_map)))
+ {
+ ERR("Failed to allocate block mapping.\n");
+ return false;
+ }
+
+ (*block_map)[*map_count].switch_label = switch_label;
+ (*block_map)[*map_count].if_label = if_label;
+ (*block_map)[*map_count].target_label = target_label;
+
+ *map_count += 1;
+
+ return true;
+}
+
+static enum vkd3d_result lower_switch_to_if_ladder(struct vsir_program *program)
+{
+ unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label;
+ size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0;
+ struct vkd3d_shader_instruction *instructions = NULL;
+ struct lower_switch_to_if_ladder_block_mapping *block_map = NULL;
+
+ if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count))
+ goto fail;
+
+ /* First subpass: convert SWITCH_MONOLITHIC instructions to
+ * selection ladders, keeping a map between blocks before and
+ * after the subpass. */
+ for (i = 0; i < program->instructions.count; ++i)
+ {
+ struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+ unsigned int case_count, j, default_label;
+
+ switch (ins->handler_idx)
+ {
+ case VKD3DSIH_LABEL:
+ current_label = label_from_src_param(&ins->src[0]);
+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
+ goto fail;
+ instructions[ins_count++] = *ins;
+ continue;
+
+ case VKD3DSIH_SWITCH_MONOLITHIC:
+ break;
+
+ default:
+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
+ goto fail;
+ instructions[ins_count++] = *ins;
+ continue;
+ }
+
+ case_count = (ins->src_count - 3) / 2;
+ default_label = label_from_src_param(&ins->src[1]);
+
+ /* In principle we can have a switch with no cases, and we
+ * just have to jump to the default label. */
+ if (case_count == 0)
+ {
+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1))
+ goto fail;
+
+ if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
+ &ins->location, VKD3DSIH_BRANCH, 0, 1))
+ goto fail;
+ vsir_src_param_init_label(&instructions[ins_count].src[0], default_label);
+ ++ins_count;
+ }
+
+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3 * case_count - 1))
+ goto fail;
+
+ if_label = current_label;
+
+ for (j = 0; j < case_count; ++j)
+ {
+ unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]);
+
+ if (!vsir_instruction_init_with_params(program,
+ &instructions[ins_count], &ins->location, VKD3DSIH_IEQ, 1, 2))
+ goto fail;
+ dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count);
+ instructions[ins_count].src[0] = ins->src[0];
+ instructions[ins_count].src[1] = ins->src[3 + 2 * j];
+ ++ins_count;
+
+ /* For all cases except the last one we fall through to
+ * the following case; the last one has to jump to the
+ * default label. */
+ if (j == case_count - 1)
+ fallthrough_label = default_label;
+ else
+ fallthrough_label = block_count + 1;
+
+ if (!vsir_instruction_init_with_params(program, &instructions[ins_count],
+ &ins->location, VKD3DSIH_BRANCH, 0, 3))
+ goto fail;
+ src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count);
+ vsir_src_param_init_label(&instructions[ins_count].src[1], case_label);
+ vsir_src_param_init_label(&instructions[ins_count].src[2], fallthrough_label);
+ ++ins_count;
+
+ ++ssa_count;
+
+ if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count,
+ current_label, if_label, case_label))
+ goto fail;
+
+ if (j == case_count - 1)
+ {
+ if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count,
+ current_label, if_label, default_label))
+ goto fail;
+ }
+ else
+ {
+ if (!vsir_instruction_init_with_params(program,
+ &instructions[ins_count], &ins->location, VKD3DSIH_LABEL, 0, 1))
+ goto fail;
+ vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count);
+ ++ins_count;
+
+ if_label = block_count;
+ }
+ }
+ }
+
+ /* Second subpass: creating new blocks might have broken
+ * references in PHI instructions, so we use the block map to fix
+ * them. */
+ current_label = 0;
+ for (i = 0; i < ins_count; ++i)
+ {
+ struct vkd3d_shader_instruction *ins = &instructions[i];
+ struct vkd3d_shader_src_param *new_src;
+ unsigned int j, l, new_src_count = 0;
+
+ switch (ins->handler_idx)
+ {
+ case VKD3DSIH_LABEL:
+ current_label = label_from_src_param(&ins->src[0]);
+ continue;
+
+ case VKD3DSIH_PHI:
+ break;
+
+ default:
+ continue;
+ }
+
+ /* First count how many source parameters we need. */
+ for (j = 0; j < ins->src_count; j += 2)
+ {
+ unsigned int source_label = label_from_src_param(&ins->src[j + 1]);
+ size_t k, match_count = 0;
+
+ for (k = 0; k < map_count; ++k)
+ {
+ struct lower_switch_to_if_ladder_block_mapping *mapping = &block_map[k];
+
+ if (mapping->switch_label == source_label && mapping->target_label == current_label)
+ match_count += 1;
+ }
+
+ new_src_count += (match_count != 0) ? 2 * match_count : 2;
+ }
+
+ assert(new_src_count >= ins->src_count);
+
+ /* Allocate more source parameters if needed. */
+ if (new_src_count == ins->src_count)
+ {
+ new_src = ins->src;
+ }
+ else
+ {
+ if (!(new_src = vsir_program_get_src_params(program, new_src_count)))
+ {
+ ERR("Failed to allocate %u source parameters.\n", new_src_count);
+ goto fail;
+ }
+ }
+
+ /* Then do the copy. */
+ for (j = 0, l = 0; j < ins->src_count; j += 2)
+ {
+ unsigned int source_label = label_from_src_param(&ins->src[j + 1]);
+ size_t k, match_count = 0;
+
+ for (k = 0; k < map_count; ++k)
+ {
+ struct lower_switch_to_if_ladder_block_mapping *mapping = &block_map[k];
+
+ if (mapping->switch_label == source_label && mapping->target_label == current_label)
+ {
+ match_count += 1;
+
+ new_src[l] = ins->src[j];
+ new_src[l + 1] = ins->src[j + 1];
+ new_src[l + 1].reg.idx[0].offset = mapping->if_label;
+ l += 2;
+ }
+ }
+
+ if (match_count == 0)
+ {
+ new_src[l] = ins->src[j];
+ new_src[l + 1] = ins->src[j + 1];
+ l += 2;
+ }
+ }
+
+ assert(l == new_src_count);
+
+ ins->src_count = new_src_count;
+ ins->src = new_src;
+ }
+
+ vkd3d_free(program->instructions.elements);
+ vkd3d_free(block_map);
+ program->instructions.elements = instructions;
+ program->instructions.capacity = ins_capacity;
+ program->instructions.count = ins_count;
+ program->block_count = block_count;
+ program->ssa_count = ssa_count;
+
+ return VKD3D_OK;
+
+fail:
+ vkd3d_free(instructions);
+ vkd3d_free(block_map);
+
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+}
+
enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
const struct vkd3d_shader_compile_info *compile_info)
{
@@ -2361,7 +2648,12 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser,
if ((result = instruction_array_lower_texkills(parser)) < 0)
return result;
- if (!parser->shader_desc.is_dxil)
+ if (parser->shader_desc.is_dxil)
+ {
+ if ((result = lower_switch_to_if_ladder(&parser->program)) < 0)
+ return result;
+ }
+ else
{
if (parser->program.shader_version.type != VKD3D_SHADER_TYPE_PIXEL)
{
@@ -2431,6 +2723,7 @@ struct validation_context
struct validation_context_ssa_data
{
enum vsir_dimension dimension;
+ enum vkd3d_data_type data_type;
size_t first_seen;
uint32_t write_mask;
uint32_t read_mask;
@@ -2587,13 +2880,20 @@ static void vsir_validate_register(struct validation_context *ctx,
if (data->dimension == VSIR_DIMENSION_NONE)
{
data->dimension = reg->dimension;
+ data->data_type = reg->data_type;
data->first_seen = ctx->instruction_idx;
}
- else if (data->dimension != reg->dimension)
+ else
{
- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a SSA register: "
- "it has already been seen with dimension %#x at instruction %zu.",
- reg->dimension, data->dimension, data->first_seen);
+ if (data->dimension != reg->dimension)
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a SSA register: "
+ "it has already been seen with dimension %#x at instruction %zu.",
+ reg->dimension, data->dimension, data->first_seen);
+
+ if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type))
+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid data type %#x for a SSA register: "
+ "it has already been seen with data type %#x at instruction %zu.",
+ reg->data_type, data->data_type, data->first_seen);
}
break;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index a86ca583e63..aedbfc24a93 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -3594,11 +3594,17 @@ static bool vkd3d_swizzle_is_equal(uint32_t dst_write_mask, uint32_t swizzle, ui
return vkd3d_compact_swizzle(VKD3D_SHADER_NO_SWIZZLE, dst_write_mask) == vkd3d_compact_swizzle(swizzle, write_mask);
}
-static bool vkd3d_swizzle_is_scalar(uint32_t swizzle)
+static bool vkd3d_swizzle_is_scalar(uint32_t swizzle, const struct vkd3d_shader_register *reg)
{
unsigned int component_idx = vsir_swizzle_get_component(swizzle, 0);
- return vsir_swizzle_get_component(swizzle, 1) == component_idx
- && vsir_swizzle_get_component(swizzle, 2) == component_idx
+
+ if (vsir_swizzle_get_component(swizzle, 1) != component_idx)
+ return false;
+
+ if (data_type_is_64_bit(reg->data_type))
+ return true;
+
+ return vsir_swizzle_get_component(swizzle, 2) == component_idx
&& vsir_swizzle_get_component(swizzle, 3) == component_idx;
}
@@ -3719,7 +3725,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi
for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
- values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component64(swizzle, i)];
+ values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component(swizzle, i)];
}
}
@@ -3886,7 +3892,7 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler
assert(compiler->failed);
return 0;
}
- assert(vkd3d_swizzle_is_scalar(swizzle));
+ assert(vkd3d_swizzle_is_scalar(swizzle, reg));
if (reg->dimension == VSIR_DIMENSION_SCALAR)
{
@@ -3954,6 +3960,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone);
}
+ swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle;
val_id = spirv_compiler_emit_swizzle(compiler,
val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask32);
@@ -7047,11 +7054,11 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp
static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
+ uint32_t val_id, dst_val_id, type_id, dst_id, src_id, write_mask32, swizzle32;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_shader_register_info dst_reg_info, src_reg_info;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
- uint32_t val_id, dst_val_id, type_id, dst_id, src_id;
uint32_t components[VKD3D_VEC4_SIZE];
unsigned int i, component_count;
@@ -7075,7 +7082,9 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
return;
}
- component_count = vsir_write_mask_component_count(dst->write_mask);
+ write_mask32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_write_mask_32_from_64(dst->write_mask) : dst->write_mask;
+ swizzle32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_swizzle_32_from_64(src->swizzle) : src->swizzle;
+ component_count = vsir_write_mask_component_count(write_mask32);
if (component_count != 1 && component_count != VKD3D_VEC4_SIZE
&& dst_reg_info.write_mask == VKD3DSP_WRITEMASK_ALL)
{
@@ -7088,8 +7097,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
for (i = 0; i < ARRAY_SIZE(components); ++i)
{
- if (dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))
- components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(src->swizzle, i);
+ if (write_mask32 & (VKD3DSP_WRITEMASK_0 << i))
+ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle32, i);
else
components[i] = i;
}
@@ -7472,7 +7481,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
enum vkd3d_shader_component_type component_type;
- unsigned int i, j, k, src_count;
+ unsigned int i, j, k, src_count, size;
uint32_t write_mask;
SpvOp op;
@@ -7481,8 +7490,9 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
- mask_id = spirv_compiler_get_constant_uint(compiler, 0x1f);
- size_id = spirv_compiler_get_constant_uint(compiler, 0x20);
+ size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20;
+ mask_id = spirv_compiler_get_constant_uint(compiler, size - 1);
+ size_id = spirv_compiler_get_constant_uint(compiler, size);
switch (instruction->handler_idx)
{
@@ -7813,13 +7823,16 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler,
if (instruction->src_count > 1)
{
/* Loop merge only. Must have a merge block and a continue block. */
- spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset);
+ if (instruction->src_count == 3)
+ spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset);
+ else
+ ERR("Invalid branch with %u sources.\n", instruction->src_count);
}
vkd3d_spirv_build_op_branch(builder, spirv_compiler_get_label_id(compiler, src[0].reg.idx[0].offset));
return;
}
- if (!vkd3d_swizzle_is_scalar(src->swizzle))
+ if (!vkd3d_swizzle_is_scalar(src->swizzle, &src->reg))
{
WARN("Unexpected src swizzle %#x.\n", src->swizzle);
spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE,
@@ -7827,11 +7840,15 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler,
}
condition_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0);
- condition_id = spirv_compiler_emit_int_to_bool(compiler,
- VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id);
+ if (src[0].reg.data_type != VKD3D_DATA_BOOL)
+ condition_id = spirv_compiler_emit_int_to_bool(compiler,
+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id);
/* Emit the merge immediately before the branch instruction. */
- spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset,
- (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0);
+ if (instruction->src_count >= 4)
+ spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset,
+ (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0);
+ else
+ ERR("Invalid branch with %u sources.\n", instruction->src_count);
vkd3d_spirv_build_op_branch_conditional(builder, condition_id,
spirv_compiler_get_label_id(compiler, src[1].reg.idx[0].offset),
spirv_compiler_get_label_id(compiler, src[2].reg.idx[0].offset));
@@ -7846,7 +7863,7 @@ static void spirv_compiler_emit_switch(struct spirv_compiler *compiler,
unsigned int i, word_count;
uint32_t *cases;
- if (!vkd3d_swizzle_is_scalar(src[0].swizzle))
+ if (!vkd3d_swizzle_is_scalar(src[0].swizzle, &src[0].reg))
{
WARN("Unexpected src swizzle %#x.\n", src[0].swizzle);
spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE,
@@ -9964,6 +9981,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler);
if (vkd3d_spirv_binary_to_text(spirv, environment, compiler->formatting, &text) != VKD3D_OK)
return VKD3D_ERROR;
+ vkd3d_shader_free_shader_code(spirv);
*spirv = text;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index 50146c2c7c9..adfddd32036 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -1742,7 +1742,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const
{
if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE)
{
- struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&priv->p, 1);
+ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&priv->p.program, 1);
if (!(reg_idx->rel_addr = rel_addr))
{
@@ -2161,6 +2161,9 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons
break;
}
+ if (data_type_is_64_bit(data_type))
+ src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle);
+
if (register_is_input_output(&src_param->reg) && !shader_sm4_validate_input_output_register(priv,
&src_param->reg, mask_from_swizzle(src_param->swizzle)))
return false;
@@ -2341,6 +2344,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d
static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins)
{
const struct vkd3d_sm4_opcode_info *opcode_info;
+ struct vsir_program *program = &sm4->p.program;
uint32_t opcode_token, opcode, previous_token;
struct vkd3d_shader_dst_param *dst_params;
struct vkd3d_shader_src_param *src_params;
@@ -2399,7 +2403,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
ins->predicate = NULL;
ins->dst_count = strnlen(opcode_info->dst_info, SM4_MAX_DST_COUNT);
ins->src_count = strnlen(opcode_info->src_info, SM4_MAX_SRC_COUNT);
- ins->src = src_params = shader_parser_get_src_params(&sm4->p, ins->src_count);
+ ins->src = src_params = vsir_program_get_src_params(program, ins->src_count);
if (!src_params && ins->src_count)
{
ERR("Failed to allocate src parameters.\n");
@@ -2441,7 +2445,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str
precise = (opcode_token & VKD3D_SM5_PRECISE_MASK) >> VKD3D_SM5_PRECISE_SHIFT;
ins->flags |= precise << VKD3DSI_PRECISE_SHIFT;
- ins->dst = dst_params = shader_parser_get_dst_params(&sm4->p, ins->dst_count);
+ ins->dst = dst_params = vsir_program_get_dst_params(program, ins->dst_count);
if (!dst_params && ins->dst_count)
{
ERR("Failed to allocate dst parameters.\n");
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index 1b7ea8dde9a..d0fd6b047b1 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -424,12 +424,12 @@ void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char
static void vkd3d_shader_dump_blob(const char *path, const char *profile,
const char *suffix, const void *data, size_t size)
{
- static LONG shader_id = 0;
+ static unsigned int shader_id = 0;
char filename[1024];
unsigned int id;
FILE *f;
- id = InterlockedIncrement(&shader_id) - 1;
+ id = vkd3d_atomic_increment_u32(&shader_id) - 1;
if (profile)
snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%u-%s.%s", path, id, profile, suffix);
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index fd0f2f0f34a..0ba7e71922a 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -895,6 +895,8 @@ struct vkd3d_shader_src_param
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type,
enum vkd3d_data_type data_type, unsigned int idx_count);
+void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type,
+ enum vkd3d_data_type data_type, unsigned int idx_count);
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id);
struct vkd3d_shader_index_range
@@ -1285,6 +1287,18 @@ struct vsir_program
bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve);
void vsir_program_cleanup(struct vsir_program *program);
+static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params(
+ struct vsir_program *program, unsigned int count)
+{
+ return shader_dst_param_allocator_get(&program->instructions.dst_params, count);
+}
+
+static inline struct vkd3d_shader_src_param *vsir_program_get_src_params(
+ struct vsir_program *program, unsigned int count)
+{
+ return shader_src_param_allocator_get(&program->instructions.src_params, count);
+}
+
struct vkd3d_shader_parser
{
struct vkd3d_shader_message_context *message_context;
@@ -1312,18 +1326,6 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser,
void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser,
enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
-static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params(
- struct vkd3d_shader_parser *parser, unsigned int count)
-{
- return shader_dst_param_allocator_get(&parser->program.instructions.dst_params, count);
-}
-
-static inline struct vkd3d_shader_src_param *shader_parser_get_src_params(
- struct vkd3d_shader_parser *parser, unsigned int count)
-{
- return shader_src_param_allocator_get(&parser->program.instructions.src_params, count);
-}
-
static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser)
{
parser->ops->parser_destroy(parser);
@@ -1603,25 +1605,89 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co
static inline uint32_t vsir_write_mask_64_from_32(uint32_t write_mask32)
{
- uint32_t write_mask64 = write_mask32 | (write_mask32 >> 1);
- return (write_mask64 & VKD3DSP_WRITEMASK_0) | ((write_mask64 & VKD3DSP_WRITEMASK_2) >> 1);
+ switch (write_mask32)
+ {
+ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1:
+ return VKD3DSP_WRITEMASK_0;
+
+ case VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3:
+ return VKD3DSP_WRITEMASK_1;
+
+ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3:
+ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1;
+
+ default:
+ ERR("Invalid 32 bit writemask when converting to 64 bit: %#x.\n", write_mask32);
+ return VKD3DSP_WRITEMASK_0;
+ }
}
static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64)
{
- uint32_t write_mask32 = (write_mask64 | (write_mask64 << 1))
- & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2);
- return write_mask32 | (write_mask32 << 1);
+ switch (write_mask64)
+ {
+ case VKD3DSP_WRITEMASK_0:
+ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1;
+
+ case VKD3DSP_WRITEMASK_1:
+ return VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
+
+ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1:
+ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3;
+
+ default:
+ ERR("Invalid 64 bit writemask: %#x.\n", write_mask64);
+ return VKD3DSP_WRITEMASK_0;
+ }
+}
+
+static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32)
+{
+ switch (swizzle32)
+ {
+ case VKD3D_SHADER_SWIZZLE(X, Y, X, Y):
+ return VKD3D_SHADER_SWIZZLE(X, X, X, X);
+
+ case VKD3D_SHADER_SWIZZLE(X, Y, Z, W):
+ return VKD3D_SHADER_SWIZZLE(X, Y, X, X);
+
+ case VKD3D_SHADER_SWIZZLE(Z, W, X, Y):
+ return VKD3D_SHADER_SWIZZLE(Y, X, X, X);
+
+ case VKD3D_SHADER_SWIZZLE(Z, W, Z, W):
+ return VKD3D_SHADER_SWIZZLE(Y, Y, X, X);
+
+ default:
+ ERR("Invalid 32 bit swizzle when converting to 64 bit: %#x.\n", swizzle32);
+ return VKD3D_SHADER_SWIZZLE(X, X, X, X);
+ }
}
-static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx)
+static inline uint32_t vsir_swizzle_32_from_64(uint32_t swizzle64)
{
- return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK;
+ switch (swizzle64)
+ {
+ case VKD3D_SHADER_SWIZZLE(X, X, X, X):
+ return VKD3D_SHADER_SWIZZLE(X, Y, X, Y);
+
+ case VKD3D_SHADER_SWIZZLE(X, Y, X, X):
+ return VKD3D_SHADER_SWIZZLE(X, Y, Z, W);
+
+ case VKD3D_SHADER_SWIZZLE(Y, X, X, X):
+ return VKD3D_SHADER_SWIZZLE(Z, W, X, Y);
+
+ case VKD3D_SHADER_SWIZZLE(Y, Y, X, X):
+ return VKD3D_SHADER_SWIZZLE(Z, W, Z, W);
+
+ default:
+ ERR("Invalid 64 bit swizzle: %#x.\n", swizzle64);
+ return VKD3D_SHADER_SWIZZLE(X, Y, X, Y);
+ }
}
-static inline unsigned int vsir_swizzle_get_component64(uint32_t swizzle, unsigned int idx)
+static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx)
{
- return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u;
+ return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK;
}
static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask)
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index 2b8558175e0..e45072b9367 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -750,7 +750,7 @@ static void vkd3d_destroy_instance(struct vkd3d_instance *instance)
ULONG vkd3d_instance_incref(struct vkd3d_instance *instance)
{
- ULONG refcount = InterlockedIncrement(&instance->refcount);
+ unsigned int refcount = vkd3d_atomic_increment_u32(&instance->refcount);
TRACE("%p increasing refcount to %u.\n", instance, refcount);
@@ -759,7 +759,7 @@ ULONG vkd3d_instance_incref(struct vkd3d_instance *instance)
ULONG vkd3d_instance_decref(struct vkd3d_instance *instance)
{
- ULONG refcount = InterlockedDecrement(&instance->refcount);
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&instance->refcount);
TRACE("%p decreasing refcount to %u.\n", instance, refcount);
@@ -2531,7 +2531,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *ifac
static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface)
{
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
- ULONG refcount = InterlockedIncrement(&device->refcount);
+ unsigned int refcount = vkd3d_atomic_increment_u32(&device->refcount);
TRACE("%p increasing refcount to %u.\n", device, refcount);
@@ -2563,7 +2563,7 @@ static HRESULT device_worker_stop(struct d3d12_device *device)
static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface)
{
struct d3d12_device *device = impl_from_ID3D12Device5(iface);
- ULONG refcount = InterlockedDecrement(&device->refcount);
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&device->refcount);
TRACE("%p decreasing refcount to %u.\n", device, refcount);
@@ -4473,8 +4473,8 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason,
va_list args;
va_start(args, message);
- WARN("Device %p is lost (reason %#x, \"%s\").\n",
- device, reason, vkd3d_dbg_vsprintf(message, args));
+ WARN("Device %p is lost (reason %s, \"%s\").\n",
+ device, debugstr_hresult(reason), vkd3d_dbg_vsprintf(message, args));
va_end(args);
device->removed_reason = reason;
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
index a360b0ef4dd..cd2f9af0e39 100644
--- a/libs/vkd3d/libs/vkd3d/resource.c
+++ b/libs/vkd3d/libs/vkd3d/resource.c
@@ -308,7 +308,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_heap_QueryInterface(ID3D12Heap *iface,
static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
{
struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
- ULONG refcount = InterlockedIncrement(&heap->refcount);
+ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
TRACE("%p increasing refcount to %u.\n", heap, refcount);
@@ -345,7 +345,7 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap)
static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
{
struct d3d12_heap *heap = impl_from_ID3D12Heap(iface);
- ULONG refcount = InterlockedDecrement(&heap->refcount);
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount);
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
@@ -358,7 +358,7 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface)
static void d3d12_heap_resource_destroyed(struct d3d12_heap *heap)
{
- if (!InterlockedDecrement(&heap->resource_count) && (!heap->refcount || heap->is_private))
+ if (!vkd3d_atomic_decrement_u32(&heap->resource_count) && (!heap->refcount || heap->is_private))
d3d12_heap_destroy(heap);
}
@@ -1003,7 +1003,7 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12
static ULONG d3d12_resource_incref(struct d3d12_resource *resource)
{
- ULONG refcount = InterlockedIncrement(&resource->internal_refcount);
+ unsigned int refcount = vkd3d_atomic_increment_u32(&resource->internal_refcount);
TRACE("%p increasing refcount to %u.\n", resource, refcount);
@@ -1012,7 +1012,7 @@ static ULONG d3d12_resource_incref(struct d3d12_resource *resource)
static ULONG d3d12_resource_decref(struct d3d12_resource *resource)
{
- ULONG refcount = InterlockedDecrement(&resource->internal_refcount);
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->internal_refcount);
TRACE("%p decreasing refcount to %u.\n", resource, refcount);
@@ -1284,7 +1284,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource1 *
static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
- ULONG refcount = InterlockedIncrement(&resource->refcount);
+ unsigned int refcount = vkd3d_atomic_increment_u32(&resource->refcount);
TRACE("%p increasing refcount to %u.\n", resource, refcount);
@@ -1302,7 +1302,7 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface)
static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource1 *iface)
{
struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface);
- ULONG refcount = InterlockedDecrement(&resource->refcount);
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->refcount);
TRACE("%p decreasing refcount to %u.\n", resource, refcount);
@@ -2174,7 +2174,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device,
{
resource->heap = heap;
resource->heap_offset = heap_offset;
- InterlockedIncrement(&heap->resource_count);
+ vkd3d_atomic_increment_u32(&heap->resource_count);
}
else
{
@@ -4010,7 +4010,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_descriptor_heap_QueryInterface(ID3D12Desc
static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap *iface)
{
struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface);
- ULONG refcount = InterlockedIncrement(&heap->refcount);
+ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
TRACE("%p increasing refcount to %u.\n", heap, refcount);
@@ -4020,7 +4020,7 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap
static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHeap *iface)
{
struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface);
- ULONG refcount = InterlockedDecrement(&heap->refcount);
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount);
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
@@ -4429,7 +4429,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_query_heap_QueryInterface(ID3D12QueryHeap
static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface)
{
struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface);
- ULONG refcount = InterlockedIncrement(&heap->refcount);
+ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
TRACE("%p increasing refcount to %u.\n", heap, refcount);
@@ -4439,7 +4439,7 @@ static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface)
static ULONG STDMETHODCALLTYPE d3d12_query_heap_Release(ID3D12QueryHeap *iface)
{
struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface);
- ULONG refcount = InterlockedDecrement(&heap->refcount);
+ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount);
TRACE("%p decreasing refcount to %u.\n", heap, refcount);
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index a6d5b94b778..92840871631 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -192,7 +192,7 @@ struct vkd3d_instance
uint64_t host_ticks_per_second;
- LONG refcount;
+ unsigned int refcount;
};
#ifdef _WIN32
@@ -665,8 +665,8 @@ VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint
struct d3d12_heap
{
ID3D12Heap ID3D12Heap_iface;
- LONG refcount;
- LONG resource_count;
+ unsigned int refcount;
+ unsigned int resource_count;
bool is_private;
D3D12_HEAP_DESC desc;
@@ -721,8 +721,8 @@ struct d3d12_resource_tile_info
struct d3d12_resource
{
ID3D12Resource1 ID3D12Resource1_iface;
- LONG refcount;
- LONG internal_refcount;
+ unsigned int refcount;
+ unsigned int internal_refcount;
D3D12_RESOURCE_DESC desc;
const struct vkd3d_format *format;
@@ -1046,7 +1046,7 @@ struct d3d12_descriptor_heap_vk_set
struct d3d12_descriptor_heap
{
ID3D12DescriptorHeap ID3D12DescriptorHeap_iface;
- LONG refcount;
+ unsigned int refcount;
uint64_t serial_id;
D3D12_DESCRIPTOR_HEAP_DESC desc;
@@ -1085,7 +1085,7 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device,
struct d3d12_query_heap
{
ID3D12QueryHeap ID3D12QueryHeap_iface;
- LONG refcount;
+ unsigned int refcount;
VkQueryPool vk_query_pool;
@@ -1749,7 +1749,7 @@ struct vkd3d_desc_object_cache
struct d3d12_device
{
ID3D12Device5 ID3D12Device5_iface;
- LONG refcount;
+ unsigned int refcount;
VkDevice vk_device;
VkPhysicalDevice vk_physical_device;
--
2.43.0