wine-staging/patches/vkd3d-latest/0003-Updated-vkd3d-to-b4bb3931c5e7e59496c07c2d4e3b6cfd3bf.patch
2023-08-03 12:06:16 +10:00

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, &copy->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(&param->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, &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(&reg_symbol, reg);
vkd3d_symbol_set_register_info(&reg_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, &reg_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, &reg);
+}
+
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