mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
5120 lines
223 KiB
Diff
5120 lines
223 KiB
Diff
From 7a3d9f859ea9571d19d388781f91855a4e06f122 Mon Sep 17 00:00:00 2001
|
|
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
|
Date: Thu, 3 Aug 2023 08:38:38 +1000
|
|
Subject: [PATCH 3/3] Updated vkd3d to
|
|
b4bb3931c5e7e59496c07c2d4e3b6cfd3bf91cf1.
|
|
|
|
---
|
|
include/d3d12.idl | 66 +++
|
|
libs/vkd3d/include/private/vkd3d_common.h | 15 +
|
|
libs/vkd3d/include/vkd3d_shader.h | 59 ++-
|
|
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 104 +++-
|
|
libs/vkd3d/libs/vkd3d-shader/dxil.c | 59 ++-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 32 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 +-
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 494 ++++++++++++------
|
|
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 152 +++---
|
|
libs/vkd3d/libs/vkd3d-shader/ir.c | 159 +++++-
|
|
libs/vkd3d/libs/vkd3d-shader/preproc.l | 140 +++--
|
|
libs/vkd3d/libs/vkd3d-shader/spirv.c | 164 ++++--
|
|
libs/vkd3d/libs/vkd3d-shader/tpf.c | 83 ++-
|
|
.../libs/vkd3d-shader/vkd3d_shader_main.c | 9 +
|
|
.../libs/vkd3d-shader/vkd3d_shader_private.h | 15 +-
|
|
libs/vkd3d/libs/vkd3d/command.c | 451 +++++++++-------
|
|
libs/vkd3d/libs/vkd3d/device.c | 20 +-
|
|
libs/vkd3d/libs/vkd3d/resource.c | 238 ++++++++-
|
|
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 55 +-
|
|
19 files changed, 1756 insertions(+), 563 deletions(-)
|
|
|
|
diff --git a/include/d3d12.idl b/include/d3d12.idl
|
|
index c6064939e1f..5811608b94f 100644
|
|
--- a/include/d3d12.idl
|
|
+++ b/include/d3d12.idl
|
|
@@ -44,6 +44,7 @@ const UINT D3D12_DEFAULT_STENCIL_WRITE_MASK = 0xff;
|
|
const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff;
|
|
cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)")
|
|
const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32;
|
|
+const UINT D3D12_PACKED_TILE = 0xffffffff;
|
|
const UINT D3D12_UAV_SLOT_COUNT = 64;
|
|
const UINT D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096;
|
|
const UINT D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096;
|
|
@@ -72,6 +73,7 @@ const UINT D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT = 4096;
|
|
const UINT D3D12_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4;
|
|
const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256;
|
|
const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512;
|
|
+const UINT D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES = 65536;
|
|
const UINT D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT = 4096;
|
|
const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32;
|
|
const UINT D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16;
|
|
@@ -1853,6 +1855,24 @@ typedef struct D3D12_WRITEBUFFERIMMEDIATE_PARAMETER
|
|
UINT32 Value;
|
|
} D3D12_WRITEBUFFERIMMEDIATE_PARAMETER;
|
|
|
|
+typedef enum D3D12_PROTECTED_RESOURCE_SESSION_FLAGS
|
|
+{
|
|
+ D3D12_PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0,
|
|
+} D3D12_PROTECTED_RESOURCE_SESSION_FLAGS;
|
|
+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_PROTECTED_RESOURCE_SESSION_FLAGS);")
|
|
+
|
|
+typedef enum D3D12_PROTECTED_SESSION_STATUS
|
|
+{
|
|
+ D3D12_PROTECTED_SESSION_STATUS_OK = 0,
|
|
+ D3D12_PROTECTED_SESSION_STATUS_INVALID = 1,
|
|
+} D3D12_PROTECTED_SESSION_STATUS;
|
|
+
|
|
+typedef struct D3D12_PROTECTED_RESOURCE_SESSION_DESC
|
|
+{
|
|
+ UINT NodeMask;
|
|
+ D3D12_PROTECTED_RESOURCE_SESSION_FLAGS Flags;
|
|
+} D3D12_PROTECTED_RESOURCE_SESSION_DESC;
|
|
+
|
|
[
|
|
uuid(c4fec28f-7966-4e95-9f94-f431cb56c3b8),
|
|
object,
|
|
@@ -2214,6 +2234,41 @@ interface ID3D12GraphicsCommandList2 : ID3D12GraphicsCommandList1
|
|
const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes);
|
|
}
|
|
|
|
+[
|
|
+ uuid(a1533d18-0ac1-4084-85b9-89a96116806b),
|
|
+ object,
|
|
+ local,
|
|
+ pointer_default(unique)
|
|
+]
|
|
+interface ID3D12ProtectedSession : ID3D12DeviceChild
|
|
+{
|
|
+ HRESULT GetStatusFence(REFIID riid, void **fence);
|
|
+
|
|
+ D3D12_PROTECTED_SESSION_STATUS GetSessionStatus();
|
|
+}
|
|
+
|
|
+[
|
|
+ uuid(6cd696f4-f289-40cc-8091-5a6c0a099c3d),
|
|
+ object,
|
|
+ local,
|
|
+ pointer_default(unique)
|
|
+]
|
|
+interface ID3D12ProtectedResourceSession : ID3D12ProtectedSession
|
|
+{
|
|
+ D3D12_PROTECTED_RESOURCE_SESSION_DESC GetDesc();
|
|
+}
|
|
+
|
|
+[
|
|
+ uuid(6fda83a7-b84c-4e38-9ac8-c7bd22016b3d),
|
|
+ object,
|
|
+ local,
|
|
+ pointer_default(unique)
|
|
+]
|
|
+interface ID3D12GraphicsCommandList3 : ID3D12GraphicsCommandList2
|
|
+{
|
|
+ void SetProtectedResourceSession(ID3D12ProtectedResourceSession *protected_resource_session);
|
|
+}
|
|
+
|
|
typedef enum D3D12_TILE_RANGE_FLAGS
|
|
{
|
|
D3D12_TILE_RANGE_FLAG_NONE = 0x0,
|
|
@@ -2378,6 +2433,17 @@ interface ID3D12Fence : ID3D12Pageable
|
|
HRESULT Signal(UINT64 value);
|
|
}
|
|
|
|
+[
|
|
+ uuid(433685fe-e22b-4ca0-a8db-b5b4f4dd0e4a),
|
|
+ object,
|
|
+ local,
|
|
+ pointer_default(unique)
|
|
+]
|
|
+interface ID3D12Fence1 : ID3D12Fence
|
|
+{
|
|
+ D3D12_FENCE_FLAGS GetCreationFlags();
|
|
+}
|
|
+
|
|
[
|
|
uuid(6102dee4-af59-4b09-b999-b44d73f09b24),
|
|
object,
|
|
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
|
|
index 0263fc47297..f7d98f327f1 100644
|
|
--- a/libs/vkd3d/include/private/vkd3d_common.h
|
|
+++ b/libs/vkd3d/include/private/vkd3d_common.h
|
|
@@ -193,6 +193,21 @@ static inline int vkd3d_u32_compare(uint32_t x, uint32_t y)
|
|
return (x > y) - (x < y);
|
|
}
|
|
|
|
+static inline bool bitmap_clear(uint32_t *map, unsigned int idx)
|
|
+{
|
|
+ return map[idx >> 5] &= ~(1u << (idx & 0x1f));
|
|
+}
|
|
+
|
|
+static inline bool bitmap_set(uint32_t *map, unsigned int idx)
|
|
+{
|
|
+ return map[idx >> 5] |= (1u << (idx & 0x1f));
|
|
+}
|
|
+
|
|
+static inline bool bitmap_is_set(const uint32_t *map, unsigned int idx)
|
|
+{
|
|
+ return map[idx >> 5] & (1u << (idx & 0x1f));
|
|
+}
|
|
+
|
|
static inline int ascii_isupper(int c)
|
|
{
|
|
return 'A' <= c && c <= 'Z';
|
|
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
|
|
index 6c17a07b9d2..d6653d18e56 100644
|
|
--- a/libs/vkd3d/include/vkd3d_shader.h
|
|
+++ b/libs/vkd3d/include/vkd3d_shader.h
|
|
@@ -139,6 +139,14 @@ enum vkd3d_shader_compile_option_formatting_flags
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FORMATTING_FLAGS),
|
|
};
|
|
|
|
+enum vkd3d_shader_compile_option_pack_matrix_order
|
|
+{
|
|
+ VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR = 0x00000001,
|
|
+ VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR = 0x00000002,
|
|
+
|
|
+ VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER),
|
|
+};
|
|
+
|
|
enum vkd3d_shader_compile_option_name
|
|
{
|
|
/**
|
|
@@ -169,6 +177,15 @@ enum vkd3d_shader_compile_option_name
|
|
* \since 1.7
|
|
*/
|
|
VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE = 0x00000006,
|
|
+ /**
|
|
+ * This option specifies default matrix packing order. It's only supported for HLSL source type.
|
|
+ * Explicit variable modifiers or pragmas will take precedence.
|
|
+ *
|
|
+ * \a value is a member of enum vkd3d_shader_compile_option_pack_matrix_order.
|
|
+ *
|
|
+ * \since 1.9
|
|
+ */
|
|
+ VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER = 0x00000007,
|
|
|
|
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
|
|
};
|
|
@@ -332,6 +349,25 @@ struct vkd3d_shader_parameter
|
|
} u;
|
|
};
|
|
|
|
+/**
|
|
+ * Symbolic register indices for mapping uniform constant register sets in
|
|
+ * legacy Direct3D bytecode to constant buffer views in the target environment.
|
|
+ *
|
|
+ * Members of this enumeration are used in
|
|
+ * \ref vkd3d_shader_resource_binding.register_index.
|
|
+ *
|
|
+ * \since 1.9
|
|
+ */
|
|
+enum vkd3d_shader_d3dbc_constant_register
|
|
+{
|
|
+ /** The float constant register set, c# in Direct3D assembly. */
|
|
+ VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER = 0x0,
|
|
+ /** The integer constant register set, i# in Direct3D assembly. */
|
|
+ VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER = 0x1,
|
|
+ /** The boolean constant register set, b# in Direct3D assembly. */
|
|
+ VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER = 0x2,
|
|
+};
|
|
+
|
|
/**
|
|
* Describes the mapping of a single resource or resource array to its binding
|
|
* point in the target environment.
|
|
@@ -356,7 +392,14 @@ struct vkd3d_shader_resource_binding
|
|
* support multiple register spaces, this parameter must be set to 0.
|
|
*/
|
|
unsigned int register_space;
|
|
- /** Register index of the DXBC resource. */
|
|
+ /**
|
|
+ * Register index of the Direct3D resource.
|
|
+ *
|
|
+ * For legacy Direct3D shaders, vkd3d-shader maps each constant register
|
|
+ * set to a single constant buffer view. This parameter names the register
|
|
+ * set to map, and must be a member of
|
|
+ * enum vkd3d_shader_d3dbc_constant_register.
|
|
+ */
|
|
unsigned int register_index;
|
|
/** Shader stage(s) to which the resource is visible. */
|
|
enum vkd3d_shader_visibility shader_visibility;
|
|
@@ -1330,6 +1373,20 @@ struct vkd3d_shader_descriptor_info
|
|
* A chained structure enumerating the descriptors declared by a shader.
|
|
*
|
|
* This structure extends vkd3d_shader_compile_info.
|
|
+ *
|
|
+ * When scanning a legacy Direct3D shader, vkd3d-shader enumerates each
|
|
+ * constant register set used by the shader as a single constant buffer
|
|
+ * descriptor, as follows:
|
|
+ * - The \ref vkd3d_shader_descriptor_info.type field is set to
|
|
+ * VKD3D_SHADER_DESCRIPTOR_TYPE_CBV.
|
|
+ * - The \ref vkd3d_shader_descriptor_info.register_space field is set to zero.
|
|
+ * - The \ref vkd3d_shader_descriptor_info.register_index field is set to a
|
|
+ * member of enum vkd3d_shader_d3dbc_constant_register denoting which set
|
|
+ * is used.
|
|
+ * - The \ref vkd3d_shader_descriptor_info.count field is set to one.
|
|
+ *
|
|
+ * In summary, there may be up to three such descriptors, one for each register
|
|
+ * set used by the shader: float, integer, and boolean.
|
|
*/
|
|
struct vkd3d_shader_scan_descriptor_info
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
index 369112ce18d..fe739339bd1 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
|
|
@@ -214,6 +214,9 @@ struct vkd3d_shader_sm1_parser
|
|
bool abort;
|
|
|
|
struct vkd3d_shader_parser p;
|
|
+
|
|
+#define MAX_CONSTANT_COUNT 8192
|
|
+ uint32_t constant_def_mask[3][MAX_CONSTANT_COUNT / 32];
|
|
};
|
|
|
|
/* This table is not order or position dependent. */
|
|
@@ -729,12 +732,60 @@ static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *
|
|
semantic->usage_idx, sysval, reg->idx[0].offset, true, mask);
|
|
}
|
|
|
|
-static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_register *reg, unsigned int mask)
|
|
+static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1,
|
|
+ enum vkd3d_shader_d3dbc_constant_register set, uint32_t index, bool from_def)
|
|
{
|
|
+ struct vkd3d_shader_desc *desc = &sm1->p.shader_desc;
|
|
+
|
|
+ desc->flat_constant_count[set].used = max(desc->flat_constant_count[set].used, index + 1);
|
|
+ if (from_def)
|
|
+ {
|
|
+ /* d3d shaders have a maximum of 8192 constants; we should not overrun
|
|
+ * this array. */
|
|
+ assert((index / 32) <= ARRAY_SIZE(sm1->constant_def_mask[set]));
|
|
+ bitmap_set(sm1->constant_def_mask[set], index);
|
|
+ }
|
|
+}
|
|
+
|
|
+static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1,
|
|
+ const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def)
|
|
+{
|
|
+ struct vkd3d_shader_desc *desc = &sm1->p.shader_desc;
|
|
uint32_t register_index = reg->idx[0].offset;
|
|
|
|
- if (reg->type == VKD3DSPR_TEMP)
|
|
- sm1->p.shader_desc.temp_count = max(sm1->p.shader_desc.temp_count, register_index + 1);
|
|
+ switch (reg->type)
|
|
+ {
|
|
+ case VKD3DSPR_TEMP:
|
|
+ desc->temp_count = max(desc->temp_count, register_index + 1);
|
|
+ break;
|
|
+
|
|
+ case VKD3DSPR_CONST:
|
|
+ record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, register_index, from_def);
|
|
+ break;
|
|
+
|
|
+ case VKD3DSPR_CONST2:
|
|
+ record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 2048 + register_index, from_def);
|
|
+ break;
|
|
+
|
|
+ case VKD3DSPR_CONST3:
|
|
+ record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 4096 + register_index, from_def);
|
|
+ break;
|
|
+
|
|
+ case VKD3DSPR_CONST4:
|
|
+ record_constant_register(sm1, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 6144 + register_index, from_def);
|
|
+ break;
|
|
+
|
|
+ case VKD3DSPR_CONSTINT:
|
|
+ record_constant_register(sm1, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, register_index, from_def);
|
|
+ break;
|
|
+
|
|
+ case VKD3DSPR_CONSTBOOL:
|
|
+ record_constant_register(sm1, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, register_index, from_def);
|
|
+ break;
|
|
+
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
|
|
add_signature_element_from_register(sm1, reg, false, mask);
|
|
}
|
|
@@ -1076,16 +1127,19 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|
{
|
|
shader_sm1_read_dst_param(sm1, &p, dst_param);
|
|
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_FLOAT);
|
|
+ shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
|
|
}
|
|
else if (ins->handler_idx == VKD3DSIH_DEFB)
|
|
{
|
|
shader_sm1_read_dst_param(sm1, &p, dst_param);
|
|
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_SCALAR, VKD3D_DATA_UINT);
|
|
+ shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
|
|
}
|
|
else if (ins->handler_idx == VKD3DSIH_DEFI)
|
|
{
|
|
shader_sm1_read_dst_param(sm1, &p, dst_param);
|
|
shader_sm1_read_immconst(sm1, &p, &src_params[0], VKD3D_IMMCONST_VEC4, VKD3D_DATA_INT);
|
|
+ shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true);
|
|
}
|
|
else
|
|
{
|
|
@@ -1093,7 +1147,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|
if (ins->dst_count)
|
|
{
|
|
shader_sm1_read_dst_param(sm1, &p, dst_param);
|
|
- shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask);
|
|
+ shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, false);
|
|
}
|
|
|
|
/* Predication token */
|
|
@@ -1104,7 +1158,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
|
|
for (i = 0; i < ins->src_count; ++i)
|
|
{
|
|
shader_sm1_read_src_param(sm1, &p, &src_params[i]);
|
|
- shader_sm1_scan_register(sm1, &src_params[i].reg, mask_from_swizzle(src_params[i].swizzle));
|
|
+ shader_sm1_scan_register(sm1, &src_params[i].reg, mask_from_swizzle(src_params[i].swizzle), false);
|
|
}
|
|
}
|
|
|
|
@@ -1212,12 +1266,30 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1,
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
+static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1,
|
|
+ enum vkd3d_shader_d3dbc_constant_register set)
|
|
+{
|
|
+ unsigned int j;
|
|
+
|
|
+ /* Find the highest constant index which is not written by a DEF
|
|
+ * instruction. We can't (easily) use an FFZ function for this since it
|
|
+ * needs to be limited by the highest used register index. */
|
|
+ for (j = sm1->p.shader_desc.flat_constant_count[set].used; j > 0; --j)
|
|
+ {
|
|
+ if (!bitmap_is_set(sm1->constant_def_mask[set], j - 1))
|
|
+ return j;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compile_info,
|
|
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser)
|
|
{
|
|
struct vkd3d_shader_instruction_array *instructions;
|
|
struct vkd3d_shader_instruction *ins;
|
|
struct vkd3d_shader_sm1_parser *sm1;
|
|
+ unsigned int i;
|
|
int ret;
|
|
|
|
if (!(sm1 = vkd3d_calloc(1, sizeof(*sm1))))
|
|
@@ -1257,6 +1329,9 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi
|
|
|
|
*parser = &sm1->p;
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(sm1->p.shader_desc.flat_constant_count); ++i)
|
|
+ sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i);
|
|
+
|
|
return sm1->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK;
|
|
}
|
|
|
|
@@ -1959,7 +2034,12 @@ static void write_sm1_sampler_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
|
|
if (var->objects_usage[HLSL_REGSET_SAMPLERS][i].used)
|
|
{
|
|
sampler_dim = var->objects_usage[HLSL_REGSET_SAMPLERS][i].sampler_dim;
|
|
- assert(sampler_dim != HLSL_SAMPLER_DIM_GENERIC);
|
|
+ if (sampler_dim == HLSL_SAMPLER_DIM_GENERIC)
|
|
+ {
|
|
+ /* These can appear in sm4-style combined sample instructions. */
|
|
+ hlsl_fixme(ctx, &var->loc, "Generic samplers need to be lowered.");
|
|
+ continue;
|
|
+ }
|
|
|
|
reg_id = var->regs[HLSL_REGSET_SAMPLERS].id + i;
|
|
write_sm1_sampler_dcl(ctx, buffer, reg_id, sampler_dim);
|
|
@@ -2362,7 +2442,6 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b
|
|
int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out)
|
|
{
|
|
struct vkd3d_bytecode_buffer buffer = {0};
|
|
- int ret;
|
|
|
|
put_u32(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version));
|
|
|
|
@@ -2375,10 +2454,17 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun
|
|
|
|
put_u32(&buffer, D3DSIO_END);
|
|
|
|
- if (!(ret = buffer.status))
|
|
+ if (buffer.status)
|
|
+ ctx->result = buffer.status;
|
|
+
|
|
+ if (!ctx->result)
|
|
{
|
|
out->code = buffer.data;
|
|
out->size = buffer.size;
|
|
}
|
|
- return ret;
|
|
+ else
|
|
+ {
|
|
+ vkd3d_free(buffer.data);
|
|
+ }
|
|
+ return ctx->result;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
index 53a4c2da4ba..f9efe47f95d 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
|
|
@@ -208,6 +208,7 @@ struct sm6_value
|
|
{
|
|
const struct sm6_type *type;
|
|
enum sm6_value_type value_type;
|
|
+ bool is_undefined;
|
|
union
|
|
{
|
|
struct sm6_function_data function;
|
|
@@ -1726,8 +1727,16 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
WARN("Unhandled constant array.\n");
|
|
break;
|
|
|
|
+ case CST_CODE_UNDEF:
|
|
+ dxil_record_validate_operand_max_count(record, 0, sm6);
|
|
+ dst->u.reg.type = VKD3DSPR_UNDEF;
|
|
+ /* Mark as explicitly undefined, not the result of a missing constant code or instruction. */
|
|
+ dst->is_undefined = true;
|
|
+ break;
|
|
+
|
|
default:
|
|
FIXME("Unhandled constant code %u.\n", record->code);
|
|
+ dst->u.reg.type = VKD3DSPR_UNDEF;
|
|
break;
|
|
}
|
|
|
|
@@ -1737,6 +1746,27 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
+static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra)
|
|
+{
|
|
+ if (!shader_instruction_array_reserve(&sm6->p.instructions, sm6->p.instructions.count + extra))
|
|
+ {
|
|
+ ERR("Failed to allocate instruction.\n");
|
|
+ return NULL;
|
|
+ }
|
|
+ return &sm6->p.instructions.elements[sm6->p.instructions.count];
|
|
+}
|
|
+
|
|
+/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */
|
|
+static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_parser *sm6,
|
|
+ enum vkd3d_shader_opcode handler_idx)
|
|
+{
|
|
+ struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1);
|
|
+ assert(ins);
|
|
+ shader_instruction_init(ins, handler_idx);
|
|
+ ++sm6->p.instructions.count;
|
|
+ return ins;
|
|
+}
|
|
+
|
|
static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
|
|
{
|
|
const struct dxil_block *block = &sm6->root_block;
|
|
@@ -1767,7 +1797,8 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
|
|
break;
|
|
|
|
case MODULE_CODE_VERSION:
|
|
- dxil_record_validate_operand_count(record, 1, 1, sm6);
|
|
+ if (!dxil_record_validate_operand_count(record, 1, 1, sm6))
|
|
+ return VKD3D_ERROR_INVALID_SHADER;
|
|
if ((version = record->operands[0]) != 1)
|
|
{
|
|
FIXME("Unsupported format version %#"PRIx64".\n", version);
|
|
@@ -1931,6 +1962,21 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
+static bool sm6_block_emit_instructions(struct sm6_block *block, struct sm6_parser *sm6)
|
|
+{
|
|
+ struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, block->instruction_count + 1);
|
|
+
|
|
+ if (!ins)
|
|
+ return false;
|
|
+
|
|
+ memcpy(ins, block->instructions, block->instruction_count * sizeof(*block->instructions));
|
|
+ sm6->p.instructions.count += block->instruction_count;
|
|
+
|
|
+ sm6_parser_add_instruction(sm6, VKD3DSIH_RET);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const struct dxil_block *block,
|
|
unsigned int level)
|
|
{
|
|
@@ -2065,6 +2111,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
struct vkd3d_shader_version version;
|
|
struct dxil_block *block;
|
|
enum vkd3d_result ret;
|
|
+ unsigned int i;
|
|
|
|
count = byte_code_size / sizeof(*byte_code);
|
|
if (count < 6)
|
|
@@ -2254,6 +2301,16 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
|
|
return ret;
|
|
}
|
|
|
|
+ for (i = 0; i < sm6->function_count; ++i)
|
|
+ {
|
|
+ if (!sm6_block_emit_instructions(sm6->functions[i].blocks[0], sm6))
|
|
+ {
|
|
+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
|
|
+ "Out of memory emitting shader instructions.");
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ }
|
|
+ }
|
|
+
|
|
dxil_block_destroy(&sm6->root_block);
|
|
|
|
return VKD3D_OK;
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
index ab508502623..4ed7712b0aa 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
|
|
@@ -2544,6 +2544,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
|
|
[HLSL_RESOURCE_GATHER_GREEN] = "gather_green",
|
|
[HLSL_RESOURCE_GATHER_BLUE] = "gather_blue",
|
|
[HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha",
|
|
+ [HLSL_RESOURCE_SAMPLE_INFO] = "sample_info",
|
|
+ [HLSL_RESOURCE_RESINFO] = "resinfo",
|
|
};
|
|
|
|
assert(load->load_type < ARRAY_SIZE(type_names));
|
|
@@ -2551,8 +2553,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
|
|
dump_deref(buffer, &load->resource);
|
|
vkd3d_string_buffer_printf(buffer, ", sampler = ");
|
|
dump_deref(buffer, &load->sampler);
|
|
- vkd3d_string_buffer_printf(buffer, ", coords = ");
|
|
- dump_src(buffer, &load->coords);
|
|
+ if (load->coords.node)
|
|
+ {
|
|
+ vkd3d_string_buffer_printf(buffer, ", coords = ");
|
|
+ dump_src(buffer, &load->coords);
|
|
+ }
|
|
if (load->sample_index.node)
|
|
{
|
|
vkd3d_string_buffer_printf(buffer, ", sample index = ");
|
|
@@ -3296,9 +3301,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
|
|
}
|
|
}
|
|
|
|
-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name,
|
|
+static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info,
|
|
const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context)
|
|
{
|
|
+ unsigned int i;
|
|
+
|
|
memset(ctx, 0, sizeof(*ctx));
|
|
|
|
ctx->profile = profile;
|
|
@@ -3307,7 +3314,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name,
|
|
|
|
if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files))))
|
|
return false;
|
|
- if (!(ctx->source_files[0] = hlsl_strdup(ctx, source_name ? source_name : "<anonymous>")))
|
|
+ if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : "<anonymous>")))
|
|
{
|
|
vkd3d_free(ctx->source_files);
|
|
return false;
|
|
@@ -3346,6 +3353,19 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name,
|
|
return false;
|
|
ctx->cur_buffer = ctx->globals_buffer;
|
|
|
|
+ for (i = 0; i < compile_info->option_count; ++i)
|
|
+ {
|
|
+ const struct vkd3d_shader_compile_option *option = &compile_info->options[i];
|
|
+
|
|
+ if (option->name == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER)
|
|
+ {
|
|
+ if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR)
|
|
+ ctx->matrix_majority = HLSL_MODIFIER_ROW_MAJOR;
|
|
+ else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR)
|
|
+ ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR;
|
|
+ }
|
|
+ }
|
|
+
|
|
return true;
|
|
}
|
|
|
|
@@ -3380,6 +3400,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx)
|
|
vkd3d_free((void *)buffer->name);
|
|
vkd3d_free(buffer);
|
|
}
|
|
+
|
|
+ vkd3d_free(ctx->constant_defs.regs);
|
|
}
|
|
|
|
int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info,
|
|
@@ -3421,7 +3443,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
|
|
return VKD3D_ERROR_INVALID_ARGUMENT;
|
|
}
|
|
|
|
- if (!hlsl_ctx_init(&ctx, compile_info->source_name, profile, message_context))
|
|
+ if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context))
|
|
return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
|
|
if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2)
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
index 1a4b995abbf..b1928312066 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
|
|
@@ -634,6 +634,8 @@ enum hlsl_resource_load_type
|
|
HLSL_RESOURCE_GATHER_GREEN,
|
|
HLSL_RESOURCE_GATHER_BLUE,
|
|
HLSL_RESOURCE_GATHER_ALPHA,
|
|
+ HLSL_RESOURCE_SAMPLE_INFO,
|
|
+ HLSL_RESOURCE_RESINFO,
|
|
};
|
|
|
|
struct hlsl_ir_resource_load
|
|
@@ -1074,7 +1076,7 @@ struct vkd3d_string_buffer *hlsl_component_to_string(struct hlsl_ctx *ctx, const
|
|
struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, unsigned int modifiers);
|
|
const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type);
|
|
|
|
-struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs,
|
|
+struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false);
|
|
void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl);
|
|
bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
index 6bf87f8f916..0695f7864bf 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
|
|
@@ -146,14 +146,6 @@ static struct list *block_to_list(struct hlsl_block *block)
|
|
return &block->instrs;
|
|
}
|
|
|
|
-static struct hlsl_block *list_to_block(struct list *list)
|
|
-{
|
|
- /* This is a temporary hack to ease the transition from lists to blocks.
|
|
- * It takes advantage of the fact that an allocated hlsl_block pointer is
|
|
- * byte-compatible with an allocated list pointer. */
|
|
- return CONTAINING_RECORD(list, struct hlsl_block, instrs);
|
|
-}
|
|
-
|
|
static struct hlsl_block *make_empty_block(struct hlsl_ctx *ctx)
|
|
{
|
|
struct hlsl_block *block;
|
|
@@ -172,12 +164,6 @@ static struct list *make_empty_list(struct hlsl_ctx *ctx)
|
|
return list;
|
|
}
|
|
|
|
-static void destroy_instr_list(struct list *list)
|
|
-{
|
|
- hlsl_free_instr_list(list);
|
|
- vkd3d_free(list);
|
|
-}
|
|
-
|
|
static void destroy_block(struct hlsl_block *block)
|
|
{
|
|
hlsl_block_cleanup(block);
|
|
@@ -308,7 +294,7 @@ static bool implicit_compatible_data_types(struct hlsl_ctx *ctx, struct hlsl_typ
|
|
return hlsl_types_are_componentwise_equal(ctx, src, dst);
|
|
}
|
|
|
|
-static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
|
|
+static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc)
|
|
{
|
|
struct hlsl_type *src_type = node->data_type;
|
|
@@ -345,7 +331,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
|
|
{
|
|
struct hlsl_ir_node *component_load;
|
|
struct hlsl_type *dst_comp_type;
|
|
- struct hlsl_block block;
|
|
+ struct hlsl_block store_block;
|
|
unsigned int src_idx;
|
|
|
|
if (broadcast)
|
|
@@ -365,21 +351,21 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
|
|
|
|
dst_comp_type = hlsl_type_get_component_type(ctx, dst_type, dst_idx);
|
|
|
|
- if (!(component_load = hlsl_add_load_component(ctx, instrs, node, src_idx, loc)))
|
|
+ if (!(component_load = hlsl_add_load_component(ctx, block_to_list(block), node, src_idx, loc)))
|
|
return NULL;
|
|
|
|
if (!(cast = hlsl_new_cast(ctx, component_load, dst_comp_type, loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &cast->entry);
|
|
+ hlsl_block_add_instr(block, cast);
|
|
|
|
- if (!hlsl_new_store_component(ctx, &block, &var_deref, dst_idx, cast))
|
|
+ if (!hlsl_new_store_component(ctx, &store_block, &var_deref, dst_idx, cast))
|
|
return NULL;
|
|
- list_move_tail(instrs, &block.instrs);
|
|
+ hlsl_block_add_block(block, &store_block);
|
|
}
|
|
|
|
if (!(load = hlsl_new_var_load(ctx, var, loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &load->node.entry);
|
|
+ hlsl_block_add_instr(block, &load->node);
|
|
|
|
return &load->node;
|
|
}
|
|
@@ -387,12 +373,12 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct list *instrs,
|
|
{
|
|
if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &cast->entry);
|
|
+ hlsl_block_add_instr(block, cast);
|
|
return cast;
|
|
}
|
|
}
|
|
|
|
-static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct list *instrs,
|
|
+static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc)
|
|
{
|
|
struct hlsl_type *src_type = node->data_type;
|
|
@@ -418,7 +404,7 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct
|
|
hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.",
|
|
src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix");
|
|
|
|
- return add_cast(ctx, instrs, node, dst_type, loc);
|
|
+ return add_cast(ctx, block, node, dst_type, loc);
|
|
}
|
|
|
|
static DWORD add_modifiers(struct hlsl_ctx *ctx, DWORD modifiers, DWORD mod,
|
|
@@ -665,7 +651,7 @@ static bool add_return(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
{
|
|
struct hlsl_ir_node *store;
|
|
|
|
- if (!(return_value = add_implicit_conversion(ctx, block_to_list(block), return_value, return_type, loc)))
|
|
+ if (!(return_value = add_implicit_conversion(ctx, block, return_value, return_type, loc)))
|
|
return false;
|
|
|
|
if (!(store = hlsl_new_simple_store(ctx, ctx->cur_function->return_var, return_value)))
|
|
@@ -736,7 +722,7 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str
|
|
enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2,
|
|
const struct vkd3d_shader_location *loc);
|
|
|
|
-static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *array,
|
|
+static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *array,
|
|
struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type;
|
|
@@ -759,13 +745,13 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h
|
|
return false;
|
|
}
|
|
|
|
- if (!(index = add_implicit_conversion(ctx, instrs, index,
|
|
+ if (!(index = add_implicit_conversion(ctx, block, index,
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc)))
|
|
return false;
|
|
|
|
if (!(return_index = hlsl_new_index(ctx, array, index, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &return_index->entry);
|
|
+ hlsl_block_add_instr(block, return_index);
|
|
|
|
return true;
|
|
}
|
|
@@ -778,7 +764,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h
|
|
|
|
if (!(cast = hlsl_new_cast(ctx, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &cast->entry);
|
|
+ hlsl_block_add_instr(block, cast);
|
|
index = cast;
|
|
|
|
if (expr_type->class != HLSL_CLASS_ARRAY && expr_type->class != HLSL_CLASS_VECTOR && expr_type->class != HLSL_CLASS_MATRIX)
|
|
@@ -792,7 +778,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct list *instrs, struct h
|
|
|
|
if (!(return_index = hlsl_new_index(ctx, array, index, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &return_index->entry);
|
|
+ hlsl_block_add_instr(block, return_index);
|
|
|
|
return true;
|
|
}
|
|
@@ -1117,17 +1103,17 @@ static struct hlsl_ir_function_decl *get_func_decl(struct rb_tree *funcs,
|
|
return NULL;
|
|
}
|
|
|
|
-static struct list *make_list(struct hlsl_ctx *ctx, struct hlsl_ir_node *node)
|
|
+static struct hlsl_block *make_block(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr)
|
|
{
|
|
- struct list *list;
|
|
+ struct hlsl_block *block;
|
|
|
|
- if (!(list = make_empty_list(ctx)))
|
|
+ if (!(block = make_empty_block(ctx)))
|
|
{
|
|
- hlsl_free_instr(node);
|
|
+ hlsl_free_instr(instr);
|
|
return NULL;
|
|
}
|
|
- list_add_tail(list, &node->entry);
|
|
- return list;
|
|
+ hlsl_block_add_instr(block, instr);
|
|
+ return block;
|
|
}
|
|
|
|
static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
@@ -1165,7 +1151,7 @@ static unsigned int evaluate_static_expression_as_uint(struct hlsl_ctx *ctx, str
|
|
return 0;
|
|
hlsl_block_add_block(&expr, block);
|
|
|
|
- if (!add_implicit_conversion(ctx, &expr.instrs, node_from_block(&expr),
|
|
+ if (!add_implicit_conversion(ctx, &expr, node_from_block(&expr),
|
|
hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))
|
|
{
|
|
hlsl_block_cleanup(&expr);
|
|
@@ -1323,7 +1309,7 @@ static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct
|
|
return true;
|
|
}
|
|
|
|
-static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
|
|
+static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS],
|
|
struct hlsl_type *type, const struct vkd3d_shader_location *loc)
|
|
{
|
|
@@ -1347,38 +1333,38 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct list *instrs,
|
|
for (i = 0; i < type->dimy * type->dimx; ++i)
|
|
{
|
|
struct hlsl_ir_node *value, *cell_operands[HLSL_MAX_OPERANDS] = { NULL };
|
|
- struct hlsl_block block;
|
|
+ struct hlsl_block store_block;
|
|
unsigned int j;
|
|
|
|
for (j = 0; j < HLSL_MAX_OPERANDS; j++)
|
|
{
|
|
if (operands[j])
|
|
{
|
|
- if (!(load = hlsl_add_load_component(ctx, instrs, operands[j], i, loc)))
|
|
+ if (!(load = hlsl_add_load_component(ctx, block_to_list(block), operands[j], i, loc)))
|
|
return NULL;
|
|
|
|
cell_operands[j] = load;
|
|
}
|
|
}
|
|
|
|
- if (!(value = add_expr(ctx, instrs, op, cell_operands, scalar_type, loc)))
|
|
+ if (!(value = add_expr(ctx, block, op, cell_operands, scalar_type, loc)))
|
|
return NULL;
|
|
|
|
- if (!hlsl_new_store_component(ctx, &block, &var_deref, i, value))
|
|
+ if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, value))
|
|
return NULL;
|
|
- list_move_tail(instrs, &block.instrs);
|
|
+ hlsl_block_add_block(block, &store_block);
|
|
}
|
|
|
|
if (!(var_load = hlsl_new_var_load(ctx, var, loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &var_load->node.entry);
|
|
+ hlsl_block_add_instr(block, &var_load->node);
|
|
|
|
return &var_load->node;
|
|
}
|
|
|
|
if (!(expr = hlsl_new_expr(ctx, op, operands, type, loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &expr->entry);
|
|
+ hlsl_block_add_instr(block, expr);
|
|
|
|
return expr;
|
|
}
|
|
@@ -1409,7 +1395,7 @@ static struct hlsl_ir_node *add_unary_arithmetic_expr(struct hlsl_ctx *ctx, stru
|
|
{
|
|
struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {arg};
|
|
|
|
- return add_expr(ctx, block_to_list(block), op, args, arg->data_type, loc);
|
|
+ return add_expr(ctx, block, op, args, arg->data_type, loc);
|
|
}
|
|
|
|
static struct hlsl_ir_node *add_unary_bitwise_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
@@ -1429,10 +1415,10 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct
|
|
bool_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_BOOL,
|
|
arg->data_type->dimx, arg->data_type->dimy);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg, bool_type, loc)))
|
|
+ if (!(args[0] = add_implicit_conversion(ctx, block, arg, bool_type, loc)))
|
|
return NULL;
|
|
|
|
- return add_expr(ctx, block_to_list(block), op, args, bool_type, loc);
|
|
+ return add_expr(ctx, block, op, args, bool_type, loc);
|
|
}
|
|
|
|
static struct hlsl_type *get_common_numeric_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *arg1,
|
|
@@ -1457,13 +1443,13 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str
|
|
|
|
common_type = get_common_numeric_type(ctx, arg1, arg2, loc);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, common_type, loc)))
|
|
+ if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc)))
|
|
return NULL;
|
|
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, common_type, loc)))
|
|
+ if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc)))
|
|
return NULL;
|
|
|
|
- return add_expr(ctx, block_to_list(block), op, args, common_type, loc);
|
|
+ return add_expr(ctx, block, op, args, common_type, loc);
|
|
}
|
|
|
|
static struct hlsl_ir_node *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
@@ -1492,13 +1478,13 @@ static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, str
|
|
common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy);
|
|
return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, common_type, loc)))
|
|
+ if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc)))
|
|
return NULL;
|
|
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, common_type, loc)))
|
|
+ if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc)))
|
|
return NULL;
|
|
|
|
- return add_expr(ctx, block_to_list(block), op, args, return_type, loc);
|
|
+ return add_expr(ctx, block, op, args, return_type, loc);
|
|
}
|
|
|
|
static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
@@ -1515,13 +1501,13 @@ static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct
|
|
|
|
common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, common_type, loc)))
|
|
+ if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc)))
|
|
return NULL;
|
|
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, common_type, loc)))
|
|
+ if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc)))
|
|
return NULL;
|
|
|
|
- return add_expr(ctx, block_to_list(block), op, args, common_type, loc);
|
|
+ return add_expr(ctx, block, op, args, common_type, loc);
|
|
}
|
|
|
|
static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct hlsl_block *block,
|
|
@@ -1546,13 +1532,13 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h
|
|
return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy);
|
|
integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block_to_list(block), arg1, return_type, loc)))
|
|
+ if (!(args[0] = add_implicit_conversion(ctx, block, arg1, return_type, loc)))
|
|
return NULL;
|
|
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block_to_list(block), arg2, integer_type, loc)))
|
|
+ if (!(args[1] = add_implicit_conversion(ctx, block, arg2, integer_type, loc)))
|
|
return NULL;
|
|
|
|
- return add_expr(ctx, block_to_list(block), op, args, return_type, loc);
|
|
+ return add_expr(ctx, block, op, args, return_type, loc);
|
|
}
|
|
|
|
static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
|
|
@@ -1599,13 +1585,13 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls
|
|
common_type = hlsl_get_vector_type(ctx, base, dim);
|
|
ret_type = hlsl_get_scalar_type(ctx, base);
|
|
|
|
- if (!(args[0] = add_implicit_conversion(ctx, block_to_list(instrs), arg1, common_type, loc)))
|
|
+ if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc)))
|
|
return NULL;
|
|
|
|
- if (!(args[1] = add_implicit_conversion(ctx, block_to_list(instrs), arg2, common_type, loc)))
|
|
+ if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc)))
|
|
return NULL;
|
|
|
|
- return add_expr(ctx, block_to_list(instrs), op, args, ret_type, loc);
|
|
+ return add_expr(ctx, instrs, op, args, ret_type, loc);
|
|
}
|
|
|
|
static struct hlsl_block *add_binary_expr_merge(struct hlsl_ctx *ctx, struct hlsl_block *block1,
|
|
@@ -1711,7 +1697,7 @@ static bool invert_swizzle(unsigned int *swizzle, unsigned int *writemask, unsig
|
|
return true;
|
|
}
|
|
|
|
-static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *lhs,
|
|
+static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *lhs,
|
|
enum parse_assign_op assign_op, struct hlsl_ir_node *rhs)
|
|
{
|
|
struct hlsl_type *lhs_type = lhs->data_type;
|
|
@@ -1720,7 +1706,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
|
|
if (assign_op == ASSIGN_OP_SUB)
|
|
{
|
|
- if (!(rhs = add_unary_arithmetic_expr(ctx, list_to_block(instrs), HLSL_OP1_NEG, rhs, &rhs->loc)))
|
|
+ if (!(rhs = add_unary_arithmetic_expr(ctx, block, HLSL_OP1_NEG, rhs, &rhs->loc)))
|
|
return NULL;
|
|
assign_op = ASSIGN_OP_ADD;
|
|
}
|
|
@@ -1729,14 +1715,14 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
enum hlsl_ir_expr_op op = op_from_assignment(assign_op);
|
|
|
|
assert(op);
|
|
- if (!(rhs = add_binary_arithmetic_expr(ctx, list_to_block(instrs), op, lhs, rhs, &rhs->loc)))
|
|
+ if (!(rhs = add_binary_arithmetic_expr(ctx, block, op, lhs, rhs, &rhs->loc)))
|
|
return NULL;
|
|
}
|
|
|
|
if (lhs_type->class <= HLSL_CLASS_LAST_NUMERIC)
|
|
writemask = (1 << lhs_type->dimx) - 1;
|
|
|
|
- if (!(rhs = add_implicit_conversion(ctx, instrs, rhs, lhs_type, &rhs->loc)))
|
|
+ if (!(rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc)))
|
|
return NULL;
|
|
|
|
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX)
|
|
@@ -1765,7 +1751,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
{
|
|
return NULL;
|
|
}
|
|
- list_add_tail(instrs, &new_swizzle->entry);
|
|
+ hlsl_block_add_instr(block, new_swizzle);
|
|
|
|
lhs = swizzle->val.node;
|
|
rhs = new_swizzle;
|
|
@@ -1811,7 +1797,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
hlsl_cleanup_deref(&resource_deref);
|
|
return NULL;
|
|
}
|
|
- list_add_tail(instrs, &store->entry);
|
|
+ hlsl_block_add_instr(block, store);
|
|
hlsl_cleanup_deref(&resource_deref);
|
|
}
|
|
else if (lhs->type == HLSL_IR_INDEX && hlsl_index_is_noncontiguous(hlsl_ir_index(lhs)))
|
|
@@ -1830,13 +1816,13 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
|
|
if (!(c = hlsl_new_uint_constant(ctx, i, &lhs->loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &c->entry);
|
|
+ hlsl_block_add_instr(block, c);
|
|
|
|
if (!(cell = hlsl_new_index(ctx, &row->node, c, &lhs->loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &cell->entry);
|
|
+ hlsl_block_add_instr(block, cell);
|
|
|
|
- if (!(load = hlsl_add_load_component(ctx, instrs, rhs, k++, &rhs->loc)))
|
|
+ if (!(load = hlsl_add_load_component(ctx, block_to_list(block), rhs, k++, &rhs->loc)))
|
|
return NULL;
|
|
|
|
if (!hlsl_init_deref_from_index_chain(ctx, &deref, cell))
|
|
@@ -1847,7 +1833,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
hlsl_cleanup_deref(&deref);
|
|
return NULL;
|
|
}
|
|
- list_add_tail(instrs, &store->entry);
|
|
+ hlsl_block_add_instr(block, store);
|
|
hlsl_cleanup_deref(&deref);
|
|
}
|
|
}
|
|
@@ -1864,7 +1850,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
hlsl_cleanup_deref(&deref);
|
|
return NULL;
|
|
}
|
|
- list_add_tail(instrs, &store->entry);
|
|
+ hlsl_block_add_instr(block, store);
|
|
hlsl_cleanup_deref(&deref);
|
|
}
|
|
|
|
@@ -1873,7 +1859,7 @@ static struct hlsl_ir_node *add_assignment(struct hlsl_ctx *ctx, struct list *in
|
|
* the last instruction in the list, we do need to copy. */
|
|
if (!(copy = hlsl_new_copy(ctx, rhs)))
|
|
return NULL;
|
|
- list_add_tail(instrs, ©->entry);
|
|
+ hlsl_block_add_instr(block, copy);
|
|
return copy;
|
|
}
|
|
|
|
@@ -1891,7 +1877,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d
|
|
return false;
|
|
hlsl_block_add_instr(block, one);
|
|
|
|
- if (!add_assignment(ctx, block_to_list(block), lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one))
|
|
+ if (!add_assignment(ctx, block, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one))
|
|
return false;
|
|
|
|
if (post)
|
|
@@ -1930,7 +1916,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i
|
|
|
|
dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index);
|
|
|
|
- if (!(conv = add_implicit_conversion(ctx, block_to_list(instrs), load, dst_comp_type, &src->loc)))
|
|
+ if (!(conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc)))
|
|
return;
|
|
|
|
if (!hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv))
|
|
@@ -2183,14 +2169,14 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v)
|
|
}
|
|
}
|
|
|
|
-static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list)
|
|
+static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list)
|
|
{
|
|
struct parse_variable_def *v, *v_next;
|
|
- struct list *statements_list;
|
|
+ struct hlsl_block *initializers;
|
|
struct hlsl_ir_var *var;
|
|
struct hlsl_type *type;
|
|
|
|
- if (!(statements_list = make_empty_list(ctx)))
|
|
+ if (!(initializers = make_empty_block(ctx)))
|
|
{
|
|
LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry)
|
|
{
|
|
@@ -2239,13 +2225,13 @@ static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list)
|
|
|
|
assert(v->initializer.args_count == 1);
|
|
hlsl_block_add_instr(v->initializer.instrs, &load->node);
|
|
- add_assignment(ctx, block_to_list(v->initializer.instrs), &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]);
|
|
+ add_assignment(ctx, v->initializer.instrs, &load->node, ASSIGN_OP_ASSIGN, v->initializer.args[0]);
|
|
}
|
|
|
|
if (var->storage_modifiers & HLSL_STORAGE_STATIC)
|
|
hlsl_block_add_block(&ctx->static_initializers, v->initializer.instrs);
|
|
else
|
|
- list_move_tail(statements_list, &v->initializer.instrs->instrs);
|
|
+ hlsl_block_add_block(initializers, v->initializer.instrs);
|
|
}
|
|
else if (var->storage_modifiers & HLSL_STORAGE_STATIC)
|
|
{
|
|
@@ -2266,7 +2252,7 @@ static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list)
|
|
}
|
|
hlsl_block_add_instr(&ctx->static_initializers, zero);
|
|
|
|
- if (!(cast = add_cast(ctx, &ctx->static_initializers.instrs, zero, var->data_type, &var->loc)))
|
|
+ if (!(cast = add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc)))
|
|
{
|
|
free_parse_variable_def(v);
|
|
continue;
|
|
@@ -2283,7 +2269,7 @@ static struct list *initialize_vars(struct hlsl_ctx *ctx, struct list *var_list)
|
|
}
|
|
|
|
vkd3d_free(var_list);
|
|
- return statements_list;
|
|
+ return initializers;
|
|
}
|
|
|
|
struct find_function_call_args
|
|
@@ -2364,7 +2350,7 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx,
|
|
return arg;
|
|
|
|
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy);
|
|
- return add_implicit_conversion(ctx, block_to_list(params->instrs), arg, type, loc);
|
|
+ return add_implicit_conversion(ctx, params->instrs, arg, type, loc);
|
|
}
|
|
|
|
static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params,
|
|
@@ -2376,7 +2362,7 @@ static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *p
|
|
{
|
|
struct hlsl_ir_node *new_arg;
|
|
|
|
- if (!(new_arg = add_implicit_conversion(ctx, block_to_list(params->instrs), params->args[i], type, loc)))
|
|
+ if (!(new_arg = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc)))
|
|
return false;
|
|
params->args[i] = new_arg;
|
|
}
|
|
@@ -2569,7 +2555,7 @@ static bool intrinsic_asfloat(struct hlsl_ctx *ctx,
|
|
data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_FLOAT);
|
|
|
|
operands[0] = params->args[0];
|
|
- return add_expr(ctx, block_to_list(params->instrs), HLSL_OP1_REINTERPRET, operands, data_type, loc);
|
|
+ return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc);
|
|
}
|
|
|
|
static bool intrinsic_asuint(struct hlsl_ctx *ctx,
|
|
@@ -2605,7 +2591,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx,
|
|
data_type = convert_numeric_type(ctx, data_type, HLSL_TYPE_UINT);
|
|
|
|
operands[0] = params->args[0];
|
|
- return add_expr(ctx, block_to_list(params->instrs), HLSL_OP1_REINTERPRET, operands, data_type, loc);
|
|
+ return add_expr(ctx, params->instrs, HLSL_OP1_REINTERPRET, operands, data_type, loc);
|
|
}
|
|
|
|
static bool intrinsic_clamp(struct hlsl_ctx *ctx,
|
|
@@ -2677,10 +2663,10 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx,
|
|
|
|
cast_type = hlsl_get_vector_type(ctx, base, 3);
|
|
|
|
- if (!(arg1_cast = add_implicit_conversion(ctx, block_to_list(params->instrs), arg1, cast_type, loc)))
|
|
+ if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc)))
|
|
return false;
|
|
|
|
- if (!(arg2_cast = add_implicit_conversion(ctx, block_to_list(params->instrs), arg2, cast_type, loc)))
|
|
+ if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc)))
|
|
return false;
|
|
|
|
if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc)))
|
|
@@ -2879,7 +2865,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer
|
|
if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc)))
|
|
return false;
|
|
|
|
- if (!(select = hlsl_add_conditional(ctx, block_to_list(params->instrs), ge, frac, neg_frac)))
|
|
+ if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac)))
|
|
return false;
|
|
|
|
return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, select, y, loc);
|
|
@@ -3042,7 +3028,7 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx,
|
|
if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc)))
|
|
return false;
|
|
|
|
- if (!(load = hlsl_add_conditional(ctx, block_to_list(params->instrs), specular_or, zero, specular_pow)))
|
|
+ if (!(load = hlsl_add_conditional(ctx, params->instrs, specular_or, zero, specular_pow)))
|
|
return false;
|
|
|
|
if (!hlsl_new_store_component(ctx, &block, &var_deref, 2, load))
|
|
@@ -3163,10 +3149,10 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx,
|
|
ret_type = hlsl_get_scalar_type(ctx, base);
|
|
}
|
|
|
|
- if (!(cast1 = add_implicit_conversion(ctx, block_to_list(params->instrs), arg1, cast_type1, loc)))
|
|
+ if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc)))
|
|
return false;
|
|
|
|
- if (!(cast2 = add_implicit_conversion(ctx, block_to_list(params->instrs), arg2, cast_type2, loc)))
|
|
+ if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc)))
|
|
return false;
|
|
|
|
if (!(var = hlsl_new_synthetic_var(ctx, "mul", matrix_type, loc)))
|
|
@@ -3216,7 +3202,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx,
|
|
return false;
|
|
hlsl_block_add_instr(params->instrs, &load->node);
|
|
|
|
- return !!add_implicit_conversion(ctx, block_to_list(params->instrs), &load->node, ret_type, loc);
|
|
+ return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc);
|
|
}
|
|
|
|
static bool intrinsic_normalize(struct hlsl_ctx *ctx,
|
|
@@ -3328,7 +3314,7 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx,
|
|
if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc)))
|
|
return false;
|
|
|
|
- if (!(op1 = add_implicit_conversion(ctx, block_to_list(params->instrs), lt, int_type, loc)))
|
|
+ if (!(op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc)))
|
|
return false;
|
|
|
|
/* Check if arg < 0, cast bool to int and invert (meaning true is -1) */
|
|
@@ -3336,7 +3322,7 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx,
|
|
if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, zero, loc)))
|
|
return false;
|
|
|
|
- if (!(op2 = add_implicit_conversion(ctx, block_to_list(params->instrs), lt, int_type, loc)))
|
|
+ if (!(op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc)))
|
|
return false;
|
|
|
|
if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, op2, loc)))
|
|
@@ -3441,7 +3427,7 @@ static bool intrinsic_step(struct hlsl_ctx *ctx,
|
|
|
|
type = ge->data_type;
|
|
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy);
|
|
- return !!add_implicit_conversion(ctx, block_to_list(params->instrs), ge, type, loc);
|
|
+ return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc);
|
|
}
|
|
|
|
static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *params,
|
|
@@ -3476,7 +3462,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
|
|
hlsl_release_string_buffer(ctx, string);
|
|
}
|
|
|
|
- if (!(coords = add_implicit_conversion(ctx, block_to_list(params->instrs), params->args[1],
|
|
+ if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc)))
|
|
coords = params->args[1];
|
|
|
|
@@ -3684,7 +3670,14 @@ static int intrinsic_function_name_compare(const void *a, const void *b)
|
|
return strcmp(a, func->name);
|
|
}
|
|
|
|
-static struct list *add_call(struct hlsl_ctx *ctx, const char *name,
|
|
+static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
|
|
+
|
|
+ return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc);
|
|
+}
|
|
+
|
|
+static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name,
|
|
struct parse_initializer *args, const struct vkd3d_shader_location *loc)
|
|
{
|
|
struct intrinsic_function *intrinsic;
|
|
@@ -3706,7 +3699,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name,
|
|
{
|
|
struct hlsl_ir_node *cast;
|
|
|
|
- if (!(cast = add_cast(ctx, block_to_list(args->instrs), arg, param->data_type, &arg->loc)))
|
|
+ if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc)))
|
|
goto fail;
|
|
args->args[i] = cast;
|
|
arg = cast;
|
|
@@ -3743,7 +3736,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name,
|
|
goto fail;
|
|
hlsl_block_add_instr(args->instrs, &load->node);
|
|
|
|
- if (!add_assignment(ctx, block_to_list(args->instrs), arg, ASSIGN_OP_ASSIGN, &load->node))
|
|
+ if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node))
|
|
goto fail;
|
|
}
|
|
}
|
|
@@ -3758,10 +3751,9 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name,
|
|
}
|
|
else
|
|
{
|
|
- struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
|
|
struct hlsl_ir_node *expr;
|
|
|
|
- if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc)))
|
|
+ if (!(expr = hlsl_new_void_expr(ctx, loc)))
|
|
goto fail;
|
|
hlsl_block_add_instr(args->instrs, expr);
|
|
}
|
|
@@ -3812,7 +3804,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name,
|
|
goto fail;
|
|
}
|
|
vkd3d_free(args->args);
|
|
- return block_to_list(args->instrs);
|
|
+ return args->instrs;
|
|
|
|
fail:
|
|
free_parse_initializer(args);
|
|
@@ -3890,7 +3882,7 @@ static bool raise_invalid_method_object_type(struct hlsl_ctx *ctx, const struct
|
|
return false;
|
|
}
|
|
|
|
-static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
@@ -3918,7 +3910,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru
|
|
}
|
|
if (multisampled)
|
|
{
|
|
- if (!(load_params.sample_index = add_implicit_conversion(ctx, instrs, params->args[1],
|
|
+ if (!(load_params.sample_index = add_implicit_conversion(ctx, block, params->args[1],
|
|
hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc)))
|
|
return false;
|
|
}
|
|
@@ -3926,7 +3918,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru
|
|
assert(offset_dim);
|
|
if (params->args_count > 1 + multisampled)
|
|
{
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[1 + multisampled],
|
|
+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[1 + multisampled],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
return false;
|
|
}
|
|
@@ -3936,7 +3928,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru
|
|
}
|
|
|
|
/* +1 for the mipmap level for non-multisampled textures */
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[0],
|
|
+ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[0],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc)))
|
|
return false;
|
|
|
|
@@ -3945,11 +3937,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru
|
|
|
|
if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &load->entry);
|
|
+ hlsl_block_add_instr(block, load);
|
|
return true;
|
|
}
|
|
|
|
-static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
@@ -3986,13 +3978,13 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1],
|
|
+ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
return false;
|
|
|
|
if (offset_dim && params->args_count > 2)
|
|
{
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2],
|
|
+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
return false;
|
|
}
|
|
@@ -4008,12 +4000,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st
|
|
|
|
if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &load->entry);
|
|
+ hlsl_block_add_instr(block, load);
|
|
|
|
return true;
|
|
}
|
|
|
|
-static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
@@ -4056,17 +4048,17 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1],
|
|
+ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
return false;
|
|
|
|
- if (!(load_params.cmp = add_implicit_conversion(ctx, instrs, params->args[2],
|
|
+ if (!(load_params.cmp = add_implicit_conversion(ctx, block, params->args[2],
|
|
hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
|
|
load_params.cmp = params->args[2];
|
|
|
|
if (offset_dim && params->args_count > 3)
|
|
{
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2],
|
|
+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
return false;
|
|
}
|
|
@@ -4082,12 +4074,12 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs
|
|
|
|
if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &load->entry);
|
|
+ hlsl_block_add_instr(block, load);
|
|
|
|
return true;
|
|
}
|
|
|
|
-static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
@@ -4154,7 +4146,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st
|
|
}
|
|
else if (offset_dim && params->args_count > 2)
|
|
{
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[2],
|
|
+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
return false;
|
|
}
|
|
@@ -4179,7 +4171,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1],
|
|
+ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
return false;
|
|
|
|
@@ -4189,11 +4181,187 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st
|
|
|
|
if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &load->entry);
|
|
+ hlsl_block_add_instr(block, load);
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *dest,
|
|
+ struct hlsl_ir_node *src, unsigned int component, const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ struct hlsl_ir_node *load;
|
|
+
|
|
+ if (!dest)
|
|
+ return true;
|
|
+
|
|
+ if (!(load = hlsl_add_load_component(ctx, block_to_list(instrs), src, component, loc)))
|
|
+ return false;
|
|
+
|
|
+ if (!add_assignment(ctx, instrs, dest, ASSIGN_OP_ASSIGN, load))
|
|
+ return false;
|
|
+
|
|
return true;
|
|
}
|
|
|
|
-static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
+ const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
+{
|
|
+ const struct hlsl_type *object_type = object->data_type;
|
|
+ bool uint_resinfo, has_uint_arg, has_float_arg;
|
|
+ struct hlsl_resource_load_params load_params;
|
|
+ struct hlsl_ir_node *sample_info, *res_info;
|
|
+ struct hlsl_ir_node *zero = NULL, *void_ret;
|
|
+ struct hlsl_type *uint_type, *float_type;
|
|
+ unsigned int i, j;
|
|
+ enum func_argument
|
|
+ {
|
|
+ ARG_MIP_LEVEL,
|
|
+ ARG_WIDTH,
|
|
+ ARG_HEIGHT,
|
|
+ ARG_ELEMENT_COUNT,
|
|
+ ARG_LEVEL_COUNT,
|
|
+ ARG_SAMPLE_COUNT,
|
|
+ ARG_MAX_ARGS,
|
|
+ };
|
|
+ struct hlsl_ir_node *args[ARG_MAX_ARGS] = { 0 };
|
|
+ static const struct overload
|
|
+ {
|
|
+ enum hlsl_sampler_dim sampler_dim;
|
|
+ unsigned int args_count;
|
|
+ enum func_argument args[ARG_MAX_ARGS];
|
|
+ }
|
|
+ overloads[] =
|
|
+ {
|
|
+ { HLSL_SAMPLER_DIM_1D, 1, { ARG_WIDTH } },
|
|
+ { HLSL_SAMPLER_DIM_1D, 3, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_LEVEL_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_1DARRAY, 2, { ARG_WIDTH, ARG_ELEMENT_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_1DARRAY, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_2D, 2, { ARG_WIDTH, ARG_HEIGHT } },
|
|
+ { HLSL_SAMPLER_DIM_2D, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_LEVEL_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_2DARRAY, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_2DARRAY, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_3D, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_3D, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_CUBE, 2, { ARG_WIDTH, ARG_HEIGHT } },
|
|
+ { HLSL_SAMPLER_DIM_CUBE, 4, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_LEVEL_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_CUBEARRAY, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_CUBEARRAY, 5, { ARG_MIP_LEVEL, ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_LEVEL_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_2DMS, 3, { ARG_WIDTH, ARG_HEIGHT, ARG_SAMPLE_COUNT } },
|
|
+ { HLSL_SAMPLER_DIM_2DMSARRAY, 4, { ARG_WIDTH, ARG_HEIGHT, ARG_ELEMENT_COUNT, ARG_SAMPLE_COUNT } },
|
|
+ };
|
|
+ const struct overload *o = NULL;
|
|
+
|
|
+ if (object_type->sampler_dim > HLSL_SAMPLER_DIM_LAST_TEXTURE)
|
|
+ {
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "GetDimensions() is not defined for this type.");
|
|
+ }
|
|
+
|
|
+ uint_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT);
|
|
+ float_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT);
|
|
+ has_uint_arg = has_float_arg = false;
|
|
+ for (i = 0; i < ARRAY_SIZE(overloads); ++i)
|
|
+ {
|
|
+ const struct overload *iter = &overloads[i];
|
|
+
|
|
+ if (iter->sampler_dim == object_type->sampler_dim && iter->args_count == params->args_count)
|
|
+ {
|
|
+ for (j = 0; j < params->args_count; ++j)
|
|
+ {
|
|
+ args[iter->args[j]] = params->args[j];
|
|
+
|
|
+ /* Input parameter. */
|
|
+ if (iter->args[j] == ARG_MIP_LEVEL)
|
|
+ {
|
|
+ if (!(args[ARG_MIP_LEVEL] = add_implicit_conversion(ctx, block, args[ARG_MIP_LEVEL],
|
|
+ hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc)))
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ has_float_arg |= hlsl_types_are_equal(params->args[j]->data_type, float_type);
|
|
+ has_uint_arg |= hlsl_types_are_equal(params->args[j]->data_type, uint_type);
|
|
+
|
|
+ if (params->args[j]->data_type->class != HLSL_CLASS_SCALAR)
|
|
+ {
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected scalar arguments.");
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ o = iter;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ uint_resinfo = !has_float_arg && has_uint_arg;
|
|
+
|
|
+ if (!o)
|
|
+ {
|
|
+ struct vkd3d_string_buffer *string;
|
|
+
|
|
+ if ((string = hlsl_type_to_string(ctx, object_type)))
|
|
+ {
|
|
+ hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX,
|
|
+ "Unexpected number of arguments %u for %s.%s().", params->args_count, string->buffer, name);
|
|
+ hlsl_release_string_buffer(ctx, string);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!args[ARG_MIP_LEVEL])
|
|
+ {
|
|
+ if (!(zero = hlsl_new_uint_constant(ctx, 0, loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, zero);
|
|
+ args[ARG_MIP_LEVEL] = zero;
|
|
+ }
|
|
+
|
|
+ memset(&load_params, 0, sizeof(load_params));
|
|
+ load_params.type = HLSL_RESOURCE_RESINFO;
|
|
+ load_params.resource = object;
|
|
+ load_params.lod = args[ARG_MIP_LEVEL];
|
|
+ load_params.format = hlsl_get_vector_type(ctx, uint_resinfo ? HLSL_TYPE_UINT : HLSL_TYPE_FLOAT, 4);
|
|
+
|
|
+ if (!(res_info = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, res_info);
|
|
+
|
|
+ if (!add_assignment_from_component(ctx, block, args[ARG_WIDTH], res_info, 0, loc))
|
|
+ return false;
|
|
+
|
|
+ if (!add_assignment_from_component(ctx, block, args[ARG_HEIGHT], res_info, 1, loc))
|
|
+ return false;
|
|
+
|
|
+ if (!add_assignment_from_component(ctx, block, args[ARG_ELEMENT_COUNT], res_info,
|
|
+ object_type->sampler_dim == HLSL_SAMPLER_DIM_1DARRAY ? 1 : 2, loc))
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (!add_assignment_from_component(ctx, block, args[ARG_LEVEL_COUNT], res_info, 3, loc))
|
|
+ return false;
|
|
+
|
|
+ if (args[ARG_SAMPLE_COUNT])
|
|
+ {
|
|
+ memset(&load_params, 0, sizeof(load_params));
|
|
+ load_params.type = HLSL_RESOURCE_SAMPLE_INFO;
|
|
+ load_params.resource = object;
|
|
+ load_params.format = args[ARG_SAMPLE_COUNT]->data_type;
|
|
+ if (!(sample_info = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, sample_info);
|
|
+
|
|
+ if (!add_assignment(ctx, block, args[ARG_SAMPLE_COUNT], ASSIGN_OP_ASSIGN, sample_info))
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (!(void_ret = hlsl_new_void_expr(ctx, loc)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, void_ret);
|
|
+
|
|
+ return true;
|
|
+}
|
|
+
|
|
+static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
@@ -4235,17 +4403,17 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1],
|
|
+ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
load_params.coords = params->args[1];
|
|
|
|
- if (!(load_params.lod = add_implicit_conversion(ctx, instrs, params->args[2],
|
|
+ if (!(load_params.lod = add_implicit_conversion(ctx, block, params->args[2],
|
|
hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc)))
|
|
load_params.lod = params->args[2];
|
|
|
|
if (offset_dim && params->args_count > 3)
|
|
{
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[3],
|
|
+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
return false;
|
|
}
|
|
@@ -4259,11 +4427,11 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs
|
|
|
|
if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &load->entry);
|
|
+ hlsl_block_add_instr(block, load);
|
|
return true;
|
|
}
|
|
|
|
-static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
@@ -4302,21 +4470,21 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr
|
|
return false;
|
|
}
|
|
|
|
- if (!(load_params.coords = add_implicit_conversion(ctx, instrs, params->args[1],
|
|
+ if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
load_params.coords = params->args[1];
|
|
|
|
- if (!(load_params.ddx = add_implicit_conversion(ctx, instrs, params->args[2],
|
|
+ if (!(load_params.ddx = add_implicit_conversion(ctx, block, params->args[2],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
load_params.ddx = params->args[2];
|
|
|
|
- if (!(load_params.ddy = add_implicit_conversion(ctx, instrs, params->args[3],
|
|
+ if (!(load_params.ddy = add_implicit_conversion(ctx, block, params->args[3],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc)))
|
|
load_params.ddy = params->args[3];
|
|
|
|
if (offset_dim && params->args_count > 4)
|
|
{
|
|
- if (!(load_params.texel_offset = add_implicit_conversion(ctx, instrs, params->args[4],
|
|
+ if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[4],
|
|
hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc)))
|
|
return false;
|
|
}
|
|
@@ -4330,14 +4498,14 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr
|
|
|
|
if (!(load = hlsl_new_resource_load(ctx, &load_params, loc)))
|
|
return false;
|
|
- list_add_tail(instrs, &load->entry);
|
|
+ hlsl_block_add_instr(block, load);
|
|
return true;
|
|
}
|
|
|
|
static const struct method_function
|
|
{
|
|
const char *name;
|
|
- bool (*handler)(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+ bool (*handler)(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc);
|
|
}
|
|
object_methods[] =
|
|
@@ -4348,6 +4516,8 @@ object_methods[] =
|
|
{ "GatherGreen", add_gather_method_call },
|
|
{ "GatherRed", add_gather_method_call },
|
|
|
|
+ { "GetDimensions", add_getdimensions_method_call },
|
|
+
|
|
{ "Load", add_load_method_call },
|
|
|
|
{ "Sample", add_sample_method_call },
|
|
@@ -4365,7 +4535,7 @@ static int object_method_function_name_compare(const void *a, const void *b)
|
|
return strcmp(a, func->name);
|
|
}
|
|
|
|
-static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_node *object,
|
|
+static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object,
|
|
const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc)
|
|
{
|
|
const struct hlsl_type *object_type = object->data_type;
|
|
@@ -4386,7 +4556,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl
|
|
if ((method = bsearch(name, object_methods, ARRAY_SIZE(object_methods),
|
|
sizeof(*method), object_method_function_name_compare)))
|
|
{
|
|
- return method->handler(ctx, instrs, object, name, params, loc);
|
|
+ return method->handler(ctx, block, object, name, params, loc);
|
|
}
|
|
else
|
|
{
|
|
@@ -4557,10 +4727,6 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type
|
|
%token <intval> C_INTEGER
|
|
%token <intval> PRE_LINE
|
|
|
|
-%type <list> declaration
|
|
-%type <list> declaration_statement
|
|
-%type <list> primary_expr
|
|
-%type <list> struct_declaration_without_vars
|
|
%type <list> type_specs
|
|
%type <list> variables_def
|
|
%type <list> variables_def_typed
|
|
@@ -4586,6 +4752,8 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type
|
|
%type <block> bitxor_expr
|
|
%type <block> compound_statement
|
|
%type <block> conditional_expr
|
|
+%type <block> declaration
|
|
+%type <block> declaration_statement
|
|
%type <block> equality_expr
|
|
%type <block> expr
|
|
%type <block> expr_optional
|
|
@@ -4597,11 +4765,13 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type
|
|
%type <block> loop_statement
|
|
%type <block> mul_expr
|
|
%type <block> postfix_expr
|
|
+%type <block> primary_expr
|
|
%type <block> relational_expr
|
|
%type <block> shift_expr
|
|
%type <block> selection_statement
|
|
%type <block> statement
|
|
%type <block> statement_list
|
|
+%type <block> struct_declaration_without_vars
|
|
%type <block> unary_expr
|
|
|
|
%type <boolval> boolean
|
|
@@ -4661,9 +4831,9 @@ hlsl_prog:
|
|
| hlsl_prog buffer_declaration buffer_body
|
|
| hlsl_prog declaration_statement
|
|
{
|
|
- if (!list_empty($2))
|
|
+ if (!list_empty(&$2->instrs))
|
|
hlsl_fixme(ctx, &@2, "Uniform initializer.");
|
|
- destroy_instr_list($2);
|
|
+ destroy_block($2);
|
|
}
|
|
| hlsl_prog preproc_directive
|
|
| hlsl_prog ';'
|
|
@@ -4731,7 +4901,7 @@ struct_declaration_without_vars:
|
|
hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER,
|
|
"Modifiers are not allowed on struct type declarations.");
|
|
|
|
- if (!($$ = make_empty_list(ctx)))
|
|
+ if (!($$ = make_empty_block(ctx)))
|
|
YYABORT;
|
|
}
|
|
|
|
@@ -5515,7 +5685,7 @@ declaration_statement:
|
|
| struct_declaration_without_vars
|
|
| typedef
|
|
{
|
|
- if (!($$ = make_empty_list(ctx)))
|
|
+ if (!($$ = make_empty_block(ctx)))
|
|
YYABORT;
|
|
}
|
|
|
|
@@ -5912,9 +6082,6 @@ statement_list:
|
|
|
|
statement:
|
|
declaration_statement
|
|
- {
|
|
- $$ = list_to_block($1);
|
|
- }
|
|
| expr_statement
|
|
| compound_statement
|
|
| jump_statement
|
|
@@ -6006,7 +6173,7 @@ loop_statement:
|
|
}
|
|
| attribute_list_optional KW_FOR '(' scope_start declaration expr_statement expr_optional ')' statement
|
|
{
|
|
- $$ = create_loop(ctx, LOOP_FOR, &$1, list_to_block($5), $6, $7, $9, &@2);
|
|
+ $$ = create_loop(ctx, LOOP_FOR, &$1, $5, $6, $7, $9, &@2);
|
|
hlsl_pop_scope(ctx);
|
|
}
|
|
|
|
@@ -6042,7 +6209,7 @@ primary_expr:
|
|
|
|
if (!(c = hlsl_new_float_constant(ctx, $1, &@1)))
|
|
YYABORT;
|
|
- if (!($$ = make_list(ctx, c)))
|
|
+ if (!($$ = make_block(ctx, c)))
|
|
YYABORT;
|
|
}
|
|
| C_INTEGER
|
|
@@ -6051,7 +6218,7 @@ primary_expr:
|
|
|
|
if (!(c = hlsl_new_int_constant(ctx, $1, &@1)))
|
|
YYABORT;
|
|
- if (!($$ = make_list(ctx, c)))
|
|
+ if (!($$ = make_block(ctx, c)))
|
|
YYABORT;
|
|
}
|
|
| boolean
|
|
@@ -6060,7 +6227,7 @@ primary_expr:
|
|
|
|
if (!(c = hlsl_new_bool_constant(ctx, $1, &@1)))
|
|
YYABORT;
|
|
- if (!($$ = make_list(ctx, c)))
|
|
+ if (!($$ = make_block(ctx, c)))
|
|
{
|
|
hlsl_free_instr(c);
|
|
YYABORT;
|
|
@@ -6078,12 +6245,12 @@ primary_expr:
|
|
}
|
|
if (!(load = hlsl_new_var_load(ctx, var, &@1)))
|
|
YYABORT;
|
|
- if (!($$ = make_list(ctx, &load->node)))
|
|
+ if (!($$ = make_block(ctx, &load->node)))
|
|
YYABORT;
|
|
}
|
|
| '(' expr ')'
|
|
{
|
|
- $$ = block_to_list($2);
|
|
+ $$ = $2;
|
|
}
|
|
| var_identifier '(' func_arguments ')'
|
|
{
|
|
@@ -6106,7 +6273,7 @@ primary_expr:
|
|
YYABORT;
|
|
if (!(load = hlsl_new_var_load(ctx, var, &@1)))
|
|
YYABORT;
|
|
- if (!($$ = make_list(ctx, &load->node)))
|
|
+ if (!($$ = make_block(ctx, &load->node)))
|
|
YYABORT;
|
|
}
|
|
else
|
|
@@ -6118,9 +6285,6 @@ primary_expr:
|
|
|
|
postfix_expr:
|
|
primary_expr
|
|
- {
|
|
- $$ = list_to_block($1);
|
|
- }
|
|
| postfix_expr OP_INC
|
|
{
|
|
if (!add_increment(ctx, $1, false, true, &@2))
|
|
@@ -6185,7 +6349,7 @@ postfix_expr:
|
|
hlsl_block_add_block($3, $1);
|
|
destroy_block($1);
|
|
|
|
- if (!add_array_access(ctx, block_to_list($3), array, index, &@2))
|
|
+ if (!add_array_access(ctx, $3, array, index, &@2))
|
|
{
|
|
destroy_block($3);
|
|
YYABORT;
|
|
@@ -6236,7 +6400,7 @@ postfix_expr:
|
|
hlsl_block_add_block($1, $5.instrs);
|
|
vkd3d_free($5.instrs);
|
|
|
|
- if (!add_method_call(ctx, block_to_list($1), object, $3, &$5, &@3))
|
|
+ if (!add_method_call(ctx, $1, object, $3, &$5, &@3))
|
|
{
|
|
destroy_block($1);
|
|
vkd3d_free($5.args);
|
|
@@ -6324,7 +6488,7 @@ unary_expr:
|
|
YYABORT;
|
|
}
|
|
|
|
- if (!add_cast(ctx, block_to_list($6), node_from_block($6), dst_type, &@3))
|
|
+ if (!add_cast(ctx, $6, node_from_block($6), dst_type, &@3))
|
|
{
|
|
destroy_block($6);
|
|
YYABORT;
|
|
@@ -6455,13 +6619,13 @@ conditional_expr:
|
|
if (!(common_type = get_common_numeric_type(ctx, first, second, &@3)))
|
|
YYABORT;
|
|
|
|
- if (!(first = add_implicit_conversion(ctx, block_to_list($1), first, common_type, &@3)))
|
|
+ if (!(first = add_implicit_conversion(ctx, $1, first, common_type, &@3)))
|
|
YYABORT;
|
|
|
|
- if (!(second = add_implicit_conversion(ctx, block_to_list($1), second, common_type, &@5)))
|
|
+ if (!(second = add_implicit_conversion(ctx, $1, second, common_type, &@5)))
|
|
YYABORT;
|
|
|
|
- if (!hlsl_add_conditional(ctx, block_to_list($1), cond, first, second))
|
|
+ if (!hlsl_add_conditional(ctx, $1, cond, first, second))
|
|
YYABORT;
|
|
$$ = $1;
|
|
}
|
|
@@ -6480,7 +6644,7 @@ assignment_expr:
|
|
}
|
|
hlsl_block_add_block($3, $1);
|
|
destroy_block($1);
|
|
- if (!add_assignment(ctx, block_to_list($3), lhs, $2, rhs))
|
|
+ if (!add_assignment(ctx, $3, lhs, $2, rhs))
|
|
YYABORT;
|
|
$$ = $3;
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
index 09a3ea4ca08..4f5a5b02a67 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
|
|
@@ -574,6 +574,37 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx,
|
|
return progress;
|
|
}
|
|
|
|
+typedef bool (*PFN_lower_func)(struct hlsl_ctx *, struct hlsl_ir_node *, struct hlsl_block *);
|
|
+
|
|
+static bool call_lower_func(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
+{
|
|
+ PFN_lower_func func = context;
|
|
+ struct hlsl_block block;
|
|
+
|
|
+ hlsl_block_init(&block);
|
|
+ if (func(ctx, instr, &block))
|
|
+ {
|
|
+ struct hlsl_ir_node *replacement = LIST_ENTRY(list_tail(&block.instrs), struct hlsl_ir_node, entry);
|
|
+
|
|
+ list_move_before(&instr->entry, &block.instrs);
|
|
+ hlsl_replace_node(instr, replacement);
|
|
+ return true;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ hlsl_block_cleanup(&block);
|
|
+ return false;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* Specific form of transform_ir() for passes which convert a single instruction
|
|
+ * to a block of one or more instructions. This helper takes care of setting up
|
|
+ * the block and calling hlsl_replace_node_with_block(). */
|
|
+static bool lower_ir(struct hlsl_ctx *ctx, PFN_lower_func func, struct hlsl_block *block)
|
|
+{
|
|
+ return hlsl_transform_ir(ctx, call_lower_func, block, func);
|
|
+}
|
|
+
|
|
static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
{
|
|
bool res;
|
|
@@ -2087,9 +2118,11 @@ static bool lower_combined_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in
|
|
case HLSL_RESOURCE_GATHER_GREEN:
|
|
case HLSL_RESOURCE_GATHER_BLUE:
|
|
case HLSL_RESOURCE_GATHER_ALPHA:
|
|
+ case HLSL_RESOURCE_RESINFO:
|
|
case HLSL_RESOURCE_SAMPLE_CMP:
|
|
case HLSL_RESOURCE_SAMPLE_CMP_LZ:
|
|
case HLSL_RESOURCE_SAMPLE_GRAD:
|
|
+ case HLSL_RESOURCE_SAMPLE_INFO:
|
|
return false;
|
|
|
|
case HLSL_RESOURCE_SAMPLE:
|
|
@@ -2356,7 +2389,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
|
|
return true;
|
|
}
|
|
|
|
-struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *instrs,
|
|
+struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_block *instrs,
|
|
struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false)
|
|
{
|
|
struct hlsl_block then_block, else_block;
|
|
@@ -2382,18 +2415,18 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *ins
|
|
|
|
if (!(iff = hlsl_new_if(ctx, condition, &then_block, &else_block, &condition->loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &iff->entry);
|
|
+ hlsl_block_add_instr(instrs, iff);
|
|
|
|
if (!(load = hlsl_new_var_load(ctx, var, &condition->loc)))
|
|
return NULL;
|
|
- list_add_tail(instrs, &load->node.entry);
|
|
+ hlsl_block_add_instr(instrs, &load->node);
|
|
|
|
return &load->node;
|
|
}
|
|
|
|
-static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
+static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
{
|
|
- struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond, *high_bit;
|
|
+ struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit;
|
|
struct hlsl_type *type = instr->data_type, *utype;
|
|
struct hlsl_constant_value high_bit_value;
|
|
struct hlsl_ir_expr *expr;
|
|
@@ -2414,56 +2447,52 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
|
|
if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &xor->entry);
|
|
+ hlsl_block_add_instr(block, xor);
|
|
|
|
for (i = 0; i < type->dimx; ++i)
|
|
high_bit_value.u[i].u = 0x80000000;
|
|
if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &high_bit->entry);
|
|
+ hlsl_block_add_instr(block, high_bit);
|
|
|
|
if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, high_bit)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &and->entry);
|
|
+ hlsl_block_add_instr(block, and);
|
|
|
|
if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &abs1->entry);
|
|
+ hlsl_block_add_instr(block, abs1);
|
|
|
|
if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &cast1->entry);
|
|
+ hlsl_block_add_instr(block, cast1);
|
|
|
|
if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &abs2->entry);
|
|
+ hlsl_block_add_instr(block, abs2);
|
|
|
|
if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &cast2->entry);
|
|
+ hlsl_block_add_instr(block, cast2);
|
|
|
|
if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, cast1, cast2)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &div->entry);
|
|
+ hlsl_block_add_instr(block, div);
|
|
|
|
if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &cast3->entry);
|
|
+ hlsl_block_add_instr(block, cast3);
|
|
|
|
if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &neg->entry);
|
|
-
|
|
- if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, cast3)))
|
|
- return false;
|
|
- hlsl_replace_node(instr, cond);
|
|
+ hlsl_block_add_instr(block, neg);
|
|
|
|
- return true;
|
|
+ return hlsl_add_conditional(ctx, block, and, neg, cast3);
|
|
}
|
|
|
|
-static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
+static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
{
|
|
- struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *cond, *high_bit;
|
|
+ struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit;
|
|
struct hlsl_type *type = instr->data_type, *utype;
|
|
struct hlsl_constant_value high_bit_value;
|
|
struct hlsl_ir_expr *expr;
|
|
@@ -2486,45 +2515,41 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
high_bit_value.u[i].u = 0x80000000;
|
|
if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &high_bit->entry);
|
|
+ hlsl_block_add_instr(block, high_bit);
|
|
|
|
if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, high_bit)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &and->entry);
|
|
+ hlsl_block_add_instr(block, and);
|
|
|
|
if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &abs1->entry);
|
|
+ hlsl_block_add_instr(block, abs1);
|
|
|
|
if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &cast1->entry);
|
|
+ hlsl_block_add_instr(block, cast1);
|
|
|
|
if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &abs2->entry);
|
|
+ hlsl_block_add_instr(block, abs2);
|
|
|
|
if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &cast2->entry);
|
|
+ hlsl_block_add_instr(block, cast2);
|
|
|
|
if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_MOD, cast1, cast2)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &div->entry);
|
|
+ hlsl_block_add_instr(block, div);
|
|
|
|
if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &cast3->entry);
|
|
+ hlsl_block_add_instr(block, cast3);
|
|
|
|
if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &neg->entry);
|
|
-
|
|
- if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, cast3)))
|
|
- return false;
|
|
- hlsl_replace_node(instr, cond);
|
|
+ hlsl_block_add_instr(block, neg);
|
|
|
|
- return true;
|
|
+ return hlsl_add_conditional(ctx, block, and, neg, cast3);
|
|
}
|
|
|
|
static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
@@ -2608,9 +2633,9 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void
|
|
return false;
|
|
}
|
|
|
|
-static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
|
|
+static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block)
|
|
{
|
|
- struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one;
|
|
+ struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one, *mul3;
|
|
struct hlsl_type *type = instr->data_type, *btype;
|
|
struct hlsl_constant_value one_value;
|
|
struct hlsl_ir_expr *expr;
|
|
@@ -2631,47 +2656,45 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
|
|
|
|
if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, arg2, arg1)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &mul1->entry);
|
|
+ hlsl_block_add_instr(block, mul1);
|
|
|
|
if (!(neg1 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &neg1->entry);
|
|
+ hlsl_block_add_instr(block, neg1);
|
|
|
|
if (!(ge = hlsl_new_binary_expr(ctx, HLSL_OP2_GEQUAL, mul1, neg1)))
|
|
return false;
|
|
ge->data_type = btype;
|
|
- list_add_before(&instr->entry, &ge->entry);
|
|
+ hlsl_block_add_instr(block, ge);
|
|
|
|
if (!(neg2 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &neg2->entry);
|
|
+ hlsl_block_add_instr(block, neg2);
|
|
|
|
- if (!(cond = hlsl_add_conditional(ctx, &instr->entry, ge, arg2, neg2)))
|
|
+ if (!(cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2)))
|
|
return false;
|
|
|
|
for (i = 0; i < type->dimx; ++i)
|
|
one_value.u[i].f = 1.0f;
|
|
if (!(one = hlsl_new_constant(ctx, type, &one_value, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &one->entry);
|
|
+ hlsl_block_add_instr(block, one);
|
|
|
|
if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, one, cond)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &div->entry);
|
|
+ hlsl_block_add_instr(block, div);
|
|
|
|
if (!(mul2 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, div, arg1)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &mul2->entry);
|
|
+ hlsl_block_add_instr(block, mul2);
|
|
|
|
if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, mul2, &instr->loc)))
|
|
return false;
|
|
- list_add_before(&instr->entry, &frc->entry);
|
|
+ hlsl_block_add_instr(block, frc);
|
|
|
|
- expr->op = HLSL_OP2_MUL;
|
|
- hlsl_src_remove(&expr->operands[0]);
|
|
- hlsl_src_remove(&expr->operands[1]);
|
|
- hlsl_src_from_node(&expr->operands[0], frc);
|
|
- hlsl_src_from_node(&expr->operands[1], cond);
|
|
+ if (!(mul3 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, frc, cond)))
|
|
+ return false;
|
|
+ hlsl_block_add_instr(block, mul3);
|
|
|
|
return true;
|
|
}
|
|
@@ -2683,8 +2706,8 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
struct hlsl_type *arg_type, *cmp_type;
|
|
struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 };
|
|
struct hlsl_ir_jump *jump;
|
|
+ struct hlsl_block block;
|
|
unsigned int i, count;
|
|
- struct list instrs;
|
|
|
|
if (instr->type != HLSL_IR_JUMP)
|
|
return false;
|
|
@@ -2692,38 +2715,38 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr,
|
|
if (jump->type != HLSL_IR_JUMP_DISCARD_NEG)
|
|
return false;
|
|
|
|
- list_init(&instrs);
|
|
+ hlsl_block_init(&block);
|
|
|
|
arg_type = jump->condition.node->data_type;
|
|
if (!(zero = hlsl_new_constant(ctx, arg_type, &zero_value, &instr->loc)))
|
|
return false;
|
|
- list_add_tail(&instrs, &zero->entry);
|
|
+ hlsl_block_add_instr(&block, zero);
|
|
|
|
operands[0] = jump->condition.node;
|
|
operands[1] = zero;
|
|
cmp_type = hlsl_get_numeric_type(ctx, arg_type->class, HLSL_TYPE_BOOL, arg_type->dimx, arg_type->dimy);
|
|
if (!(cmp = hlsl_new_expr(ctx, HLSL_OP2_LESS, operands, cmp_type, &instr->loc)))
|
|
return false;
|
|
- list_add_tail(&instrs, &cmp->entry);
|
|
+ hlsl_block_add_instr(&block, cmp);
|
|
|
|
if (!(bool_false = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc)))
|
|
return false;
|
|
- list_add_tail(&instrs, &bool_false->entry);
|
|
+ hlsl_block_add_instr(&block, bool_false);
|
|
|
|
or = bool_false;
|
|
|
|
count = hlsl_type_component_count(cmp_type);
|
|
for (i = 0; i < count; ++i)
|
|
{
|
|
- if (!(load = hlsl_add_load_component(ctx, &instrs, cmp, i, &instr->loc)))
|
|
+ if (!(load = hlsl_add_load_component(ctx, &block.instrs, cmp, i, &instr->loc)))
|
|
return false;
|
|
|
|
if (!(or = hlsl_new_binary_expr(ctx, HLSL_OP2_LOGIC_OR, or, load)))
|
|
return NULL;
|
|
- list_add_tail(&instrs, &or->entry);
|
|
+ hlsl_block_add_instr(&block, or);
|
|
}
|
|
|
|
- list_move_tail(&instr->entry, &instrs);
|
|
+ list_move_tail(&instr->entry, &block.instrs);
|
|
hlsl_src_remove(&jump->condition);
|
|
hlsl_src_from_node(&jump->condition, or);
|
|
jump->type = HLSL_IR_JUMP_DISCARD_NZ;
|
|
@@ -2953,7 +2976,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop
|
|
load->sampler.offset.node->last_read = last_read;
|
|
}
|
|
|
|
- load->coords.node->last_read = last_read;
|
|
+ if (load->coords.node)
|
|
+ load->coords.node->last_read = last_read;
|
|
if (load->texel_offset.node)
|
|
load->texel_offset.node->last_read = last_read;
|
|
if (load->lod.node)
|
|
@@ -4268,10 +4292,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
|
|
hlsl_transform_ir(ctx, lower_narrowing_casts, body, NULL);
|
|
hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL);
|
|
hlsl_transform_ir(ctx, lower_int_dot, body, NULL);
|
|
- hlsl_transform_ir(ctx, lower_int_division, body, NULL);
|
|
- hlsl_transform_ir(ctx, lower_int_modulus, body, NULL);
|
|
+ lower_ir(ctx, lower_int_division, body);
|
|
+ lower_ir(ctx, lower_int_modulus, body);
|
|
hlsl_transform_ir(ctx, lower_int_abs, body, NULL);
|
|
- hlsl_transform_ir(ctx, lower_float_modulus, body, NULL);
|
|
+ lower_ir(ctx, lower_float_modulus, body);
|
|
hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
|
|
do
|
|
{
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
index 9eefb82c226..d74f81afc39 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c
|
|
@@ -247,13 +247,13 @@ static void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_s
|
|
reg->immconst_type = VKD3D_IMMCONST_SCALAR;
|
|
}
|
|
|
|
-static void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx)
|
|
+void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx)
|
|
{
|
|
memset(ins, 0, sizeof(*ins));
|
|
ins->handler_idx = handler_idx;
|
|
}
|
|
|
|
-enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd3d_shader_instruction_array *src_instructions)
|
|
+static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd3d_shader_instruction_array *src_instructions)
|
|
{
|
|
struct hull_flattener flattener = {*src_instructions};
|
|
struct vkd3d_shader_instruction_array *instructions;
|
|
@@ -388,7 +388,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p
|
|
return VKD3D_OK;
|
|
}
|
|
|
|
-enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io(
|
|
+static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io(
|
|
struct vkd3d_shader_instruction_array *src_instructions, const struct shader_signature *input_signature)
|
|
{
|
|
struct vkd3d_shader_instruction_array *instructions;
|
|
@@ -999,7 +999,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
|
|
shader_instruction_init(ins, VKD3DSIH_NOP);
|
|
}
|
|
|
|
-enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions,
|
|
+static enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions,
|
|
enum vkd3d_shader_type shader_type, struct shader_signature *input_signature,
|
|
struct shader_signature *output_signature, struct shader_signature *patch_constant_signature)
|
|
{
|
|
@@ -1070,3 +1070,154 @@ enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_i
|
|
*instructions = normaliser.instructions;
|
|
return VKD3D_OK;
|
|
}
|
|
+
|
|
+struct flat_constant_def
|
|
+{
|
|
+ enum vkd3d_shader_d3dbc_constant_register set;
|
|
+ uint32_t index;
|
|
+ uint32_t value[4];
|
|
+};
|
|
+
|
|
+struct flat_constants_normaliser
|
|
+{
|
|
+ struct vkd3d_shader_parser *parser;
|
|
+ struct flat_constant_def *defs;
|
|
+ size_t def_count, defs_capacity;
|
|
+};
|
|
+
|
|
+static bool get_flat_constant_register_type(const struct vkd3d_shader_register *reg,
|
|
+ enum vkd3d_shader_d3dbc_constant_register *set, uint32_t *index)
|
|
+{
|
|
+ static const struct
|
|
+ {
|
|
+ enum vkd3d_shader_register_type type;
|
|
+ enum vkd3d_shader_d3dbc_constant_register set;
|
|
+ uint32_t offset;
|
|
+ }
|
|
+ regs[] =
|
|
+ {
|
|
+ {VKD3DSPR_CONST, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 0},
|
|
+ {VKD3DSPR_CONST2, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 2048},
|
|
+ {VKD3DSPR_CONST3, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 4096},
|
|
+ {VKD3DSPR_CONST4, VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, 6144},
|
|
+ {VKD3DSPR_CONSTINT, VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, 0},
|
|
+ {VKD3DSPR_CONSTBOOL, VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, 0},
|
|
+ };
|
|
+
|
|
+ unsigned int i;
|
|
+
|
|
+ for (i = 0; i < ARRAY_SIZE(regs); ++i)
|
|
+ {
|
|
+ if (reg->type == regs[i].type)
|
|
+ {
|
|
+ if (reg->idx[0].rel_addr)
|
|
+ {
|
|
+ FIXME("Unhandled relative address.\n");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ *set = regs[i].set;
|
|
+ *index = regs[i].offset + reg->idx[0].offset;
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
+
|
|
+static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_param *param,
|
|
+ const struct flat_constants_normaliser *normaliser)
|
|
+{
|
|
+ enum vkd3d_shader_d3dbc_constant_register set;
|
|
+ uint32_t index;
|
|
+ size_t i, j;
|
|
+
|
|
+ if (!get_flat_constant_register_type(¶m->reg, &set, &index))
|
|
+ return;
|
|
+
|
|
+ for (i = 0; i < normaliser->def_count; ++i)
|
|
+ {
|
|
+ if (normaliser->defs[i].set == set && normaliser->defs[i].index == index)
|
|
+ {
|
|
+ param->reg.type = VKD3DSPR_IMMCONST;
|
|
+ param->reg.idx_count = 0;
|
|
+ param->reg.immconst_type = VKD3D_IMMCONST_VEC4;
|
|
+ for (j = 0; j < 4; ++j)
|
|
+ param->reg.u.immconst_uint[j] = normaliser->defs[i].value[j];
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ param->reg.type = VKD3DSPR_CONSTBUFFER;
|
|
+ param->reg.idx[0].offset = set; /* register ID */
|
|
+ param->reg.idx[1].offset = set; /* register index */
|
|
+ param->reg.idx[2].offset = index; /* buffer index */
|
|
+ param->reg.idx_count = 3;
|
|
+}
|
|
+
|
|
+static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d_shader_parser *parser)
|
|
+{
|
|
+ struct flat_constants_normaliser normaliser = {.parser = parser};
|
|
+ unsigned int i, j;
|
|
+
|
|
+ for (i = 0; i < parser->instructions.count; ++i)
|
|
+ {
|
|
+ struct vkd3d_shader_instruction *ins = &parser->instructions.elements[i];
|
|
+
|
|
+ if (ins->handler_idx == VKD3DSIH_DEF || ins->handler_idx == VKD3DSIH_DEFI || ins->handler_idx == VKD3DSIH_DEFB)
|
|
+ {
|
|
+ struct flat_constant_def *def;
|
|
+
|
|
+ if (!vkd3d_array_reserve((void **)&normaliser.defs, &normaliser.defs_capacity,
|
|
+ normaliser.def_count + 1, sizeof(*normaliser.defs)))
|
|
+ {
|
|
+ vkd3d_free(normaliser.defs);
|
|
+ return VKD3D_ERROR_OUT_OF_MEMORY;
|
|
+ }
|
|
+
|
|
+ def = &normaliser.defs[normaliser.def_count++];
|
|
+
|
|
+ get_flat_constant_register_type((struct vkd3d_shader_register *)&ins->dst[0].reg, &def->set, &def->index);
|
|
+ for (j = 0; j < 4; ++j)
|
|
+ def->value[j] = ins->src[0].reg.u.immconst_uint[j];
|
|
+
|
|
+ vkd3d_shader_instruction_make_nop(ins);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ for (j = 0; j < ins->src_count; ++j)
|
|
+ shader_register_normalise_flat_constants((struct vkd3d_shader_src_param *)&ins->src[j], &normaliser);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ vkd3d_free(normaliser.defs);
|
|
+ return VKD3D_OK;
|
|
+}
|
|
+
|
|
+enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser)
|
|
+{
|
|
+ struct vkd3d_shader_instruction_array *instructions = &parser->instructions;
|
|
+ enum vkd3d_result result = VKD3D_OK;
|
|
+
|
|
+ if (parser->shader_desc.is_dxil)
|
|
+ return result;
|
|
+
|
|
+ if (parser->shader_version.type == VKD3D_SHADER_TYPE_HULL
|
|
+ && (result = instruction_array_flatten_hull_shader_phases(instructions)) >= 0)
|
|
+ {
|
|
+ result = instruction_array_normalise_hull_shader_control_point_io(instructions,
|
|
+ &parser->shader_desc.input_signature);
|
|
+ }
|
|
+ if (result >= 0)
|
|
+ result = instruction_array_normalise_io_registers(instructions, parser->shader_version.type,
|
|
+ &parser->shader_desc.input_signature, &parser->shader_desc.output_signature,
|
|
+ &parser->shader_desc.patch_constant_signature);
|
|
+
|
|
+ if (result >= 0)
|
|
+ result = instruction_array_normalise_flat_constants(parser);
|
|
+
|
|
+ if (result >= 0 && TRACE_ON())
|
|
+ vkd3d_shader_trace(instructions, &parser->shader_version);
|
|
+
|
|
+ return result;
|
|
+}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l
|
|
index 94079696280..6fb61eff6c3 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/preproc.l
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l
|
|
@@ -30,6 +30,13 @@
|
|
|
|
#define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
|
|
|
|
+static struct preproc_macro *preproc_get_top_macro(struct preproc_ctx *ctx)
|
|
+{
|
|
+ if (!ctx->expansion_count)
|
|
+ return NULL;
|
|
+ return ctx->expansion_stack[ctx->expansion_count - 1].macro;
|
|
+}
|
|
+
|
|
static void update_location(struct preproc_ctx *ctx);
|
|
|
|
#define YY_USER_ACTION update_location(yyget_extra(yyscanner));
|
|
@@ -125,7 +132,20 @@ INT_SUFFIX [uUlL]{0,2}
|
|
const char *p;
|
|
|
|
if (!ctx->last_was_newline)
|
|
- return T_HASHSTRING;
|
|
+ {
|
|
+ struct preproc_macro *macro;
|
|
+
|
|
+ /* Stringification is only done for function-like macro bodies.
|
|
+ * Anywhere else, we need to parse it as two separate tokens.
|
|
+ * We could use a state for this, but yyless() is easier and cheap.
|
|
+ */
|
|
+
|
|
+ if ((macro = preproc_get_top_macro(ctx)) && macro->arg_count)
|
|
+ return T_HASHSTRING;
|
|
+
|
|
+ yyless(1);
|
|
+ return T_TEXT;
|
|
+ }
|
|
|
|
for (p = yytext + 1; strchr(" \t", *p); ++p)
|
|
;
|
|
@@ -219,13 +239,6 @@ static bool preproc_is_writing(struct preproc_ctx *ctx)
|
|
return file->if_stack[file->if_count - 1].current_true;
|
|
}
|
|
|
|
-static struct preproc_macro *preproc_get_top_macro(struct preproc_ctx *ctx)
|
|
-{
|
|
- if (!ctx->expansion_count)
|
|
- return NULL;
|
|
- return ctx->expansion_stack[ctx->expansion_count - 1].macro;
|
|
-}
|
|
-
|
|
/* Concatenation is not done for object-like macros, but is done for both
|
|
* function-like macro bodies and their arguments. */
|
|
static bool should_concat(struct preproc_ctx *ctx)
|
|
@@ -334,6 +347,43 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx,
|
|
return true;
|
|
}
|
|
|
|
+static void preproc_stringify(struct preproc_ctx *ctx, struct vkd3d_string_buffer *buffer, const char *text)
|
|
+{
|
|
+ const struct preproc_text *expansion;
|
|
+ const char *p = text + 1;
|
|
+ unsigned int i;
|
|
+
|
|
+ while (*p == ' ' || *p == '\t')
|
|
+ ++p;
|
|
+
|
|
+ vkd3d_string_buffer_printf(buffer, "\"");
|
|
+ if ((expansion = find_arg_expansion(ctx, p)))
|
|
+ {
|
|
+ size_t len = expansion->text.content_size;
|
|
+ size_t start = 0;
|
|
+
|
|
+ while (len && strchr(" \t\r\n", expansion->text.buffer[len - 1]))
|
|
+ --len;
|
|
+
|
|
+ while (start < len && strchr(" \t\r\n", expansion->text.buffer[start]))
|
|
+ ++start;
|
|
+
|
|
+ for (i = start; i < len; ++i)
|
|
+ {
|
|
+ char c = expansion->text.buffer[i];
|
|
+
|
|
+ if (c == '\\' || c == '"')
|
|
+ vkd3d_string_buffer_printf(buffer, "\\");
|
|
+ vkd3d_string_buffer_printf(buffer, "%c", c);
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ vkd3d_string_buffer_printf(buffer, "%s", p);
|
|
+ }
|
|
+ vkd3d_string_buffer_printf(buffer, "\"");
|
|
+}
|
|
+
|
|
int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
{
|
|
struct preproc_ctx *ctx = yyget_extra(scanner);
|
|
@@ -441,9 +491,6 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
switch (func_state->state)
|
|
{
|
|
case STATE_NONE:
|
|
- {
|
|
- struct preproc_macro *macro;
|
|
-
|
|
if (token == T_CONCAT && should_concat(ctx))
|
|
{
|
|
while (ctx->buffer.content_size
|
|
@@ -452,37 +499,17 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
break;
|
|
}
|
|
|
|
- /* Stringification, however, is only done for function-like
|
|
- * macro bodies. */
|
|
- if (token == T_HASHSTRING && (macro = preproc_get_top_macro(ctx)) && macro->arg_count)
|
|
+ if (token == T_HASHSTRING)
|
|
{
|
|
- const struct preproc_text *expansion;
|
|
- const char *p = text + 1;
|
|
- unsigned int i;
|
|
+ struct vkd3d_string_buffer buffer;
|
|
|
|
if (ctx->current_directive)
|
|
return return_token(token, lval, text);
|
|
|
|
- while (*p == ' ' || *p == '\t')
|
|
- ++p;
|
|
-
|
|
- vkd3d_string_buffer_printf(&ctx->buffer, "\"");
|
|
- if ((expansion = find_arg_expansion(ctx, p)))
|
|
- {
|
|
- for (i = 0; i < expansion->text.content_size; ++i)
|
|
- {
|
|
- char c = expansion->text.buffer[i];
|
|
-
|
|
- if (c == '\\' || c == '"')
|
|
- vkd3d_string_buffer_printf(&ctx->buffer, "\\");
|
|
- vkd3d_string_buffer_printf(&ctx->buffer, "%c", c);
|
|
- }
|
|
- }
|
|
- else
|
|
- {
|
|
- vkd3d_string_buffer_printf(&ctx->buffer, "%s", p);
|
|
- }
|
|
- vkd3d_string_buffer_printf(&ctx->buffer, "\"");
|
|
+ vkd3d_string_buffer_init(&buffer);
|
|
+ preproc_stringify(ctx, &buffer, text);
|
|
+ vkd3d_string_buffer_printf(&ctx->buffer, "%s", buffer.buffer);
|
|
+ vkd3d_string_buffer_cleanup(&buffer);
|
|
break;
|
|
}
|
|
|
|
@@ -586,7 +613,6 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
else
|
|
vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text);
|
|
break;
|
|
- }
|
|
|
|
case STATE_IDENTIFIER:
|
|
if (token == '(')
|
|
@@ -628,6 +654,41 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
|
|
switch (token)
|
|
{
|
|
+ /* Most text gets left alone (e.g. if it contains macros,
|
|
+ * the macros should be evaluated later).
|
|
+ * Arguments are a special case, and are replaced with
|
|
+ * their values immediately. */
|
|
+ case T_IDENTIFIER:
|
|
+ case T_IDENTIFIER_PAREN:
|
|
+ {
|
|
+ const struct preproc_text *expansion;
|
|
+
|
|
+ if ((expansion = find_arg_expansion(ctx, text)))
|
|
+ {
|
|
+ preproc_push_expansion(ctx, expansion, NULL);
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ if (current_arg)
|
|
+ preproc_text_add(current_arg, text);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* Stringification is another special case. Unsurprisingly,
|
|
+ * we need to stringify if this is an argument. More
|
|
+ * surprisingly, we need to stringify even if it's not. */
|
|
+ case T_HASHSTRING:
|
|
+ {
|
|
+ struct vkd3d_string_buffer buffer;
|
|
+
|
|
+ vkd3d_string_buffer_init(&buffer);
|
|
+ preproc_stringify(ctx, &buffer, text);
|
|
+ if (current_arg)
|
|
+ preproc_text_add(current_arg, buffer.buffer);
|
|
+ vkd3d_string_buffer_cleanup(&buffer);
|
|
+ break;
|
|
+ }
|
|
+
|
|
case T_NEWLINE:
|
|
if (current_arg)
|
|
preproc_text_add(current_arg, " ");
|
|
@@ -686,6 +747,9 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
|
|
if (current_arg)
|
|
preproc_text_add(current_arg, text);
|
|
}
|
|
+
|
|
+ if (current_arg)
|
|
+ preproc_text_add(current_arg, " ");
|
|
break;
|
|
}
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
index 9725a5c7e25..d71f0a698d9 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
|
|
@@ -199,6 +199,21 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d
|
|
}
|
|
}
|
|
|
|
+static inline bool register_is_undef(const struct vkd3d_shader_register *reg)
|
|
+{
|
|
+ return reg->type == VKD3DSPR_UNDEF;
|
|
+}
|
|
+
|
|
+static inline bool register_is_constant(const struct vkd3d_shader_register *reg)
|
|
+{
|
|
+ return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64);
|
|
+}
|
|
+
|
|
+static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg)
|
|
+{
|
|
+ return register_is_constant(reg) || register_is_undef(reg);
|
|
+}
|
|
+
|
|
#define VKD3D_SPIRV_VERSION 0x00010000
|
|
#define VKD3D_SPIRV_GENERATOR_ID 18
|
|
#define VKD3D_SPIRV_GENERATOR_VERSION 8
|
|
@@ -1746,6 +1761,38 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder,
|
|
}
|
|
}
|
|
|
|
+static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder,
|
|
+ enum vkd3d_data_type data_type, unsigned int component_count)
|
|
+{
|
|
+ uint32_t scalar_id;
|
|
+
|
|
+ if (component_count == 1)
|
|
+ {
|
|
+ switch (data_type)
|
|
+ {
|
|
+ case VKD3D_DATA_FLOAT:
|
|
+ case VKD3D_DATA_SNORM:
|
|
+ case VKD3D_DATA_UNORM:
|
|
+ return vkd3d_spirv_get_op_type_float(builder, 32);
|
|
+ break;
|
|
+ case VKD3D_DATA_INT:
|
|
+ case VKD3D_DATA_UINT:
|
|
+ return vkd3d_spirv_get_op_type_int(builder, 32, data_type == VKD3D_DATA_INT);
|
|
+ break;
|
|
+ case VKD3D_DATA_DOUBLE:
|
|
+ return vkd3d_spirv_get_op_type_float(builder, 64);
|
|
+ default:
|
|
+ FIXME("Unhandled data type %#x.\n", data_type);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ scalar_id = vkd3d_spirv_get_type_id_for_data_type(builder, data_type, 1);
|
|
+ return vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count);
|
|
+ }
|
|
+}
|
|
+
|
|
static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point)
|
|
{
|
|
vkd3d_spirv_stream_init(&builder->debug_stream);
|
|
@@ -2429,13 +2476,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
|
|
|
|
compiler->shader_type = shader_version->type;
|
|
|
|
- compiler->input_signature = shader_desc->input_signature;
|
|
- compiler->output_signature = shader_desc->output_signature;
|
|
- compiler->patch_constant_signature = shader_desc->patch_constant_signature;
|
|
- memset(&shader_desc->input_signature, 0, sizeof(shader_desc->input_signature));
|
|
- memset(&shader_desc->output_signature, 0, sizeof(shader_desc->output_signature));
|
|
- memset(&shader_desc->patch_constant_signature, 0, sizeof(shader_desc->patch_constant_signature));
|
|
-
|
|
if ((shader_interface = vkd3d_find_struct(compile_info->next, INTERFACE_INFO)))
|
|
{
|
|
compiler->xfb_info = vkd3d_find_struct(compile_info->next, TRANSFORM_FEEDBACK_INFO);
|
|
@@ -2536,13 +2576,13 @@ static bool spirv_compiler_check_shader_visibility(const struct spirv_compiler *
|
|
}
|
|
|
|
static struct vkd3d_push_constant_buffer_binding *spirv_compiler_find_push_constant_buffer(
|
|
- const struct spirv_compiler *compiler, const struct vkd3d_shader_constant_buffer *cb)
|
|
+ const struct spirv_compiler *compiler, const struct vkd3d_shader_register_range *range)
|
|
{
|
|
- unsigned int register_space = cb->range.space;
|
|
- unsigned int reg_idx = cb->range.first;
|
|
+ unsigned int register_space = range->space;
|
|
+ unsigned int reg_idx = range->first;
|
|
unsigned int i;
|
|
|
|
- if (cb->range.first != cb->range.last)
|
|
+ if (range->first != range->last)
|
|
return NULL;
|
|
|
|
for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i)
|
|
@@ -3211,7 +3251,7 @@ static bool spirv_compiler_get_register_info(const struct spirv_compiler *compil
|
|
struct vkd3d_symbol reg_symbol, *symbol;
|
|
struct rb_entry *entry;
|
|
|
|
- assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
|
|
+ assert(!register_is_constant_or_undef(reg));
|
|
|
|
if (reg->type == VKD3DSPR_TEMP)
|
|
{
|
|
@@ -3553,6 +3593,19 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi
|
|
vkd3d_component_type_from_data_type(reg->data_type), component_count, values);
|
|
}
|
|
|
|
+static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler,
|
|
+ const struct vkd3d_shader_register *reg, DWORD write_mask)
|
|
+{
|
|
+ unsigned int component_count = vkd3d_write_mask_component_count(write_mask);
|
|
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ uint32_t type_id;
|
|
+
|
|
+ assert(reg->type == VKD3DSPR_UNDEF);
|
|
+
|
|
+ type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count);
|
|
+ return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
|
|
+}
|
|
+
|
|
static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask,
|
|
const struct vkd3d_shader_register_info *reg_info)
|
|
@@ -3563,7 +3616,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler,
|
|
enum vkd3d_shader_component_type component_type;
|
|
unsigned int skipped_component_mask;
|
|
|
|
- assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
|
|
+ assert(!register_is_constant_or_undef(reg));
|
|
assert(vkd3d_write_mask_component_count(write_mask) == 1);
|
|
|
|
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
|
|
@@ -3615,6 +3668,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler,
|
|
return spirv_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
|
|
else if (reg->type == VKD3DSPR_IMMCONST64)
|
|
return spirv_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask);
|
|
+ else if (reg->type == VKD3DSPR_UNDEF)
|
|
+ return spirv_compiler_emit_load_undef(compiler, reg, write_mask);
|
|
|
|
component_count = vkd3d_write_mask_component_count(write_mask);
|
|
component_type = vkd3d_component_type_from_data_type(reg->data_type);
|
|
@@ -3827,7 +3882,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler,
|
|
unsigned int src_write_mask = write_mask;
|
|
uint32_t type_id;
|
|
|
|
- assert(reg->type != VKD3DSPR_IMMCONST && reg->type != VKD3DSPR_IMMCONST64);
|
|
+ assert(!register_is_constant_or_undef(reg));
|
|
|
|
if (!spirv_compiler_get_register_info(compiler, reg, ®_info))
|
|
return;
|
|
@@ -5477,28 +5532,24 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler *
|
|
return var_id;
|
|
}
|
|
|
|
-static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler,
|
|
- const struct vkd3d_shader_instruction *instruction)
|
|
+static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, unsigned int size,
|
|
+ const struct vkd3d_shader_register_range *range, const struct vkd3d_shader_register *reg)
|
|
{
|
|
- const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
uint32_t vec4_id, array_type_id, length_id, struct_id, var_id;
|
|
const SpvStorageClass storage_class = SpvStorageClassUniform;
|
|
- const struct vkd3d_shader_register *reg = &cb->src.reg;
|
|
struct vkd3d_push_constant_buffer_binding *push_cb;
|
|
struct vkd3d_descriptor_variable_info var_info;
|
|
struct vkd3d_symbol reg_symbol;
|
|
|
|
- assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC));
|
|
-
|
|
- if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, cb)))
|
|
+ if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range)))
|
|
{
|
|
/* Push constant buffers are handled in
|
|
* spirv_compiler_emit_push_constant_buffers().
|
|
*/
|
|
- unsigned int cb_size_in_bytes = cb->size * VKD3D_VEC4_SIZE * sizeof(uint32_t);
|
|
+ unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t);
|
|
push_cb->reg = *reg;
|
|
- push_cb->size = cb->size;
|
|
+ push_cb->size = size;
|
|
if (cb_size_in_bytes > push_cb->pc.size)
|
|
{
|
|
WARN("Constant buffer size %u exceeds push constant size %u.\n",
|
|
@@ -5508,17 +5559,17 @@ static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compi
|
|
}
|
|
|
|
vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE);
|
|
- length_id = spirv_compiler_get_constant_uint(compiler, cb->size);
|
|
+ length_id = spirv_compiler_get_constant_uint(compiler, size);
|
|
array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id);
|
|
vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16);
|
|
|
|
struct_id = vkd3d_spirv_build_op_type_struct(builder, &array_type_id, 1);
|
|
vkd3d_spirv_build_op_decorate(builder, struct_id, SpvDecorationBlock, NULL, 0);
|
|
vkd3d_spirv_build_op_member_decorate1(builder, struct_id, 0, SpvDecorationOffset, 0);
|
|
- vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", cb->size);
|
|
+ vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", size);
|
|
|
|
var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id,
|
|
- reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info);
|
|
+ reg, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info);
|
|
|
|
vkd3d_symbol_make_register(®_symbol, reg);
|
|
vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class,
|
|
@@ -5528,6 +5579,16 @@ static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compi
|
|
spirv_compiler_put_symbol(compiler, ®_symbol);
|
|
}
|
|
|
|
+static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler,
|
|
+ const struct vkd3d_shader_instruction *instruction)
|
|
+{
|
|
+ const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb;
|
|
+
|
|
+ assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC));
|
|
+
|
|
+ spirv_compiler_emit_constant_buffer(compiler, cb->size, &cb->range, &cb->src.reg);
|
|
+}
|
|
+
|
|
static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_instruction *instruction)
|
|
{
|
|
@@ -6641,7 +6702,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler,
|
|
uint32_t components[VKD3D_VEC4_SIZE];
|
|
unsigned int i, component_count;
|
|
|
|
- if (src->reg.type == VKD3DSPR_IMMCONST || src->reg.type == VKD3DSPR_IMMCONST64 || dst->modifiers || src->modifiers)
|
|
+ if (register_is_constant_or_undef(&src->reg) || dst->modifiers || src->modifiers)
|
|
goto general_implementation;
|
|
|
|
spirv_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info);
|
|
@@ -9436,6 +9497,26 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler,
|
|
return ret;
|
|
}
|
|
|
|
+static void spirv_compiler_emit_sm1_constant_buffer(struct spirv_compiler *compiler,
|
|
+ const struct vkd3d_shader_desc *desc, enum vkd3d_shader_d3dbc_constant_register set,
|
|
+ enum vkd3d_data_type data_type)
|
|
+{
|
|
+ struct vkd3d_shader_register_range range = {.space = 0, .first = set, .last = set};
|
|
+ uint32_t count = desc->flat_constant_count[set].external;
|
|
+ struct vkd3d_shader_register reg =
|
|
+ {
|
|
+ .type = VKD3DSPR_CONSTBUFFER,
|
|
+ .idx[0].offset = set, /* register ID */
|
|
+ .idx[1].offset = set, /* register index */
|
|
+ .idx[2].offset = count, /* size */
|
|
+ .idx_count = 3,
|
|
+ .data_type = data_type,
|
|
+ };
|
|
+
|
|
+ if (count)
|
|
+ spirv_compiler_emit_constant_buffer(compiler, count, &range, ®);
|
|
+}
|
|
+
|
|
static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_parser *parser,
|
|
struct vkd3d_shader_code *spirv)
|
|
@@ -9443,6 +9524,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
|
|
const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info;
|
|
const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info;
|
|
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
|
|
+ struct vkd3d_shader_desc *shader_desc = &parser->shader_desc;
|
|
struct vkd3d_shader_instruction_array instructions;
|
|
enum vkd3d_result result = VKD3D_OK;
|
|
unsigned int i;
|
|
@@ -9450,24 +9532,28 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler,
|
|
if (parser->shader_desc.temp_count)
|
|
spirv_compiler_emit_temps(compiler, parser->shader_desc.temp_count);
|
|
|
|
+ spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc,
|
|
+ VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, VKD3D_DATA_FLOAT);
|
|
+ spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc,
|
|
+ VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, VKD3D_DATA_INT);
|
|
+ spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc,
|
|
+ VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, VKD3D_DATA_UINT);
|
|
+
|
|
compiler->location.column = 0;
|
|
compiler->location.line = 1;
|
|
|
|
+ if ((result = vkd3d_shader_normalise(parser)) < 0)
|
|
+ return result;
|
|
+
|
|
instructions = parser->instructions;
|
|
memset(&parser->instructions, 0, sizeof(parser->instructions));
|
|
|
|
- if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL
|
|
- && (result = instruction_array_flatten_hull_shader_phases(&instructions)) >= 0)
|
|
- {
|
|
- result = instruction_array_normalise_hull_shader_control_point_io(&instructions,
|
|
- &compiler->input_signature);
|
|
- }
|
|
- if (result >= 0)
|
|
- result = instruction_array_normalise_io_registers(&instructions, parser->shader_version.type,
|
|
- &compiler->input_signature, &compiler->output_signature, &compiler->patch_constant_signature);
|
|
-
|
|
- if (result >= 0 && TRACE_ON())
|
|
- vkd3d_shader_trace(&instructions, &parser->shader_version);
|
|
+ compiler->input_signature = shader_desc->input_signature;
|
|
+ compiler->output_signature = shader_desc->output_signature;
|
|
+ compiler->patch_constant_signature = shader_desc->patch_constant_signature;
|
|
+ memset(&shader_desc->input_signature, 0, sizeof(shader_desc->input_signature));
|
|
+ memset(&shader_desc->output_signature, 0, sizeof(shader_desc->output_signature));
|
|
+ memset(&shader_desc->patch_constant_signature, 0, sizeof(shader_desc->patch_constant_signature));
|
|
|
|
if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL)
|
|
spirv_compiler_emit_shader_signature_outputs(compiler);
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
index 801c688a297..351943e2e53 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
|
|
@@ -2627,7 +2627,8 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant
|
|
return true;
|
|
}
|
|
|
|
-static void add_section(struct dxbc_writer *dxbc, uint32_t tag, struct vkd3d_bytecode_buffer *buffer)
|
|
+static void add_section(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
|
|
+ uint32_t tag, struct vkd3d_bytecode_buffer *buffer)
|
|
{
|
|
/* Native D3DDisassemble() expects at least the sizes of the ISGN and OSGN
|
|
* sections to be aligned. Without this, the sections themselves will be
|
|
@@ -2635,6 +2636,9 @@ static void add_section(struct dxbc_writer *dxbc, uint32_t tag, struct vkd3d_byt
|
|
size_t size = bytecode_align(buffer);
|
|
|
|
dxbc_writer_add_section(dxbc, tag, buffer->data, size);
|
|
+
|
|
+ if (buffer->status < 0)
|
|
+ ctx->result = buffer->status;
|
|
}
|
|
|
|
static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, bool output)
|
|
@@ -2742,7 +2746,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc,
|
|
|
|
set_u32(&buffer, count_position, i);
|
|
|
|
- add_section(dxbc, output ? TAG_OSGN : TAG_ISGN, &buffer);
|
|
+ add_section(ctx, dxbc, output ? TAG_OSGN : TAG_ISGN, &buffer);
|
|
}
|
|
|
|
static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type)
|
|
@@ -2830,6 +2834,22 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type)
|
|
return D3D_SVT_VERTEXSHADER;
|
|
case HLSL_TYPE_VOID:
|
|
return D3D_SVT_VOID;
|
|
+ case HLSL_TYPE_UAV:
|
|
+ switch (type->sampler_dim)
|
|
+ {
|
|
+ case HLSL_SAMPLER_DIM_1D:
|
|
+ return D3D_SVT_RWTEXTURE1D;
|
|
+ case HLSL_SAMPLER_DIM_2D:
|
|
+ return D3D_SVT_RWTEXTURE2D;
|
|
+ case HLSL_SAMPLER_DIM_3D:
|
|
+ return D3D_SVT_RWTEXTURE3D;
|
|
+ case HLSL_SAMPLER_DIM_1DARRAY:
|
|
+ return D3D_SVT_RWTEXTURE1DARRAY;
|
|
+ case HLSL_SAMPLER_DIM_2DARRAY:
|
|
+ return D3D_SVT_RWTEXTURE2DARRAY;
|
|
+ default:
|
|
+ vkd3d_unreachable();
|
|
+ }
|
|
default:
|
|
vkd3d_unreachable();
|
|
}
|
|
@@ -3341,7 +3361,7 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc)
|
|
creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL));
|
|
set_u32(&buffer, creator_position, creator_offset);
|
|
|
|
- add_section(dxbc, TAG_RDEF, &buffer);
|
|
+ add_section(ctx, dxbc, TAG_RDEF, &buffer);
|
|
|
|
sm4_free_extern_resources(extern_resources, extern_resources_count);
|
|
}
|
|
@@ -4283,6 +4303,53 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer
|
|
write_sm4_instruction(buffer, &instr);
|
|
}
|
|
|
|
+static void write_sm4_sampleinfo(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
|
+ const struct hlsl_ir_resource_load *load)
|
|
+{
|
|
+ const struct hlsl_deref *resource = &load->resource;
|
|
+ const struct hlsl_ir_node *dst = &load->node;
|
|
+ struct sm4_instruction instr;
|
|
+
|
|
+ assert(dst->data_type->base_type == HLSL_TYPE_UINT || dst->data_type->base_type == HLSL_TYPE_FLOAT);
|
|
+
|
|
+ memset(&instr, 0, sizeof(instr));
|
|
+ instr.opcode = VKD3D_SM4_OP_SAMPLE_INFO;
|
|
+ if (dst->data_type->base_type == HLSL_TYPE_UINT)
|
|
+ instr.opcode |= VKD3DSI_SAMPLE_INFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT;
|
|
+
|
|
+ sm4_dst_from_node(&instr.dsts[0], dst);
|
|
+ instr.dst_count = 1;
|
|
+
|
|
+ sm4_src_from_deref(ctx, &instr.srcs[0], resource, instr.dsts[0].writemask);
|
|
+ instr.src_count = 1;
|
|
+
|
|
+ write_sm4_instruction(buffer, &instr);
|
|
+}
|
|
+
|
|
+static void write_sm4_resinfo(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer,
|
|
+ const struct hlsl_ir_resource_load *load)
|
|
+{
|
|
+ const struct hlsl_deref *resource = &load->resource;
|
|
+ const struct hlsl_ir_node *dst = &load->node;
|
|
+ struct sm4_instruction instr;
|
|
+
|
|
+ assert(dst->data_type->base_type == HLSL_TYPE_UINT || dst->data_type->base_type == HLSL_TYPE_FLOAT);
|
|
+
|
|
+ memset(&instr, 0, sizeof(instr));
|
|
+ instr.opcode = VKD3D_SM4_OP_RESINFO;
|
|
+ if (dst->data_type->base_type == HLSL_TYPE_UINT)
|
|
+ instr.opcode |= VKD3DSI_RESINFO_UINT << VKD3D_SM4_INSTRUCTION_FLAGS_SHIFT;
|
|
+
|
|
+ sm4_dst_from_node(&instr.dsts[0], dst);
|
|
+ instr.dst_count = 1;
|
|
+
|
|
+ sm4_src_from_node(&instr.srcs[0], load->lod.node, VKD3DSP_WRITEMASK_ALL);
|
|
+ sm4_src_from_deref(ctx, &instr.srcs[1], resource, instr.dsts[0].writemask);
|
|
+ instr.src_count = 2;
|
|
+
|
|
+ write_sm4_instruction(buffer, &instr);
|
|
+}
|
|
+
|
|
static bool type_is_float(const struct hlsl_type *type)
|
|
{
|
|
return type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF;
|
|
@@ -5101,6 +5168,14 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx,
|
|
write_sm4_gather(ctx, buffer, &load->node, &load->resource, &load->sampler, coords,
|
|
HLSL_SWIZZLE(W, W, W, W), texel_offset);
|
|
break;
|
|
+
|
|
+ case HLSL_RESOURCE_SAMPLE_INFO:
|
|
+ write_sm4_sampleinfo(ctx, buffer, load);
|
|
+ break;
|
|
+
|
|
+ case HLSL_RESOURCE_RESINFO:
|
|
+ write_sm4_resinfo(ctx, buffer, load);
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
@@ -5306,7 +5381,7 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx,
|
|
|
|
set_u32(&buffer, token_count_position, bytecode_get_size(&buffer) / sizeof(uint32_t));
|
|
|
|
- add_section(dxbc, TAG_SHDR, &buffer);
|
|
+ add_section(ctx, dxbc, TAG_SHDR, &buffer);
|
|
|
|
sm4_free_extern_resources(extern_resources, extern_resources_count);
|
|
}
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
index 33d8c60e59a..d59cd704ceb 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
|
|
@@ -1152,6 +1152,15 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info
|
|
}
|
|
}
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(parser->shader_desc.flat_constant_count); ++i)
|
|
+ {
|
|
+ struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i};
|
|
+
|
|
+ if (parser->shader_desc.flat_constant_count[i].external)
|
|
+ vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
|
|
+ &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0);
|
|
+ }
|
|
+
|
|
if (!ret && signature_info)
|
|
{
|
|
if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &parser->shader_desc.input_signature)
|
|
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
index 0e93f3a556a..d35f49a63a2 100644
|
|
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
|
|
@@ -507,6 +507,7 @@ enum vkd3d_shader_register_type
|
|
VKD3DSPR_DEPTHOUTLE,
|
|
VKD3DSPR_RASTERIZER,
|
|
VKD3DSPR_OUTSTENCILREF,
|
|
+ VKD3DSPR_UNDEF,
|
|
|
|
VKD3DSPR_INVALID = ~0u,
|
|
};
|
|
@@ -840,6 +841,11 @@ struct vkd3d_shader_desc
|
|
struct shader_signature patch_constant_signature;
|
|
|
|
uint32_t temp_count;
|
|
+
|
|
+ struct
|
|
+ {
|
|
+ uint32_t used, external;
|
|
+ } flat_constant_count[3];
|
|
};
|
|
|
|
struct vkd3d_shader_register_semantic
|
|
@@ -971,6 +977,8 @@ struct vkd3d_shader_instruction
|
|
} declaration;
|
|
};
|
|
|
|
+void shader_instruction_init(struct vkd3d_shader_instruction *ins, enum vkd3d_shader_opcode handler_idx);
|
|
+
|
|
static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins)
|
|
{
|
|
return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w;
|
|
@@ -1398,11 +1406,6 @@ void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void
|
|
void dxbc_writer_init(struct dxbc_writer *dxbc);
|
|
int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *code);
|
|
|
|
-enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd3d_shader_instruction_array *instructions);
|
|
-enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io(
|
|
- struct vkd3d_shader_instruction_array *instructions, const struct shader_signature *input_signature);
|
|
-enum vkd3d_result instruction_array_normalise_io_registers(struct vkd3d_shader_instruction_array *instructions,
|
|
- enum vkd3d_shader_type shader_type, struct shader_signature *input_signature,
|
|
- struct shader_signature *output_signature, struct shader_signature *patch_constant_signature);
|
|
+enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser);
|
|
|
|
#endif /* __VKD3D_SHADER_PRIVATE_H */
|
|
diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c
|
|
index 53cb5d9582c..8b5f7899cf3 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/command.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/command.c
|
|
@@ -454,9 +454,9 @@ static const struct d3d12_root_parameter *root_signature_get_root_descriptor(
|
|
}
|
|
|
|
/* ID3D12Fence */
|
|
-static struct d3d12_fence *impl_from_ID3D12Fence(ID3D12Fence *iface)
|
|
+static struct d3d12_fence *impl_from_ID3D12Fence1(ID3D12Fence1 *iface)
|
|
{
|
|
- return CONTAINING_RECORD(iface, struct d3d12_fence, ID3D12Fence_iface);
|
|
+ return CONTAINING_RECORD(iface, struct d3d12_fence, ID3D12Fence1_iface);
|
|
}
|
|
|
|
static VkResult d3d12_fence_create_vk_fence(struct d3d12_fence *fence, VkFence *vk_fence)
|
|
@@ -900,18 +900,19 @@ static void d3d12_fence_signal_timeline_semaphore(struct d3d12_fence *fence, uin
|
|
vkd3d_mutex_unlock(&fence->mutex);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence1 *iface,
|
|
REFIID riid, void **object)
|
|
{
|
|
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
|
|
|
|
- if (IsEqualGUID(riid, &IID_ID3D12Fence)
|
|
+ if (IsEqualGUID(riid, &IID_ID3D12Fence1)
|
|
+ || IsEqualGUID(riid, &IID_ID3D12Fence)
|
|
|| IsEqualGUID(riid, &IID_ID3D12Pageable)
|
|
|| IsEqualGUID(riid, &IID_ID3D12DeviceChild)
|
|
|| IsEqualGUID(riid, &IID_ID3D12Object)
|
|
|| IsEqualGUID(riid, &IID_IUnknown))
|
|
{
|
|
- ID3D12Fence_AddRef(iface);
|
|
+ ID3D12Fence1_AddRef(iface);
|
|
*object = iface;
|
|
return S_OK;
|
|
}
|
|
@@ -922,9 +923,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_QueryInterface(ID3D12Fence *iface,
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
-static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence *iface)
|
|
+static ULONG STDMETHODCALLTYPE d3d12_fence_AddRef(ID3D12Fence1 *iface)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
ULONG refcount = InterlockedIncrement(&fence->refcount);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", fence, refcount);
|
|
@@ -937,9 +938,9 @@ static void d3d12_fence_incref(struct d3d12_fence *fence)
|
|
InterlockedIncrement(&fence->internal_refcount);
|
|
}
|
|
|
|
-static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence *iface)
|
|
+static ULONG STDMETHODCALLTYPE d3d12_fence_Release(ID3D12Fence1 *iface)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
ULONG refcount = InterlockedDecrement(&fence->refcount);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", fence, refcount);
|
|
@@ -972,10 +973,10 @@ static void d3d12_fence_decref(struct d3d12_fence *fence)
|
|
}
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence1 *iface,
|
|
REFGUID guid, UINT *data_size, void *data)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
|
|
TRACE("iface %p, guid %s, data_size %p, data %p.\n",
|
|
iface, debugstr_guid(guid), data_size, data);
|
|
@@ -983,10 +984,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_GetPrivateData(ID3D12Fence *iface,
|
|
return vkd3d_get_private_data(&fence->private_store, guid, data_size, data);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateData(ID3D12Fence *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateData(ID3D12Fence1 *iface,
|
|
REFGUID guid, UINT data_size, const void *data)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
|
|
TRACE("iface %p, guid %s, data_size %u, data %p.\n",
|
|
iface, debugstr_guid(guid), data_size, data);
|
|
@@ -994,37 +995,37 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateData(ID3D12Fence *iface,
|
|
return vkd3d_set_private_data(&fence->private_store, guid, data_size, data);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateDataInterface(ID3D12Fence *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_SetPrivateDataInterface(ID3D12Fence1 *iface,
|
|
REFGUID guid, const IUnknown *data)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
|
|
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
|
|
|
|
return vkd3d_set_private_data_interface(&fence->private_store, guid, data);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_SetName(ID3D12Fence *iface, const WCHAR *name)
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_SetName(ID3D12Fence1 *iface, const WCHAR *name)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
|
|
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, fence->device->wchar_size));
|
|
|
|
return name ? S_OK : E_INVALIDARG;
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_GetDevice(ID3D12Fence *iface, REFIID iid, void **device)
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_GetDevice(ID3D12Fence1 *iface, REFIID iid, void **device)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
|
|
TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device);
|
|
|
|
return d3d12_device_query_interface(fence->device, iid, device);
|
|
}
|
|
|
|
-static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence *iface)
|
|
+static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence1 *iface)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
uint64_t completed_value;
|
|
|
|
TRACE("iface %p.\n", iface);
|
|
@@ -1035,10 +1036,10 @@ static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence *iface
|
|
return completed_value;
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence1 *iface,
|
|
UINT64 value, HANDLE event)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
unsigned int i;
|
|
bool latch = false;
|
|
|
|
@@ -1106,9 +1107,9 @@ static HRESULT d3d12_fence_signal_cpu_timeline_semaphore(struct d3d12_fence *fen
|
|
return d3d12_device_flush_blocked_queues(fence->device);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 value)
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence1 *iface, UINT64 value)
|
|
{
|
|
- struct d3d12_fence *fence = impl_from_ID3D12Fence(iface);
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
|
|
TRACE("iface %p, value %#"PRIx64".\n", iface, value);
|
|
|
|
@@ -1117,7 +1118,16 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_Signal(ID3D12Fence *iface, UINT64 v
|
|
return d3d12_fence_signal(fence, value, VK_NULL_HANDLE, true);
|
|
}
|
|
|
|
-static const struct ID3D12FenceVtbl d3d12_fence_vtbl =
|
|
+static D3D12_FENCE_FLAGS STDMETHODCALLTYPE d3d12_fence_GetCreationFlags(ID3D12Fence1 *iface)
|
|
+{
|
|
+ struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface);
|
|
+
|
|
+ TRACE("iface %p.\n", iface);
|
|
+
|
|
+ return fence->flags;
|
|
+}
|
|
+
|
|
+static const struct ID3D12Fence1Vtbl d3d12_fence_vtbl =
|
|
{
|
|
/* IUnknown methods */
|
|
d3d12_fence_QueryInterface,
|
|
@@ -1134,14 +1144,18 @@ static const struct ID3D12FenceVtbl d3d12_fence_vtbl =
|
|
d3d12_fence_GetCompletedValue,
|
|
d3d12_fence_SetEventOnCompletion,
|
|
d3d12_fence_Signal,
|
|
+ /* ID3D12Fence1 methods */
|
|
+ d3d12_fence_GetCreationFlags,
|
|
};
|
|
|
|
static struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface)
|
|
{
|
|
- if (!iface)
|
|
+ ID3D12Fence1 *iface1;
|
|
+
|
|
+ if (!(iface1 = (ID3D12Fence1 *)iface))
|
|
return NULL;
|
|
- assert(iface->lpVtbl == &d3d12_fence_vtbl);
|
|
- return impl_from_ID3D12Fence(iface);
|
|
+ assert(iface1->lpVtbl == &d3d12_fence_vtbl);
|
|
+ return impl_from_ID3D12Fence1(iface1);
|
|
}
|
|
|
|
static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *device,
|
|
@@ -1151,7 +1165,7 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
|
VkResult vr;
|
|
HRESULT hr;
|
|
|
|
- fence->ID3D12Fence_iface.lpVtbl = &d3d12_fence_vtbl;
|
|
+ fence->ID3D12Fence1_iface.lpVtbl = &d3d12_fence_vtbl;
|
|
fence->internal_refcount = 1;
|
|
fence->refcount = 1;
|
|
|
|
@@ -1162,7 +1176,7 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
|
|
|
|
vkd3d_cond_init(&fence->null_event_cond);
|
|
|
|
- if (flags)
|
|
+ if ((fence->flags = flags))
|
|
FIXME("Ignoring flags %#x.\n", flags);
|
|
|
|
fence->events = NULL;
|
|
@@ -1316,32 +1330,26 @@ static HRESULT d3d12_command_allocator_allocate_command_buffer(struct d3d12_comm
|
|
return hr;
|
|
}
|
|
|
|
- allocator->current_command_list = list;
|
|
-
|
|
- return S_OK;
|
|
-}
|
|
-
|
|
-static void d3d12_command_allocator_free_command_buffer(struct d3d12_command_allocator *allocator,
|
|
- struct d3d12_command_list *list)
|
|
-{
|
|
- struct d3d12_device *device = allocator->device;
|
|
- const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
-
|
|
- TRACE("allocator %p, list %p.\n", allocator, list);
|
|
-
|
|
- if (allocator->current_command_list == list)
|
|
- allocator->current_command_list = NULL;
|
|
-
|
|
if (!vkd3d_array_reserve((void **)&allocator->command_buffers, &allocator->command_buffers_size,
|
|
allocator->command_buffer_count + 1, sizeof(*allocator->command_buffers)))
|
|
{
|
|
WARN("Failed to add command buffer.\n");
|
|
VK_CALL(vkFreeCommandBuffers(device->vk_device, allocator->vk_command_pool,
|
|
1, &list->vk_command_buffer));
|
|
- return;
|
|
+ return E_OUTOFMEMORY;
|
|
}
|
|
-
|
|
allocator->command_buffers[allocator->command_buffer_count++] = list->vk_command_buffer;
|
|
+
|
|
+ allocator->current_command_list = list;
|
|
+
|
|
+ return S_OK;
|
|
+}
|
|
+
|
|
+static void d3d12_command_allocator_remove_command_list(struct d3d12_command_allocator *allocator,
|
|
+ const struct d3d12_command_list *list)
|
|
+{
|
|
+ if (allocator->current_command_list == list)
|
|
+ allocator->current_command_list = NULL;
|
|
}
|
|
|
|
static bool d3d12_command_allocator_add_render_pass(struct d3d12_command_allocator *allocator, VkRenderPass pass)
|
|
@@ -1911,10 +1919,32 @@ HRESULT d3d12_command_allocator_create(struct d3d12_device *device,
|
|
return S_OK;
|
|
}
|
|
|
|
+static void d3d12_command_signature_incref(struct d3d12_command_signature *signature)
|
|
+{
|
|
+ vkd3d_atomic_increment(&signature->internal_refcount);
|
|
+}
|
|
+
|
|
+static void d3d12_command_signature_decref(struct d3d12_command_signature *signature)
|
|
+{
|
|
+ unsigned int refcount = vkd3d_atomic_decrement(&signature->internal_refcount);
|
|
+
|
|
+ if (!refcount)
|
|
+ {
|
|
+ struct d3d12_device *device = signature->device;
|
|
+
|
|
+ vkd3d_private_store_destroy(&signature->private_store);
|
|
+
|
|
+ vkd3d_free((void *)signature->desc.pArgumentDescs);
|
|
+ vkd3d_free(signature);
|
|
+
|
|
+ d3d12_device_release(device);
|
|
+ }
|
|
+}
|
|
+
|
|
/* ID3D12CommandList */
|
|
-static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList2(ID3D12GraphicsCommandList2 *iface)
|
|
+static inline struct d3d12_command_list *impl_from_ID3D12GraphicsCommandList3(ID3D12GraphicsCommandList3 *iface)
|
|
{
|
|
- return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList2_iface);
|
|
+ return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface);
|
|
}
|
|
|
|
static void d3d12_command_list_invalidate_current_framebuffer(struct d3d12_command_list *list)
|
|
@@ -2260,12 +2290,13 @@ static void d3d12_command_list_track_resource_usage(struct d3d12_command_list *l
|
|
}
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList2 *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12GraphicsCommandList3 *iface,
|
|
REFIID iid, void **object)
|
|
{
|
|
TRACE("iface %p, iid %s, object %p.\n", iface, debugstr_guid(iid), object);
|
|
|
|
- if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2)
|
|
+ if (IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList3)
|
|
+ || IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList2)
|
|
|| IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList1)
|
|
|| IsEqualGUID(iid, &IID_ID3D12GraphicsCommandList)
|
|
|| IsEqualGUID(iid, &IID_ID3D12CommandList)
|
|
@@ -2273,7 +2304,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic
|
|
|| IsEqualGUID(iid, &IID_ID3D12Object)
|
|
|| IsEqualGUID(iid, &IID_IUnknown))
|
|
{
|
|
- ID3D12GraphicsCommandList2_AddRef(iface);
|
|
+ ID3D12GraphicsCommandList3_AddRef(iface);
|
|
*object = iface;
|
|
return S_OK;
|
|
}
|
|
@@ -2284,9 +2315,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic
|
|
return E_NOINTERFACE;
|
|
}
|
|
|
|
-static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList2 *iface)
|
|
+static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList3 *iface)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
ULONG refcount = InterlockedIncrement(&list->refcount);
|
|
|
|
TRACE("%p increasing refcount to %u.\n", list, refcount);
|
|
@@ -2299,9 +2330,9 @@ static void vkd3d_pipeline_bindings_cleanup(struct vkd3d_pipeline_bindings *bind
|
|
vkd3d_free(bindings->vk_uav_counter_views);
|
|
}
|
|
|
|
-static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList2 *iface)
|
|
+static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandList3 *iface)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
ULONG refcount = InterlockedDecrement(&list->refcount);
|
|
|
|
TRACE("%p decreasing refcount to %u.\n", list, refcount);
|
|
@@ -2314,7 +2345,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL
|
|
|
|
/* When command pool is destroyed, all command buffers are implicitly freed. */
|
|
if (list->allocator)
|
|
- d3d12_command_allocator_free_command_buffer(list->allocator, list);
|
|
+ d3d12_command_allocator_remove_command_list(list->allocator, list);
|
|
|
|
vkd3d_pipeline_bindings_cleanup(&list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_COMPUTE]);
|
|
vkd3d_pipeline_bindings_cleanup(&list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_GRAPHICS]);
|
|
@@ -2327,66 +2358,66 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL
|
|
return refcount;
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList2 *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetPrivateData(ID3D12GraphicsCommandList3 *iface,
|
|
REFGUID guid, UINT *data_size, void *data)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, guid %s, data_size %p, data %p.\n", iface, debugstr_guid(guid), data_size, data);
|
|
|
|
return vkd3d_get_private_data(&list->private_store, guid, data_size, data);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList2 *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateData(ID3D12GraphicsCommandList3 *iface,
|
|
REFGUID guid, UINT data_size, const void *data)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, guid %s, data_size %u, data %p.\n", iface, debugstr_guid(guid), data_size, data);
|
|
|
|
return vkd3d_set_private_data(&list->private_store, guid, data_size, data);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList2 *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetPrivateDataInterface(ID3D12GraphicsCommandList3 *iface,
|
|
REFGUID guid, const IUnknown *data)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data);
|
|
|
|
return vkd3d_set_private_data_interface(&list->private_store, guid, data);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList2 *iface, const WCHAR *name)
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_SetName(ID3D12GraphicsCommandList3 *iface, const WCHAR *name)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, name %s.\n", iface, debugstr_w(name, list->device->wchar_size));
|
|
|
|
return name ? S_OK : E_INVALIDARG;
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList2 *iface, REFIID iid, void **device)
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_GetDevice(ID3D12GraphicsCommandList3 *iface, REFIID iid, void **device)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, iid %s, device %p.\n", iface, debugstr_guid(iid), device);
|
|
|
|
return d3d12_device_query_interface(list->device, iid, device);
|
|
}
|
|
|
|
-static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList2 *iface)
|
|
+static D3D12_COMMAND_LIST_TYPE STDMETHODCALLTYPE d3d12_command_list_GetType(ID3D12GraphicsCommandList3 *iface)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p.\n", iface);
|
|
|
|
return list->type;
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList2 *iface)
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandList3 *iface)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
VkResult vr;
|
|
|
|
@@ -2412,7 +2443,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL
|
|
|
|
if (list->allocator)
|
|
{
|
|
- d3d12_command_allocator_free_command_buffer(list->allocator, list);
|
|
+ d3d12_command_allocator_remove_command_list(list->allocator, list);
|
|
list->allocator = NULL;
|
|
}
|
|
|
|
@@ -2430,7 +2461,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Close(ID3D12GraphicsCommandL
|
|
static void d3d12_command_list_reset_state(struct d3d12_command_list *list,
|
|
ID3D12PipelineState *initial_pipeline_state)
|
|
{
|
|
- ID3D12GraphicsCommandList2 *iface = &list->ID3D12GraphicsCommandList2_iface;
|
|
+ ID3D12GraphicsCommandList3 *iface = &list->ID3D12GraphicsCommandList3_iface;
|
|
|
|
memset(list->strides, 0, sizeof(list->strides));
|
|
list->primitive_topology = D3D_PRIMITIVE_TOPOLOGY_POINTLIST;
|
|
@@ -2466,14 +2497,14 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list,
|
|
|
|
list->descriptor_heap_count = 0;
|
|
|
|
- ID3D12GraphicsCommandList2_SetPipelineState(iface, initial_pipeline_state);
|
|
+ ID3D12GraphicsCommandList3_SetPipelineState(iface, initial_pipeline_state);
|
|
}
|
|
|
|
-static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList2 *iface,
|
|
+static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12CommandAllocator *allocator, ID3D12PipelineState *initial_pipeline_state)
|
|
{
|
|
struct d3d12_command_allocator *allocator_impl = unsafe_impl_from_ID3D12CommandAllocator(allocator);
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
HRESULT hr;
|
|
|
|
TRACE("iface %p, allocator %p, initial_pipeline_state %p.\n",
|
|
@@ -2500,7 +2531,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_Reset(ID3D12GraphicsCommandL
|
|
return hr;
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12PipelineState *pipeline_state)
|
|
{
|
|
FIXME("iface %p, pipline_state %p stub!\n", iface, pipeline_state);
|
|
@@ -3186,6 +3217,20 @@ static void command_list_flush_vk_heap_updates(struct d3d12_command_list *list)
|
|
}
|
|
}
|
|
|
|
+static void command_list_add_descriptor_heap(struct d3d12_command_list *list, struct d3d12_descriptor_heap *heap)
|
|
+{
|
|
+ if (!contains_heap(list->descriptor_heaps, list->descriptor_heap_count, heap))
|
|
+ {
|
|
+ if (list->descriptor_heap_count == ARRAY_SIZE(list->descriptor_heaps))
|
|
+ {
|
|
+ /* Descriptors can be written after binding. */
|
|
+ FIXME("Flushing descriptor updates while list %p is not closed.\n", list);
|
|
+ command_list_flush_vk_heap_updates(list);
|
|
+ }
|
|
+ list->descriptor_heaps[list->descriptor_heap_count++] = heap;
|
|
+ }
|
|
+}
|
|
+
|
|
static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *list,
|
|
enum vkd3d_pipeline_bind_point bind_point, struct d3d12_descriptor_heap *heap)
|
|
{
|
|
@@ -3210,18 +3255,6 @@ static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *l
|
|
bindings->sampler_heap_id = heap->serial_id;
|
|
}
|
|
|
|
- if (!contains_heap(list->descriptor_heaps, list->descriptor_heap_count, heap))
|
|
- {
|
|
- if (list->descriptor_heap_count == ARRAY_SIZE(list->descriptor_heaps))
|
|
- {
|
|
- /* Descriptors can be written after binding. */
|
|
- FIXME("Flushing descriptor updates while list %p is not closed.\n", list);
|
|
- command_list_flush_vk_heap_updates(list);
|
|
- list->descriptor_heap_count = 0;
|
|
- }
|
|
- list->descriptor_heaps[list->descriptor_heap_count++] = heap;
|
|
- }
|
|
-
|
|
vkd3d_mutex_lock(&heap->vk_sets_mutex);
|
|
|
|
for (set = 0; set < ARRAY_SIZE(heap->vk_descriptor_sets); ++set)
|
|
@@ -3354,11 +3387,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c
|
|
}
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCommandList3 *iface,
|
|
UINT vertex_count_per_instance, UINT instance_count, UINT start_vertex_location,
|
|
UINT start_instance_location)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
|
|
TRACE("iface %p, vertex_count_per_instance %u, instance_count %u, "
|
|
@@ -3378,11 +3411,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom
|
|
instance_count, start_vertex_location, start_instance_location));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12GraphicsCommandList3 *iface,
|
|
UINT index_count_per_instance, UINT instance_count, UINT start_vertex_location,
|
|
INT base_vertex_location, UINT start_instance_location)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
|
|
TRACE("iface %p, index_count_per_instance %u, instance_count %u, start_vertex_location %u, "
|
|
@@ -3404,10 +3437,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap
|
|
instance_count, start_vertex_location, base_vertex_location, start_instance_location));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandList3 *iface,
|
|
UINT x, UINT y, UINT z)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
|
|
TRACE("iface %p, x %u, y %u, z %u.\n", iface, x, y, z);
|
|
@@ -3423,10 +3456,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL
|
|
VK_CALL(vkCmdDispatch(list->vk_command_buffer, x, y, z));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_CopyBufferRegion(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *dst, UINT64 dst_offset, ID3D12Resource *src, UINT64 src_offset, UINT64 byte_count)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_resource *dst_resource, *src_resource;
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
VkBufferCopy buffer_copy;
|
|
@@ -3708,11 +3741,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box)
|
|
&& box->back > box->front;
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12GraphicsCommandList3 *iface,
|
|
const D3D12_TEXTURE_COPY_LOCATION *dst, UINT dst_x, UINT dst_y, UINT dst_z,
|
|
const D3D12_TEXTURE_COPY_LOCATION *src, const D3D12_BOX *src_box)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_resource *dst_resource, *src_resource;
|
|
const struct vkd3d_format *src_format, *dst_format;
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
@@ -3833,10 +3866,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic
|
|
}
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *dst, ID3D12Resource *src)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_resource *dst_resource, *src_resource;
|
|
const struct vkd3d_format *dst_format, *src_format;
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
@@ -3903,7 +3936,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm
|
|
}
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *tiled_resource, const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate,
|
|
const D3D12_TILE_REGION_SIZE *tile_region_size, ID3D12Resource *buffer, UINT64 buffer_offset,
|
|
D3D12_TILE_COPY_FLAGS flags)
|
|
@@ -3914,11 +3947,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand
|
|
buffer, buffer_offset, flags);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *dst, UINT dst_sub_resource_idx,
|
|
ID3D12Resource *src, UINT src_sub_resource_idx, DXGI_FORMAT format)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_format *src_format, *dst_format, *vk_format;
|
|
struct d3d12_resource *dst_resource, *src_resource;
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
@@ -3981,10 +4014,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi
|
|
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_resolve));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12GraphicsCommandList3 *iface,
|
|
D3D12_PRIMITIVE_TOPOLOGY topology)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, topology %#x.\n", iface, topology);
|
|
|
|
@@ -3995,11 +4028,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr
|
|
d3d12_command_list_invalidate_current_pipeline(list);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCommandList3 *iface,
|
|
UINT viewport_count, const D3D12_VIEWPORT *viewports)
|
|
{
|
|
VkViewport vk_viewports[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
unsigned int i;
|
|
|
|
@@ -4033,10 +4066,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo
|
|
VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList3 *iface,
|
|
UINT rect_count, const D3D12_RECT *rects)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
VkRect2D vk_rects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
unsigned int i;
|
|
@@ -4061,10 +4094,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic
|
|
VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList3 *iface,
|
|
const FLOAT blend_factor[4])
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
|
|
TRACE("iface %p, blend_factor %p.\n", iface, blend_factor);
|
|
@@ -4073,10 +4106,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics
|
|
VK_CALL(vkCmdSetBlendConstants(list->vk_command_buffer, blend_factor));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsCommandList3 *iface,
|
|
UINT stencil_ref)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
|
|
TRACE("iface %p, stencil_ref %u.\n", iface, stencil_ref);
|
|
@@ -4085,11 +4118,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC
|
|
VK_CALL(vkCmdSetStencilReference(list->vk_command_buffer, VK_STENCIL_FRONT_AND_BACK, stencil_ref));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12PipelineState *pipeline_state)
|
|
{
|
|
struct d3d12_pipeline_state *state = unsafe_impl_from_ID3D12PipelineState(pipeline_state);
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state);
|
|
|
|
@@ -4140,10 +4173,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA
|
|
return 0;
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList3 *iface,
|
|
UINT barrier_count, const D3D12_RESOURCE_BARRIER *barriers)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
bool have_aliasing_barriers = false, have_split_barriers = false;
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
const struct vkd3d_vulkan_info *vk_info;
|
|
@@ -4366,13 +4399,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC
|
|
WARN("Issuing split barrier(s) on D3D12_RESOURCE_BARRIER_FLAG_END_ONLY.\n");
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ExecuteBundle(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12GraphicsCommandList *command_list)
|
|
{
|
|
FIXME("iface %p, command_list %p stub!\n", iface, command_list);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetDescriptorHeaps(ID3D12GraphicsCommandList3 *iface,
|
|
UINT heap_count, ID3D12DescriptorHeap *const *heaps)
|
|
{
|
|
TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps);
|
|
@@ -4398,10 +4431,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis
|
|
d3d12_command_list_invalidate_root_parameters(list, bind_point);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12RootSignature *root_signature)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_signature %p.\n", iface, root_signature);
|
|
|
|
@@ -4409,10 +4442,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G
|
|
unsafe_impl_from_ID3D12RootSignature(root_signature));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootSignature(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12RootSignature *root_signature)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_signature %p.\n", iface, root_signature);
|
|
|
|
@@ -4425,6 +4458,7 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l
|
|
{
|
|
struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point];
|
|
const struct d3d12_root_signature *root_signature = bindings->root_signature;
|
|
+ struct d3d12_descriptor_heap *descriptor_heap;
|
|
struct d3d12_desc *desc;
|
|
|
|
assert(root_signature_get_descriptor_table(root_signature, index));
|
|
@@ -4435,15 +4469,25 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l
|
|
if (bindings->descriptor_tables[index] == desc)
|
|
return;
|
|
|
|
+ descriptor_heap = d3d12_desc_get_descriptor_heap(desc);
|
|
+ if (!(descriptor_heap->desc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE))
|
|
+ {
|
|
+ /* GetGPUDescriptorHandleForHeapStart() returns a null handle in this case,
|
|
+ * but a CPU handle could be passed. */
|
|
+ WARN("Descriptor heap %p is not shader visible.\n", descriptor_heap);
|
|
+ return;
|
|
+ }
|
|
+ command_list_add_descriptor_heap(list, descriptor_heap);
|
|
+
|
|
bindings->descriptor_tables[index] = desc;
|
|
bindings->descriptor_table_dirty_mask |= (uint64_t)1 << index;
|
|
bindings->descriptor_table_active_mask |= (uint64_t)1 << index;
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(ID3D12GraphicsCommandList3 *iface,
|
|
UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n",
|
|
iface, root_parameter_index, base_descriptor.ptr);
|
|
@@ -4452,10 +4496,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I
|
|
root_parameter_index, base_descriptor);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable(ID3D12GraphicsCommandList3 *iface,
|
|
UINT root_parameter_index, D3D12_GPU_DESCRIPTOR_HANDLE base_descriptor)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n",
|
|
iface, root_parameter_index, base_descriptor.ptr);
|
|
@@ -4477,10 +4521,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis
|
|
c->stage_flags, c->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3D12GraphicsCommandList3 *iface,
|
|
UINT root_parameter_index, UINT data, UINT dst_offset)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n",
|
|
iface, root_parameter_index, data, dst_offset);
|
|
@@ -4489,10 +4533,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3
|
|
root_parameter_index, dst_offset, 1, &data);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID3D12GraphicsCommandList3 *iface,
|
|
UINT root_parameter_index, UINT data, UINT dst_offset)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n",
|
|
iface, root_parameter_index, data, dst_offset);
|
|
@@ -4501,10 +4545,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID
|
|
root_parameter_index, dst_offset, 1, &data);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID3D12GraphicsCommandList3 *iface,
|
|
UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n",
|
|
iface, root_parameter_index, constant_count, data, dst_offset);
|
|
@@ -4513,10 +4557,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID
|
|
root_parameter_index, dst_offset, constant_count, data);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstants(ID3D12GraphicsCommandList3 *iface,
|
|
UINT root_parameter_index, UINT constant_count, const void *data, UINT dst_offset)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n",
|
|
iface, root_parameter_index, constant_count, data, dst_offset);
|
|
@@ -4578,9 +4622,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list,
|
|
}
|
|
|
|
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView(
|
|
- ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
+ ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
|
|
iface, root_parameter_index, address);
|
|
@@ -4589,9 +4633,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie
|
|
}
|
|
|
|
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView(
|
|
- ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
+ ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
|
|
iface, root_parameter_index, address);
|
|
@@ -4650,9 +4694,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li
|
|
}
|
|
|
|
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView(
|
|
- ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
+ ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
|
|
iface, root_parameter_index, address);
|
|
@@ -4662,9 +4706,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie
|
|
}
|
|
|
|
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceView(
|
|
- ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
+ ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
|
|
iface, root_parameter_index, address);
|
|
@@ -4674,9 +4718,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi
|
|
}
|
|
|
|
static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView(
|
|
- ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
+ ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
|
|
iface, root_parameter_index, address);
|
|
@@ -4686,9 +4730,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi
|
|
}
|
|
|
|
static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView(
|
|
- ID3D12GraphicsCommandList2 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
+ ID3D12GraphicsCommandList3 *iface, UINT root_parameter_index, D3D12_GPU_VIRTUAL_ADDRESS address)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
|
|
TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n",
|
|
iface, root_parameter_index, address);
|
|
@@ -4697,10 +4741,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV
|
|
root_parameter_index, address);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12GraphicsCommandList3 *iface,
|
|
const D3D12_INDEX_BUFFER_VIEW *view)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
struct d3d12_resource *resource;
|
|
enum VkIndexType index_type;
|
|
@@ -4740,10 +4784,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics
|
|
view->BufferLocation - resource->gpu_address, index_type));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12GraphicsCommandList3 *iface,
|
|
UINT start_slot, UINT view_count, const D3D12_VERTEX_BUFFER_VIEW *views)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct vkd3d_null_resources *null_resources;
|
|
struct vkd3d_gpu_va_allocator *gpu_va_allocator;
|
|
VkDeviceSize offsets[ARRAY_SIZE(list->strides)];
|
|
@@ -4798,10 +4842,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi
|
|
d3d12_command_list_invalidate_current_pipeline(list);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsCommandList3 *iface,
|
|
UINT start_slot, UINT view_count, const D3D12_STREAM_OUTPUT_BUFFER_VIEW *views)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)];
|
|
VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)];
|
|
VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)];
|
|
@@ -4863,11 +4907,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm
|
|
VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12GraphicsCommandList3 *iface,
|
|
UINT render_target_descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE *render_target_descriptors,
|
|
BOOL single_descriptor_handle, const D3D12_CPU_DESCRIPTOR_HANDLE *depth_stencil_descriptor)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct d3d12_rtv_desc *rtv_desc;
|
|
const struct d3d12_dsv_desc *dsv_desc;
|
|
VkFormat prev_dsv_format;
|
|
@@ -5068,12 +5112,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list,
|
|
}
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12GraphicsCommandList3 *iface,
|
|
D3D12_CPU_DESCRIPTOR_HANDLE dsv, D3D12_CLEAR_FLAGS flags, float depth, UINT8 stencil,
|
|
UINT rect_count, const D3D12_RECT *rects)
|
|
{
|
|
const union VkClearValue clear_value = {.depthStencil = {depth, stencil}};
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(dsv);
|
|
struct VkAttachmentDescription attachment_desc;
|
|
struct VkAttachmentReference ds_reference;
|
|
@@ -5117,10 +5161,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra
|
|
&clear_value, rect_count, rects);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList3 *iface,
|
|
D3D12_CPU_DESCRIPTOR_HANDLE rtv, const FLOAT color[4], UINT rect_count, const D3D12_RECT *rects)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(rtv);
|
|
struct VkAttachmentDescription attachment_desc;
|
|
struct VkAttachmentReference color_reference;
|
|
@@ -5365,11 +5409,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12
|
|
}
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList3 *iface,
|
|
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource,
|
|
const UINT values[4], UINT rect_count, const D3D12_RECT *rects)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct vkd3d_view *descriptor, *uint_view = NULL;
|
|
struct d3d12_device *device = list->device;
|
|
struct vkd3d_texture_view_desc view_desc;
|
|
@@ -5431,11 +5475,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID
|
|
vkd3d_view_decref(uint_view, device);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(ID3D12GraphicsCommandList3 *iface,
|
|
D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, ID3D12Resource *resource,
|
|
const float values[4], UINT rect_count, const D3D12_RECT *rects)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_resource *resource_impl;
|
|
VkClearColorValue colour;
|
|
struct vkd3d_view *view;
|
|
@@ -5451,16 +5495,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I
|
|
d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_DiscardResource(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *resource, const D3D12_DISCARD_REGION *region)
|
|
{
|
|
FIXME_ONCE("iface %p, resource %p, region %p stub!\n", iface, resource, region);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
VkQueryControlFlags flags = 0;
|
|
@@ -5487,10 +5531,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman
|
|
VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags));
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_EndQuery(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT index)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
|
|
@@ -5532,12 +5576,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type)
|
|
return sizeof(uint64_t);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12QueryHeap *heap, D3D12_QUERY_TYPE type, UINT start_index, UINT query_count,
|
|
ID3D12Resource *dst_buffer, UINT64 aligned_dst_buffer_offset)
|
|
{
|
|
const struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap);
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer);
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
unsigned int i, first, count;
|
|
@@ -5613,10 +5657,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics
|
|
}
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *buffer, UINT64 aligned_buffer_offset, D3D12_PREDICATION_OP operation)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer);
|
|
const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info;
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
@@ -5685,19 +5729,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo
|
|
}
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetMarker(ID3D12GraphicsCommandList3 *iface,
|
|
UINT metadata, const void *data, UINT size)
|
|
{
|
|
FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_BeginEvent(ID3D12GraphicsCommandList3 *iface,
|
|
UINT metadata, const void *data, UINT size)
|
|
{
|
|
FIXME("iface %p, metadata %#x, data %p, size %u stub!\n", iface, metadata, data, size);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList2 *iface)
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_EndEvent(ID3D12GraphicsCommandList3 *iface)
|
|
{
|
|
FIXME("iface %p stub!\n", iface);
|
|
}
|
|
@@ -5706,14 +5750,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN
|
|
STATIC_ASSERT(sizeof(VkDrawIndexedIndirectCommand) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS));
|
|
STATIC_ASSERT(sizeof(VkDrawIndirectCommand) == sizeof(D3D12_DRAW_ARGUMENTS));
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12CommandSignature *command_signature, UINT max_command_count, ID3D12Resource *arg_buffer,
|
|
UINT64 arg_buffer_offset, ID3D12Resource *count_buffer, UINT64 count_buffer_offset)
|
|
{
|
|
struct d3d12_command_signature *sig_impl = unsafe_impl_from_ID3D12CommandSignature(command_signature);
|
|
struct d3d12_resource *count_impl = unsafe_impl_from_ID3D12Resource(count_buffer);
|
|
struct d3d12_resource *arg_impl = unsafe_impl_from_ID3D12Resource(arg_buffer);
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
const D3D12_COMMAND_SIGNATURE_DESC *signature_desc;
|
|
const struct vkd3d_vk_device_procs *vk_procs;
|
|
unsigned int i;
|
|
@@ -5731,6 +5775,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC
|
|
return;
|
|
}
|
|
|
|
+ d3d12_command_signature_incref(sig_impl);
|
|
+
|
|
signature_desc = &sig_impl->desc;
|
|
for (i = 0; i < signature_desc->NumArgumentDescs; ++i)
|
|
{
|
|
@@ -5793,6 +5839,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC
|
|
if (!d3d12_command_list_update_compute_state(list))
|
|
{
|
|
WARN("Failed to update compute state, ignoring dispatch.\n");
|
|
+ d3d12_command_signature_decref(sig_impl);
|
|
return;
|
|
}
|
|
|
|
@@ -5805,9 +5852,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC
|
|
break;
|
|
}
|
|
}
|
|
+
|
|
+ d3d12_command_signature_decref(sig_impl);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *dst_buffer, UINT64 dst_offset,
|
|
ID3D12Resource *src_buffer, UINT64 src_offset,
|
|
UINT dependent_resource_count, ID3D12Resource * const *dependent_resources,
|
|
@@ -5820,7 +5869,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap
|
|
dependent_resource_count, dependent_resources, dependent_sub_resource_ranges);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *dst_buffer, UINT64 dst_offset,
|
|
ID3D12Resource *src_buffer, UINT64 src_offset,
|
|
UINT dependent_resource_count, ID3D12Resource * const *dependent_resources,
|
|
@@ -5833,20 +5882,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr
|
|
dependent_resource_count, dependent_resources, dependent_sub_resource_ranges);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_OMSetDepthBounds(ID3D12GraphicsCommandList3 *iface,
|
|
FLOAT min, FLOAT max)
|
|
{
|
|
FIXME("iface %p, min %.8e, max %.8e stub!\n", iface, min, max);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetSamplePositions(ID3D12GraphicsCommandList3 *iface,
|
|
UINT sample_count, UINT pixel_count, D3D12_SAMPLE_POSITION *sample_positions)
|
|
{
|
|
FIXME("iface %p, sample_count %u, pixel_count %u, sample_positions %p stub!\n",
|
|
iface, sample_count, pixel_count, sample_positions);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12GraphicsCommandList3 *iface,
|
|
ID3D12Resource *dst_resource, UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y,
|
|
ID3D12Resource *src_resource, UINT src_sub_resource_idx,
|
|
D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode)
|
|
@@ -5858,16 +5907,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12
|
|
src_resource, src_sub_resource_idx, src_rect, format, mode);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList2 *iface, UINT mask)
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetViewInstanceMask(ID3D12GraphicsCommandList3 *iface, UINT mask)
|
|
{
|
|
FIXME("iface %p, mask %#x stub!\n", iface, mask);
|
|
}
|
|
|
|
-static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList2 *iface,
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12GraphicsCommandList3 *iface,
|
|
UINT count, const D3D12_WRITEBUFFERIMMEDIATE_PARAMETER *parameters,
|
|
const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes)
|
|
{
|
|
- struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList2(iface);
|
|
+ struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList3(iface);
|
|
struct d3d12_resource *resource;
|
|
unsigned int i;
|
|
|
|
@@ -5880,7 +5929,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap
|
|
}
|
|
}
|
|
|
|
-static const struct ID3D12GraphicsCommandList2Vtbl d3d12_command_list_vtbl =
|
|
+static void STDMETHODCALLTYPE d3d12_command_list_SetProtectedResourceSession(ID3D12GraphicsCommandList3 *iface,
|
|
+ ID3D12ProtectedResourceSession *protected_session)
|
|
+{
|
|
+ FIXME("iface %p, protected_session %p stub!\n", iface, protected_session);
|
|
+}
|
|
+
|
|
+static const struct ID3D12GraphicsCommandList3Vtbl d3d12_command_list_vtbl =
|
|
{
|
|
/* IUnknown methods */
|
|
d3d12_command_list_QueryInterface,
|
|
@@ -5956,6 +6011,8 @@ static const struct ID3D12GraphicsCommandList2Vtbl d3d12_command_list_vtbl =
|
|
d3d12_command_list_SetViewInstanceMask,
|
|
/* ID3D12GraphicsCommandList2 methods */
|
|
d3d12_command_list_WriteBufferImmediate,
|
|
+ /* ID3D12GraphicsCommandList3 methods */
|
|
+ d3d12_command_list_SetProtectedResourceSession,
|
|
};
|
|
|
|
static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12CommandList *iface)
|
|
@@ -5963,7 +6020,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma
|
|
if (!iface)
|
|
return NULL;
|
|
assert(iface->lpVtbl == (struct ID3D12CommandListVtbl *)&d3d12_command_list_vtbl);
|
|
- return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList2_iface);
|
|
+ return CONTAINING_RECORD(iface, struct d3d12_command_list, ID3D12GraphicsCommandList3_iface);
|
|
}
|
|
|
|
static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device,
|
|
@@ -5972,7 +6029,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d
|
|
{
|
|
HRESULT hr;
|
|
|
|
- list->ID3D12GraphicsCommandList2_iface.lpVtbl = &d3d12_command_list_vtbl;
|
|
+ list->ID3D12GraphicsCommandList3_iface.lpVtbl = &d3d12_command_list_vtbl;
|
|
list->refcount = 1;
|
|
|
|
list->type = type;
|
|
@@ -7299,16 +7356,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSign
|
|
TRACE("%p decreasing refcount to %u.\n", signature, refcount);
|
|
|
|
if (!refcount)
|
|
- {
|
|
- struct d3d12_device *device = signature->device;
|
|
-
|
|
- vkd3d_private_store_destroy(&signature->private_store);
|
|
-
|
|
- vkd3d_free((void *)signature->desc.pArgumentDescs);
|
|
- vkd3d_free(signature);
|
|
-
|
|
- d3d12_device_release(device);
|
|
- }
|
|
+ d3d12_command_signature_decref(signature);
|
|
|
|
return refcount;
|
|
}
|
|
@@ -7415,6 +7463,7 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_
|
|
|
|
object->ID3D12CommandSignature_iface.lpVtbl = &d3d12_command_signature_vtbl;
|
|
object->refcount = 1;
|
|
+ object->internal_refcount = 1;
|
|
|
|
object->desc = *desc;
|
|
if (!(object->desc.pArgumentDescs = vkd3d_calloc(desc->NumArgumentDescs, sizeof(*desc->pArgumentDescs))))
|
|
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
|
|
index b9a8943cc08..a2e1f13dec3 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/device.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/device.c
|
|
@@ -2657,8 +2657,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device *if
|
|
initial_pipeline_state, &object)))
|
|
return hr;
|
|
|
|
- return return_interface(&object->ID3D12GraphicsCommandList2_iface,
|
|
- &IID_ID3D12GraphicsCommandList2, riid, command_list);
|
|
+ return return_interface(&object->ID3D12GraphicsCommandList3_iface,
|
|
+ &IID_ID3D12GraphicsCommandList3, riid, command_list);
|
|
}
|
|
|
|
/* Direct3D feature levels restrict which formats can be optionally supported. */
|
|
@@ -3414,6 +3414,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface,
|
|
struct d3d12_device *device = impl_from_ID3D12Device(iface);
|
|
unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx;
|
|
unsigned int dst_range_size, src_range_size;
|
|
+ struct d3d12_descriptor_heap *dst_heap;
|
|
const struct d3d12_desc *src;
|
|
struct d3d12_desc *dst;
|
|
|
|
@@ -3443,13 +3444,14 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface,
|
|
src_range_size = src_descriptor_range_sizes ? src_descriptor_range_sizes[src_range_idx] : 1;
|
|
|
|
dst = d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[dst_range_idx]);
|
|
+ dst_heap = d3d12_desc_get_descriptor_heap(dst);
|
|
src = d3d12_desc_from_cpu_handle(src_descriptor_range_offsets[src_range_idx]);
|
|
|
|
for (; dst_idx < dst_range_size && src_idx < src_range_size; ++dst_idx, ++src_idx)
|
|
{
|
|
if (dst[dst_idx].s.u.object == src[src_idx].s.u.object)
|
|
continue;
|
|
- d3d12_desc_copy(&dst[dst_idx], &src[src_idx], device);
|
|
+ d3d12_desc_copy(&dst[dst_idx], &src[src_idx], dst_heap, device);
|
|
}
|
|
|
|
if (dst_idx >= dst_range_size)
|
|
@@ -3747,7 +3749,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface,
|
|
if (FAILED(hr = d3d12_fence_create(device, initial_value, flags, &object)))
|
|
return hr;
|
|
|
|
- return return_interface(&object->ID3D12Fence_iface, &IID_ID3D12Fence, riid, fence);
|
|
+ return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence);
|
|
}
|
|
|
|
static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device *iface)
|
|
@@ -3891,12 +3893,18 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface
|
|
UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling,
|
|
D3D12_SUBRESOURCE_TILING *sub_resource_tilings)
|
|
{
|
|
- FIXME("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, "
|
|
+ const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource);
|
|
+ struct d3d12_device *device = impl_from_ID3D12Device(iface);
|
|
+
|
|
+ TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, "
|
|
"standard_title_shape %p, sub_resource_tiling_count %p, "
|
|
- "first_sub_resource_tiling %u, sub_resource_tilings %p stub!\n",
|
|
+ "first_sub_resource_tiling %u, sub_resource_tilings %p.\n",
|
|
iface, resource, total_tile_count, packed_mip_info, standard_tile_shape,
|
|
sub_resource_tiling_count, first_sub_resource_tiling,
|
|
sub_resource_tilings);
|
|
+
|
|
+ d3d12_resource_get_tiling(device, resource_impl, total_tile_count, packed_mip_info, standard_tile_shape,
|
|
+ sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings);
|
|
}
|
|
|
|
static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid)
|
|
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
|
|
index 4c07d326504..cd3856c2937 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/resource.c
|
|
+++ b/libs/vkd3d/libs/vkd3d/resource.c
|
|
@@ -971,6 +971,11 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device,
|
|
return hr;
|
|
}
|
|
|
|
+static void d3d12_resource_tile_info_cleanup(struct d3d12_resource *resource)
|
|
+{
|
|
+ vkd3d_free(resource->tiles.subresources);
|
|
+}
|
|
+
|
|
static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12_device *device)
|
|
{
|
|
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
@@ -986,6 +991,8 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12
|
|
else
|
|
VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL));
|
|
|
|
+ d3d12_resource_tile_info_cleanup(resource);
|
|
+
|
|
if (resource->heap)
|
|
d3d12_heap_resource_destroyed(resource->heap);
|
|
}
|
|
@@ -1057,9 +1064,193 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource,
|
|
box->back = d3d12_resource_desc_get_depth(&resource->desc, level);
|
|
}
|
|
|
|
-static void d3d12_resource_init_tiles(struct d3d12_resource *resource)
|
|
+static void compute_image_subresource_size_in_tiles(const VkExtent3D *tile_extent,
|
|
+ const struct D3D12_RESOURCE_DESC *desc, unsigned int miplevel_idx,
|
|
+ struct vkd3d_tiled_region_extent *size)
|
|
+{
|
|
+ unsigned int width, height, depth;
|
|
+
|
|
+ width = d3d12_resource_desc_get_width(desc, miplevel_idx);
|
|
+ height = d3d12_resource_desc_get_height(desc, miplevel_idx);
|
|
+ depth = d3d12_resource_desc_get_depth(desc, miplevel_idx);
|
|
+ size->width = (width + tile_extent->width - 1) / tile_extent->width;
|
|
+ size->height = (height + tile_extent->height - 1) / tile_extent->height;
|
|
+ size->depth = (depth + tile_extent->depth - 1) / tile_extent->depth;
|
|
+}
|
|
+
|
|
+void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource,
|
|
+ UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape,
|
|
+ UINT *subresource_tiling_count, UINT first_subresource_tiling,
|
|
+ D3D12_SUBRESOURCE_TILING *subresource_tilings)
|
|
{
|
|
- resource->tiles.subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
|
|
+ unsigned int i, subresource, subresource_count, miplevel_idx, count;
|
|
+ const struct vkd3d_subresource_tile_info *tile_info;
|
|
+ const VkExtent3D *tile_extent;
|
|
+
|
|
+ tile_extent = &resource->tiles.tile_extent;
|
|
+
|
|
+ if (packed_mip_info)
|
|
+ {
|
|
+ packed_mip_info->NumStandardMips = resource->tiles.standard_mip_count;
|
|
+ packed_mip_info->NumPackedMips = resource->desc.MipLevels - packed_mip_info->NumStandardMips;
|
|
+ packed_mip_info->NumTilesForPackedMips = !!resource->tiles.packed_mip_tile_count; /* non-zero dummy value */
|
|
+ packed_mip_info->StartTileIndexInOverallResource = packed_mip_info->NumPackedMips
|
|
+ ? resource->tiles.subresources[resource->tiles.standard_mip_count].offset : 0;
|
|
+ }
|
|
+
|
|
+ if (standard_tile_shape)
|
|
+ {
|
|
+ /* D3D12 docs say tile shape is cleared to zero if there is no standard mip, but drivers don't to do this. */
|
|
+ standard_tile_shape->WidthInTexels = tile_extent->width;
|
|
+ standard_tile_shape->HeightInTexels = tile_extent->height;
|
|
+ standard_tile_shape->DepthInTexels = tile_extent->depth;
|
|
+ }
|
|
+
|
|
+ if (total_tile_count)
|
|
+ *total_tile_count = resource->tiles.total_count;
|
|
+
|
|
+ if (!subresource_tiling_count)
|
|
+ return;
|
|
+
|
|
+ subresource_count = resource->tiles.subresource_count;
|
|
+
|
|
+ count = subresource_count - min(first_subresource_tiling, subresource_count);
|
|
+ count = min(count, *subresource_tiling_count);
|
|
+
|
|
+ for (i = 0; i < count; ++i)
|
|
+ {
|
|
+ subresource = i + first_subresource_tiling;
|
|
+ miplevel_idx = subresource % resource->desc.MipLevels;
|
|
+ if (miplevel_idx >= resource->tiles.standard_mip_count)
|
|
+ {
|
|
+ memset(&subresource_tilings[i], 0, sizeof(subresource_tilings[i]));
|
|
+ subresource_tilings[i].StartTileIndexInOverallResource = D3D12_PACKED_TILE;
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ tile_info = &resource->tiles.subresources[subresource];
|
|
+ subresource_tilings[i].StartTileIndexInOverallResource = tile_info->offset;
|
|
+ subresource_tilings[i].WidthInTiles = tile_info->extent.width;
|
|
+ subresource_tilings[i].HeightInTiles = tile_info->extent.height;
|
|
+ subresource_tilings[i].DepthInTiles = tile_info->extent.depth;
|
|
+ }
|
|
+ *subresource_tiling_count = i;
|
|
+}
|
|
+
|
|
+static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device)
|
|
+{
|
|
+ unsigned int i, start_idx, subresource_count, tile_count, miplevel_idx;
|
|
+ const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
|
|
+ VkSparseImageMemoryRequirements *sparse_requirements_array;
|
|
+ VkSparseImageMemoryRequirements sparse_requirements = {0};
|
|
+ struct vkd3d_subresource_tile_info *tile_info;
|
|
+ VkMemoryRequirements requirements;
|
|
+ const VkExtent3D *tile_extent;
|
|
+ uint32_t requirement_count;
|
|
+
|
|
+ subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
|
|
+
|
|
+ if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources))))
|
|
+ {
|
|
+ ERR("Failed to allocate subresource info array.\n");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (d3d12_resource_is_buffer(resource))
|
|
+ {
|
|
+ assert(subresource_count == 1);
|
|
+
|
|
+ VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements));
|
|
+ if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
|
|
+ FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n");
|
|
+
|
|
+ tile_info = &resource->tiles.subresources[0];
|
|
+ tile_info->offset = 0;
|
|
+ tile_info->extent.width = align(resource->desc.Width, D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
|
|
+ / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES;
|
|
+ tile_info->extent.height = 1;
|
|
+ tile_info->extent.depth = 1;
|
|
+ tile_info->count = tile_info->extent.width;
|
|
+
|
|
+ resource->tiles.tile_extent.width = D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES;
|
|
+ resource->tiles.tile_extent.height = 1;
|
|
+ resource->tiles.tile_extent.depth = 1;
|
|
+ resource->tiles.total_count = tile_info->extent.width;
|
|
+ resource->tiles.subresource_count = 1;
|
|
+ resource->tiles.standard_mip_count = 1;
|
|
+ resource->tiles.packed_mip_tile_count = 0;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ VK_CALL(vkGetImageMemoryRequirements(device->vk_device, resource->u.vk_image, &requirements));
|
|
+ if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES)
|
|
+ FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n");
|
|
+
|
|
+ requirement_count = 0;
|
|
+ VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image, &requirement_count, NULL));
|
|
+ if (!(sparse_requirements_array = vkd3d_calloc(requirement_count, sizeof(*sparse_requirements_array))))
|
|
+ {
|
|
+ ERR("Failed to allocate sparse requirements array.\n");
|
|
+ return false;
|
|
+ }
|
|
+ VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image,
|
|
+ &requirement_count, sparse_requirements_array));
|
|
+
|
|
+ for (i = 0; i < requirement_count; ++i)
|
|
+ {
|
|
+ if (sparse_requirements_array[i].formatProperties.aspectMask & resource->format->vk_aspect_mask)
|
|
+ {
|
|
+ if (sparse_requirements.formatProperties.aspectMask)
|
|
+ {
|
|
+ WARN("Ignoring properties for aspect mask %#x.\n",
|
|
+ sparse_requirements_array[i].formatProperties.aspectMask);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ sparse_requirements = sparse_requirements_array[i];
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ vkd3d_free(sparse_requirements_array);
|
|
+ if (!sparse_requirements.formatProperties.aspectMask)
|
|
+ {
|
|
+ WARN("Failed to get sparse requirements.\n");
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ resource->tiles.tile_extent = sparse_requirements.formatProperties.imageGranularity;
|
|
+ resource->tiles.subresource_count = subresource_count;
|
|
+ resource->tiles.standard_mip_count = sparse_requirements.imageMipTailSize
|
|
+ ? sparse_requirements.imageMipTailFirstLod : resource->desc.MipLevels;
|
|
+ resource->tiles.packed_mip_tile_count = (resource->tiles.standard_mip_count < resource->desc.MipLevels)
|
|
+ ? sparse_requirements.imageMipTailSize / requirements.alignment : 0;
|
|
+
|
|
+ for (i = 0, start_idx = 0; i < subresource_count; ++i)
|
|
+ {
|
|
+ miplevel_idx = i % resource->desc.MipLevels;
|
|
+
|
|
+ tile_extent = &sparse_requirements.formatProperties.imageGranularity;
|
|
+ tile_info = &resource->tiles.subresources[i];
|
|
+ compute_image_subresource_size_in_tiles(tile_extent, &resource->desc, miplevel_idx, &tile_info->extent);
|
|
+ tile_info->offset = start_idx;
|
|
+ tile_info->count = 0;
|
|
+
|
|
+ if (miplevel_idx < resource->tiles.standard_mip_count)
|
|
+ {
|
|
+ tile_count = tile_info->extent.width * tile_info->extent.height * tile_info->extent.depth;
|
|
+ start_idx += tile_count;
|
|
+ tile_info->count = tile_count;
|
|
+ }
|
|
+ else if (miplevel_idx == resource->tiles.standard_mip_count)
|
|
+ {
|
|
+ tile_info->count = 1; /* Non-zero dummy value */
|
|
+ start_idx += 1;
|
|
+ }
|
|
+ }
|
|
+ resource->tiles.total_count = start_idx;
|
|
+ }
|
|
+
|
|
+ return true;
|
|
}
|
|
|
|
/* ID3D12Resource */
|
|
@@ -2013,7 +2204,11 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device,
|
|
desc, initial_state, optimized_clear_value, &object)))
|
|
return hr;
|
|
|
|
- d3d12_resource_init_tiles(object);
|
|
+ if (!d3d12_resource_init_tiles(object, device))
|
|
+ {
|
|
+ d3d12_resource_Release(&object->ID3D12Resource_iface);
|
|
+ return E_OUTOFMEMORY;
|
|
+ }
|
|
|
|
TRACE("Created reserved resource %p.\n", object);
|
|
|
|
@@ -2411,13 +2606,11 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr
|
|
descriptor_writes_free_object_refs(&writes, device);
|
|
}
|
|
|
|
-static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst)
|
|
+static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst, struct d3d12_descriptor_heap *descriptor_heap)
|
|
{
|
|
- struct d3d12_descriptor_heap *descriptor_heap;
|
|
unsigned int i, head;
|
|
|
|
i = dst->index;
|
|
- descriptor_heap = d3d12_desc_get_descriptor_heap(dst);
|
|
head = descriptor_heap->dirty_list_head;
|
|
|
|
/* Only one thread can swap the value away from zero. */
|
|
@@ -2431,14 +2624,20 @@ static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst)
|
|
}
|
|
}
|
|
|
|
-void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *src,
|
|
- struct d3d12_device *device)
|
|
+static inline void descriptor_heap_write_atomic(struct d3d12_descriptor_heap *descriptor_heap, struct d3d12_desc *dst,
|
|
+ const struct d3d12_desc *src, struct d3d12_device *device)
|
|
{
|
|
void *object = src->s.u.object;
|
|
|
|
d3d12_desc_replace(dst, object, device);
|
|
- if (device->use_vk_heaps && object && !dst->next)
|
|
- d3d12_desc_mark_as_modified(dst);
|
|
+ if (descriptor_heap->use_vk_heaps && object && !dst->next)
|
|
+ d3d12_desc_mark_as_modified(dst, descriptor_heap);
|
|
+}
|
|
+
|
|
+void d3d12_desc_write_atomic(struct d3d12_desc *dst, const struct d3d12_desc *src,
|
|
+ struct d3d12_device *device)
|
|
+{
|
|
+ descriptor_heap_write_atomic(d3d12_desc_get_descriptor_heap(dst), dst, src, device);
|
|
}
|
|
|
|
static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_device *device)
|
|
@@ -2446,7 +2645,9 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_devic
|
|
d3d12_desc_replace(descriptor, NULL, device);
|
|
}
|
|
|
|
-void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src,
|
|
+/* This is a major performance bottleneck for some games, so do not load the device
|
|
+ * pointer from dst_heap. In some cases device will not be used. */
|
|
+void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_descriptor_heap *dst_heap,
|
|
struct d3d12_device *device)
|
|
{
|
|
struct d3d12_desc tmp;
|
|
@@ -2454,7 +2655,7 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src,
|
|
assert(dst != src);
|
|
|
|
tmp.s.u.object = d3d12_desc_get_object_ref(src, device);
|
|
- d3d12_desc_write_atomic(dst, &tmp, device);
|
|
+ descriptor_heap_write_atomic(dst_heap, dst, &tmp, device);
|
|
}
|
|
|
|
static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12_device *device,
|
|
@@ -3853,7 +4054,15 @@ static D3D12_GPU_DESCRIPTOR_HANDLE * STDMETHODCALLTYPE d3d12_descriptor_heap_Get
|
|
|
|
TRACE("iface %p, descriptor %p.\n", iface, descriptor);
|
|
|
|
- descriptor->ptr = (uint64_t)(intptr_t)heap->descriptors;
|
|
+ if (heap->desc.Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE)
|
|
+ {
|
|
+ descriptor->ptr = (uint64_t)(intptr_t)heap->descriptors;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ WARN("Heap %p is not shader-visible.\n", iface);
|
|
+ descriptor->ptr = 0;
|
|
+ }
|
|
|
|
return descriptor;
|
|
}
|
|
@@ -3956,7 +4165,7 @@ static HRESULT d3d12_descriptor_heap_vk_descriptor_sets_init(struct d3d12_descri
|
|
descriptor_heap->vk_descriptor_pool = VK_NULL_HANDLE;
|
|
memset(descriptor_heap->vk_descriptor_sets, 0, sizeof(descriptor_heap->vk_descriptor_sets));
|
|
|
|
- if (!device->use_vk_heaps || (desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV
|
|
+ if (!descriptor_heap->use_vk_heaps || (desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV
|
|
&& desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER))
|
|
return S_OK;
|
|
|
|
@@ -3987,6 +4196,7 @@ static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descript
|
|
if (FAILED(hr = vkd3d_private_store_init(&descriptor_heap->private_store)))
|
|
return hr;
|
|
|
|
+ descriptor_heap->use_vk_heaps = device->use_vk_heaps && (desc->Flags & D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE);
|
|
d3d12_descriptor_heap_vk_descriptor_sets_init(descriptor_heap, device, desc);
|
|
vkd3d_mutex_init(&descriptor_heap->vk_sets_mutex);
|
|
|
|
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
index c5259420acf..4bd6812b16e 100644
|
|
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
|
|
@@ -253,6 +253,11 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond)
|
|
{
|
|
}
|
|
|
|
+static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x)
|
|
+{
|
|
+ return InterlockedIncrement((LONG volatile *)x);
|
|
+}
|
|
+
|
|
static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x)
|
|
{
|
|
return InterlockedDecrement((LONG volatile *)x);
|
|
@@ -387,6 +392,15 @@ static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x)
|
|
}
|
|
# else
|
|
# error "vkd3d_atomic_decrement() not implemented for this platform"
|
|
+# endif /* HAVE_SYNC_SUB_AND_FETCH */
|
|
+
|
|
+# if HAVE_SYNC_ADD_AND_FETCH
|
|
+static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x)
|
|
+{
|
|
+ return __sync_add_and_fetch(x, 1);
|
|
+}
|
|
+# else
|
|
+# error "vkd3d_atomic_increment() not implemented for this platform"
|
|
# endif /* HAVE_SYNC_ADD_AND_FETCH */
|
|
|
|
# if HAVE_SYNC_BOOL_COMPARE_AND_SWAP
|
|
@@ -602,10 +616,12 @@ struct vkd3d_signaled_semaphore
|
|
/* ID3D12Fence */
|
|
struct d3d12_fence
|
|
{
|
|
- ID3D12Fence ID3D12Fence_iface;
|
|
+ ID3D12Fence1 ID3D12Fence1_iface;
|
|
LONG internal_refcount;
|
|
LONG refcount;
|
|
|
|
+ D3D12_FENCE_FLAGS flags;
|
|
+
|
|
uint64_t value;
|
|
uint64_t max_pending_value;
|
|
struct vkd3d_mutex mutex;
|
|
@@ -673,9 +689,28 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface);
|
|
#define VKD3D_RESOURCE_DEDICATED_HEAP 0x00000008
|
|
#define VKD3D_RESOURCE_LINEAR_TILING 0x00000010
|
|
|
|
+struct vkd3d_tiled_region_extent
|
|
+{
|
|
+ unsigned int width;
|
|
+ unsigned int height;
|
|
+ unsigned int depth;
|
|
+};
|
|
+
|
|
+struct vkd3d_subresource_tile_info
|
|
+{
|
|
+ unsigned int offset;
|
|
+ unsigned int count;
|
|
+ struct vkd3d_tiled_region_extent extent;
|
|
+};
|
|
+
|
|
struct d3d12_resource_tile_info
|
|
{
|
|
+ VkExtent3D tile_extent;
|
|
+ unsigned int total_count;
|
|
+ unsigned int standard_mip_count;
|
|
+ unsigned int packed_mip_tile_count;
|
|
unsigned int subresource_count;
|
|
+ struct vkd3d_subresource_tile_info *subresources;
|
|
};
|
|
|
|
/* ID3D12Resource */
|
|
@@ -728,6 +763,10 @@ static inline bool d3d12_resource_is_texture(const struct d3d12_resource *resour
|
|
|
|
bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource);
|
|
HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device);
|
|
+void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource,
|
|
+ UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape,
|
|
+ UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling,
|
|
+ D3D12_SUBRESOURCE_TILING *sub_resource_tilings);
|
|
|
|
HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
|
|
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
|
|
@@ -868,8 +907,9 @@ static inline void *d3d12_desc_get_object_ref(const volatile struct d3d12_desc *
|
|
{
|
|
do
|
|
{
|
|
- view = src->s.u.object;
|
|
- } while (view && !vkd3d_view_incref(view));
|
|
+ if (!(view = src->s.u.object))
|
|
+ return NULL;
|
|
+ } while (!vkd3d_view_incref(view));
|
|
|
|
/* Check if the object is still in src to handle the case where it was
|
|
* already freed and reused elsewhere when the refcount was incremented. */
|
|
@@ -895,7 +935,10 @@ static inline void d3d12_desc_copy_raw(struct d3d12_desc *dst, const struct d3d1
|
|
dst->s = src->s;
|
|
}
|
|
|
|
-void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_device *device);
|
|
+struct d3d12_descriptor_heap;
|
|
+
|
|
+void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, struct d3d12_descriptor_heap *dst_heap,
|
|
+ struct d3d12_device *device);
|
|
void d3d12_desc_create_cbv(struct d3d12_desc *descriptor,
|
|
struct d3d12_device *device, const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc);
|
|
void d3d12_desc_create_srv(struct d3d12_desc *descriptor,
|
|
@@ -998,6 +1041,7 @@ struct d3d12_descriptor_heap
|
|
D3D12_DESCRIPTOR_HEAP_DESC desc;
|
|
|
|
struct d3d12_device *device;
|
|
+ bool use_vk_heaps;
|
|
|
|
struct vkd3d_private_store private_store;
|
|
|
|
@@ -1382,7 +1426,7 @@ enum vkd3d_pipeline_bind_point
|
|
/* ID3D12CommandList */
|
|
struct d3d12_command_list
|
|
{
|
|
- ID3D12GraphicsCommandList2 ID3D12GraphicsCommandList2_iface;
|
|
+ ID3D12GraphicsCommandList3 ID3D12GraphicsCommandList3_iface;
|
|
LONG refcount;
|
|
|
|
D3D12_COMMAND_LIST_TYPE type;
|
|
@@ -1575,6 +1619,7 @@ struct d3d12_command_signature
|
|
{
|
|
ID3D12CommandSignature ID3D12CommandSignature_iface;
|
|
LONG refcount;
|
|
+ unsigned int internal_refcount;
|
|
|
|
D3D12_COMMAND_SIGNATURE_DESC desc;
|
|
|
|
--
|
|
2.40.1
|
|
|