wine-staging/patches/vkd3d-latest/0002-Updated-vkd3d-to-f75bdd6e217863840cc5fb3251a171ca0ab.patch
2023-11-11 09:57:14 +11:00

2700 lines
109 KiB
Diff

From 05cfafa2f32ee22e6f455d5e646a26ef7c4f9fbd Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Mon, 30 Oct 2023 06:37:46 +1100
Subject: [PATCH] Updated vkd3d to f75bdd6e217863840cc5fb3251a171ca0abe729b.
---
libs/vkd3d/include/private/vkd3d_common.h | 21 +
libs/vkd3d/include/vkd3d_d3dcompiler.h | 37 +
libs/vkd3d/include/vkd3d_shader.h | 35 +-
libs/vkd3d/include/vkd3d_utils.h | 17 +
libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 21 +-
libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 2 +-
libs/vkd3d/libs/vkd3d-shader/dxbc.c | 2 +
libs/vkd3d/libs/vkd3d-shader/dxil.c | 1589 ++++++++++++++++-
libs/vkd3d/libs/vkd3d-shader/hlsl.c | 4 +
libs/vkd3d/libs/vkd3d-shader/hlsl.h | 7 +-
libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 +
libs/vkd3d/libs/vkd3d-shader/hlsl.y | 12 +
libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 4 +-
libs/vkd3d/libs/vkd3d-shader/spirv.c | 28 +-
libs/vkd3d/libs/vkd3d-shader/tpf.c | 22 +-
.../libs/vkd3d-shader/vkd3d_shader_main.c | 10 +-
.../libs/vkd3d-shader/vkd3d_shader_private.h | 69 +-
libs/vkd3d/libs/vkd3d/device.c | 19 +-
libs/vkd3d/libs/vkd3d/resource.c | 6 +-
libs/vkd3d/libs/vkd3d/vkd3d_private.h | 3 +-
20 files changed, 1746 insertions(+), 164 deletions(-)
diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h
index f7d98f327f1..44045b436dd 100644
--- a/libs/vkd3d/include/private/vkd3d_common.h
+++ b/libs/vkd3d/include/private/vkd3d_common.h
@@ -49,6 +49,27 @@
((uint32_t)(ch0) | ((uint32_t)(ch1) << 8) \
| ((uint32_t)(ch2) << 16) | ((uint32_t)(ch3) << 24))
+#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
+#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
+#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
+#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
+#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
+#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
+#define TAG_OSG5 VKD3D_MAKE_TAG('O', 'S', 'G', '5')
+#define TAG_OSGN VKD3D_MAKE_TAG('O', 'S', 'G', 'N')
+#define TAG_PCSG VKD3D_MAKE_TAG('P', 'C', 'S', 'G')
+#define TAG_PSG1 VKD3D_MAKE_TAG('P', 'S', 'G', '1')
+#define TAG_RD11 VKD3D_MAKE_TAG('R', 'D', '1', '1')
+#define TAG_RDEF VKD3D_MAKE_TAG('R', 'D', 'E', 'F')
+#define TAG_RTS0 VKD3D_MAKE_TAG('R', 'T', 'S', '0')
+#define TAG_SDBG VKD3D_MAKE_TAG('S', 'D', 'B', 'G')
+#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R')
+#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
+#define TAG_STAT VKD3D_MAKE_TAG('S', 'T', 'A', 'T')
+#define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T')
+#define TAG_XNAP VKD3D_MAKE_TAG('X', 'N', 'A', 'P')
+#define TAG_XNAS VKD3D_MAKE_TAG('X', 'N', 'A', 'S')
+
static inline size_t align(size_t addr, size_t alignment)
{
return (addr + (alignment - 1)) & ~(alignment - 1);
diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler.h b/libs/vkd3d/include/vkd3d_d3dcompiler.h
index c934835dc0a..78d52948310 100644
--- a/libs/vkd3d/include/vkd3d_d3dcompiler.h
+++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h
@@ -58,6 +58,37 @@
#define D3DCOMPILE_SECDATA_PRESERVE_TEMPLATE_SLOTS 0x00000002
#define D3DCOMPILE_SECDATA_REQUIRE_TEMPLATE_MATCH 0x00000004
+typedef enum D3D_BLOB_PART
+{
+ D3D_BLOB_INPUT_SIGNATURE_BLOB,
+ D3D_BLOB_OUTPUT_SIGNATURE_BLOB,
+ D3D_BLOB_INPUT_AND_OUTPUT_SIGNATURE_BLOB,
+ D3D_BLOB_PATCH_CONSTANT_SIGNATURE_BLOB,
+ D3D_BLOB_ALL_SIGNATURE_BLOB,
+ D3D_BLOB_DEBUG_INFO,
+ D3D_BLOB_LEGACY_SHADER,
+ D3D_BLOB_XNA_PREPASS_SHADER,
+ D3D_BLOB_XNA_SHADER,
+ D3D_BLOB_PDB,
+ D3D_BLOB_PRIVATE_DATA,
+ D3D_BLOB_ROOT_SIGNATURE,
+ D3D_BLOB_DEBUG_NAME,
+ D3D_BLOB_TEST_ALTERNATE_SHADER = 0x8000,
+ D3D_BLOB_TEST_COMPILE_DETAILS,
+ D3D_BLOB_TEST_COMPILE_PERF,
+ D3D_BLOB_TEST_COMPILE_REPORT
+} D3D_BLOB_PART;
+
+typedef enum D3DCOMPILER_STRIP_FLAGS
+{
+ D3DCOMPILER_STRIP_REFLECTION_DATA = 0x00000001,
+ D3DCOMPILER_STRIP_DEBUG_INFO = 0x00000002,
+ D3DCOMPILER_STRIP_TEST_BLOBS = 0x00000004,
+ D3DCOMPILER_STRIP_PRIVATE_DATA = 0x00000008,
+ D3DCOMPILER_STRIP_ROOT_SIGNATURE = 0x00000010,
+ D3DCOMPILER_STRIP_FORCE_DWORD = 0x7fffffff,
+} D3DCOMPILER_STRIP_FLAGS;
+
HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename,
const D3D_SHADER_MACRO *macros, ID3DInclude *include, const char *entrypoint,
const char *profile, UINT flags, UINT effect_flags, ID3DBlob **shader, ID3DBlob **error_messages);
@@ -67,8 +98,14 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen
const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader,
ID3DBlob **error_messages);
HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob);
+HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
+HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob);
+HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
+HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
+HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename, const D3D_SHADER_MACRO *macros,
ID3DInclude *include, ID3DBlob **shader, ID3DBlob **error_messages);
+HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
#endif /* __D3DCOMPILER_H__ */
#endif /* __VKD3D_D3DCOMPILER_H */
diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h
index 9d0d768b43d..94f79c7c7c2 100644
--- a/libs/vkd3d/include/vkd3d_shader.h
+++ b/libs/vkd3d/include/vkd3d_shader.h
@@ -154,6 +154,25 @@ enum vkd3d_shader_compile_option_pack_matrix_order
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER),
};
+/** Individual options to enable various backward compatibility features. \since 1.10 */
+enum vkd3d_shader_compile_option_backward_compatibility
+{
+ /**
+ * Causes compiler to convert SM1-3 semantics to corresponding System Value semantics,
+ * when compiling HLSL sources for SM4+ targets.
+ *
+ * This option does the following conversions:
+ *
+ * - POSITION to SV_Position for vertex shader outputs, pixel shader inputs,
+ * and geometry shader inputs and outputs;
+ * - COLORN to SV_TargetN for pixel shader outputs;
+ * - DEPTH to SV_Depth for pixel shader outputs.
+ */
+ VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES = 0x00000001,
+
+ VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY),
+};
+
enum vkd3d_shader_compile_option_name
{
/**
@@ -193,6 +212,14 @@ enum vkd3d_shader_compile_option_name
* \since 1.9
*/
VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ORDER = 0x00000007,
+ /**
+ * This option is used to enable various backward compatibility features.
+ *
+ * \a value is a mask of values from enum vkd3d_shader_compile_option_backward_compatibility.
+ *
+ * \since 1.10
+ */
+ VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY = 0x00000008,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME),
};
@@ -1387,7 +1414,10 @@ struct vkd3d_shader_descriptor_info
* as follows:
*
* - Each constant register set used by the shader is scanned as a single
- * constant buffer descriptor, as follows:
+ * constant buffer descriptor.
+ * There may therefore be up to three such descriptors, one for each register
+ * set used by the shader: float, integer, and boolean.
+ * The fields are set 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.
@@ -1407,9 +1437,6 @@ struct vkd3d_shader_descriptor_info
* * The \ref vkd3d_shader_descriptor_info.register_index field is set to the
* binding index of the original sampler, for both descriptors.
* * 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/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h
index e8462563576..b5ec7981356 100644
--- a/libs/vkd3d/include/vkd3d_utils.h
+++ b/libs/vkd3d/include/vkd3d_utils.h
@@ -51,6 +51,9 @@ extern "C" {
# define VKD3D_UTILS_API VKD3D_IMPORT
#endif
+/** \since 1.10 */
+typedef enum D3D_BLOB_PART D3D_BLOB_PART;
+
/* 1.0 */
VKD3D_UTILS_API HANDLE vkd3d_create_event(void);
VKD3D_UTILS_API HRESULT vkd3d_signal_event(HANDLE event);
@@ -101,6 +104,20 @@ VKD3D_UTILS_API HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, cons
*/
VKD3D_UTILS_API void vkd3d_utils_set_log_callback(PFN_vkd3d_log callback);
+/** \since 1.10 */
+VKD3D_UTILS_API HRESULT WINAPI D3DGetBlobPart(const void *data,
+ SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob);
+/** \since 1.10 */
+VKD3D_UTILS_API HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob);
+/** \since 1.10 */
+VKD3D_UTILS_API HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
+/** \since 1.10 */
+VKD3D_UTILS_API HRESULT WINAPI D3DGetInputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
+/** \since 1.10 */
+VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob);
+/** \since 1.10 */
+VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
index 38a607351fe..40daa5354d8 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c
@@ -391,13 +391,14 @@ static unsigned int shader_get_float_offset(enum vkd3d_shader_register_type regi
}
}
-static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t global_flags)
+static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler,
+ enum vkd3d_shader_global_flags global_flags)
{
unsigned int i;
static const struct
{
- unsigned int flag;
+ enum vkd3d_shader_global_flags flag;
const char *name;
}
global_flag_info[] =
@@ -423,7 +424,7 @@ static void shader_dump_global_flags(struct vkd3d_d3d_asm_compiler *compiler, ui
}
if (global_flags)
- vkd3d_string_buffer_printf(&compiler->buffer, "unknown_flags(%#x)", global_flags);
+ vkd3d_string_buffer_printf(&compiler->buffer, "unknown_flags(%#"PRIx64")", global_flags);
}
static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint32_t sync_flags)
@@ -477,6 +478,11 @@ static void shader_dump_uav_flags(struct vkd3d_d3d_asm_compiler *compiler, uint3
vkd3d_string_buffer_printf(&compiler->buffer, "_opc");
uav_flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER;
}
+ if (uav_flags & VKD3DSUF_RASTERISER_ORDERED_VIEW)
+ {
+ vkd3d_string_buffer_printf(&compiler->buffer, "_rov");
+ uav_flags &= ~VKD3DSUF_RASTERISER_ORDERED_VIEW;
+ }
if (uav_flags)
vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", uav_flags);
@@ -1620,8 +1626,10 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_CONSTANT_BUFFER:
vkd3d_string_buffer_printf(buffer, " ");
shader_dump_register(compiler, &ins->declaration.cb.src.reg, true);
- if (shader_ver_ge(&compiler->shader_version, 5, 1))
+ if (shader_ver_ge(&compiler->shader_version, 6, 0))
shader_print_subscript(compiler, ins->declaration.cb.size, NULL);
+ else if (shader_ver_ge(&compiler->shader_version, 5, 1))
+ shader_print_subscript(compiler, ins->declaration.cb.size / VKD3D_VEC4_SIZE / sizeof(float), NULL);
shader_addline(buffer, ", %s",
ins->flags & VKD3DSI_INDEXED_DYNAMIC ? "dynamicIndexed" : "immediateIndexed");
shader_dump_register_space(compiler, ins->declaration.cb.range.space);
@@ -1637,7 +1645,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_GLOBAL_FLAGS:
vkd3d_string_buffer_printf(buffer, " ");
- shader_dump_global_flags(compiler, ins->flags);
+ shader_dump_global_flags(compiler, ins->declaration.global_flags);
break;
case VKD3DSIH_DCL_HS_MAX_TESSFACTOR:
@@ -1646,7 +1654,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER:
vkd3d_string_buffer_printf(buffer, " {\n");
- for (i = 0; i < ins->declaration.icb->vec4_count; ++i)
+ assert(ins->declaration.icb->component_count == VKD3D_VEC4_SIZE);
+ for (i = 0; i < ins->declaration.icb->element_count; ++i)
{
shader_print_hex_literal(compiler, " {", ins->declaration.icb->data[4 * i + 0], "");
shader_print_hex_literal(compiler, ", ", ins->declaration.icb->data[4 * i + 1], "");
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
index 598b7518394..67fa32710fd 100644
--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c
@@ -2221,7 +2221,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b
struct sm1_instruction instr =
{
- .opcode = VKD3D_SM1_OP_TEXKILL,
+ .opcode = D3DSIO_TEXKILL,
.dst.type = D3DSPR_TEMP,
.dst.reg = reg->id,
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
index dbbf8a5c458..a9a7aefe8aa 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c
@@ -435,6 +435,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s
else
e[i].min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE;
+ e[i].interpolation_mode = VKD3DSIM_NONE;
+
TRACE("Stream: %u, semantic: %s, semantic idx: %u, sysval_semantic %#x, "
"type %u, register idx: %u, use_mask %#x, input_mask %#x, precision %u.\n",
e[i].stream_index, debugstr_a(e[i].semantic_name), e[i].semantic_index, e[i].sysval_semantic,
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c
index bb50ad62b68..19ce2936acb 100644
--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c
+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c
@@ -20,9 +20,14 @@
#define VKD3D_SM6_VERSION_MAJOR(version) (((version) >> 4) & 0xf)
#define VKD3D_SM6_VERSION_MINOR(version) (((version) >> 0) & 0xf)
+/* Two seems to be the maximum but leave some extra room. */
+#define VKD3D_SM6_MAX_METADATA_TABLES 4
#define BITCODE_MAGIC VKD3D_MAKE_TAG('B', 'C', 0xc0, 0xde)
#define DXIL_OP_MAX_OPERANDS 17
+static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4;
+
+static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64};
enum bitcode_block_id
{
@@ -114,6 +119,19 @@ enum bitcode_function_code
FUNC_CODE_INST_CMPXCHG = 46,
};
+enum bitcode_metadata_code
+{
+ METADATA_STRING = 1,
+ METADATA_VALUE = 2,
+ METADATA_NODE = 3,
+ METADATA_NAME = 4,
+ METADATA_DISTINCT_NODE = 5,
+ METADATA_KIND = 6,
+ METADATA_LOCATION = 7,
+ METADATA_NAMED_NODE = 10,
+ METADATA_ATTACHMENT = 11,
+};
+
enum bitcode_type_code
{
TYPE_CODE_NUMENTRY = 1,
@@ -139,6 +157,91 @@ enum bitcode_value_symtab_code
VST_CODE_BBENTRY = 2,
};
+enum dxil_component_type
+{
+ COMPONENT_TYPE_INVALID = 0,
+ COMPONENT_TYPE_I1 = 1,
+ COMPONENT_TYPE_I16 = 2,
+ COMPONENT_TYPE_U16 = 3,
+ COMPONENT_TYPE_I32 = 4,
+ COMPONENT_TYPE_U32 = 5,
+ COMPONENT_TYPE_I64 = 6,
+ COMPONENT_TYPE_U64 = 7,
+ COMPONENT_TYPE_F16 = 8,
+ COMPONENT_TYPE_F32 = 9,
+ COMPONENT_TYPE_F64 = 10,
+ COMPONENT_TYPE_SNORMF16 = 11,
+ COMPONENT_TYPE_UNORMF16 = 12,
+ COMPONENT_TYPE_SNORMF32 = 13,
+ COMPONENT_TYPE_UNORMF32 = 14,
+ COMPONENT_TYPE_SNORMF64 = 15,
+ COMPONENT_TYPE_UNORMF64 = 16,
+ COMPONENT_TYPE_PACKEDS8X32 = 17,
+ COMPONENT_TYPE_PACKEDU8X32 = 18,
+};
+
+enum dxil_semantic_kind
+{
+ SEMANTIC_KIND_ARBITRARY = 0,
+ SEMANTIC_KIND_VERTEXID = 1,
+ SEMANTIC_KIND_INSTANCEID = 2,
+ SEMANTIC_KIND_POSITION = 3,
+ SEMANTIC_KIND_RTARRAYINDEX = 4,
+ SEMANTIC_KIND_VIEWPORTARRAYINDEX = 5,
+ SEMANTIC_KIND_CLIPDISTANCE = 6,
+ SEMANTIC_KIND_CULLDISTANCE = 7,
+ SEMANTIC_KIND_OUTPUTCONTROLPOINTID = 8,
+ SEMANTIC_KIND_DOMAINLOCATION = 9,
+ SEMANTIC_KIND_PRIMITIVEID = 10,
+ SEMANTIC_KIND_GSINSTANCEID = 11,
+ SEMANTIC_KIND_SAMPLEINDEX = 12,
+ SEMANTIC_KIND_ISFRONTFACE = 13,
+ SEMANTIC_KIND_COVERAGE = 14,
+ SEMANTIC_KIND_INNERCOVERAGE = 15,
+ SEMANTIC_KIND_TARGET = 16,
+ SEMANTIC_KIND_DEPTH = 17,
+ SEMANTIC_KIND_DEPTHLESSEQUAL = 18,
+ SEMANTIC_KIND_DEPTHGREATEREQUAL = 19,
+ SEMANTIC_KIND_STENCILREF = 20,
+ SEMANTIC_KIND_DISPATCHTHREADID = 21,
+ SEMANTIC_KIND_GROUPID = 22,
+ SEMANTIC_KIND_GROUPINDEX = 23,
+ SEMANTIC_KIND_GROUPTHREADID = 24,
+ SEMANTIC_KIND_TESSFACTOR = 25,
+ SEMANTIC_KIND_INSIDETESSFACTOR = 26,
+ SEMANTIC_KIND_VIEWID = 27,
+ SEMANTIC_KIND_BARYCENTRICS = 28,
+ SEMANTIC_KIND_SHADINGRATE = 29,
+ SEMANTIC_KIND_CULLPRIMITIVE = 30,
+ SEMANTIC_KIND_COUNT = 31,
+ SEMANTIC_KIND_INVALID = SEMANTIC_KIND_COUNT,
+};
+
+enum dxil_element_additional_tag
+{
+ ADDITIONAL_TAG_STREAM_INDEX = 0,
+ ADDITIONAL_TAG_GLOBAL_SYMBOL = 1, /* not used */
+ ADDITIONAL_TAG_RELADDR_MASK = 2,
+ ADDITIONAL_TAG_USED_MASK = 3,
+};
+
+enum dxil_shader_properties_tag
+{
+ SHADER_PROPERTIES_FLAGS = 0,
+ SHADER_PROPERTIES_GEOMETRY = 1,
+ SHADER_PROPERTIES_DOMAIN = 2,
+ SHADER_PROPERTIES_HULL = 3,
+ SHADER_PROPERTIES_COMPUTE = 4,
+ SHADER_PROPERTIES_AUTO_BINDING_SPACE = 5,
+ SHADER_PROPERTIES_RAY_PAYLOAD_SIZE = 6,
+ SHADER_PROPERTIES_RAY_ATTRIB_SIZE = 7,
+ SHADER_PROPERTIES_SHADER_KIND = 8,
+ SHADER_PROPERTIES_MESH = 9,
+ SHADER_PROPERTIES_AMPLIFICATION = 10,
+ SHADER_PROPERTIES_WAVE_SIZE = 11,
+ SHADER_PROPERTIES_ENTRY_ROOT_SIG = 12,
+};
+
enum dx_intrinsic_opcode
{
DX_LOAD_INPUT = 4,
@@ -278,6 +381,52 @@ struct dxil_block
size_t record_count;
};
+enum sm6_metadata_type
+{
+ VKD3D_METADATA_KIND,
+ VKD3D_METADATA_NODE,
+ VKD3D_METADATA_STRING,
+ VKD3D_METADATA_VALUE,
+};
+
+struct sm6_metadata_node
+{
+ bool is_distinct;
+ unsigned int operand_count;
+ struct sm6_metadata_value *operands[];
+};
+
+struct sm6_metadata_kind
+{
+ uint64_t id;
+ char *name;
+};
+
+struct sm6_metadata_value
+{
+ enum sm6_metadata_type type;
+ const struct sm6_type *value_type;
+ union
+ {
+ char *string_value;
+ const struct sm6_value *value;
+ struct sm6_metadata_node *node;
+ struct sm6_metadata_kind kind;
+ } u;
+};
+
+struct sm6_metadata_table
+{
+ struct sm6_metadata_value *values;
+ unsigned int count;
+};
+
+struct sm6_named_metadata
+{
+ char *name;
+ struct sm6_metadata_value value;
+};
+
struct sm6_parser
{
const uint32_t *ptr, *start, *end;
@@ -292,16 +441,23 @@ struct sm6_parser
struct sm6_type *types;
size_t type_count;
+ struct sm6_type *metadata_type;
struct sm6_symbol *global_symbols;
size_t global_symbol_count;
+ const char *entry_point;
+
struct vkd3d_shader_dst_param *output_params;
struct vkd3d_shader_dst_param *input_params;
struct sm6_function *functions;
size_t function_count;
+ struct sm6_metadata_table metadata_tables[VKD3D_SM6_MAX_METADATA_TABLES];
+ struct sm6_named_metadata *named_metadata;
+ unsigned int named_metadata_count;
+
struct sm6_value *values;
size_t value_count;
size_t value_capacity;
@@ -973,14 +1129,18 @@ static const struct dxil_block *sm6_parser_get_level_one_block(const struct sm6_
return found;
}
-static char *dxil_record_to_string(const struct dxil_record *record, unsigned int offset)
+static char *dxil_record_to_string(const struct dxil_record *record, unsigned int offset, struct sm6_parser *sm6)
{
unsigned int i;
char *str;
assert(offset <= record->operand_count);
if (!(str = vkd3d_calloc(record->operand_count - offset + 1, 1)))
+ {
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
+ "Out of memory allocating a string of length %u.", record->operand_count - offset);
return NULL;
+ }
for (i = offset; i < record->operand_count; ++i)
str[i - offset] = record->operands[i];
@@ -1169,6 +1329,7 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6)
case TYPE_CODE_METADATA:
type->class = TYPE_CLASS_METADATA;
+ sm6->metadata_type = type;
break;
case TYPE_CODE_NUMENTRY:
@@ -1235,7 +1396,7 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6)
break;
case TYPE_CODE_STRUCT_NAME:
- if (!(struct_name = dxil_record_to_string(record, 0)))
+ if (!(struct_name = dxil_record_to_string(record, 0, sm6)))
{
ERR("Failed to allocate struct name.\n");
return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -1324,6 +1485,11 @@ static bool sm6_type_is_numeric_aggregate(const struct sm6_type *type)
}
}
+static bool sm6_type_is_array(const struct sm6_type *type)
+{
+ return type->class == TYPE_CLASS_ARRAY;
+}
+
static inline bool sm6_type_is_struct(const struct sm6_type *type)
{
return type->class == TYPE_CLASS_STRUCT;
@@ -1454,7 +1620,7 @@ static enum vkd3d_result sm6_parser_symtab_init(struct sm6_parser *sm6)
symbol = &sm6->global_symbols[sm6->global_symbol_count];
symbol->id = record->operands[0];
- if (!(symbol->name = dxil_record_to_string(record, 1)))
+ if (!(symbol->name = dxil_record_to_string(record, 1, sm6)))
{
ERR("Failed to allocate symbol name.\n");
return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -1511,6 +1677,17 @@ static unsigned int register_get_uint_value(const struct vkd3d_shader_register *
return reg->u.immconst_uint[0];
}
+static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg)
+{
+ if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type))
+ return UINT64_MAX;
+
+ if (reg->dimension == VSIR_DIMENSION_VEC4)
+ WARN("Returning vec4.x.\n");
+
+ return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_uint64[0] : reg->u.immconst_uint[0];
+}
+
static inline bool sm6_value_is_function_dcl(const struct sm6_value *value)
{
return value->value_type == VALUE_TYPE_FUNCTION;
@@ -1543,6 +1720,11 @@ static inline bool sm6_value_is_undef(const struct sm6_value *value)
return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF;
}
+static bool sm6_value_is_icb(const struct sm6_value *value)
+{
+ return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_IMMCONSTBUFFER;
+}
+
static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value)
{
if (!sm6_value_is_constant(value))
@@ -1604,6 +1786,8 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type
return VKD3D_DATA_UINT8;
case 32:
return VKD3D_DATA_UINT;
+ case 64:
+ return VKD3D_DATA_UINT64;
default:
FIXME("Unhandled width %u.\n", type->u.width);
return VKD3D_DATA_UINT;
@@ -1773,6 +1957,17 @@ static size_t sm6_parser_get_value_index(struct sm6_parser *sm6, uint64_t idx)
return i;
}
+static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsigned int idx)
+{
+ if (idx < sm6->value_count)
+ return &sm6->values[idx];
+
+ WARN("Invalid value index %u.\n", idx);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Invalid value index %u.", idx);
+ return NULL;
+}
+
static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const struct dxil_record *record,
const struct sm6_type *fwd_type, unsigned int *rec_idx)
{
@@ -1916,12 +2111,80 @@ static inline double bitcast_uint64_to_double(uint64_t value)
return u.double_value;
}
+static enum vkd3d_result register_allocate_constant_array(struct vkd3d_shader_register *reg, const struct sm6_type *type,
+ const uint64_t *operands, struct sm6_parser *sm6)
+{
+ struct vkd3d_shader_immediate_constant_buffer *icb;
+ const struct sm6_type *elem_type;
+ unsigned int i, size, count;
+
+ elem_type = type->u.array.elem_type;
+ /* Multidimensional arrays are emitted in flattened form. */
+ if (elem_type->class != TYPE_CLASS_INTEGER && elem_type->class != TYPE_CLASS_FLOAT)
+ {
+ FIXME("Unhandled element type %u for data array.\n", elem_type->class);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "The element data type for an immediate constant buffer is not scalar integer or floating point.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ /* Arrays of bool are not used in DXIL. dxc will emit an array of int32 instead if necessary. */
+ if (!(size = elem_type->u.width / CHAR_BIT))
+ {
+ WARN("Invalid data type width %u.\n", elem_type->u.width);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "An immediate constant buffer is declared with boolean elements.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ size = max(size, sizeof(icb->data[0]));
+ count = type->u.array.count * size / sizeof(icb->data[0]);
+
+ if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count]))))
+ {
+ ERR("Failed to allocate buffer, count %u.\n", count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
+ "Out of memory allocating an immediate constant buffer of count %u.", count);
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ if ((reg->idx[0].offset = shader_instruction_array_add_icb(&sm6->p.instructions, icb)) == UINT_MAX)
+ {
+ ERR("Failed to store icb object.\n");
+ vkd3d_free(icb);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
+ "Out of memory storing an immediate constant buffer object.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+
+ reg->type = VKD3DSPR_IMMCONSTBUFFER;
+ reg->idx_count = 1;
+
+ icb->data_type = vkd3d_data_type_from_sm6_type(elem_type);
+ icb->element_count = type->u.array.count;
+ icb->component_count = 1;
+
+ count = type->u.array.count;
+ if (size > sizeof(icb->data[0]))
+ {
+ uint64_t *data = (uint64_t *)icb->data;
+ for (i = 0; i < count; ++i)
+ data[i] = operands[i];
+ }
+ else
+ {
+ for (i = 0; i < count; ++i)
+ icb->data[i] = operands[i];
+ }
+
+ return VKD3D_OK;
+}
+
static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block)
{
enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID;
const struct sm6_type *type, *elem_type;
enum vkd3d_data_type reg_data_type;
const struct dxil_record *record;
+ enum vkd3d_result ret;
struct sm6_value *dst;
size_t i, value_idx;
uint64_t value;
@@ -1974,7 +2237,14 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
switch (record->code)
{
case CST_CODE_NULL:
- /* Register constant data is already zero-filled. */
+ if (sm6_type_is_array(type))
+ {
+ FIXME("Constant null arrays are not supported.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "Constant null arrays are not supported.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ /* For non-aggregates, register constant data is already zero-filled. */
break;
case CST_CODE_INTEGER:
@@ -2017,7 +2287,19 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
break;
case CST_CODE_DATA:
- WARN("Unhandled constant array.\n");
+ if (!sm6_type_is_array(type))
+ {
+ WARN("Invalid type %u for data constant idx %zu.\n", type->class, value_idx);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND,
+ "The type of a constant array is not an array type.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ if (!dxil_record_validate_operand_count(record, type->u.array.count, type->u.array.count, sm6))
+ return VKD3D_ERROR_INVALID_SHADER;
+
+ if ((ret = register_allocate_constant_array(&dst->u.reg, type, record->operands, sm6)) < 0)
+ return ret;
+
break;
case CST_CODE_UNDEF:
@@ -2064,6 +2346,7 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
{
const struct dxil_block *block = &sm6->root_block;
const struct dxil_record *record;
+ enum vkd3d_result ret;
uint64_t version;
size_t i;
@@ -2106,6 +2389,13 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6)
}
}
+ for (i = 0; i < block->child_block_count; ++i)
+ {
+ if (block->child_blocks[i]->id == CONSTANTS_BLOCK
+ && (ret = sm6_parser_constants_init(sm6, block->child_blocks[i])) < 0)
+ return ret;
+ }
+
return VKD3D_OK;
}
@@ -2127,7 +2417,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
{
struct vkd3d_shader_dst_param *param;
const struct signature_element *e;
- unsigned int i;
+ unsigned int i, count;
for (i = 0; i < s->element_count; ++i)
{
@@ -2135,8 +2425,11 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
param = &params[i];
dst_param_io_init(param, e, reg_type);
- param->reg.idx[0].offset = i;
- param->reg.idx_count = 1;
+ count = 0;
+ if (e->register_count > 1)
+ param->reg.idx[count++].offset = 0;
+ param->reg.idx[count++].offset = i;
+ param->reg.idx_count = count;
}
}
@@ -2168,9 +2461,14 @@ static void sm6_parser_emit_signature(struct sm6_parser *sm6, const struct shade
param = &ins->declaration.dst;
}
- /* TODO: set the interpolation mode when signatures are loaded from DXIL metadata. */
- ins->flags = (handler_idx == VKD3DSIH_DCL_INPUT_PS) ? VKD3DSIM_LINEAR_NOPERSPECTIVE : 0;
+ ins->flags = e->interpolation_mode;
*param = params[i];
+
+ if (e->register_count > 1)
+ {
+ param->reg.idx[0].rel_addr = NULL;
+ param->reg.idx[0].offset = e->register_count;
+ }
}
}
@@ -2518,6 +2816,59 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record
ins->handler_idx = VKD3DSIH_NOP;
}
+static bool sm6_metadata_value_is_node(const struct sm6_metadata_value *m)
+{
+ return m && m->type == VKD3D_METADATA_NODE;
+}
+
+static bool sm6_metadata_value_is_value(const struct sm6_metadata_value *m)
+{
+ return m && m->type == VKD3D_METADATA_VALUE;
+}
+
+static bool sm6_metadata_value_is_string(const struct sm6_metadata_value *m)
+{
+ return m && m->type == VKD3D_METADATA_STRING;
+}
+
+static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6,
+ const struct sm6_metadata_value *m, unsigned int *u)
+{
+ const struct sm6_value *value;
+
+ if (!m || m->type != VKD3D_METADATA_VALUE)
+ return false;
+
+ value = m->u.value;
+ if (!sm6_value_is_constant(value))
+ return false;
+ if (!sm6_type_is_integer(value->type))
+ return false;
+
+ *u = register_get_uint_value(&value->u.reg);
+
+ return true;
+}
+
+static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6,
+ const struct sm6_metadata_value *m, uint64_t *u)
+{
+ const struct sm6_value *value;
+
+ if (!m || m->type != VKD3D_METADATA_VALUE)
+ return false;
+
+ value = m->u.value;
+ if (!sm6_value_is_constant(value))
+ return false;
+ if (!sm6_type_is_integer(value->type))
+ return false;
+
+ *u = register_get_uint64_value(&value->u.reg);
+
+ return true;
+}
+
static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block,
struct sm6_function *function)
{
@@ -2678,6 +3029,9 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st
switch (block->id)
{
case CONSTANTS_BLOCK:
+ /* Level 1 (global) constants are already done in sm6_parser_globals_init(). */
+ if (level < 2)
+ break;
function = &sm6->functions[sm6->function_count];
sm6->cur_max_value = function->value_count;
return sm6_parser_constants_init(sm6, block);
@@ -2711,105 +3065,1119 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st
return VKD3D_OK;
}
-static void sm6_type_table_cleanup(struct sm6_type *types, size_t count)
+static bool sm6_parser_allocate_named_metadata(struct sm6_parser *sm6)
{
- size_t i;
-
- if (!types)
- return;
+ struct dxil_block *block;
+ unsigned int i, j, count;
- for (i = 0; i < count; ++i)
+ for (i = 0, count = 0; i < sm6->root_block.child_block_count; ++i)
{
- switch (types[i].class)
- {
- case TYPE_CLASS_STRUCT:
- vkd3d_free((void *)types[i].u.struc->name);
- vkd3d_free(types[i].u.struc);
- break;
- case TYPE_CLASS_FUNCTION:
- vkd3d_free(types[i].u.function);
- break;
- default:
- break;
- }
+ block = sm6->root_block.child_blocks[i];
+ if (block->id != METADATA_BLOCK)
+ continue;
+ for (j = 0; j < block->record_count; ++j)
+ count += block->records[j]->code == METADATA_NAMED_NODE;
}
- vkd3d_free(types);
+ if (!count)
+ return true;
+
+ return !!(sm6->named_metadata = vkd3d_calloc(count, sizeof(*sm6->named_metadata)));
}
-static void sm6_symtab_cleanup(struct sm6_symbol *symbols, size_t count)
+static enum vkd3d_result metadata_value_create_node(struct sm6_metadata_value *m, struct sm6_metadata_table *table,
+ unsigned int dst_idx, unsigned int end_count, const struct dxil_record *record, struct sm6_parser *sm6)
{
- size_t i;
+ struct sm6_metadata_node *node;
+ unsigned int i, offset;
- for (i = 0; i < count; ++i)
- vkd3d_free((void *)symbols[i].name);
- vkd3d_free(symbols);
-}
+ m->type = VKD3D_METADATA_NODE;
+ if (!(m->value_type = sm6->metadata_type))
+ {
+ WARN("Metadata type not found.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "The type for metadata values was not found.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ if (!(node = vkd3d_malloc(offsetof(struct sm6_metadata_node, operands[record->operand_count]))))
+ {
+ ERR("Failed to allocate metadata node with %u operands.\n", record->operand_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
+ "Out of memory allocating a metadata node with %u operands.", record->operand_count);
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ m->u.node = node;
-static void sm6_block_destroy(struct sm6_block *block)
-{
- vkd3d_free(block->instructions);
- vkd3d_free(block);
-}
+ node->is_distinct = record->code == METADATA_DISTINCT_NODE;
-static void sm6_functions_cleanup(struct sm6_function *functions, size_t count)
-{
- size_t i, j;
+ offset = record->code != METADATA_NAMED_NODE;
- for (i = 0; i < count; ++i)
+ for (i = 0; i < record->operand_count; ++i)
{
- for (j = 0; j < functions[i].block_count; ++j)
- sm6_block_destroy(functions[i].blocks[j]);
+ uint64_t ref;
+
+ ref = record->operands[i] - offset;
+ if (record->operands[i] >= offset && ref >= end_count)
+ {
+ WARN("Invalid metadata index %"PRIu64".\n", ref);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "Metadata index %"PRIu64" is invalid.", ref);
+ vkd3d_free(node);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (!node->is_distinct && ref == dst_idx)
+ {
+ WARN("Metadata self-reference at index %u.\n", dst_idx);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "Metadata index %u is self-referencing.", dst_idx);
+ vkd3d_free(node);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ node->operands[i] = (record->operands[i] >= offset) ? &table->values[ref] : NULL;
+ if (record->code == METADATA_NAMED_NODE && !sm6_metadata_value_is_node(node->operands[i]))
+ {
+ WARN("Named node operand is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "The operand of a metadata named node is not a node.");
+ vkd3d_free(node);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
}
- vkd3d_free(functions);
-}
-static void sm6_parser_destroy(struct vkd3d_shader_parser *parser)
-{
- struct sm6_parser *sm6 = sm6_parser(parser);
+ node->operand_count = record->operand_count;
- dxil_block_destroy(&sm6->root_block);
- dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
- shader_instruction_array_destroy(&parser->instructions);
- sm6_type_table_cleanup(sm6->types, sm6->type_count);
- sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
- sm6_functions_cleanup(sm6->functions, sm6->function_count);
- vkd3d_free(sm6->values);
- free_shader_desc(&parser->shader_desc);
- vkd3d_free(sm6);
+ return VKD3D_OK;
}
-static const struct vkd3d_shader_parser_ops sm6_parser_ops =
-{
- .parser_destroy = sm6_parser_destroy,
-};
-
-static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t *byte_code, size_t byte_code_size,
- const char *source_name, struct vkd3d_shader_message_context *message_context)
+static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const struct dxil_block *block,
+ struct sm6_metadata_table *table)
{
- const struct shader_signature *output_signature = &sm6->p.shader_desc.output_signature;
- const struct shader_signature *input_signature = &sm6->p.shader_desc.input_signature;
- const struct vkd3d_shader_location location = {.source_name = source_name};
- uint32_t version_token, dxil_version, token_count, magic;
- unsigned int chunk_offset, chunk_size;
- size_t count, length, function_count;
- enum bitcode_block_abbreviation abbr;
- struct vkd3d_shader_version version;
- struct dxil_block *block;
+ unsigned int i, count, table_idx, value_idx;
+ struct sm6_metadata_value *values, *m;
+ const struct dxil_record *record;
+ const struct sm6_value *value;
enum vkd3d_result ret;
- unsigned int i;
+ char *name;
- count = byte_code_size / sizeof(*byte_code);
- if (count < 6)
+ for (i = 0, count = 0; i < block->record_count; ++i)
+ count += block->records[i]->code != METADATA_NAME;
+
+ if (!(values = vkd3d_calloc(count, sizeof(*values))))
{
- WARN("Invalid data size %zu.\n", byte_code_size);
- vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_SIZE,
- "DXIL chunk size %zu is smaller than the DXIL header size.", byte_code_size);
- return VKD3D_ERROR_INVALID_SHADER;
+ ERR("Failed to allocate metadata tables.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
+ "Out of memory allocating metadata tables.");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
}
+ table->values = values;
- version_token = byte_code[0];
- TRACE("Compiler version: 0x%08x.\n", version_token);
+ for (i = 0, name = NULL; i < block->record_count; ++i)
+ {
+ record = block->records[i];
+
+ table_idx = table->count;
+ m = &values[table_idx];
+
+ switch (record->code)
+ {
+ case METADATA_NAMED_NODE:
+ if (!name)
+ {
+ WARN("Named node has no name.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "A metadata named node has no name.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ /* When DXC emits metadata value array reference indices it assumes named nodes
+ * are not included in the array. Store named nodes separately. */
+ m = &sm6->named_metadata[sm6->named_metadata_count].value;
+ sm6->named_metadata[sm6->named_metadata_count].name = name;
+ name = NULL;
+
+ if ((ret = metadata_value_create_node(m, table, UINT_MAX, count, record, sm6)) < 0)
+ return ret;
+ ++sm6->named_metadata_count;
+ /* Skip incrementing the table count. */
+ continue;
+
+ case METADATA_DISTINCT_NODE:
+ case METADATA_NODE:
+ if ((ret = metadata_value_create_node(m, table, table_idx, count, record, sm6)) < 0)
+ return ret;
+ break;
+
+ case METADATA_KIND:
+ if (!dxil_record_validate_operand_min_count(record, 2, sm6))
+ return VKD3D_ERROR_INVALID_SHADER;
+
+ m->type = VKD3D_METADATA_KIND;
+ m->u.kind.id = record->operands[0];
+ if (!(m->u.kind.name = dxil_record_to_string(record, 1, sm6)))
+ {
+ ERR("Failed to allocate name of a kind.\n");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ break;
+
+ case METADATA_NAME:
+ /* Check the next record to avoid freeing 'name' in all exit paths. */
+ if (i + 1 == block->record_count || block->records[i + 1]->code != METADATA_NAMED_NODE)
+ {
+ WARN("Name is not followed by a named node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "A metadata node name is not followed by a named node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ /* LLVM allows an empty string here. */
+ if (!(name = dxil_record_to_string(record, 0, sm6)))
+ {
+ ERR("Failed to allocate name.\n");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ continue;
+
+ case METADATA_STRING:
+ /* LLVM allows an empty string here. */
+ m->type = VKD3D_METADATA_STRING;
+ if (!(m->u.string_value = dxil_record_to_string(record, 0, sm6)))
+ {
+ ERR("Failed to allocate string.\n");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ break;
+
+ case METADATA_VALUE:
+ if (!dxil_record_validate_operand_count(record, 2, 2, sm6))
+ return VKD3D_ERROR_INVALID_SHADER;
+
+ m->type = VKD3D_METADATA_VALUE;
+ if (!(m->value_type = sm6_parser_get_type(sm6, record->operands[0])))
+ return VKD3D_ERROR_INVALID_SHADER;
+
+ if (record->operands[1] > UINT_MAX)
+ WARN("Truncating value index %"PRIu64".\n", record->operands[1]);
+ value_idx = record->operands[1];
+ if (!(value = sm6_parser_get_value_safe(sm6, value_idx)))
+ return VKD3D_ERROR_INVALID_SHADER;
+
+ if (!sm6_value_is_constant(value) && !sm6_value_is_undef(value) && !sm6_value_is_icb(value)
+ && !sm6_value_is_function_dcl(value))
+ {
+ WARN("Value at index %u is not a constant or a function declaration.\n", value_idx);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "Metadata value at index %u is not a constant or a function declaration.", value_idx);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ m->u.value = value;
+
+ if (value->type != m->value_type)
+ {
+ WARN("Type mismatch.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
+ "The type of a metadata value does not match its referenced value at index %u.", value_idx);
+ }
+
+ break;
+
+ default:
+ FIXME("Unhandled metadata type %u.\n", record->code);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "Metadata type %u is unhandled.", record->code);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ ++table->count;
+ }
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component_type(enum dxil_component_type type)
+{
+ switch (type)
+ {
+ case COMPONENT_TYPE_I1:
+ return VKD3D_SHADER_COMPONENT_BOOL;
+ case COMPONENT_TYPE_I16:
+ case COMPONENT_TYPE_I32:
+ return VKD3D_SHADER_COMPONENT_INT;
+ case COMPONENT_TYPE_U16:
+ case COMPONENT_TYPE_U32:
+ return VKD3D_SHADER_COMPONENT_UINT;
+ case COMPONENT_TYPE_F16:
+ case COMPONENT_TYPE_F32:
+ case COMPONENT_TYPE_SNORMF32:
+ case COMPONENT_TYPE_UNORMF32:
+ return VKD3D_SHADER_COMPONENT_FLOAT;
+ case COMPONENT_TYPE_F64:
+ case COMPONENT_TYPE_SNORMF64:
+ case COMPONENT_TYPE_UNORMF64:
+ return VKD3D_SHADER_COMPONENT_DOUBLE;
+ default:
+ FIXME("Unhandled component type %u.\n", type);
+ return VKD3D_SHADER_COMPONENT_UINT;
+ }
+}
+
+static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component_type(enum dxil_component_type type)
+{
+ switch (type)
+ {
+ case COMPONENT_TYPE_F16:
+ return VKD3D_SHADER_MINIMUM_PRECISION_FLOAT_16;
+ case COMPONENT_TYPE_I16:
+ return VKD3D_SHADER_MINIMUM_PRECISION_INT_16;
+ case COMPONENT_TYPE_U16:
+ return VKD3D_SHADER_MINIMUM_PRECISION_UINT_16;
+ default:
+ return VKD3D_SHADER_MINIMUM_PRECISION_NONE;
+ }
+}
+
+static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] =
+{
+ [SEMANTIC_KIND_ARBITRARY] = VKD3D_SHADER_SV_NONE,
+ [SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION,
+ [SEMANTIC_KIND_TARGET] = VKD3D_SHADER_SV_NONE,
+};
+
+static enum vkd3d_shader_sysval_semantic sysval_semantic_from_dxil_semantic_kind(enum dxil_semantic_kind kind)
+{
+ if (kind < ARRAY_SIZE(sysval_semantic_table))
+ {
+ return sysval_semantic_table[kind];
+ }
+ else
+ {
+ return VKD3D_SHADER_SV_NONE;
+ }
+}
+
+static const struct sm6_metadata_value *sm6_parser_find_named_metadata(struct sm6_parser *sm6, const char *name)
+{
+ const struct sm6_metadata_node *node;
+ unsigned int i;
+
+ for (i = 0; i < sm6->named_metadata_count; ++i)
+ {
+ if (strcmp(sm6->named_metadata[i].name, name))
+ continue;
+
+ node = sm6->named_metadata[i].value.u.node;
+ if (!node->operand_count)
+ return NULL;
+ if (node->operand_count > 1)
+ {
+ FIXME("Ignoring %u extra operands for %s.\n", node->operand_count - 1, name);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+ "Ignoring %u extra operands for metadata node %s.", node->operand_count - 1, name);
+ }
+ return node->operands[0];
+ }
+
+ return NULL;
+}
+
+static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6,
+ const struct sm6_metadata_node *node, struct vkd3d_shader_register_range *range)
+{
+ unsigned int size;
+
+ if (!sm6_metadata_value_is_value(node->operands[1]))
+ {
+ WARN("Resource data type is not a value.\n");
+ return false;
+ }
+ if (!sm6_type_is_pointer(node->operands[1]->value_type))
+ {
+ WARN("Resource type is not a pointer.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH,
+ "Resource metadata value type is not a pointer.");
+ }
+
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[3], &range->space))
+ {
+ WARN("Failed to load register space.\n");
+ return false;
+ }
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[4], &range->first))
+ {
+ WARN("Failed to load register first.\n");
+ return false;
+ }
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[5], &size))
+ {
+ WARN("Failed to load register range size.\n");
+ return false;
+ }
+ if (!size || (size != UINT_MAX && !vkd3d_bound_range(range->first, size, UINT_MAX)))
+ {
+ WARN("Invalid register range, first %u, size %u.\n", range->first, size);
+ return false;
+ }
+ range->last = (size == UINT_MAX) ? UINT_MAX : range->first + size - 1;
+
+ return true;
+}
+
+static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6,
+ const struct sm6_metadata_node *node, const struct vkd3d_shader_register_range *range,
+ unsigned int register_id, struct vkd3d_shader_instruction *ins)
+{
+ struct vkd3d_shader_register *reg;
+ unsigned int buffer_size;
+
+ if (node->operand_count < 7)
+ {
+ WARN("Invalid operand count %u.\n", node->operand_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT,
+ "Invalid operand count %u for a CBV descriptor.", node->operand_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ if (node->operand_count > 7 && node->operands[7])
+ {
+ WARN("Ignoring %u extra operands.\n", node->operand_count - 7);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+ "Ignoring %u extra operands for a CBV descriptor.", node->operand_count - 7);
+ }
+
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &buffer_size))
+ {
+ WARN("Failed to load buffer size.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Constant buffer size metadata value is not an integer.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_CONSTANT_BUFFER);
+ ins->resource_type = VKD3D_SHADER_RESOURCE_BUFFER;
+ ins->declaration.cb.size = buffer_size;
+ ins->declaration.cb.src.swizzle = VKD3D_SHADER_NO_SWIZZLE;
+ ins->declaration.cb.src.modifiers = VKD3DSPSM_NONE;
+
+ reg = &ins->declaration.cb.src.reg;
+ vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3);
+ reg->idx[0].offset = register_id;
+ reg->idx[1].offset = range->first;
+ reg->idx[2].offset = range->last;
+
+ ins->declaration.cb.range = *range;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6,
+ enum vkd3d_shader_descriptor_type type, const struct sm6_metadata_node *descriptor_node)
+{
+ struct vkd3d_shader_register_range range;
+ struct vkd3d_shader_instruction *ins;
+ const struct sm6_metadata_node *node;
+ const struct sm6_metadata_value *m;
+ unsigned int i, register_id;
+ enum vkd3d_result ret;
+
+ for (i = 0; i < descriptor_node->operand_count; ++i)
+ {
+ m = descriptor_node->operands[i];
+ if (!sm6_metadata_value_is_node(m))
+ {
+ WARN("Resource descriptor is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Resource descriptor is not a metadata node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ node = m->u.node;
+ if (node->operand_count < 6)
+ {
+ WARN("Invalid operand count %u.\n", node->operand_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT,
+ "Invalid operand count %u for a descriptor.", node->operand_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[0], &register_id))
+ {
+ WARN("Failed to load resource id.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Resource id metadata value is not an integer.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (!sm6_parser_resources_load_register_range(sm6, node, &range))
+ {
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Resource register range is invalid.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (!(ins = sm6_parser_require_space(sm6, 1)))
+ {
+ ERR("Failed to allocate instruction.\n");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+
+ switch (type)
+ {
+ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV:
+ if ((ret = sm6_parser_resources_load_cbv(sm6, node, &range, register_id, ins)) < 0)
+ return ret;
+ break;
+ default:
+ FIXME("Unsupported descriptor type %u.\n", type);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Resource descriptor type %u is unsupported.", type);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ ++sm6->p.instructions.count;
+ }
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result sm6_parser_resources_init(struct sm6_parser *sm6)
+{
+ const struct sm6_metadata_value *m = sm6_parser_find_named_metadata(sm6, "dx.resources");
+ enum vkd3d_shader_descriptor_type type;
+ const struct sm6_metadata_node *node;
+ enum vkd3d_result ret;
+
+ if (!m)
+ return VKD3D_OK;
+
+ node = m->u.node;
+ if (node->operand_count != SHADER_DESCRIPTOR_TYPE_COUNT)
+ {
+ WARN("Unexpected descriptor type count %u.\n", node->operand_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Descriptor type count %u is invalid.", node->operand_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ for (type = 0; type < SHADER_DESCRIPTOR_TYPE_COUNT; ++type)
+ {
+ if (!(m = node->operands[type]))
+ continue;
+
+ if (!sm6_metadata_value_is_node(m))
+ {
+ WARN("Resource list is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES,
+ "Resource list is not a metadata node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if ((ret = sm6_parser_descriptor_type_init(sm6, type, m->u.node)) < 0)
+ return ret;
+ }
+
+ return VKD3D_OK;
+}
+
+static void signature_element_read_additional_element_values(struct signature_element *e,
+ const struct sm6_metadata_node *node, struct sm6_parser *sm6)
+{
+ unsigned int i, operand_count, value;
+ enum dxil_element_additional_tag tag;
+
+ if (node->operand_count < 11 || !node->operands[10])
+ return;
+
+ if (!sm6_metadata_value_is_node(node->operands[10]))
+ {
+ WARN("Additional values list is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element additional values list is not a metadata node.");
+ return;
+ }
+
+ node = node->operands[10]->u.node;
+ if (node->operand_count & 1)
+ {
+ WARN("Operand count is not even.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+ "Operand count for signature element additional tag/value pairs is not even.");
+ }
+ operand_count = node->operand_count & ~1u;
+
+ for (i = 0; i < operand_count; i += 2)
+ {
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &tag)
+ || !sm6_metadata_get_uint_value(sm6, node->operands[i + 1], &value))
+ {
+ WARN("Failed to extract tag/value pair.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element tag/value pair at index %u is not an integer pair.", i);
+ continue;
+ }
+
+ switch (tag)
+ {
+ case ADDITIONAL_TAG_STREAM_INDEX:
+ e->stream_index = value;
+ break;
+ case ADDITIONAL_TAG_RELADDR_MASK:
+ /* A mask of components accessed via relative addressing. Seems to replace TPF 'dcl_index_range'. */
+ if (value > VKD3DSP_WRITEMASK_ALL)
+ {
+ WARN("Invalid relative addressed mask %#x.\n", value);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_INVALID_MASK,
+ "Mask %#x of relative-addressed components is invalid.", value);
+ }
+ break;
+ case ADDITIONAL_TAG_USED_MASK:
+ if (value > VKD3DSP_WRITEMASK_ALL)
+ {
+ WARN("Invalid used mask %#x.\n", value);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_INVALID_MASK,
+ "Mask %#x of used components is invalid.", value);
+ value &= VKD3DSP_WRITEMASK_ALL;
+ }
+ e->used_mask = value;
+ break;
+ default:
+ FIXME("Unhandled tag %u, value %u.\n", tag, value);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+ "Tag %#x for signature element additional value %#x is unhandled.", tag, value);
+ break;
+ }
+ }
+}
+
+static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const struct sm6_metadata_value *m,
+ struct shader_signature *s)
+{
+ unsigned int i, j, column_count, operand_count, index;
+ const struct sm6_metadata_node *node, *element_node;
+ struct signature_element *elements, *e;
+ unsigned int values[10];
+
+ if (!m)
+ return VKD3D_OK;
+
+ if (!sm6_metadata_value_is_node(m))
+ {
+ WARN("Signature element list is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element list is not a metadata node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ node = m->u.node;
+ operand_count = node->operand_count;
+
+ if (!(elements = vkd3d_calloc(operand_count, sizeof(*elements))))
+ {
+ ERR("Failed to allocate %u signature elements.\n", operand_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY,
+ "Out of memory allocating %u signature elements.", operand_count);
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+
+ for (i = 0; i < operand_count; ++i)
+ {
+ m = node->operands[i];
+
+ if (!sm6_metadata_value_is_node(m))
+ {
+ WARN("Signature element is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element is not a metadata node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ element_node = m->u.node;
+ if (element_node->operand_count < 10)
+ {
+ WARN("Invalid operand count %u.\n", element_node->operand_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Invalid signature element operand count %u.", element_node->operand_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ if (element_node->operand_count > 11)
+ {
+ WARN("Ignoring %u extra operands.\n", element_node->operand_count - 11);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+ "Ignoring %u extra operands for a signature element.", element_node->operand_count - 11);
+ }
+
+ for (j = 0; j < 10; ++j)
+ {
+ /* 1 is the semantic name, 4 is semantic index metadata. */
+ if (j == 1 || j == 4)
+ continue;
+ if (!sm6_metadata_get_uint_value(sm6, element_node->operands[j], &values[j]))
+ {
+ WARN("Failed to load uint value at index %u.\n", j);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element value at index %u is not an integer.", j);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ }
+
+ e = &elements[i];
+
+ if (values[0] != i)
+ {
+ FIXME("Unsupported element id %u not equal to its index %u.\n", values[0], i);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "A non-sequential and non-zero-based element id is not supported.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (!sm6_metadata_value_is_string(element_node->operands[1]))
+ {
+ WARN("Element name is not a string.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element name is not a metadata string.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ e->semantic_name = element_node->operands[1]->u.string_value;
+
+ e->component_type = vkd3d_component_type_from_dxil_component_type(values[2]);
+ e->min_precision = minimum_precision_from_dxil_component_type(values[2]);
+
+ j = values[3];
+ e->sysval_semantic = sysval_semantic_from_dxil_semantic_kind(j);
+ if (j != SEMANTIC_KIND_ARBITRARY && j != SEMANTIC_KIND_TARGET && e->sysval_semantic == VKD3D_SHADER_SV_NONE)
+ {
+ WARN("Unhandled semantic kind %u.\n", j);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "DXIL semantic kind %u is unhandled.", j);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if ((e->interpolation_mode = values[5]) >= VKD3DSIM_COUNT)
+ {
+ WARN("Unhandled interpolation mode %u.\n", e->interpolation_mode);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Interpolation mode %u is unhandled.", e->interpolation_mode);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ e->register_count = values[6];
+ column_count = values[7];
+ e->register_index = values[8];
+ e->target_location = e->register_index;
+ if (e->register_index > MAX_REG_OUTPUT || e->register_count > MAX_REG_OUTPUT - e->register_index)
+ {
+ WARN("Invalid row start %u with row count %u.\n", e->register_index, e->register_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "A signature element starting row of %u with count %u is invalid.",
+ e->register_index, e->register_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ index = values[9];
+ if (index >= VKD3D_VEC4_SIZE || column_count > VKD3D_VEC4_SIZE - index)
+ {
+ WARN("Invalid column start %u with count %u.\n", index, column_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "A signature element starting column %u with count %u is invalid.", index, column_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ e->mask = vkd3d_write_mask_from_component_count(column_count) << index;
+ e->used_mask = e->mask;
+
+ signature_element_read_additional_element_values(e, element_node, sm6);
+
+ m = element_node->operands[4];
+ if (!sm6_metadata_value_is_node(m))
+ {
+ WARN("Semantic index list is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element semantic index list is not a metadata node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ element_node = m->u.node;
+ for (j = 0; j < element_node->operand_count; ++j)
+ {
+ if (!sm6_metadata_get_uint_value(sm6, element_node->operands[j], &index))
+ {
+ WARN("Failed to get semantic index for row %u.\n", j);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element semantic index for row %u is not an integer.", j);
+ }
+ else if (!j)
+ {
+ e->semantic_index = index;
+ }
+ else if (index != e->semantic_index + j)
+ {
+ WARN("Semantic index %u for row %u is not of an incrementing sequence.\n", index, j);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature element semantic index %u for row %u is not of an incrementing sequence.", index, j);
+ }
+ }
+ }
+
+ vkd3d_free(s->elements);
+ s->elements = elements;
+ s->element_count = operand_count;
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
+{
+ enum vkd3d_result ret;
+
+ if (!sm6_metadata_value_is_node(m))
+ {
+ WARN("Signature table is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE,
+ "Signature table is not a metadata node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (m->u.node->operand_count && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[0],
+ &sm6->p.shader_desc.input_signature)) < 0)
+ {
+ return ret;
+ }
+ if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[1],
+ &sm6->p.shader_desc.output_signature)) < 0)
+ {
+ return ret;
+ }
+ /* TODO: patch constant signature in operand 2. */
+
+ sm6_parser_init_input_signature(sm6, &sm6->p.shader_desc.input_signature);
+ sm6_parser_init_output_signature(sm6, &sm6->p.shader_desc.output_signature);
+
+ return VKD3D_OK;
+}
+
+static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
+{
+ enum vkd3d_shader_global_flags global_flags, mask, rotated_flags;
+ struct vkd3d_shader_instruction *ins;
+
+ if (!sm6_metadata_get_uint64_value(sm6, m, &global_flags))
+ {
+ WARN("Failed to load global flags.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Global flags metadata value is not an integer.");
+ return;
+ }
+ /* Rotate SKIP_OPTIMIZATION from bit 0 to bit 4 to match vkd3d_shader_global_flags. */
+ mask = (VKD3DSGF_SKIP_OPTIMIZATION << 1) - 1;
+ rotated_flags = global_flags & mask;
+ rotated_flags = (rotated_flags >> 1) | ((rotated_flags & 1) << 4);
+ global_flags = (global_flags & ~mask) | rotated_flags;
+
+ ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_GLOBAL_FLAGS);
+ ins->declaration.global_flags = global_flags;
+}
+
+static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m)
+{
+ const struct sm6_metadata_node *node;
+ struct vkd3d_shader_instruction *ins;
+ unsigned int group_sizes[3];
+ unsigned int i;
+
+ if (sm6->p.shader_version.type != VKD3D_SHADER_TYPE_COMPUTE)
+ {
+ WARN("Shader of type %#x has thread group dimensions.\n", sm6->p.shader_version.type);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Shader has thread group dimensions but is not a compute shader.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (!m || !sm6_metadata_value_is_node(m))
+ {
+ WARN("Thread group dimension value is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Thread group dimension metadata value is not a node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ node = m->u.node;
+ if (node->operand_count != 3)
+ {
+ WARN("Invalid operand count %u.\n", node->operand_count);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT,
+ "Thread group dimension operand count %u is invalid.", node->operand_count);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ for (i = 0; i < 3; ++i)
+ {
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &group_sizes[i]))
+ {
+ WARN("Thread group dimension is not an integer value.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Thread group dimension metadata value is not an integer.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ if (!group_sizes[i] || group_sizes[i] > dx_max_thread_group_size[i])
+ {
+ char dim = "XYZ"[i];
+ WARN("Invalid thread group %c dimension %u.\n", dim, group_sizes[i]);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Thread group %c dimension %u is invalid.", dim, group_sizes[i]);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+ }
+
+ ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_THREAD_GROUP);
+ ins->declaration.thread_group_size.x = group_sizes[0];
+ ins->declaration.thread_group_size.y = group_sizes[1];
+ ins->declaration.thread_group_size.z = group_sizes[2];
+
+ return VKD3D_OK;
+}
+
+static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6)
+{
+ const struct sm6_metadata_value *m = sm6_parser_find_named_metadata(sm6, "dx.entryPoints");
+ const struct sm6_metadata_node *node, *entry_node = m ? m->u.node : NULL;
+ enum dxil_shader_properties_tag tag;
+ unsigned int i, operand_count;
+ const struct sm6_value *value;
+ enum vkd3d_result ret;
+
+ if (!entry_node || entry_node->operand_count < 2 || !(m = entry_node->operands[0]))
+ {
+ WARN("No entry point definition found.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT,
+ "No entry point definition found in the metadata.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if (m->type != VKD3D_METADATA_VALUE)
+ {
+ WARN("Entry point definition is not a value.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT,
+ "Entry point definition is not a metadata value.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ value = m->u.value;
+ if (!sm6_value_is_function_dcl(value))
+ {
+ WARN("Entry point value is not a function definition.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT,
+ "Entry point metadata value does not contain a function definition.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ sm6->entry_point = value->u.function.name;
+ if (!sm6_metadata_value_is_string(entry_node->operands[1])
+ || ascii_strcasecmp(sm6->entry_point, entry_node->operands[1]->u.string_value))
+ {
+ WARN("Entry point function name %s mismatch.\n", sm6->entry_point);
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH,
+ "Entry point function name %s does not match the name in metadata.", sm6->entry_point);
+ }
+
+ if (entry_node->operand_count >= 3 && (m = entry_node->operands[2])
+ && (ret = sm6_parser_signatures_init(sm6, m)) < 0)
+ {
+ return ret;
+ }
+
+ if (entry_node->operand_count >= 5 && (m = entry_node->operands[4]))
+ {
+ if (!sm6_metadata_value_is_node(m))
+ {
+ WARN("Shader properties list is not a node.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Shader properties tag/value list is not a metadata node.");
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ node = m->u.node;
+ if (node->operand_count & 1)
+ {
+ WARN("Operand count is not even.\n");
+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS,
+ "Operand count for shader properties tag/value pairs is not even.");
+ }
+ operand_count = node->operand_count & ~1u;
+
+ for (i = 0; i < operand_count; i += 2)
+ {
+ if (!sm6_metadata_get_uint_value(sm6, node->operands[i], &tag))
+ {
+ WARN("Tag is not an integer value.\n");
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Shader properties tag at index %u is not an integer.", i);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ switch (tag)
+ {
+ case SHADER_PROPERTIES_FLAGS:
+ sm6_parser_emit_global_flags(sm6, node->operands[i + 1]);
+ break;
+ case SHADER_PROPERTIES_COMPUTE:
+ if ((ret = sm6_parser_emit_thread_group(sm6, node->operands[i + 1])) < 0)
+ return ret;
+ break;
+ default:
+ FIXME("Unhandled tag %#x.\n", tag);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES,
+ "Shader properties tag %#x is unhandled.", tag);
+ break;
+ }
+ }
+ }
+
+ return VKD3D_OK;
+}
+
+static void sm6_metadata_value_destroy(struct sm6_metadata_value *m)
+{
+ switch (m->type)
+ {
+ case VKD3D_METADATA_NODE:
+ vkd3d_free(m->u.node);
+ break;
+ case VKD3D_METADATA_KIND:
+ vkd3d_free(m->u.kind.name);
+ break;
+ case VKD3D_METADATA_STRING:
+ vkd3d_free(m->u.string_value);
+ break;
+ default:
+ break;
+ }
+}
+
+static void sm6_parser_metadata_cleanup(struct sm6_parser *sm6)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(sm6->metadata_tables); ++i)
+ {
+ for (j = 0; j < sm6->metadata_tables[i].count; ++j)
+ sm6_metadata_value_destroy(&sm6->metadata_tables[i].values[j]);
+ vkd3d_free(sm6->metadata_tables[i].values);
+ }
+ for (i = 0; i < sm6->named_metadata_count; ++i)
+ {
+ sm6_metadata_value_destroy(&sm6->named_metadata[i].value);
+ vkd3d_free(sm6->named_metadata[i].name);
+ }
+ vkd3d_free(sm6->named_metadata);
+}
+
+static void sm6_type_table_cleanup(struct sm6_type *types, size_t count)
+{
+ size_t i;
+
+ if (!types)
+ return;
+
+ for (i = 0; i < count; ++i)
+ {
+ switch (types[i].class)
+ {
+ case TYPE_CLASS_STRUCT:
+ vkd3d_free((void *)types[i].u.struc->name);
+ vkd3d_free(types[i].u.struc);
+ break;
+ case TYPE_CLASS_FUNCTION:
+ vkd3d_free(types[i].u.function);
+ break;
+ default:
+ break;
+ }
+ }
+
+ vkd3d_free(types);
+}
+
+static void sm6_symtab_cleanup(struct sm6_symbol *symbols, size_t count)
+{
+ size_t i;
+
+ for (i = 0; i < count; ++i)
+ vkd3d_free((void *)symbols[i].name);
+ vkd3d_free(symbols);
+}
+
+static void sm6_block_destroy(struct sm6_block *block)
+{
+ vkd3d_free(block->instructions);
+ vkd3d_free(block);
+}
+
+static void sm6_functions_cleanup(struct sm6_function *functions, size_t count)
+{
+ size_t i, j;
+
+ for (i = 0; i < count; ++i)
+ {
+ for (j = 0; j < functions[i].block_count; ++j)
+ sm6_block_destroy(functions[i].blocks[j]);
+ }
+ vkd3d_free(functions);
+}
+
+static void sm6_parser_destroy(struct vkd3d_shader_parser *parser)
+{
+ struct sm6_parser *sm6 = sm6_parser(parser);
+
+ dxil_block_destroy(&sm6->root_block);
+ dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count);
+ shader_instruction_array_destroy(&parser->instructions);
+ sm6_type_table_cleanup(sm6->types, sm6->type_count);
+ sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count);
+ sm6_functions_cleanup(sm6->functions, sm6->function_count);
+ sm6_parser_metadata_cleanup(sm6);
+ vkd3d_free(sm6->values);
+ free_shader_desc(&parser->shader_desc);
+ vkd3d_free(sm6);
+}
+
+static const struct vkd3d_shader_parser_ops sm6_parser_ops =
+{
+ .parser_destroy = sm6_parser_destroy,
+};
+
+static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6, const char *name)
+{
+ size_t i;
+ for (i = 0; i < sm6->function_count; ++i)
+ if (!ascii_strcasecmp(sm6->functions[i].declaration->u.function.name, name))
+ return &sm6->functions[i];
+ return NULL;
+}
+
+static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t *byte_code, size_t byte_code_size,
+ const char *source_name, struct vkd3d_shader_message_context *message_context)
+{
+ const struct shader_signature *output_signature = &sm6->p.shader_desc.output_signature;
+ const struct shader_signature *input_signature = &sm6->p.shader_desc.input_signature;
+ const struct vkd3d_shader_location location = {.source_name = source_name};
+ uint32_t version_token, dxil_version, token_count, magic;
+ unsigned int chunk_offset, chunk_size;
+ size_t count, length, function_count;
+ enum bitcode_block_abbreviation abbr;
+ struct vkd3d_shader_version version;
+ struct dxil_block *block;
+ struct sm6_function *fn;
+ enum vkd3d_result ret;
+ unsigned int i, j;
+
+ count = byte_code_size / sizeof(*byte_code);
+ if (count < 6)
+ {
+ WARN("Invalid data size %zu.\n", byte_code_size);
+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_SIZE,
+ "DXIL chunk size %zu is smaller than the DXIL header size.", byte_code_size);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ version_token = byte_code[0];
+ TRACE("Compiler version: 0x%08x.\n", version_token);
token_count = byte_code[1];
TRACE("Token count: %u.\n", token_count);
@@ -2984,8 +4352,35 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
return ret;
}
- sm6_parser_init_output_signature(sm6, output_signature);
- sm6_parser_init_input_signature(sm6, input_signature);
+ if (!sm6_parser_allocate_named_metadata(sm6))
+ {
+ ERR("Failed to allocate named metadata array.\n");
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+
+ for (i = 0, j = 0; i < sm6->root_block.child_block_count; ++i)
+ {
+ block = sm6->root_block.child_blocks[i];
+ if (block->id != METADATA_BLOCK)
+ continue;
+
+ if (j == ARRAY_SIZE(sm6->metadata_tables))
+ {
+ FIXME("Too many metadata tables.\n");
+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA,
+ "A metadata table count greater than %zu is unsupported.", ARRAY_SIZE(sm6->metadata_tables));
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ if ((ret = sm6_parser_metadata_init(sm6, block, &sm6->metadata_tables[j++])) < 0)
+ return ret;
+ }
+
+ if ((ret = sm6_parser_entry_point_init(sm6)) < 0)
+ return ret;
+
+ if ((ret = sm6_parser_resources_init(sm6)) < 0)
+ return ret;
if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0)
{
@@ -3009,14 +4404,20 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t
sm6->p.shader_desc.ssa_count = sm6->ssa_next_id;
- for (i = 0; i < sm6->function_count; ++i)
+ if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point)))
{
- 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;
- }
+ WARN("Failed to find entry point %s.\n", sm6->entry_point);
+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT,
+ "The definition of the entry point function '%s' was not found.", sm6->entry_point);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
+ assert(sm6->function_count == 1);
+ if (!sm6_block_emit_instructions(fn->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);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
index b42e30888a9..2d383bc2fb5 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c
@@ -3421,6 +3421,10 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
else if (option->value == VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_COLUMN_MAJOR)
ctx->matrix_majority = HLSL_MODIFIER_COLUMN_MAJOR;
}
+ else if (option->name == VKD3D_SHADER_COMPILE_OPTION_BACKWARD_COMPATIBILITY)
+ {
+ ctx->semantic_compat_mapping = option->value & VKD3D_SHADER_COMPILE_OPTION_BACKCOMPAT_MAP_SEMANTIC_NAMES;
+ }
}
return true;
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
index 29259767104..ea2117e5128 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h
@@ -862,13 +862,8 @@ struct hlsl_ctx
uint32_t in_state_block : 1;
/* Whether the numthreads() attribute has been provided in the entry-point function. */
uint32_t found_numthreads : 1;
-};
-enum hlsl_error_level
-{
- HLSL_LEVEL_ERROR = 0,
- HLSL_LEVEL_WARNING,
- HLSL_LEVEL_NOTE,
+ bool semantic_compat_mapping;
};
struct hlsl_resource_load_params
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
index 90abd64a3c6..b3d4aeee839 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l
@@ -109,7 +109,9 @@ register {return KW_REGISTER; }
RWBuffer {return KW_RWBUFFER; }
RWStructuredBuffer {return KW_RWSTRUCTUREDBUFFER; }
RWTexture1D {return KW_RWTEXTURE1D; }
+RWTexture1DArray {return KW_RWTEXTURE1DARRAY; }
RWTexture2D {return KW_RWTEXTURE2D; }
+RWTexture2DArray {return KW_RWTEXTURE2DARRAY; }
RWTexture3D {return KW_RWTEXTURE3D; }
sampler {return KW_SAMPLER; }
sampler1D {return KW_SAMPLER1D; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
index ba738473ffd..e58574f7560 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y
@@ -4722,7 +4722,9 @@ static struct hlsl_scope *get_loop_scope(struct hlsl_scope *scope)
%token KW_RWBUFFER
%token KW_RWSTRUCTUREDBUFFER
%token KW_RWTEXTURE1D
+%token KW_RWTEXTURE1DARRAY
%token KW_RWTEXTURE2D
+%token KW_RWTEXTURE2DARRAY
%token KW_RWTEXTURE3D
%token KW_SAMPLER
%token KW_SAMPLER1D
@@ -5547,10 +5549,18 @@ uav_type:
{
$$ = HLSL_SAMPLER_DIM_1D;
}
+ | KW_RWTEXTURE1DARRAY
+ {
+ $$ = HLSL_SAMPLER_DIM_1DARRAY;
+ }
| KW_RWTEXTURE2D
{
$$ = HLSL_SAMPLER_DIM_2D;
}
+ | KW_RWTEXTURE2DARRAY
+ {
+ $$ = HLSL_SAMPLER_DIM_2DARRAY;
+ }
| KW_RWTEXTURE3D
{
$$ = HLSL_SAMPLER_DIM_3D;
@@ -5697,7 +5707,9 @@ type_no_void:
{
case HLSL_SAMPLER_DIM_BUFFER:
case HLSL_SAMPLER_DIM_1D:
+ case HLSL_SAMPLER_DIM_1DARRAY:
case HLSL_SAMPLER_DIM_2D:
+ case HLSL_SAMPLER_DIM_2DARRAY:
case HLSL_SAMPLER_DIM_3D:
if ($3->class == HLSL_CLASS_ARRAY)
{
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
index 5c816e89523..7d17ca8cec6 100644
--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c
@@ -249,7 +249,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir
{
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
"Output semantic \"%s%u\" is used multiple times.", semantic->name, index);
- hlsl_note(ctx, &ext_var->loc, HLSL_LEVEL_ERROR,
+ hlsl_note(ctx, &ext_var->loc, VKD3D_SHADER_LOG_ERROR,
"First use of \"%s%u\" is here.", semantic->name, index);
semantic->reported_duplicated_output_next_index = index + 1;
}
@@ -262,7 +262,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir
hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC,
"Input semantic \"%s%u\" is used multiple times with incompatible types.",
semantic->name, index);
- hlsl_note(ctx, &ext_var->loc, HLSL_LEVEL_ERROR,
+ hlsl_note(ctx, &ext_var->loc, VKD3D_SHADER_LOG_ERROR,
"First declaration of \"%s%u\" is here.", semantic->name, index);
semantic->reported_duplicated_input_incompatible_next_index = index + 1;
}
diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c
index 1c8b52e6d37..2dab97ccbb3 100644
--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c
@@ -2464,9 +2464,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
compiler->formatting = option->value;
break;
- default:
- WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value);
-
case VKD3D_SHADER_COMPILE_OPTION_API_VERSION:
break;
@@ -2482,6 +2479,10 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve
case VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE:
compiler->write_tess_geom_point_size = option->value;
break;
+
+ default:
+ WARN("Ignoring unrecognised option %#x with value %#x.\n", option->name, option->value);
+ break;
}
}
@@ -5377,7 +5378,7 @@ static size_t spirv_compiler_get_current_function_location(struct spirv_compiler
static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
- unsigned int flags = instruction->flags;
+ enum vkd3d_shader_global_flags flags = instruction->declaration.global_flags;
if (flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL)
{
@@ -5392,9 +5393,9 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler
}
if (flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS))
- FIXME("Unhandled global flags %#x.\n", flags);
+ FIXME("Unhandled global flags %#"PRIx64".\n", flags);
else
- WARN("Unhandled global flags %#x.\n", flags);
+ WARN("Unhandled global flags %#"PRIx64".\n", flags);
}
static void spirv_compiler_emit_temps(struct spirv_compiler *compiler, uint32_t count)
@@ -5638,7 +5639,8 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler,
reg.idx[1].offset = range->first;
reg.idx[2].offset = range->last;
- size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t));
+ size = align(size_in_bytes, VKD3D_VEC4_SIZE * sizeof(uint32_t));
+ size /= VKD3D_VEC4_SIZE * sizeof(uint32_t);
if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range)))
{
@@ -5686,15 +5688,18 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi
struct vkd3d_symbol reg_symbol;
unsigned int i;
- if (!(elements = vkd3d_calloc(icb->vec4_count, sizeof(*elements))))
+ assert(icb->data_type == VKD3D_DATA_FLOAT);
+ assert(icb->component_count == VKD3D_VEC4_SIZE);
+
+ if (!(elements = vkd3d_calloc(icb->element_count, sizeof(*elements))))
return;
- for (i = 0; i < icb->vec4_count; ++i)
+ for (i = 0; i < icb->element_count; ++i)
elements[i] = spirv_compiler_get_constant(compiler,
VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE, &icb->data[4 * i]);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE);
- length_id = spirv_compiler_get_constant_uint(compiler, icb->vec4_count);
+ length_id = spirv_compiler_get_constant_uint(compiler, icb->element_count);
type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id);
- const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->vec4_count);
+ const_id = vkd3d_spirv_build_op_constant_composite(builder, type_id, elements, icb->element_count);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id);
icb_id = vkd3d_spirv_build_op_variable(builder, &builder->global_stream,
ptr_type_id, SpvStorageClassPrivate, const_id);
@@ -5900,6 +5905,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi
current->sampler_index == VKD3D_SHADER_DUMMY_SAMPLER_INDEX ? 0 : current->sampler_space,
current->sampler_index);
symbol.id = var_id;
+ symbol.descriptor_array = NULL;
symbol.info.resource.range = *resource_range;
symbol.info.resource.sampled_type = sampled_type;
symbol.info.resource.type_id = image_type_id;
diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c
index c471d1c586b..0ea5a682fa4 100644
--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c
+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c
@@ -784,7 +784,9 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui
ins->handler_idx = VKD3DSIH_INVALID;
return;
}
- icb->vec4_count = icb_size / 4;
+ icb->data_type = VKD3D_DATA_FLOAT;
+ icb->component_count = VKD3D_VEC4_SIZE;
+ icb->element_count = icb_size / VKD3D_VEC4_SIZE;
memcpy(icb->data, tokens, sizeof(*tokens) * icb_size);
shader_instruction_array_add_icb(&priv->p.instructions, icb);
ins->declaration.icb = icb;
@@ -882,6 +884,8 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction
ins->declaration.cb.size = *tokens++;
shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.cb.range.space);
}
+
+ ins->declaration.cb.size *= VKD3D_VEC4_SIZE * sizeof(float);
}
static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
@@ -1090,7 +1094,7 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction *
static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *ins, uint32_t opcode,
uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv)
{
- ins->flags = (opcode_token & VKD3D_SM4_GLOBAL_FLAGS_MASK) >> VKD3D_SM4_GLOBAL_FLAGS_SHIFT;
+ ins->declaration.global_flags = (opcode_token & VKD3D_SM4_GLOBAL_FLAGS_MASK) >> VKD3D_SM4_GLOBAL_FLAGS_SHIFT;
}
static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token,
@@ -1803,10 +1807,11 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui
*modifier = VKD3DSPSM_ABSNEG;
break;
+ case VKD3D_SM4_REGISTER_MODIFIER_NONE:
+ break;
+
default:
FIXME("Unhandled register modifier %#x.\n", m);
- /* fall-through */
- case VKD3D_SM4_REGISTER_MODIFIER_NONE:
break;
}
@@ -2728,7 +2733,7 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant
const char *name;
bool output;
enum vkd3d_shader_type shader_type;
- D3DDECLUSAGE usage;
+ D3D_NAME usage;
}
semantics[] =
{
@@ -2759,20 +2764,21 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant
{"position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION},
{"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_POSITION},
};
+ bool needs_compat_mapping = ascii_strncasecmp(semantic->name, "sv_", 3);
for (i = 0; i < ARRAY_SIZE(semantics); ++i)
{
if (!ascii_strcasecmp(semantic->name, semantics[i].name)
&& output == semantics[i].output
- && ctx->profile->type == semantics[i].shader_type
- && !ascii_strncasecmp(semantic->name, "sv_", 3))
+ && (ctx->semantic_compat_mapping == needs_compat_mapping || !needs_compat_mapping)
+ && ctx->profile->type == semantics[i].shader_type)
{
*usage = semantics[i].usage;
return true;
}
}
- if (!ascii_strncasecmp(semantic->name, "sv_", 3))
+ if (!needs_compat_mapping)
return false;
*usage = D3D_NAME_UNDEFINED;
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
index d9b6995a11e..4ce1c9daf90 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -817,7 +817,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV,
&cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT)))
return;
- d->buffer_size = cb->size * 16;
+ d->buffer_size = cb->size;
}
static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_context *context,
@@ -1852,14 +1852,14 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins
return true;
}
-bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
+unsigned int shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
struct vkd3d_shader_immediate_constant_buffer *icb)
{
if (!vkd3d_array_reserve((void **)&instructions->icbs, &instructions->icb_capacity, instructions->icb_count + 1,
sizeof(*instructions->icbs)))
- return false;
- instructions->icbs[instructions->icb_count++] = icb;
- return true;
+ return UINT_MAX;
+ instructions->icbs[instructions->icb_count] = icb;
+ return instructions->icb_count++;
}
static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params(
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
index 37c9625874f..c9d2dec8b89 100644
--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -176,12 +176,20 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011,
VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND = 8012,
VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC = 8013,
+ VKD3D_SHADER_ERROR_DXIL_INVALID_METADATA = 8014,
+ VKD3D_SHADER_ERROR_DXIL_INVALID_ENTRY_POINT = 8015,
+ VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE = 8016,
+ VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES = 8017,
+ VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES = 8018,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301,
VKD3D_SHADER_WARNING_DXIL_INVALID_BLOCK_LENGTH = 8302,
VKD3D_SHADER_WARNING_DXIL_INVALID_MODULE_LENGTH = 8303,
VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS = 8304,
+ VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH = 8305,
+ VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH = 8306,
+ VKD3D_SHADER_WARNING_DXIL_INVALID_MASK = 8307,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000,
VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001,
@@ -565,11 +573,13 @@ enum vkd3d_data_type
VKD3D_DATA_CONTINUED,
VKD3D_DATA_UNUSED,
VKD3D_DATA_UINT8,
+ VKD3D_DATA_UINT64,
};
static inline bool data_type_is_integer(enum vkd3d_data_type data_type)
{
- return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT;
+ return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT
+ || data_type == VKD3D_DATA_UINT64;
}
enum vsir_dimension
@@ -623,6 +633,8 @@ enum vkd3d_shader_interpolation_mode
VKD3DSIM_LINEAR_NOPERSPECTIVE_CENTROID = 5,
VKD3DSIM_LINEAR_SAMPLE = 6,
VKD3DSIM_LINEAR_NOPERSPECTIVE_SAMPLE = 7,
+
+ VKD3DSIM_COUNT = 8,
};
enum vkd3d_shader_global_flags
@@ -634,6 +646,32 @@ enum vkd3d_shader_global_flags
VKD3DSGF_SKIP_OPTIMIZATION = 0x10,
VKD3DSGF_ENABLE_MINIMUM_PRECISION = 0x20,
VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS = 0x40,
+ VKD3DSGF_ENABLE_SHADER_EXTENSIONS = 0x80, /* never emitted? */
+ VKD3DSGF_BIND_FOR_DURATION = 0x100,
+ VKD3DSGF_ENABLE_VP_AND_RT_ARRAY_INDEX = 0x200,
+ VKD3DSGF_ENABLE_INNER_COVERAGE = 0x400,
+ VKD3DSGF_ENABLE_STENCIL_REF = 0x800,
+ VKD3DSGF_ENABLE_TILED_RESOURCE_INTRINSICS = 0x1000,
+ VKD3DSGF_ENABLE_RELAXED_TYPED_UAV_FORMATS = 0x2000,
+ VKD3DSGF_ENABLE_LVL_9_COMPARISON_FILTERING = 0x4000,
+ VKD3DSGF_ENABLE_UP_TO_64_UAVS = 0x8000,
+ VKD3DSGF_ENABLE_UAVS_AT_EVERY_STAGE = 0x10000,
+ VKD3DSGF_ENABLE_CS4_RAW_STRUCTURED_BUFFERS = 0x20000,
+ VKD3DSGF_ENABLE_RASTERIZER_ORDERED_VIEWS = 0x40000,
+ VKD3DSGF_ENABLE_WAVE_INTRINSICS = 0x80000,
+ VKD3DSGF_ENABLE_INT64 = 0x100000,
+ VKD3DSGF_ENABLE_VIEWID = 0x200000,
+ VKD3DSGF_ENABLE_BARYCENTRICS = 0x400000,
+ VKD3DSGF_FORCE_NATIVE_LOW_PRECISION = 0x800000,
+ VKD3DSGF_ENABLE_SHADINGRATE = 0x1000000,
+ VKD3DSGF_ENABLE_RAYTRACING_TIER_1_1 = 0x2000000,
+ VKD3DSGF_ENABLE_SAMPLER_FEEDBACK = 0x4000000,
+ VKD3DSGF_ENABLE_ATOMIC_INT64_ON_TYPED_RESOURCE = 0x8000000,
+ VKD3DSGF_ENABLE_ATOMIC_INT64_ON_GROUP_SHARED = 0x10000000,
+ VKD3DSGF_ENABLE_DERIVATIVES_IN_MESH_AND_AMPLIFICATION_SHADERS = 0x20000000,
+ VKD3DSGF_ENABLE_RESOURCE_DESCRIPTOR_HEAP_INDEXING = 0x40000000,
+ VKD3DSGF_ENABLE_SAMPLER_DESCRIPTOR_HEAP_INDEXING = 0x80000000,
+ VKD3DSGF_ENABLE_ATOMIC_INT64_ON_DESCRIPTOR_HEAP_RESOURCE = 0x100000000ull,
};
enum vkd3d_shader_sync_flags
@@ -645,7 +683,8 @@ enum vkd3d_shader_sync_flags
enum vkd3d_shader_uav_flags
{
- VKD3DSUF_GLOBALLY_COHERENT = 0x2,
+ VKD3DSUF_GLOBALLY_COHERENT = 0x002,
+ VKD3DSUF_RASTERISER_ORDERED_VIEW = 0x004,
VKD3DSUF_ORDER_PRESERVING_COUNTER = 0x100,
};
@@ -716,7 +755,10 @@ struct vkd3d_shader_version
struct vkd3d_shader_immediate_constant_buffer
{
- unsigned int vec4_count;
+ enum vkd3d_data_type data_type;
+ /* total count is element_count * component_count */
+ unsigned int element_count;
+ unsigned int component_count;
uint32_t data[];
};
@@ -860,6 +902,7 @@ struct signature_element
unsigned int mask;
unsigned int used_mask;
enum vkd3d_shader_minimum_precision min_precision;
+ enum vkd3d_shader_interpolation_mode interpolation_mode;
/* Register index / location in the target shader.
* If SIGNATURE_TARGET_LOCATION_UNUSED, this element should not be written. */
unsigned int target_location;
@@ -1004,6 +1047,7 @@ struct vkd3d_shader_instruction
const struct vkd3d_shader_src_param *predicate;
union
{
+ enum vkd3d_shader_global_flags global_flags;
struct vkd3d_shader_semantic semantic;
struct vkd3d_shader_register_semantic register_semantic;
struct vkd3d_shader_primitive_type primitive_type;
@@ -1102,7 +1146,7 @@ struct vkd3d_shader_instruction_array
bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve);
-bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
+unsigned int shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions,
struct vkd3d_shader_immediate_constant_buffer *icb);
bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions,
unsigned int dst, unsigned int src);
@@ -1482,23 +1526,6 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain,
#define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t))
#define VKD3D_DXBC_CHUNK_ALIGNMENT sizeof(uint32_t)
-#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9')
-#define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C')
-#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L')
-#define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1')
-#define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N')
-#define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1')
-#define TAG_OSG5 VKD3D_MAKE_TAG('O', 'S', 'G', '5')
-#define TAG_OSGN VKD3D_MAKE_TAG('O', 'S', 'G', 'N')
-#define TAG_PCSG VKD3D_MAKE_TAG('P', 'C', 'S', 'G')
-#define TAG_PSG1 VKD3D_MAKE_TAG('P', 'S', 'G', '1')
-#define TAG_RD11 VKD3D_MAKE_TAG('R', 'D', '1', '1')
-#define TAG_RDEF VKD3D_MAKE_TAG('R', 'D', 'E', 'F')
-#define TAG_RTS0 VKD3D_MAKE_TAG('R', 'T', 'S', '0')
-#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R')
-#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X')
-#define TAG_TEXT VKD3D_MAKE_TAG('T', 'E', 'X', 'T')
-
#define DXBC_MAX_SECTION_COUNT 5
struct dxbc_writer
diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c
index 3e17400a78a..2d7051f3a3b 100644
--- a/libs/vkd3d/libs/vkd3d/device.c
+++ b/libs/vkd3d/libs/vkd3d/device.c
@@ -3626,7 +3626,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi
optimized_clear_value, debugstr_guid(iid), resource);
if (FAILED(hr = d3d12_committed_resource_create(device, heap_properties, heap_flags,
- desc, initial_state, optimized_clear_value, &object)))
+ desc, initial_state, optimized_clear_value, NULL, &object)))
{
*resource = NULL;
return hr;
@@ -4012,12 +4012,23 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Dev
const D3D12_CLEAR_VALUE *optimized_clear_value,
ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource)
{
- FIXME("iface %p, heap_properties %p, heap_flags %#x, desc %p, initial_state %#x, "
- "optimized_clear_value %p, protected_session %p, iid %s, resource %p stub!\n",
+ struct d3d12_device *device = impl_from_ID3D12Device5(iface);
+ struct d3d12_resource *object;
+ HRESULT hr;
+
+ TRACE("iface %p, heap_properties %p, heap_flags %#x, desc %p, initial_state %#x, "
+ "optimized_clear_value %p, protected_session %p, iid %s, resource %p.\n",
iface, heap_properties, heap_flags, desc, initial_state,
optimized_clear_value, protected_session, debugstr_guid(iid), resource);
- return E_NOTIMPL;
+ if (FAILED(hr = d3d12_committed_resource_create(device, heap_properties, heap_flags,
+ desc, initial_state, optimized_clear_value, protected_session, &object)))
+ {
+ *resource = NULL;
+ return hr;
+ }
+
+ return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource);
}
static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface,
diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c
index ad1d2d66692..8898c247abf 100644
--- a/libs/vkd3d/libs/vkd3d/resource.c
+++ b/libs/vkd3d/libs/vkd3d/resource.c
@@ -2076,7 +2076,8 @@ static HRESULT vkd3d_allocate_resource_memory(
HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
- const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource)
+ const D3D12_CLEAR_VALUE *optimized_clear_value, ID3D12ProtectedResourceSession *protected_session,
+ struct d3d12_resource **resource)
{
struct d3d12_resource *object;
HRESULT hr;
@@ -2087,6 +2088,9 @@ HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
return E_INVALIDARG;
}
+ if (protected_session)
+ FIXME("Protected session is not supported.\n");
+
if (FAILED(hr = d3d12_resource_create(device, heap_properties, heap_flags,
desc, initial_state, optimized_clear_value, &object)))
return hr;
diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
index 625a43125c9..2e9845dfa6d 100644
--- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h
@@ -773,7 +773,8 @@ void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_r
HRESULT d3d12_committed_resource_create(struct d3d12_device *device,
const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
- const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
+ const D3D12_CLEAR_VALUE *optimized_clear_value, ID3D12ProtectedResourceSession *protected_session,
+ struct d3d12_resource **resource);
HRESULT d3d12_placed_resource_create(struct d3d12_device *device, struct d3d12_heap *heap, uint64_t heap_offset,
const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state,
const D3D12_CLEAR_VALUE *optimized_clear_value, struct d3d12_resource **resource);
--
2.42.0