mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
1766 lines
78 KiB
Diff
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(¶m->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
|
|
|