From 40a934e71b0dee6d0419d0edf3909fb5d409edff Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Thu, 15 Feb 2024 11:04:48 +1100 Subject: [PATCH] Updated vkd3d-latest patchset Squash to 9.2 and add latest git. --- ...5c917552c927835c6f446dbecf1aa6ff2cc.patch} | 5541 ++++++++++++++--- ...-628acb6b96eaae24861402dfa2be641c44c.patch | 638 ++ ...-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch | 1766 ------ ...-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch | 1877 ------ ...-5c917552c927835c6f446dbecf1aa6ff2cc.patch | 1667 ----- ...-5eba031fa1c7f606ffacf3cb7310615728d.patch | 113 - 6 files changed, 5423 insertions(+), 6179 deletions(-) rename patches/vkd3d-latest/{0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch => 0001-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch} (74%) create mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-628acb6b96eaae24861402dfa2be641c44c.patch delete mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch delete mode 100644 patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch delete mode 100644 patches/vkd3d-latest/0004-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch delete mode 100644 patches/vkd3d-latest/0005-Updated-vkd3d-to-5eba031fa1c7f606ffacf3cb7310615728d.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch similarity index 74% rename from patches/vkd3d-latest/0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch rename to patches/vkd3d-latest/0001-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch index 608645f9..32847ab1 100644 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-fd7d23f64bc8c33fe3b59431219e14c0865.patch +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch @@ -1,48 +1,47 @@ -From ceefa7472488abad8434bb1ad515b09ab74f5a71 Mon Sep 17 00:00:00 2001 +From 65f5978cdf827d674f90160484af94c32cbf540a Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 8 Dec 2023 13:21:19 +1100 -Subject: [PATCH 1/5] Updated vkd3d to - fd7d23f64bc8c33fe3b59431219e14c0865be37a. +Subject: [PATCH] Updated vkd3d to 5c917552c927835c6f446dbecf1aa6ff2cc30cbe. --- libs/vkd3d/Makefile.in | 1 + - libs/vkd3d/include/private/list.h | 270 +++ - libs/vkd3d/include/private/rbtree.h | 378 ++++ - libs/vkd3d/include/private/vkd3d_common.h | 59 +- - libs/vkd3d/include/private/vkd3d_debug.h | 23 + - libs/vkd3d/include/private/vkd3d_test.h | 432 ++++ + libs/vkd3d/include/private/list.h | 270 ++ + libs/vkd3d/include/private/rbtree.h | 378 +++ + libs/vkd3d/include/private/vkd3d_common.h | 51 +- + libs/vkd3d/include/private/vkd3d_debug.h | 27 + + libs/vkd3d/include/private/vkd3d_test.h | 430 +++ libs/vkd3d/include/vkd3d_d3d9types.h | 237 ++ - libs/vkd3d/include/vkd3d_d3dcompiler.h | 93 + + libs/vkd3d/include/vkd3d_d3dcompiler.h | 97 + libs/vkd3d/include/vkd3d_d3dcompiler_types.h | 45 + - libs/vkd3d/include/vkd3d_shader.h | 30 + - libs/vkd3d/include/vkd3d_utils.h | 126 ++ - libs/vkd3d/include/vkd3d_windows.h | 289 +++ + libs/vkd3d/include/vkd3d_shader.h | 38 +- + libs/vkd3d/include/vkd3d_utils.h | 128 + + libs/vkd3d/include/vkd3d_windows.h | 289 ++ libs/vkd3d/libs/vkd3d-common/blob.c | 8 +- libs/vkd3d/libs/vkd3d-common/debug.c | 6 +- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 222 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 115 +- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 237 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 128 +- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 38 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 1920 +++++++++++++++-- - libs/vkd3d/libs/vkd3d-shader/fx.c | 515 +++++ + libs/vkd3d/libs/vkd3d-shader/dxil.c | 2521 +++++++++++++++-- + libs/vkd3d/libs/vkd3d-shader/fx.c | 515 ++++ libs/vkd3d/libs/vkd3d-shader/glsl.c | 6 +- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 103 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 38 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 352 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 79 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 1840 ++++++++++++++-- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 1602 +++++++------- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 173 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 167 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 152 +- - libs/vkd3d/libs/vkd3d/command.c | 64 +- - libs/vkd3d/libs/vkd3d/device.c | 175 +- - libs/vkd3d/libs/vkd3d/resource.c | 121 +- - libs/vkd3d/libs/vkd3d/state.c | 64 +- - libs/vkd3d/libs/vkd3d/utils.c | 14 +- - libs/vkd3d/libs/vkd3d/vkd3d_main.c | 10 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 43 +- - 37 files changed, 8133 insertions(+), 1678 deletions(-) + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 216 +- + libs/vkd3d/libs/vkd3d-shader/ir.c | 2492 ++++++++++++++-- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 1840 ++++++------ + libs/vkd3d/libs/vkd3d-shader/tpf.c | 183 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 171 +- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 264 +- + libs/vkd3d/libs/vkd3d/command.c | 100 +- + libs/vkd3d/libs/vkd3d/device.c | 727 +++-- + libs/vkd3d/libs/vkd3d/resource.c | 163 +- + libs/vkd3d/libs/vkd3d/state.c | 72 +- + libs/vkd3d/libs/vkd3d/utils.c | 24 +- + libs/vkd3d/libs/vkd3d/vkd3d_main.c | 34 +- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 120 +- + 37 files changed, 10153 insertions(+), 2197 deletions(-) create mode 100644 libs/vkd3d/include/private/list.h create mode 100644 libs/vkd3d/include/private/rbtree.h create mode 100644 libs/vkd3d/include/private/vkd3d_test.h @@ -726,7 +725,7 @@ index 00000000000..b5d38bca54c + +#endif /* __WINE_WINE_RBTREE_H */ diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h -index 34fde1a2aa0..979676c4d5a 100644 +index 34fde1a2aa0..b5a8240d28e 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -52,6 +52,7 @@ @@ -737,6 +736,15 @@ index 34fde1a2aa0..979676c4d5a 100644 #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') +@@ -70,7 +71,7 @@ + #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) ++static inline uint64_t align(uint64_t addr, size_t alignment) + { + return (addr + (alignment - 1)) & ~(alignment - 1); + } @@ -80,7 +81,7 @@ static inline size_t align(size_t addr, size_t alignment) # ifdef __MINGW_PRINTF_FORMAT # define VKD3D_PRINTF_FUNC(fmt, args) __attribute__((format(__MINGW_PRINTF_FORMAT, fmt, args))) @@ -755,7 +763,7 @@ index 34fde1a2aa0..979676c4d5a 100644 return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; -@@ -266,33 +267,53 @@ static inline int ascii_strcasecmp(const char *a, const char *b) +@@ -266,34 +267,42 @@ static inline int ascii_strcasecmp(const char *a, const char *b) return c_a - c_b; } @@ -808,29 +816,30 @@ index 34fde1a2aa0..979676c4d5a 100644 -# error "InterlockedDecrement() not implemented for this platform" -# endif +-#endif /* _WIN32 */ +static inline uint32_t vkd3d_atomic_increment_u32(uint32_t volatile *x) +{ + return vkd3d_atomic_add_fetch_u32(x, 1); +} -+ -+#ifndef _WIN32 -+static inline LONG InterlockedIncrement(LONG volatile *x) -+{ -+ return vkd3d_atomic_increment_u32((uint32_t *)x); -+} -+ -+static inline LONG InterlockedDecrement(LONG volatile *x) -+{ -+ return vkd3d_atomic_decrement_u32((uint32_t *)x); -+} - #endif /* _WIN32 */ static inline void vkd3d_parse_version(const char *version, int *major, int *minor) + { diff --git a/libs/vkd3d/include/private/vkd3d_debug.h b/libs/vkd3d/include/private/vkd3d_debug.h -index 6708cad344f..663fc311adf 100644 +index 6708cad344f..c5b6ccedf81 100644 --- a/libs/vkd3d/include/private/vkd3d_debug.h +++ b/libs/vkd3d/include/private/vkd3d_debug.h -@@ -104,6 +104,29 @@ static inline const char *debugstr_guid(const GUID *guid) +@@ -89,6 +89,10 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size); + #define TRACE_ON() (vkd3d_dbg_get_level() == VKD3D_DBG_LEVEL_TRACE) + #endif + ++#ifndef WARN_ON ++#define WARN_ON() (vkd3d_dbg_get_level() >= VKD3D_DBG_LEVEL_WARN) ++#endif ++ + #define FIXME_ONCE VKD3D_DBG_LOG_ONCE(FIXME, WARN) + + #define VKD3D_DEBUG_ENV_NAME(name) const char *const vkd3d_dbg_env_name = name +@@ -104,6 +108,29 @@ static inline const char *debugstr_guid(const GUID *guid) guid->Data4[5], guid->Data4[6], guid->Data4[7]); } @@ -862,10 +871,10 @@ index 6708cad344f..663fc311adf 100644 struct vkd3d_debug_option diff --git a/libs/vkd3d/include/private/vkd3d_test.h b/libs/vkd3d/include/private/vkd3d_test.h new file mode 100644 -index 00000000000..081443c4fa6 +index 00000000000..a337ac07269 --- /dev/null +++ b/libs/vkd3d/include/private/vkd3d_test.h -@@ -0,0 +1,432 @@ +@@ -0,0 +1,430 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * @@ -969,12 +978,12 @@ index 00000000000..081443c4fa6 + +struct vkd3d_test_state +{ -+ LONG success_count; -+ LONG failure_count; -+ LONG skip_count; -+ LONG todo_count; -+ LONG todo_success_count; -+ LONG bug_count; ++ unsigned int success_count; ++ unsigned int failure_count; ++ unsigned int skip_count; ++ unsigned int todo_count; ++ unsigned int todo_success_count; ++ unsigned int bug_count; + + unsigned int debug_level; + @@ -1018,13 +1027,13 @@ index 00000000000..081443c4fa6 +{ + if (result) + { -+ InterlockedIncrement(&vkd3d_test_state.success_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.success_count); + if (vkd3d_test_state.debug_level > 1) + vkd3d_test_printf(line, "Test succeeded.\n"); + } + else + { -+ InterlockedIncrement(&vkd3d_test_state.failure_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.failure_count); + vkd3d_test_printf(line, "Test failed: "); + vprintf(fmt, args); + } @@ -1048,7 +1057,7 @@ index 00000000000..081443c4fa6 + + if (is_bug && vkd3d_test_state.bug_enabled) + { -+ InterlockedIncrement(&vkd3d_test_state.bug_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.bug_count); + if (is_todo) + result = !result; + if (result) @@ -1061,12 +1070,12 @@ index 00000000000..081443c4fa6 + { + if (result) + { -+ InterlockedIncrement(&vkd3d_test_state.todo_success_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.todo_success_count); + vkd3d_test_printf(line, "Todo succeeded: "); + } + else + { -+ InterlockedIncrement(&vkd3d_test_state.todo_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.todo_count); + vkd3d_test_printf(line, "Todo: "); + } + vprintf(fmt, args); @@ -1095,7 +1104,7 @@ index 00000000000..081443c4fa6 + vkd3d_test_printf(line, "Test skipped: "); + vprintf(fmt, args); + va_end(args); -+ InterlockedIncrement(&vkd3d_test_state.skip_count); ++ vkd3d_atomic_increment_u32(&vkd3d_test_state.skip_count); +} + +static void VKD3D_PRINTF_FUNC(2, 3) VKD3D_UNUSED @@ -1161,16 +1170,14 @@ index 00000000000..081443c4fa6 + + vkd3d_test_main(argc, argv); + -+ printf("%s: %lu tests executed (%lu failures, %lu skipped, %lu todo, %lu bugs).\n", ++ printf("%s: %u tests executed (%u failures, %u skipped, %u todo, %u bugs).\n", + vkd3d_test_name, -+ (unsigned long)(vkd3d_test_state.success_count -+ + vkd3d_test_state.failure_count + vkd3d_test_state.todo_count -+ + vkd3d_test_state.todo_success_count), -+ (unsigned long)(vkd3d_test_state.failure_count -+ + vkd3d_test_state.todo_success_count), -+ (unsigned long)vkd3d_test_state.skip_count, -+ (unsigned long)vkd3d_test_state.todo_count, -+ (unsigned long)vkd3d_test_state.bug_count); ++ vkd3d_test_state.success_count + vkd3d_test_state.failure_count ++ + vkd3d_test_state.todo_count + vkd3d_test_state.todo_success_count, ++ vkd3d_test_state.failure_count + vkd3d_test_state.todo_success_count, ++ vkd3d_test_state.skip_count, ++ vkd3d_test_state.todo_count, ++ vkd3d_test_state.bug_count); + + if (test_platform) + free(test_platform); @@ -1543,10 +1550,10 @@ index 00000000000..75d0461409d +#endif /* __VKD3D_D3D9TYPES_H */ diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler.h b/libs/vkd3d/include/vkd3d_d3dcompiler.h new file mode 100644 -index 00000000000..1975f4f980a +index 00000000000..872a90bbc4b --- /dev/null +++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h -@@ -0,0 +1,93 @@ +@@ -0,0 +1,97 @@ +/* + * Copyright 2010 Matteo Bruni for CodeWeavers + * @@ -1628,6 +1635,7 @@ index 00000000000..1975f4f980a + const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, + ID3DBlob **error_messages); +HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob); ++HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob); +HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob); +HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob); +HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); @@ -1638,6 +1646,9 @@ index 00000000000..1975f4f980a +HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection); +HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob); + ++typedef HRESULT (WINAPI *pD3DDisassemble)(const void *data, SIZE_T data_size, ++ UINT flags, const char *comments, ID3DBlob **blob); ++ +#endif /* __D3DCOMPILER_H__ */ +#endif /* __VKD3D_D3DCOMPILER_H */ diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler_types.h b/libs/vkd3d/include/vkd3d_d3dcompiler_types.h @@ -1692,7 +1703,7 @@ index 00000000000..b3a47cdd912 +#endif /* __D3DCOMPILER_H__ */ +#endif /* __VKD3D_D3DCOMPILER_TYPES_H */ diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index 290f9085d2d..a8cc3a336a3 100644 +index 290f9085d2d..2f4478a7983 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -196,6 +196,15 @@ enum vkd3d_shader_compile_option_fragment_coordinate_origin @@ -1767,12 +1778,27 @@ index 290f9085d2d..a8cc3a336a3 100644 VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE), }; +@@ -1747,10 +1777,10 @@ struct vkd3d_shader_dxbc_desc + * \endcode + */ + #define VKD3D_SHADER_SWIZZLE(x, y, z, w) \ +- vkd3d_shader_create_swizzle(VKD3D_SHADER_SWIZZLE_ ## x, \ +- VKD3D_SHADER_SWIZZLE_ ## y, \ +- VKD3D_SHADER_SWIZZLE_ ## z, \ +- VKD3D_SHADER_SWIZZLE_ ## w) ++ (VKD3D_SHADER_SWIZZLE_ ## x << VKD3D_SHADER_SWIZZLE_SHIFT(0) \ ++ | VKD3D_SHADER_SWIZZLE_ ## y << VKD3D_SHADER_SWIZZLE_SHIFT(1) \ ++ | VKD3D_SHADER_SWIZZLE_ ## z << VKD3D_SHADER_SWIZZLE_SHIFT(2) \ ++ | VKD3D_SHADER_SWIZZLE_ ## w << VKD3D_SHADER_SWIZZLE_SHIFT(3)) + + /** The identity swizzle ".xyzw". */ + #define VKD3D_SHADER_NO_SWIZZLE VKD3D_SHADER_SWIZZLE(X, Y, Z, W) diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h new file mode 100644 -index 00000000000..adcac5fcf64 +index 00000000000..7616a3f3c46 --- /dev/null +++ b/libs/vkd3d/include/vkd3d_utils.h -@@ -0,0 +1,126 @@ +@@ -0,0 +1,128 @@ +/* + * Copyright 2016 Józef Kucia for CodeWeavers + * @@ -1892,6 +1918,8 @@ index 00000000000..adcac5fcf64 +VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob); + +/** \since 1.11 */ ++VKD3D_UTILS_API HRESULT WINAPI D3DDisassemble(const void *data, ++ SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob); +VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection); + +#ifdef __cplusplus @@ -2255,10 +2283,22 @@ index aa7df5bd764..e12cd39450a 100644 } diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 82d1d71d9d3..af939396a08 100644 +index 82d1d71d9d3..3f86bd45960 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -44,6 +44,7 @@ static const char * const shader_opcode_names[] = +@@ -30,8 +30,11 @@ + static const char * const shader_opcode_names[] = + { + [VKD3DSIH_ABS ] = "abs", ++ [VKD3DSIH_ACOS ] = "acos", + [VKD3DSIH_ADD ] = "add", + [VKD3DSIH_AND ] = "and", ++ [VKD3DSIH_ASIN ] = "asin", ++ [VKD3DSIH_ATAN ] = "atan", + [VKD3DSIH_ATOMIC_AND ] = "atomic_and", + [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", + [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", +@@ -44,6 +47,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_BEM ] = "bem", [VKD3DSIH_BFI ] = "bfi", [VKD3DSIH_BFREV ] = "bfrev", @@ -2266,7 +2306,21 @@ index 82d1d71d9d3..af939396a08 100644 [VKD3DSIH_BREAK ] = "break", [VKD3DSIH_BREAKC ] = "breakc", [VKD3DSIH_BREAKP ] = "breakp", -@@ -197,8 +198,11 @@ static const char * const shader_opcode_names[] = +@@ -167,10 +171,13 @@ static const char * const shader_opcode_names[] = + [VKD3DSIH_GATHER4_S ] = "gather4_s", + [VKD3DSIH_GEO ] = "ge", + [VKD3DSIH_GEU ] = "ge_unord", ++ [VKD3DSIH_HCOS ] = "hcos", + [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", + [VKD3DSIH_HS_DECLS ] = "hs_decls", + [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", + [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", ++ [VKD3DSIH_HSIN ] = "hsin", ++ [VKD3DSIH_HTAN ] = "htan", + [VKD3DSIH_IADD ] = "iadd", + [VKD3DSIH_IBFE ] = "ibfe", + [VKD3DSIH_IDIV ] = "idiv", +@@ -197,8 +204,11 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_IMUL ] = "imul", [VKD3DSIH_INE ] = "ine", [VKD3DSIH_INEG ] = "ineg", @@ -2278,7 +2332,7 @@ index 82d1d71d9d3..af939396a08 100644 [VKD3DSIH_ITOD ] = "itod", [VKD3DSIH_ITOF ] = "itof", [VKD3DSIH_ITOI ] = "itoi", -@@ -241,6 +245,7 @@ static const char * const shader_opcode_names[] = +@@ -241,6 +251,7 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_NRM ] = "nrm", [VKD3DSIH_OR ] = "or", [VKD3DSIH_PHASE ] = "phase", @@ -2286,7 +2340,7 @@ index 82d1d71d9d3..af939396a08 100644 [VKD3DSIH_POW ] = "pow", [VKD3DSIH_RCP ] = "rcp", [VKD3DSIH_REP ] = "rep", -@@ -278,7 +283,9 @@ static const char * const shader_opcode_names[] = +@@ -278,7 +289,9 @@ static const char * const shader_opcode_names[] = [VKD3DSIH_SUB ] = "sub", [VKD3DSIH_SWAPC ] = "swapc", [VKD3DSIH_SWITCH ] = "switch", @@ -2296,7 +2350,7 @@ index 82d1d71d9d3..af939396a08 100644 [VKD3DSIH_TEX ] = "texld", [VKD3DSIH_TEXBEM ] = "texbem", [VKD3DSIH_TEXBEML ] = "texbeml", -@@ -364,6 +371,8 @@ struct vkd3d_d3d_asm_compiler +@@ -364,6 +377,8 @@ struct vkd3d_d3d_asm_compiler struct vkd3d_string_buffer buffer; struct vkd3d_shader_version shader_version; struct vkd3d_d3d_asm_colours colours; @@ -2305,7 +2359,7 @@ index 82d1d71d9d3..af939396a08 100644 }; static int VKD3D_PRINTF_FUNC(2, 3) shader_addline(struct vkd3d_string_buffer *buffer, const char *format, ...) -@@ -437,6 +446,11 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint +@@ -437,6 +452,11 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint vkd3d_string_buffer_printf(&compiler->buffer, "_uglobal"); sync_flags &= ~VKD3DSSF_GLOBAL_UAV; } @@ -2317,7 +2371,7 @@ index 82d1d71d9d3..af939396a08 100644 if (sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY) { vkd3d_string_buffer_printf(&compiler->buffer, "_g"); -@@ -606,7 +620,7 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e +@@ -606,7 +626,7 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e vkd3d_string_buffer_printf(&compiler->buffer, "unknown"); } @@ -2326,7 +2380,7 @@ index 82d1d71d9d3..af939396a08 100644 { static const char *const data_type_names[] = { -@@ -623,19 +637,31 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -623,19 +643,31 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, const [VKD3D_DATA_DOUBLE ] = "double", [VKD3D_DATA_CONTINUED] = "", [VKD3D_DATA_UNUSED ] = "", @@ -2363,7 +2417,7 @@ index 82d1d71d9d3..af939396a08 100644 } vkd3d_string_buffer_printf(&compiler->buffer, ")"); -@@ -682,7 +708,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, +@@ -682,7 +714,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, if (semantic->resource.reg.reg.type == VKD3DSPR_UAV) shader_dump_uav_flags(compiler, flags); shader_addline(buffer, " "); @@ -2372,7 +2426,7 @@ index 82d1d71d9d3..af939396a08 100644 } else { -@@ -814,6 +840,13 @@ static void shader_print_uint_literal(struct vkd3d_d3d_asm_compiler *compiler, +@@ -814,6 +846,13 @@ static void shader_print_uint_literal(struct vkd3d_d3d_asm_compiler *compiler, prefix, compiler->colours.literal, i, compiler->colours.reset, suffix); } @@ -2386,7 +2440,7 @@ index 82d1d71d9d3..af939396a08 100644 static void shader_print_hex_literal(struct vkd3d_d3d_asm_compiler *compiler, const char *prefix, unsigned int i, const char *suffix) { -@@ -828,6 +861,27 @@ static void shader_print_bool_literal(struct vkd3d_d3d_asm_compiler *compiler, +@@ -828,6 +867,27 @@ static void shader_print_bool_literal(struct vkd3d_d3d_asm_compiler *compiler, compiler->colours.literal, b ? "true" : "false", compiler->colours.reset, suffix); } @@ -2414,7 +2468,7 @@ index 82d1d71d9d3..af939396a08 100644 static void shader_print_subscript(struct vkd3d_d3d_asm_compiler *compiler, unsigned int offset, const struct vkd3d_shader_src_param *rel_addr) { -@@ -1089,6 +1143,19 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -1089,6 +1149,19 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const if (reg->type == VKD3DSPR_IMMCONST) { @@ -2434,7 +2488,7 @@ index 82d1d71d9d3..af939396a08 100644 shader_addline(buffer, "%s(", compiler->colours.reset); switch (reg->dimension) { -@@ -1096,15 +1163,18 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -1096,15 +1169,18 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const switch (reg->data_type) { case VKD3D_DATA_FLOAT: @@ -2456,7 +2510,7 @@ index 82d1d71d9d3..af939396a08 100644 break; default: shader_addline(buffer, "", reg->data_type); -@@ -1116,24 +1186,34 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -1116,24 +1192,34 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const switch (reg->data_type) { case VKD3D_DATA_FLOAT: @@ -2503,25 +2557,25 @@ index 82d1d71d9d3..af939396a08 100644 break; default: shader_addline(buffer, "", reg->data_type); -@@ -1155,9 +1235,15 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const +@@ -1155,9 +1241,15 @@ static void shader_dump_register(struct vkd3d_d3d_asm_compiler *compiler, const { if (reg->data_type == VKD3D_DATA_DOUBLE) { - shader_print_double_literal(compiler, "", reg->u.immconst_double[0], ""); + shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], ""); - if (reg->dimension == VSIR_DIMENSION_VEC4) -- shader_print_double_literal(compiler, ", ", reg->u.immconst_double[1], ""); ++ if (reg->dimension == VSIR_DIMENSION_VEC4) + shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], ""); + } + else if (reg->data_type == VKD3D_DATA_UINT64) + { + shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], ""); -+ if (reg->dimension == VSIR_DIMENSION_VEC4) + if (reg->dimension == VSIR_DIMENSION_VEC4) +- shader_print_double_literal(compiler, ", ", reg->u.immconst_double[1], ""); + shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[1], ""); } else { -@@ -1265,6 +1351,32 @@ static void shader_print_non_uniform(struct vkd3d_d3d_asm_compiler *compiler, co +@@ -1265,6 +1357,32 @@ static void shader_print_non_uniform(struct vkd3d_d3d_asm_compiler *compiler, co compiler->colours.modifier, compiler->colours.reset); } @@ -2554,16 +2608,18 @@ index 82d1d71d9d3..af939396a08 100644 static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, const struct vkd3d_shader_dst_param *param, bool is_declaration) { -@@ -1278,7 +1390,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1277,8 +1395,8 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, + { static const char write_mask_chars[] = "xyzw"; - if (param->reg.data_type == VKD3D_DATA_DOUBLE) +- if (param->reg.data_type == VKD3D_DATA_DOUBLE) - write_mask = vkd3d_write_mask_32_from_64(write_mask); ++ if (data_type_is_64_bit(param->reg.data_type)) + write_mask = vsir_write_mask_32_from_64(write_mask); shader_addline(buffer, ".%s", compiler->colours.write_mask); if (write_mask & VKD3DSP_WRITEMASK_0) -@@ -1294,6 +1406,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1294,6 +1412,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, shader_print_precision(compiler, ¶m->reg); shader_print_non_uniform(compiler, ¶m->reg); @@ -2571,7 +2627,7 @@ index 82d1d71d9d3..af939396a08 100644 } static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, -@@ -1341,10 +1454,10 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1341,13 +1460,18 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64 && param->reg.dimension == VSIR_DIMENSION_VEC4) { @@ -2579,14 +2635,23 @@ index 82d1d71d9d3..af939396a08 100644 - unsigned int swizzle_y = vkd3d_swizzle_get_component(swizzle, 1); - unsigned int swizzle_z = vkd3d_swizzle_get_component(swizzle, 2); - unsigned int swizzle_w = vkd3d_swizzle_get_component(swizzle, 3); -+ unsigned int swizzle_x = vsir_swizzle_get_component(swizzle, 0); -+ unsigned int swizzle_y = vsir_swizzle_get_component(swizzle, 1); -+ unsigned int swizzle_z = vsir_swizzle_get_component(swizzle, 2); -+ unsigned int swizzle_w = vsir_swizzle_get_component(swizzle, 3); - +- static const char swizzle_chars[] = "xyzw"; -@@ -1367,6 +1480,7 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, ++ unsigned int swizzle_x, swizzle_y, swizzle_z, swizzle_w; ++ ++ if (data_type_is_64_bit(param->reg.data_type)) ++ swizzle = vsir_swizzle_32_from_64(swizzle); ++ ++ swizzle_x = vsir_swizzle_get_component(swizzle, 0); ++ swizzle_y = vsir_swizzle_get_component(swizzle, 1); ++ swizzle_z = vsir_swizzle_get_component(swizzle, 2); ++ swizzle_w = vsir_swizzle_get_component(swizzle, 3); ++ + if (swizzle_x == swizzle_y + && swizzle_x == swizzle_z + && swizzle_x == swizzle_w) +@@ -1367,6 +1491,7 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, shader_print_precision(compiler, ¶m->reg); shader_print_non_uniform(compiler, ¶m->reg); @@ -2594,7 +2659,7 @@ index 82d1d71d9d3..af939396a08 100644 } static void shader_dump_ins_modifiers(struct vkd3d_d3d_asm_compiler *compiler, -@@ -1577,6 +1691,12 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile +@@ -1577,6 +1702,12 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile shader_addline(buffer, "p"); break; @@ -2607,7 +2672,7 @@ index 82d1d71d9d3..af939396a08 100644 default: shader_dump_precise_flags(compiler, ins->flags); break; -@@ -1631,6 +1751,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1631,6 +1762,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, struct vkd3d_string_buffer *buffer = &compiler->buffer; unsigned int i; @@ -2616,7 +2681,7 @@ index 82d1d71d9d3..af939396a08 100644 if (ins->predicate) { vkd3d_string_buffer_printf(buffer, "("); -@@ -1835,25 +1957,25 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1835,25 +1968,25 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, vkd3d_string_buffer_printf(buffer, " %sc%u%s", compiler->colours.reg, shader_get_float_offset(ins->dst[0].reg.type, ins->dst[0].reg.idx[0].offset), compiler->colours.reset); @@ -2651,7 +2716,7 @@ index 82d1d71d9d3..af939396a08 100644 break; default: -@@ -1883,7 +2005,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1883,7 +2016,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, || ins->resource_data_type[1] != VKD3D_DATA_FLOAT || ins->resource_data_type[2] != VKD3D_DATA_FLOAT || ins->resource_data_type[3] != VKD3D_DATA_FLOAT) @@ -2660,7 +2725,7 @@ index 82d1d71d9d3..af939396a08 100644 for (i = 0; i < ins->dst_count; ++i) { -@@ -1904,12 +2026,16 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, +@@ -1904,12 +2037,16 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_addline(buffer, "\n"); } @@ -2681,7 +2746,7 @@ index 82d1d71d9d3..af939396a08 100644 enum vkd3d_result result = VKD3D_OK; struct vkd3d_string_buffer *buffer; unsigned int indent, i, j; -@@ -1973,9 +2099,9 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio +@@ -1973,9 +2110,9 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio shader_version->minor, compiler.colours.reset); indent = 0; @@ -2693,7 +2758,7 @@ index 82d1d71d9d3..af939396a08 100644 switch (ins->handler_idx) { -@@ -2002,6 +2128,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio +@@ -2002,6 +2139,7 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio { case VKD3DSIH_ELSE: case VKD3DSIH_IF: @@ -2701,7 +2766,7 @@ index 82d1d71d9d3..af939396a08 100644 case VKD3DSIH_LOOP: case VKD3DSIH_SWITCH: ++indent; -@@ -2028,13 +2155,12 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio +@@ -2028,13 +2166,12 @@ enum vkd3d_result vkd3d_dxbc_binary_to_text(const struct vkd3d_shader_instructio return result; } @@ -2718,7 +2783,7 @@ index 82d1d71d9d3..af939396a08 100644 end = (const char *)code.code + code.size; diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 3d139416b61..4ba001ea4cd 100644 +index 3d139416b61..9ad9f735dd1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -414,6 +414,7 @@ static bool has_relative_address(uint32_t param) @@ -2801,6 +2866,15 @@ index 3d139416b61..4ba001ea4cd 100644 element->interpolation_mode = VKD3DSIM_LINEAR; return true; +@@ -574,7 +587,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, + + if (!(element = find_signature_element_by_register_index(signature, register_index))) + { +- vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC, ++ vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC, + "%s register %u was used without being declared.", output ? "Output" : "Input", register_index); + return; + } @@ -585,20 +598,20 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) @@ -2934,6 +3008,24 @@ index 3d139416b61..4ba001ea4cd 100644 free_shader_desc(&sm1->p.shader_desc); vkd3d_free(sm1); } +@@ -885,7 +899,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_read_param(sm1, ptr, &token, &addr_token); + if (has_relative_address(token)) + { +- if (!(src_rel_addr = shader_parser_get_src_params(&sm1->p, 1))) ++ if (!(src_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); +@@ -906,7 +920,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_read_param(sm1, ptr, &token, &addr_token); + if (has_relative_address(token)) + { +- if (!(dst_rel_addr = shader_parser_get_src_params(&sm1->p, 1))) ++ if (!(dst_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); @@ -987,7 +1001,7 @@ static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const src_param->reg.idx[2].rel_addr = NULL; src_param->reg.idx_count = 0; @@ -2943,7 +3035,7 @@ index 3d139416b61..4ba001ea4cd 100644 src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; src_param->modifiers = 0; -@@ -1063,12 +1077,12 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, +@@ -1063,18 +1077,19 @@ static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, } } @@ -2961,16 +3053,38 @@ index 3d139416b61..4ba001ea4cd 100644 } static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins) -@@ -1097,7 +1111,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + { + struct vkd3d_shader_src_param *src_params, *predicate; + const struct vkd3d_sm1_opcode_info *opcode_info; ++ struct vsir_program *program = &sm1->p.program; + struct vkd3d_shader_dst_param *dst_param; + const uint32_t **ptr = &sm1->ptr; + uint32_t opcode_token; +@@ -1097,7 +1112,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, "Invalid opcode %#x (token 0x%08x, shader version %u.%u).", opcode_token & VKD3D_SM1_OPCODE_MASK, opcode_token, - sm1->p.shader_version.major, sm1->p.shader_version.minor); -+ sm1->p.program.shader_version.major, sm1->p.program.shader_version.minor); ++ program->shader_version.major, program->shader_version.minor); goto fail; } -@@ -1322,7 +1336,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -1107,11 +1122,11 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + ins->raw = false; + ins->structured = false; + predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED); +- ins->predicate = predicate = predicated ? shader_parser_get_src_params(&sm1->p, 1) : NULL; ++ ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL; + ins->dst_count = opcode_info->dst_count; +- ins->dst = dst_param = shader_parser_get_dst_params(&sm1->p, ins->dst_count); ++ ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count); + ins->src_count = opcode_info->src_count; +- ins->src = src_params = shader_parser_get_src_params(&sm1->p, ins->src_count); ++ ins->src = src_params = vsir_program_get_src_params(program, ins->src_count); + if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count)) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); +@@ -1322,7 +1337,7 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi return ret; } @@ -2979,7 +3093,7 @@ index 3d139416b61..4ba001ea4cd 100644 while (!shader_sm1_is_end(sm1)) { if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -@@ -1348,18 +1362,21 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -1348,18 +1363,21 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi sm1->p.shader_desc.flat_constant_count[i].external = get_external_constant_count(sm1, i); if (!sm1->p.failed) @@ -3005,7 +3119,7 @@ index 3d139416b61..4ba001ea4cd 100644 } bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, -@@ -1374,7 +1391,7 @@ bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem +@@ -1374,7 +1392,7 @@ bool hlsl_sm1_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem enum vkd3d_shader_type shader_type; unsigned int major_version; D3DSHADER_PARAM_REGISTER_TYPE type; @@ -3014,7 +3128,7 @@ index 3d139416b61..4ba001ea4cd 100644 } register_table[] = { -@@ -2253,7 +2270,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2253,7 +2271,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b { struct hlsl_reg *reg = &jump->condition.node->reg; @@ -3023,7 +3137,7 @@ index 3d139416b61..4ba001ea4cd 100644 { .opcode = D3DSIO_TEXKILL, -@@ -2263,7 +2280,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -2263,7 +2281,7 @@ static void write_sm1_jump(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b .has_dst = 1, }; @@ -3032,7 +3146,7 @@ index 3d139416b61..4ba001ea4cd 100644 break; } -@@ -2328,8 +2345,6 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ +@@ -2328,8 +2346,6 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ sm1_instr = (struct sm1_instruction) { @@ -3041,7 +3155,7 @@ index 3d139416b61..4ba001ea4cd 100644 .dst.type = D3DSPR_TEMP, .dst.reg = instr->reg.id, .dst.writemask = instr->reg.writemask, -@@ -2345,8 +2360,22 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ +@@ -2345,8 +2361,22 @@ static void write_sm1_resource_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ .src_count = 2, }; @@ -3224,10 +3338,10 @@ index 7834c1e1615..37ebc73c099 100644 WARN("Invalid data size %#x (offset %u, count %u).\n", context->data_size, offset, count); return VKD3D_ERROR_INVALID_ARGUMENT; diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index beb9ae574dc..8a31d03c531 100644 +index beb9ae574dc..a001f6f0642 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -29,6 +29,9 @@ static const uint64_t MAX_ALIGNMENT_EXPONENT = 29; +@@ -29,10 +29,18 @@ static const uint64_t MAX_ALIGNMENT_EXPONENT = 29; static const uint64_t GLOBALVAR_FLAG_IS_CONSTANT = 1; static const uint64_t GLOBALVAR_FLAG_EXPLICIT_TYPE = 2; static const unsigned int GLOBALVAR_ADDRESS_SPACE_SHIFT = 2; @@ -3235,9 +3349,18 @@ index beb9ae574dc..8a31d03c531 100644 +static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE = 0x40; +static const uint64_t ALLOCA_ALIGNMENT_MASK = ALLOCA_FLAG_IN_ALLOCA - 1; static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4; ++static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 5; static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64}; -@@ -168,6 +171,35 @@ enum bitcode_linkage + ++#define VKD3D_SHADER_SWIZZLE_64_MASK \ ++ (VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(0) \ ++ | VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(1)) ++ + enum bitcode_block_id + { + BLOCKINFO_BLOCK = 0, +@@ -168,6 +176,35 @@ enum bitcode_linkage LINKAGE_INTERNAL = 3, }; @@ -3273,7 +3396,7 @@ index beb9ae574dc..8a31d03c531 100644 enum dxil_component_type { COMPONENT_TYPE_INVALID = 0, -@@ -296,8 +328,41 @@ enum dx_intrinsic_opcode +@@ -296,8 +333,53 @@ enum dx_intrinsic_opcode { DX_LOAD_INPUT = 4, DX_STORE_OUTPUT = 5, @@ -3283,6 +3406,12 @@ index beb9ae574dc..8a31d03c531 100644 + DX_COS = 12, + DX_SIN = 13, + DX_TAN = 14, ++ DX_ACOS = 15, ++ DX_ASIN = 16, ++ DX_ATAN = 17, ++ DX_HCOS = 18, ++ DX_HSIN = 19, ++ DX_HTAN = 20, + DX_EXP = 21, + DX_FRC = 22, + DX_LOG = 23, @@ -3303,19 +3432,25 @@ index beb9ae574dc..8a31d03c531 100644 + DX_IMIN = 38, + DX_UMAX = 39, + DX_UMIN = 40, ++ DX_IBFE = 51, ++ DX_UBFE = 52, DX_CREATE_HANDLE = 57, DX_CBUFFER_LOAD_LEGACY = 59, ++ DX_TEXTURE_LOAD = 66, ++ DX_TEXTURE_STORE = 67, + DX_BUFFER_LOAD = 68, + DX_DERIV_COARSEX = 83, + DX_DERIV_COARSEY = 84, + DX_DERIV_FINEX = 85, + DX_DERIV_FINEY = 86, ++ DX_SPLIT_DOUBLE = 102, + DX_LEGACY_F32TOF16 = 130, + DX_LEGACY_F16TOF32 = 131, ++ DX_RAW_BUFFER_LOAD = 139, }; enum dxil_cast_code -@@ -439,6 +504,7 @@ struct dxil_record +@@ -439,6 +521,7 @@ struct dxil_record { unsigned int code; unsigned int operand_count; @@ -3323,7 +3458,7 @@ index beb9ae574dc..8a31d03c531 100644 uint64_t operands[]; }; -@@ -448,18 +514,67 @@ struct sm6_symbol +@@ -448,18 +531,67 @@ struct sm6_symbol const char *name; }; @@ -3392,7 +3527,7 @@ index beb9ae574dc..8a31d03c531 100644 size_t block_count; size_t value_count; -@@ -541,6 +656,11 @@ struct sm6_descriptor_info +@@ -541,6 +673,11 @@ struct sm6_descriptor_info enum vkd3d_shader_descriptor_type type; unsigned int id; struct vkd3d_shader_register_range range; @@ -3404,7 +3539,7 @@ index beb9ae574dc..8a31d03c531 100644 }; struct sm6_parser -@@ -581,6 +701,7 @@ struct sm6_parser +@@ -581,6 +718,7 @@ struct sm6_parser size_t descriptor_count; unsigned int indexable_temp_count; @@ -3412,7 +3547,7 @@ index beb9ae574dc..8a31d03c531 100644 struct sm6_value *values; size_t value_count; -@@ -796,6 +917,7 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6) +@@ -796,6 +934,7 @@ static enum vkd3d_result sm6_parser_read_unabbrev_record(struct sm6_parser *sm6) record->code = code; record->operand_count = count; @@ -3420,7 +3555,7 @@ index beb9ae574dc..8a31d03c531 100644 for (i = 0; i < count; ++i) record->operands[i] = sm6_parser_read_vbr(sm6, 6); -@@ -1012,6 +1134,7 @@ static enum vkd3d_result sm6_parser_read_abbrev_record(struct sm6_parser *sm6, u +@@ -1012,6 +1151,7 @@ static enum vkd3d_result sm6_parser_read_abbrev_record(struct sm6_parser *sm6, u if (!abbrev->operands[i + 1].read_operand(sm6, abbrev->operands[i + 1].context, &record->operands[i])) goto fail; record->operand_count = count; @@ -3428,7 +3563,7 @@ index beb9ae574dc..8a31d03c531 100644 /* An array can occur only as the last operand. */ if (abbrev->is_array) -@@ -1210,7 +1333,7 @@ static size_t dxil_block_compute_module_decl_count(const struct dxil_block *bloc +@@ -1210,7 +1350,7 @@ static size_t dxil_block_compute_module_decl_count(const struct dxil_block *bloc size_t i, count; for (i = 0, count = 0; i < block->record_count; ++i) @@ -3437,7 +3572,7 @@ index beb9ae574dc..8a31d03c531 100644 return count; } -@@ -1517,7 +1640,7 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6) +@@ -1517,7 +1657,7 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6) break; } @@ -3446,7 +3581,7 @@ index beb9ae574dc..8a31d03c531 100644 sm6->handle_type = type; type->u.struc->name = struct_name; -@@ -1572,6 +1695,11 @@ static bool sm6_type_is_bool_i16_i32_i64(const struct sm6_type *type) +@@ -1572,6 +1712,11 @@ static bool sm6_type_is_bool_i16_i32_i64(const struct sm6_type *type) return type->class == TYPE_CLASS_INTEGER && (type->u.width == 1 || type->u.width >= 16); } @@ -3458,7 +3593,7 @@ index beb9ae574dc..8a31d03c531 100644 static bool sm6_type_is_bool(const struct sm6_type *type) { return type->class == TYPE_CLASS_INTEGER && type->u.width == 1; -@@ -1587,6 +1715,16 @@ static inline bool sm6_type_is_i32(const struct sm6_type *type) +@@ -1587,6 +1732,21 @@ static inline bool sm6_type_is_i32(const struct sm6_type *type) return type->class == TYPE_CLASS_INTEGER && type->u.width == 32; } @@ -3471,11 +3606,16 @@ index beb9ae574dc..8a31d03c531 100644 +{ + return type->class == TYPE_CLASS_FLOAT && (type->u.width == 16 || type->u.width == 32); +} ++ ++static bool sm6_type_is_double(const struct sm6_type *type) ++{ ++ return type->class == TYPE_CLASS_FLOAT && type->u.width == 64; ++} + static inline bool sm6_type_is_floating_point(const struct sm6_type *type) { return type->class == TYPE_CLASS_FLOAT; -@@ -1844,12 +1982,12 @@ static unsigned int register_get_uint_value(const struct vkd3d_shader_register * +@@ -1844,12 +2004,12 @@ static unsigned int register_get_uint_value(const struct vkd3d_shader_register * if (reg->type == VKD3DSPR_IMMCONST64) { @@ -3491,7 +3631,7 @@ index beb9ae574dc..8a31d03c531 100644 } static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg) -@@ -1860,7 +1998,7 @@ static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *re +@@ -1860,7 +2020,7 @@ static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *re if (reg->dimension == VSIR_DIMENSION_VEC4) WARN("Returning vec4.x.\n"); @@ -3500,7 +3640,7 @@ index beb9ae574dc..8a31d03c531 100644 } static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) -@@ -1895,6 +2033,12 @@ static inline bool sm6_value_is_constant(const struct sm6_value *value) +@@ -1895,6 +2055,12 @@ static inline bool sm6_value_is_constant(const struct sm6_value *value) return sm6_value_is_register(value) && register_is_constant(&value->u.reg); } @@ -3513,7 +3653,7 @@ index beb9ae574dc..8a31d03c531 100644 static inline bool sm6_value_is_undef(const struct sm6_value *value) { return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF; -@@ -1905,6 +2049,11 @@ static bool sm6_value_is_icb(const struct sm6_value *value) +@@ -1905,6 +2071,11 @@ static bool sm6_value_is_icb(const struct sm6_value *value) return value->value_type == VALUE_TYPE_ICB; } @@ -3525,7 +3665,7 @@ index beb9ae574dc..8a31d03c531 100644 static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) { if (!sm6_value_is_constant(value)) -@@ -1912,11 +2061,25 @@ static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *v +@@ -1912,16 +2083,33 @@ static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *v return register_get_uint_value(&value->u.reg); } @@ -3546,12 +3686,219 @@ index beb9ae574dc..8a31d03c531 100644 +{ + vsir_instruction_init(ins, &sm6->p.location, handler_idx); + ins->resource_type = resource->u.handle.d->resource_type; ++ ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; ++ ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER; +} + static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, unsigned int count, struct sm6_parser *sm6) { -@@ -2289,8 +2452,8 @@ static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm +- struct vkd3d_shader_src_param *params = shader_parser_get_src_params(&sm6->p, count); +- if (!params) ++ struct vkd3d_shader_src_param *params; ++ ++ if (!(params = vsir_program_get_src_params(&sm6->p.program, count))) + { + ERR("Failed to allocate src params.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -1936,8 +2124,9 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ + static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_shader_instruction *ins, + unsigned int count, struct sm6_parser *sm6) + { +- struct vkd3d_shader_dst_param *params = shader_parser_get_dst_params(&sm6->p, count); +- if (!params) ++ struct vkd3d_shader_dst_param *params; ++ ++ if (!(params = vsir_program_get_dst_params(&sm6->p.program, count))) + { + ERR("Failed to allocate dst params.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -1994,21 +2183,29 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type + } + + static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type, +- unsigned int component_count, struct sm6_parser *sm6) ++ unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6) + { + enum vkd3d_data_type data_type; + unsigned int id; + +- id = sm6_parser_alloc_ssa_id(sm6); ++ if (value && register_is_ssa(&value->u.reg) && value->u.reg.idx[0].offset) ++ { ++ id = value->u.reg.idx[0].offset; ++ TRACE("Using forward-allocated id %u.\n", id); ++ } ++ else ++ { ++ id = sm6_parser_alloc_ssa_id(sm6); ++ } + data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0)); + register_init_with_id(reg, VKD3DSPR_SSA, data_type, id); + reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; + } + + static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, +- struct sm6_parser *sm6) ++ struct sm6_value *value, struct sm6_parser *sm6) + { +- register_init_ssa_vector(reg, type, 1, sm6); ++ register_init_ssa_vector(reg, sm6_type_get_scalar_type(type, 0), 1, value, sm6); + } + + static void dst_param_init(struct vkd3d_shader_dst_param *param) +@@ -2018,6 +2215,13 @@ static void dst_param_init(struct vkd3d_shader_dst_param *param) + param->shift = 0; + } + ++static void dst_param_init_with_mask(struct vkd3d_shader_dst_param *param, unsigned int mask) ++{ ++ param->write_mask = mask; ++ param->modifiers = 0; ++ param->shift = 0; ++} ++ + static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx) + { + param->write_mask = 1u << component_idx; +@@ -2033,10 +2237,10 @@ static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned + } + + static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, +- struct sm6_parser *sm6) ++ struct sm6_value *value, struct sm6_parser *sm6) + { + dst_param_init(param); +- register_init_ssa_scalar(¶m->reg, type, sm6); ++ register_init_ssa_scalar(¶m->reg, type, value, sm6); + } + + static inline void src_param_init(struct vkd3d_shader_src_param *param) +@@ -2048,6 +2252,8 @@ static inline void src_param_init(struct vkd3d_shader_src_param *param) + static void src_param_init_scalar(struct vkd3d_shader_src_param *param, unsigned int component_idx) + { + param->swizzle = vkd3d_shader_create_swizzle(component_idx, component_idx, component_idx, component_idx); ++ if (data_type_is_64_bit(param->reg.data_type)) ++ param->swizzle &= VKD3D_SHADER_SWIZZLE_64_MASK; + param->modifiers = VKD3DSPSM_NONE; + } + +@@ -2078,7 +2284,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, + } + else + { +- struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&sm6->p, 1); ++ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&sm6->p.program, 1); + if (rel_addr) + src_param_init_from_value(rel_addr, address); + idx->offset = 0; +@@ -2091,7 +2297,7 @@ static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio + struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6); + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + +- dst_param_init_ssa_scalar(param, dst->type, sm6); ++ dst_param_init_ssa_scalar(param, dst->type, dst, sm6); + param->write_mask = VKD3DSP_WRITEMASK_0; + dst->u.reg = param->reg; + } +@@ -2103,7 +2309,7 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio + struct sm6_value *dst = sm6_parser_get_current_value(sm6); + + dst_param_init_vector(param, component_count); +- register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, sm6); ++ register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, dst, sm6); + dst->u.reg = param->reg; + } + +@@ -2195,6 +2401,26 @@ static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct s + return true; + } + ++static bool sm6_value_validate_is_texture_handle(const struct sm6_value *value, enum dx_intrinsic_opcode op, ++ struct sm6_parser *sm6) ++{ ++ enum dxil_resource_kind kind; ++ ++ if (!sm6_value_validate_is_handle(value, sm6)) ++ return false; ++ ++ kind = value->u.handle.d->kind; ++ if (kind < RESOURCE_KIND_TEXTURE1D || kind > RESOURCE_KIND_TEXTURECUBEARRAY) ++ { ++ WARN("Resource kind %u for op %u is not a texture.\n", kind, op); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE, ++ "Resource kind %u for texture operation %u is not a texture.", kind, op); ++ return false; ++ } ++ ++ return true; ++} ++ + static bool sm6_value_validate_is_pointer(const struct sm6_value *value, struct sm6_parser *sm6) + { + if (!sm6_type_is_pointer(value->type)) +@@ -2246,6 +2472,7 @@ static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, + 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) + { ++ struct sm6_value *value; + unsigned int idx; + uint64_t val_ref; + size_t operand; +@@ -2259,23 +2486,39 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru + if (operand == SIZE_MAX) + return SIZE_MAX; + +- if (operand >= sm6->value_count) ++ if (operand >= sm6->value_count && !fwd_type) ++ { ++ /* Forward references are followed by a type id unless an earlier operand set the type, ++ * or it is contained in a function declaration. */ ++ if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) ++ return SIZE_MAX; ++ if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++]))) ++ return SIZE_MAX; ++ } ++ *rec_idx = idx; ++ ++ if (fwd_type) + { +- if (!fwd_type) ++ value = &sm6->values[operand]; ++ if (value->type) + { +- /* Forward references are followed by a type id unless an earlier operand set the type, +- * or it is contained in a function declaration. */ +- if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) +- return SIZE_MAX; +- if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++]))) +- return SIZE_MAX; ++ if (value->type != fwd_type) ++ { ++ WARN("Value already has a mismatching type.\n"); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, ++ "The type of a source value does not match the predefined type."); ++ } ++ } ++ else ++ { ++ value->type = fwd_type; ++ value->value_type = VALUE_TYPE_REG; ++ register_init_with_id(&value->u.reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type( ++ sm6_type_get_scalar_type(fwd_type, 0)), sm6_parser_alloc_ssa_id(sm6)); ++ value->u.reg.dimension = sm6_type_is_scalar(fwd_type) ? VSIR_DIMENSION_SCALAR ++ : VSIR_DIMENSION_VEC4; + } +- FIXME("Forward value references are not supported yet.\n"); +- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, +- "Unsupported value forward reference."); +- return SIZE_MAX; + } +- *rec_idx = idx; + + return operand; + } +@@ -2289,8 +2532,8 @@ static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxil_record *record) { @@ -3561,7 +3908,7 @@ index beb9ae574dc..8a31d03c531 100644 struct sm6_value *fn; unsigned int i, j; -@@ -2305,18 +2468,18 @@ static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxi +@@ -2305,18 +2548,18 @@ static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxi fn->u.function.name = ""; } @@ -3585,7 +3932,7 @@ index beb9ae574dc..8a31d03c531 100644 return false; } -@@ -2412,7 +2575,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co +@@ -2412,7 +2655,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co return VKD3D_ERROR_INVALID_SHADER; } size = max(size, sizeof(icb->data[0])); @@ -3594,7 +3941,7 @@ index beb9ae574dc..8a31d03c531 100644 if (!(icb = vkd3d_malloc(offsetof(struct vkd3d_shader_immediate_constant_buffer, data[count])))) { -@@ -2421,7 +2584,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co +@@ -2421,7 +2664,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co "Out of memory allocating an immediate constant buffer of count %u.", count); return VKD3D_ERROR_OUT_OF_MEMORY; } @@ -3603,7 +3950,7 @@ index beb9ae574dc..8a31d03c531 100644 { ERR("Failed to store icb object.\n"); vkd3d_free(icb); -@@ -2433,9 +2596,14 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co +@@ -2433,9 +2676,14 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co dst->value_type = VALUE_TYPE_ICB; dst->u.icb = icb; @@ -3618,7 +3965,7 @@ index beb9ae574dc..8a31d03c531 100644 count = type->u.array.count; if (size > sizeof(icb->data[0])) -@@ -2510,12 +2678,10 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const +@@ -2510,12 +2758,10 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const switch (record->code) { case CST_CODE_NULL: @@ -3634,7 +3981,7 @@ index beb9ae574dc..8a31d03c531 100644 } /* For non-aggregates, register constant data is already zero-filled. */ break; -@@ -2532,9 +2698,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const +@@ -2532,9 +2778,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const value = decode_rotated_signed_value(record->operands[0]); if (type->u.width <= 32) @@ -3646,7 +3993,7 @@ index beb9ae574dc..8a31d03c531 100644 break; -@@ -2551,9 +2717,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const +@@ -2551,9 +2797,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const if (type->u.width == 16) FIXME("Half float type is not supported yet.\n"); else if (type->u.width == 32) @@ -3658,7 +4005,7 @@ index beb9ae574dc..8a31d03c531 100644 else vkd3d_unreachable(); -@@ -2588,6 +2754,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const +@@ -2588,6 +2834,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const break; } @@ -3672,7 +4019,7 @@ index beb9ae574dc..8a31d03c531 100644 ++sm6->value_count; } -@@ -2607,12 +2780,12 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al +@@ -2607,12 +2860,12 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra) { @@ -3687,7 +4034,7 @@ index beb9ae574dc..8a31d03c531 100644 } /* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */ -@@ -2622,22 +2795,38 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa +@@ -2622,22 +2875,38 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); assert(ins); vsir_instruction_init(ins, &sm6->p.location, handler_idx); @@ -3730,7 +4077,7 @@ index beb9ae574dc..8a31d03c531 100644 /* The initialiser value index will be resolved later so forward references can be handled. */ ins->declaration.indexable_temp.initialiser = (void *)(uintptr_t)init; -@@ -2762,7 +2951,10 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ +@@ -2762,7 +3031,10 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_ if (address_space == ADDRESS_SPACE_DEFAULT) { @@ -3742,7 +4089,7 @@ index beb9ae574dc..8a31d03c531 100644 } else if (address_space == ADDRESS_SPACE_GROUPSHARED) { -@@ -2790,31 +2982,37 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init +@@ -2790,31 +3062,37 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init assert(index); --index; @@ -3783,7 +4130,7 @@ index beb9ae574dc..8a31d03c531 100644 for (i = 0; i < block->record_count; ++i) { sm6->p.location.column = i; -@@ -2860,14 +3058,29 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) +@@ -2860,14 +3138,29 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) } /* Resolve initialiser forward references. */ @@ -3815,7 +4162,23 @@ index beb9ae574dc..8a31d03c531 100644 } return VKD3D_OK; -@@ -2908,45 +3121,6 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade +@@ -2887,6 +3180,15 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, + param->reg.dimension = VSIR_DIMENSION_VEC4; + } + ++static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, ++ const struct sm6_value **operands, unsigned int count) ++{ ++ unsigned int i; ++ ++ for (i = 0; i < count; ++i) ++ src_param_init_from_value(&src_params[i], operands[i]); ++} ++ + static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, + enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) + { +@@ -2908,45 +3210,6 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade } } @@ -3861,7 +4224,7 @@ index beb9ae574dc..8a31d03c531 100644 static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) { sm6_parser_init_signature(sm6, output_signature, VKD3DSPR_OUTPUT, sm6->output_params); -@@ -2957,19 +3131,6 @@ static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct +@@ -2957,19 +3220,6 @@ static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct sm6_parser_init_signature(sm6, input_signature, VKD3DSPR_INPUT, sm6->input_params); } @@ -3881,7 +4244,7 @@ index beb9ae574dc..8a31d03c531 100644 static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6) { size_t i, count = sm6->function_count; -@@ -2992,6 +3153,107 @@ static struct sm6_block *sm6_block_create() +@@ -2992,6 +3242,108 @@ static struct sm6_block *sm6_block_create() return block; } @@ -3909,6 +4272,7 @@ index beb9ae574dc..8a31d03c531 100644 +{ + struct sm6_block *code_block; + struct vkd3d_shader_instruction *ins; ++ unsigned int temp_idx; +}; + +static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record, @@ -3989,7 +4353,7 @@ index beb9ae574dc..8a31d03c531 100644 static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, const struct sm6_type *type_b, struct sm6_parser *sm6) { -@@ -3092,8 +3354,10 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +@@ -3092,8 +3444,10 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco unsigned int i = 0; a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i); @@ -4001,7 +4365,14 @@ index beb9ae574dc..8a31d03c531 100644 return; if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6)) -@@ -3167,14 +3431,181 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco +@@ -3161,52 +3515,322 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); +- register_init_ssa_scalar(&dst_params[index].reg, a->type, sm6); ++ register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6); + vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + dst->u.reg = dst_params[index].reg; } else { @@ -4019,7 +4390,28 @@ index beb9ae574dc..8a31d03c531 100644 - enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) +static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, + struct sm6_parser *sm6) -+{ + { +- struct sm6_value *dst = sm6_parser_get_current_value(sm6); +- struct vkd3d_shader_src_param *src_param; +- const struct sm6_value *buffer; +- const struct sm6_type *type; +- +- buffer = operands[0]; +- if (!sm6_value_validate_is_handle(buffer, sm6)) +- return; +- +- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); +- +- src_param = instruction_src_params_alloc(ins, 1, sm6); +- src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); +- register_index_address_init(&src_param->reg.idx[2], operands[1], sm6); +- assert(src_param->reg.idx_count == 3); +- +- type = sm6_type_get_scalar_type(dst->type, 0); +- assert(type); +- src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); +- +- instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); + if (index >= function->block_count) + { + WARN("Invalid code block index %#"PRIx64".\n", index); @@ -4028,16 +4420,23 @@ index beb9ae574dc..8a31d03c531 100644 + return NULL; + } + return function->blocks[index]; -+} -+ + } + +-static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, +- enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address) +static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record *record, + struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) -+{ + { +- const struct sm6_descriptor_info *d; +- unsigned int register_index; +- size_t i; + const struct sm6_value *value; + unsigned int i = 2; -+ + +- for (i = 0; i < sm6->descriptor_count; ++i) + if (record->operand_count != 1 && record->operand_count < 3) -+ { + { +- d = &sm6->descriptors[i]; + WARN("Invalid operand count %u.\n", record->operand_count); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + "Invalid operand count %u for a branch instruction.", record->operand_count); @@ -4072,6 +4471,95 @@ index beb9ae574dc..8a31d03c531 100644 + ins->handler_idx = VKD3DSIH_NOP; +} + ++static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, ++ unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) ++{ ++ struct vkd3d_shader_instruction *ins = state->ins; ++ struct vkd3d_shader_src_param *src_params; ++ struct vkd3d_shader_dst_param *dst_param; ++ bool all_constant = true; ++ unsigned int i; ++ ++ if (component_count == 1) ++ { ++ *reg = *operand_regs[0]; ++ return true; ++ } ++ ++ for (i = 0; i < component_count; ++i) ++ all_constant &= register_is_constant(operand_regs[i]); ++ ++ if (all_constant) ++ { ++ vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0]->data_type, 0); ++ reg->dimension = VSIR_DIMENSION_VEC4; ++ for (i = 0; i < component_count; ++i) ++ reg->u.immconst_u32[i] = operand_regs[i]->u.immconst_u32[0]; ++ for (; i < VKD3D_VEC4_SIZE; ++i) ++ reg->u.immconst_u32[i] = 0; ++ return true; ++ } ++ ++ register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0]->data_type, state->temp_idx++); ++ reg->dimension = VSIR_DIMENSION_VEC4; ++ ++ for (i = 0; i < component_count; ++i, ++ins) ++ { ++ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); ++ ++ if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) ++ return false; ++ ++ src_param_init(&src_params[0]); ++ src_params[0].reg = *operand_regs[i]; ++ ++ if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) ++ return false; ++ ++ dst_param_init_scalar(dst_param, i); ++ dst_param->reg = *reg; ++ } ++ ++ state->ins = ins; ++ state->code_block->instruction_count += component_count; ++ ++ return true; ++} ++ ++static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const struct sm6_value **operands, ++ unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) ++{ ++ const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; ++ unsigned int i; ++ ++ for (i = 0; i < component_count; ++i) ++ operand_regs[i] = &operands[i]->u.reg; ++ ++ return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); ++} ++ ++static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, ++ const struct sm6_value *z_operand, struct function_emission_state *state, ++ struct vkd3d_shader_register *reg) ++{ ++ const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; ++ const unsigned int max_operands = 3; ++ unsigned int component_count; ++ ++ for (component_count = 0; component_count < max_operands; ++component_count) ++ { ++ if (!z_operand && operands[component_count]->is_undefined) ++ break; ++ operand_regs[component_count] = &operands[component_count]->u.reg; ++ } ++ if (z_operand) ++ { ++ operand_regs[component_count++] = &z_operand->u.reg; ++ } ++ ++ return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); ++} ++ +static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) +{ + switch (op) @@ -4084,6 +4572,18 @@ index beb9ae574dc..8a31d03c531 100644 + return VKD3DSIH_ISFINITE; + case DX_TAN: + return VKD3DSIH_TAN; ++ case DX_ACOS: ++ return VKD3DSIH_ACOS; ++ case DX_ASIN: ++ return VKD3DSIH_ASIN; ++ case DX_ATAN: ++ return VKD3DSIH_ATAN; ++ case DX_HCOS: ++ return VKD3DSIH_HCOS; ++ case DX_HSIN: ++ return VKD3DSIH_HSIN; ++ case DX_HTAN: ++ return VKD3DSIH_HTAN; + case DX_EXP: + return VKD3DSIH_EXP; + case DX_FRC: @@ -4179,13 +4679,47 @@ index beb9ae574dc..8a31d03c531 100644 + +static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) - { - struct sm6_value *dst = sm6_parser_get_current_value(sm6); ++{ ++ struct sm6_value *dst = sm6_parser_get_current_value(sm6); + struct vkd3d_shader_instruction *ins = state->ins; - struct vkd3d_shader_src_param *src_param; - const struct sm6_value *buffer; - const struct sm6_type *type; -@@ -3222,9 +3653,10 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa ++ struct vkd3d_shader_src_param *src_param; ++ const struct sm6_value *buffer; ++ const struct sm6_type *type; ++ ++ buffer = operands[0]; ++ if (!sm6_value_validate_is_handle(buffer, sm6)) ++ return; ++ ++ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); ++ ++ src_param = instruction_src_params_alloc(ins, 1, sm6); ++ src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); ++ register_index_address_init(&src_param->reg.idx[2], operands[1], sm6); ++ assert(src_param->reg.idx_count == 3); ++ ++ type = sm6_type_get_scalar_type(dst->type, 0); ++ assert(type); ++ src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); ++ if (data_type_is_64_bit(src_param->reg.data_type)) ++ src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); ++ ++ instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); ++} ++ ++static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, ++ enum vkd3d_shader_descriptor_type type, unsigned int id, const struct sm6_value *address) ++{ ++ const struct sm6_descriptor_info *d; ++ unsigned int register_index; ++ size_t i; ++ ++ for (i = 0; i < sm6->descriptor_count; ++i) ++ { ++ d = &sm6->descriptors[i]; + + if (d->type != type || d->id != id) + continue; +@@ -3222,9 +3846,10 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa return NULL; } @@ -4198,7 +4732,7 @@ index beb9ae574dc..8a31d03c531 100644 enum vkd3d_shader_descriptor_type type; const struct sm6_descriptor_info *d; struct vkd3d_shader_register *reg; -@@ -3246,9 +3678,9 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_ +@@ -3246,9 +3871,9 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_ dst->u.handle.d = d; reg = &dst->u.handle.reg; @@ -4211,12 +4745,40 @@ index beb9ae574dc..8a31d03c531 100644 reg->idx[0].offset = id; register_index_address_init(®->idx[1], operands[2], sm6); reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]); -@@ -3257,9 +3689,10 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_ +@@ -3257,9 +3882,38 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, struct sm6_ ins->handler_idx = VKD3DSIH_NOP; } -static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_block *code_block, - enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) ++static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode op) ++{ ++ switch (op) ++ { ++ case DX_IBFE: ++ return VKD3DSIH_IBFE; ++ case DX_UBFE: ++ return VKD3DSIH_UBFE; ++ default: ++ vkd3d_unreachable(); ++ } ++} ++ ++static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ struct vkd3d_shader_instruction *ins = state->ins; ++ struct vkd3d_shader_src_param *src_params; ++ unsigned int i; ++ ++ vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_tertiary_op(op)); ++ src_params = instruction_src_params_alloc(ins, 3, sm6); ++ for (i = 0; i < 3; ++i) ++ src_param_init_from_value(&src_params[i], operands[i]); ++ ++ instruction_dst_param_init_ssa_scalar(ins, sm6); ++} ++ +static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) { @@ -4224,47 +4786,74 @@ index beb9ae574dc..8a31d03c531 100644 struct vkd3d_shader_src_param *src_param; const struct shader_signature *signature; unsigned int row_index, column_index; -@@ -3289,35 +3722,93 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_blo +@@ -3289,9 +3943,142 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, struct sm6_blo instruction_dst_param_init_ssa_scalar(ins, sm6); } -static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_block *code_block, - enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct vkd3d_shader_instruction *ins) -+static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) - { -- struct vkd3d_shader_src_param *src_param; -- struct vkd3d_shader_dst_param *dst_param; -- const struct shader_signature *signature; -- unsigned int row_index, column_index; -- const struct signature_element *e; -- const struct sm6_value *value; -- -- row_index = sm6_value_get_constant_uint(operands[0]); -- column_index = sm6_value_get_constant_uint(operands[2]); ++{ ++ unsigned int operand_count, write_mask, component_count = VKD3D_VEC4_SIZE; + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_params; + const struct sm6_value *resource; - -- signature = &sm6->p.shader_desc.output_signature; -- if (row_index >= signature->element_count) -- { -- WARN("Invalid row index %u.\n", row_index); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "Invalid output row index %u.", row_index); ++ bool raw; ++ + resource = operands[0]; + if (!sm6_value_validate_is_handle(resource, sm6)) - return; -- } -- e = &signature->elements[row_index]; - -- if (column_index >= VKD3D_VEC4_SIZE) ++ return; ++ raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; ++ ++ if (op == DX_RAW_BUFFER_LOAD) ++ { ++ write_mask = sm6_value_get_constant_uint(operands[3]); ++ if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) ++ { ++ WARN("Invalid write mask %#x.\n", write_mask); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Write mask %#x for a raw/structured buffer load operation is invalid.", write_mask); ++ return; ++ } ++ else if (write_mask & (write_mask + 1)) ++ { ++ FIXME("Unhandled write mask %#x.\n", write_mask); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Write mask %#x for a raw/structured buffer load operation is unhandled.", write_mask); ++ } ++ component_count = vsir_write_mask_component_count(write_mask); ++ } ++ ++ instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6); ++ operand_count = 2 + !raw; ++ if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) ++ return; ++ src_params_init_from_operands(src_params, &operands[1], operand_count - 1); ++ src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg); ++ ++ instruction_dst_param_init_ssa_vector(ins, component_count, sm6); ++} ++ ++static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ struct vkd3d_shader_instruction *ins = state->ins; ++ struct vkd3d_shader_src_param *src_params; ++ const struct sm6_value *resource; ++ ++ resource = operands[0]; ++ if (!sm6_value_validate_is_handle(resource, sm6)) ++ return; ++ ++ if (resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER ++ || resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER) ++ { ++ return sm6_parser_emit_dx_raw_buffer_load(sm6, op, operands, state); ++ } ++ + if (resource->u.handle.d->kind != RESOURCE_KIND_TYPEDBUFFER) - { -- WARN("Invalid column index %u.\n", column_index); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "Invalid output column index %u.", column_index); -- return; ++ { + WARN("Resource is not a typed buffer.\n"); + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION, + "Resource for a typed buffer load is not a typed buffer."); @@ -4287,6 +4876,19 @@ index beb9ae574dc..8a31d03c531 100644 + instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); +} + ++static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value) ++{ ++ return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value); ++} ++ ++static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, ++ const struct sm6_value **operands, struct sm6_parser *sm6) ++{ ++ ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]); ++ ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]); ++ ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); ++} ++ +static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ @@ -4304,46 +4906,129 @@ index beb9ae574dc..8a31d03c531 100644 + dst_params = instruction_dst_params_alloc(ins, 2, sm6); + dst_param_init(&dst_params[0]); + dst_param_init(&dst_params[1]); -+ register_init_ssa_scalar(&dst_params[index].reg, dst->type, sm6); ++ register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6); + vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + dst->u.reg = dst_params[index].reg; +} + -+static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) +{ + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; -+ struct vkd3d_shader_dst_param *dst_param; -+ const struct shader_signature *signature; -+ unsigned int row_index, column_index; -+ const struct signature_element *e; -+ const struct sm6_value *value; + -+ row_index = sm6_value_get_constant_uint(operands[0]); -+ column_index = sm6_value_get_constant_uint(operands[2]); ++ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); ++ src_param = instruction_src_params_alloc(ins, 1, sm6); ++ src_param_init_from_value(src_param, operands[0]); + -+ signature = &sm6->p.shader_desc.output_signature; -+ if (row_index >= signature->element_count) ++ instruction_dst_param_init_ssa_vector(ins, 2, sm6); ++} ++ ++static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) + { ++ struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_dst_param *dst_param; + const struct shader_signature *signature; +@@ -3342,33 +4129,181 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b + src_param_init_from_value(src_param, value); + } + ++static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ const struct sm6_value *resource, *mip_level_or_sample_count; ++ enum vkd3d_shader_resource_type resource_type; ++ struct vkd3d_shader_src_param *src_params; ++ struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_register coord; ++ bool is_multisample, is_uav; ++ unsigned int i; ++ ++ resource = operands[0]; ++ if (!sm6_value_validate_is_texture_handle(resource, op, sm6)) ++ return; ++ ++ resource_type = resource->u.handle.d->resource_type; ++ is_multisample = resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS ++ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY; ++ is_uav = resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; ++ ++ mip_level_or_sample_count = (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) ? operands[1] : NULL; ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], ++ is_multisample ? NULL : mip_level_or_sample_count, state, &coord)) + { -+ WARN("Invalid row index %u.\n", row_index); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Invalid output row index %u.", row_index); + return; + } -+ e = &signature->elements[row_index]; + -+ if (column_index >= VKD3D_VEC4_SIZE) -+ { -+ WARN("Invalid column index %u.\n", column_index); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Invalid output column index %u.", column_index); ++ ins = state->ins; ++ instruction_init_with_resource(ins, is_uav ? VKD3DSIH_LD_UAV_TYPED ++ : is_multisample ? VKD3DSIH_LD2DMS : VKD3DSIH_LD, resource, sm6); ++ instruction_set_texel_offset(ins, &operands[5], sm6); ++ ++ for (i = 0; i < VKD3D_VEC4_SIZE; ++i) ++ ins->resource_data_type[i] = resource->u.handle.d->resource_data_type; ++ ++ src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6); ++ src_param_init_vector_from_reg(&src_params[0], &coord); ++ src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); ++ if (is_multisample) ++ src_param_init_from_value(&src_params[2], mip_level_or_sample_count); ++ ++ instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); ++} ++ ++static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ struct vkd3d_shader_register coord, texel; ++ struct vkd3d_shader_src_param *src_params; ++ struct vkd3d_shader_dst_param *dst_param; ++ unsigned int write_mask, component_count; ++ struct vkd3d_shader_instruction *ins; ++ const struct sm6_value *resource; ++ ++ resource = operands[0]; ++ if (!sm6_value_validate_is_texture_handle(resource, op, sm6)) + return; - } - - value = operands[3]; -@@ -3344,31 +3835,70 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, struct sm6_b - ++ ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], NULL, state, &coord)) ++ return; ++ ++ write_mask = sm6_value_get_constant_uint(operands[8]); ++ if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) ++ { ++ WARN("Invalid write mask %#x.\n", write_mask); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Write mask %#x for a texture store operation is invalid.", write_mask); ++ return; ++ } ++ else if (write_mask & (write_mask + 1)) ++ { ++ /* In this case, it is unclear which source operands will be defined unless we encounter it in a shader. */ ++ FIXME("Unhandled write mask %#x.\n", write_mask); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Write mask %#x for a texture store operation is unhandled.", write_mask); ++ } ++ component_count = vsir_write_mask_component_count(write_mask); ++ ++ if (!sm6_parser_emit_composite_construct(sm6, &operands[4], component_count, state, &texel)) ++ return; ++ ++ ins = state->ins; ++ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED); ++ ++ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) ++ return; ++ src_param_init_vector_from_reg(&src_params[0], &coord); ++ src_param_init_vector_from_reg(&src_params[1], &texel); ++ ++ dst_param = instruction_dst_params_alloc(ins, 1, sm6); ++ dst_param->reg = resource->u.handle.reg; ++ dst_param_init_with_mask(dst_param, write_mask); ++} ++ struct sm6_dx_opcode_info { - const char ret_type; @@ -4360,12 +5045,15 @@ index beb9ae574dc..8a31d03c531 100644 8 -> int8 b -> constant int1 c -> constant int8/16/32 ++ C -> constant or undefined int8/16/32 i -> int32 + m -> int16/32/64 + f -> float ++ d -> double + e -> half/float + g -> half/float/double H -> handle ++ S -> splitdouble v -> void o -> overloaded + R -> matches the return type @@ -4376,6 +5064,9 @@ index beb9ae574dc..8a31d03c531 100644 - [DX_CREATE_HANDLE ] = {'H', "ccib", sm6_parser_emit_dx_create_handle}, - [DX_LOAD_INPUT ] = {'o', "ii8i", sm6_parser_emit_dx_load_input}, - [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output}, ++ [DX_ACOS ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_ASIN ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_ATAN ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary}, + [DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load}, + [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, @@ -4393,6 +5084,10 @@ index beb9ae574dc..8a31d03c531 100644 + [DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary}, + [DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary}, + [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, ++ [DX_HCOS ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_HSIN ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_HTAN ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary}, @@ -4402,15 +5097,20 @@ index beb9ae574dc..8a31d03c531 100644 + [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary}, + [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input}, + [DX_LOG ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_RAW_BUFFER_LOAD ] = {"o", "Hii8i", sm6_parser_emit_dx_raw_buffer_load}, + [DX_ROUND_NE ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_ROUND_NI ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, ++ [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, + [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, + [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load}, ++ [DX_TEXTURE_STORE ] = {"v", "Hiiiooooc", sm6_parser_emit_dx_texture_store}, ++ [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, + [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, + [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, }; @@ -4421,7 +5121,7 @@ index beb9ae574dc..8a31d03c531 100644 { const struct sm6_type *type = value->type; -@@ -3380,6 +3910,8 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc +@@ -3380,6 +4315,8 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 0: FIXME("Invalid operand count.\n"); return false; @@ -4430,22 +5130,31 @@ index beb9ae574dc..8a31d03c531 100644 case '8': return sm6_type_is_i8(type); case 'b': -@@ -3389,6 +3921,14 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc +@@ -3387,15 +4324,32 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc + case 'c': + return sm6_value_is_constant(value) && sm6_type_is_integer(type) && type->u.width >= 8 && type->u.width <= 32; ++ case 'C': ++ return (sm6_value_is_constant(value) || sm6_value_is_undef(value)) ++ && sm6_type_is_integer(type) && type->u.width >= 8 && type->u.width <= 32; case 'i': return sm6_type_is_i32(type); + case 'm': + return sm6_type_is_i16_i32_i64(type); + case 'f': + return sm6_type_is_float(type); ++ case 'd': ++ return sm6_type_is_double(type); + case 'e': + return sm6_type_is_f16_f32(type); + case 'g': + return sm6_type_is_floating_point(type); case 'H': return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type; ++ case 'S': ++ return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.splitdouble"); case 'v': -@@ -3396,6 +3936,8 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc + return !type; case 'o': /* TODO: some type checking may be possible */ return true; @@ -4454,7 +5163,7 @@ index beb9ae574dc..8a31d03c531 100644 default: FIXME("Unhandled operand code '%c'.\n", info_type); return false; -@@ -3410,7 +3952,8 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -3410,7 +4364,8 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ info = &sm6_dx_op_table[op]; @@ -4464,7 +5173,7 @@ index beb9ae574dc..8a31d03c531 100644 { WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name); /* Return type validation failure is not so critical. We only need to set -@@ -3420,7 +3963,7 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ +@@ -3420,7 +4375,7 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ for (i = 0; i < operand_count; ++i) { const struct sm6_value *value = operands[i]; @@ -4473,7 +5182,7 @@ index beb9ae574dc..8a31d03c531 100644 { WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -@@ -3454,27 +3997,27 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade +@@ -3454,27 +4409,27 @@ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shade /* dst->is_undefined is not set here because it flags only explicitly undefined values. */ } @@ -4507,7 +5216,7 @@ index beb9ae574dc..8a31d03c531 100644 { const struct sm6_value *operands[DXIL_OP_MAX_OPERANDS]; const struct sm6_value *fn_value, *op_value; -@@ -3556,8 +4099,8 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor +@@ -3556,8 +4511,8 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor "Expected a constant integer dx intrinsic function id."); return; } @@ -4518,7 +5227,7 @@ index beb9ae574dc..8a31d03c531 100644 } static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from, -@@ -3700,6 +4243,9 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor +@@ -3700,6 +4655,9 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor if (handler_idx == VKD3DSIH_NOP) { dst->u.reg = value->u.reg; @@ -4528,7 +5237,7 @@ index beb9ae574dc..8a31d03c531 100644 return; } -@@ -3775,8 +4321,10 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor +@@ -3775,8 +4733,10 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor } a = sm6_parser_get_value_by_ref(sm6, record, NULL, &i); @@ -4540,21 +5249,46 @@ index beb9ae574dc..8a31d03c531 100644 return; if (!dxil_record_validate_operand_count(record, i + 1, i + 2, sm6)) -@@ -4053,6 +4601,102 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor +@@ -3896,8 +4856,8 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + + src_param = instruction_src_params_alloc(ins, 1, sm6); +- src_param_init_from_value(src_param, src); +- src_param->swizzle = vkd3d_shader_create_swizzle(elem_idx, elem_idx, elem_idx, elem_idx); ++ src_param->reg = src->u.reg; ++ src_param_init_scalar(src_param, elem_idx); + + instruction_dst_param_init_ssa_scalar(ins, sm6); + } +@@ -4053,25 +5013,257 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor instruction_dst_param_init_ssa_scalar(ins, sm6); } +-static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record *record, +- struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) +static int phi_incoming_compare(const void *a, const void *b) -+{ + { +- if (!dxil_record_validate_operand_count(record, 0, 1, sm6)) +- return; +- +- if (record->operand_count) +- FIXME("Non-void return is not implemented.\n"); + const struct incoming_value *incoming_a = a, *incoming_b = b; -+ + +- ins->handler_idx = VKD3DSIH_NOP; + return (incoming_a->block > incoming_b->block) - (incoming_a->block < incoming_b->block); -+} -+ + } + +-static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, +- struct vkd3d_shader_instruction *ins, struct sm6_value *dst) +static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record *record, + struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, + struct sm6_value *dst) -+{ + { +- struct vkd3d_shader_src_param *src_params; +- const struct sm6_value *src[3]; +- unsigned int i = 0; +- + struct incoming_value *incoming; + const struct sm6_type *type; + struct sm6_phi *phi; @@ -4581,7 +5315,7 @@ index beb9ae574dc..8a31d03c531 100644 + } + + dst->type = type; -+ register_init_ssa_scalar(&dst->u.reg, type, sm6); ++ register_init_ssa_scalar(&dst->u.reg, type, dst, sm6); + + if (!(phi = sm6_block_phi_require_space(code_block, sm6))) + return; @@ -4640,13 +5374,15 @@ index beb9ae574dc..8a31d03c531 100644 + phi->incoming_count = j; +} + - static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) - { -@@ -4062,6 +4706,142 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record - if (record->operand_count) - FIXME("Non-void return is not implemented.\n"); - ++static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record *record, ++ struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) ++{ ++ if (!dxil_record_validate_operand_count(record, 0, 1, sm6)) ++ return; ++ ++ if (record->operand_count) ++ FIXME("Non-void return is not implemented.\n"); ++ + code_block->terminator.type = TERMINATOR_RET; + + ins->handler_idx = VKD3DSIH_NOP; @@ -4783,10 +5519,20 @@ index beb9ae574dc..8a31d03c531 100644 + terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src); + } + - ins->handler_idx = VKD3DSIH_NOP; - } - -@@ -4115,6 +4895,12 @@ static bool sm6_metadata_value_is_string(const struct sm6_metadata_value *m) ++ ins->handler_idx = VKD3DSIH_NOP; ++} ++ ++static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, ++ struct vkd3d_shader_instruction *ins, struct sm6_value *dst) ++{ ++ struct vkd3d_shader_src_param *src_params; ++ const struct sm6_value *src[3]; ++ unsigned int i = 0; ++ + if (!(src[1] = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)) + || !(src[2] = sm6_parser_get_value_by_ref(sm6, record, src[1]->type, &i)) + || !(src[0] = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))) +@@ -4115,6 +5307,12 @@ static bool sm6_metadata_value_is_string(const struct sm6_metadata_value *m) return m && m->type == VKD3D_METADATA_STRING; } @@ -4799,7 +5545,7 @@ index beb9ae574dc..8a31d03c531 100644 static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, const struct sm6_metadata_value *m, unsigned int *u) { -@@ -4153,6 +4939,272 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, +@@ -4153,12 +5351,279 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, return true; } @@ -5072,7 +5818,14 @@ index beb9ae574dc..8a31d03c531 100644 static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, struct sm6_function *function) { -@@ -4192,16 +5244,18 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + struct vkd3d_shader_instruction *ins; + size_t i, block_idx, block_count; + const struct dxil_record *record; ++ const struct sm6_type *fwd_type; + bool ret_found, is_terminator; + struct sm6_block *code_block; + struct sm6_value *dst; +@@ -4192,16 +5657,18 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const WARN("Function contains no blocks.\n"); return VKD3D_ERROR_INVALID_SHADER; } @@ -5099,7 +5852,7 @@ index beb9ae574dc..8a31d03c531 100644 } function->block_count = block_count; code_block = function->blocks[0]; -@@ -4220,10 +5274,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const +@@ -4220,10 +5687,10 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; } @@ -5108,11 +5861,20 @@ index beb9ae574dc..8a31d03c531 100644 + /* Some instructions can emit >1 IR instruction, so extra may be used. */ if (!vkd3d_array_reserve((void **)&code_block->instructions, &code_block->instruction_capacity, - max(code_block->instruction_count + 1, block->record_count), sizeof(*code_block->instructions))) -+ code_block->instruction_count + 1, sizeof(*code_block->instructions))) ++ code_block->instruction_count + MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION, ++ sizeof(*code_block->instructions))) { ERR("Failed to allocate instructions.\n"); return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -4240,12 +5293,22 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const +@@ -4233,6 +5700,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const + ins->handler_idx = VKD3DSIH_INVALID; + + dst = sm6_parser_get_current_value(sm6); ++ fwd_type = dst->type; + dst->type = NULL; + dst->value_type = VALUE_TYPE_REG; + is_terminator = false; +@@ -4240,12 +5708,23 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const record = block->records[i]; switch (record->code) { @@ -5131,12 +5893,13 @@ index beb9ae574dc..8a31d03c531 100644 + { + struct function_emission_state state = {code_block, ins}; + sm6_parser_emit_call(sm6, record, &state, dst); ++ sm6->p.program.temp_count = max(sm6->p.program.temp_count, state.temp_idx); break; + } case FUNC_CODE_INST_CAST: sm6_parser_emit_cast(sm6, record, ins, dst); break; -@@ -4261,11 +5324,21 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const +@@ -4261,11 +5740,21 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const case FUNC_CODE_INST_LOAD: sm6_parser_emit_load(sm6, record, ins, dst); break; @@ -5158,34 +5921,57 @@ index beb9ae574dc..8a31d03c531 100644 case FUNC_CODE_INST_VSELECT: sm6_parser_emit_vselect(sm6, record, ins, dst); break; -@@ -4278,6 +5351,9 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const +@@ -4278,41 +5767,159 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_ERROR; assert(ins->handler_idx != VKD3DSIH_INVALID); +- if (is_terminator) +- { +- ++block_idx; +- code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL; +- } +- if (code_block) +- code_block->instruction_count += ins->handler_idx != VKD3DSIH_NOP; +- else +- assert(ins->handler_idx == VKD3DSIH_NOP); + if (record->attachment) + metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6); + - if (is_terminator) - { - ++block_idx; -@@ -4297,22 +5373,130 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - return VKD3D_ERROR_INVALID_SHADER; - } - -- return VKD3D_OK; ++ if (is_terminator) ++ { ++ ++block_idx; ++ code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL; ++ } ++ if (code_block) ++ code_block->instruction_count += ins->handler_idx != VKD3DSIH_NOP; ++ else ++ assert(ins->handler_idx == VKD3DSIH_NOP); ++ ++ if (dst->type && fwd_type && dst->type != fwd_type) ++ { ++ WARN("Type mismatch.\n"); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, ++ "The type of a result value does not match the type defined by a forward reference."); ++ } ++ ++ sm6->value_count += !!dst->type; ++ } ++ ++ if (!ret_found) ++ { ++ WARN("Function contains no RET instruction.\n"); ++ return VKD3D_ERROR_INVALID_SHADER; ++ } ++ + return sm6_function_resolve_phi_incomings(function, sm6); - } - --static bool sm6_block_emit_instructions(struct sm6_block *block, struct sm6_parser *sm6) ++} ++ +static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_parser *sm6) - { -- struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, block->instruction_count + 1); ++{ + struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_instruction *ins; + unsigned int i, count; - -- if (!ins) -- return false; ++ + switch (block->terminator.type) + { + case TERMINATOR_UNCOND_BR: @@ -5208,9 +5994,7 @@ index beb9ae574dc..8a31d03c531 100644 + vsir_src_param_init_label(&src_params[1], block->terminator.true_block->id); + vsir_src_param_init_label(&src_params[2], block->terminator.false_block->id); + break; - -- memcpy(ins, block->instructions, block->instruction_count * sizeof(*block->instructions)); -- sm6->p.instructions.count += block->instruction_count; ++ + case TERMINATOR_SWITCH: + ins = sm6_parser_add_instruction(sm6, VKD3DSIH_SWITCH_MONOLITHIC); + if (!(src_params = instruction_src_params_alloc(ins, block->terminator.case_count * 2u + 1, sm6))) @@ -5219,14 +6003,12 @@ index beb9ae574dc..8a31d03c531 100644 + src_params[0].reg = block->terminator.conditional_reg; + /* TODO: emit the merge block id. */ + vsir_src_param_init_label(&src_params[2], 0); - -- sm6_parser_add_instruction(sm6, VKD3DSIH_RET); ++ + for (i = 0, count = 3; i < block->terminator.case_count; ++i) + { + const struct terminator_case *switch_case; + const struct sm6_block *case_block; - -- return true; ++ + switch_case = &block->terminator.cases[i]; + if (!(case_block = switch_case->block)) + { @@ -5259,36 +6041,52 @@ index beb9ae574dc..8a31d03c531 100644 + } + + break; -+ + +- sm6->value_count += !!dst->type; +- } + case TERMINATOR_RET: + sm6_parser_add_instruction(sm6, VKD3DSIH_RET); + break; -+ + +- if (!ret_found) +- { +- WARN("Function contains no RET instruction.\n"); +- return VKD3D_ERROR_INVALID_SHADER; + default: + vkd3d_unreachable(); -+ } -+} -+ + } +- +- return VKD3D_OK; + } + +-static bool sm6_block_emit_instructions(struct sm6_block *block, struct sm6_parser *sm6) +static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser *sm6) -+{ + { +- struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, block->instruction_count + 1); + struct vkd3d_shader_instruction *ins; + unsigned int i, j, incoming_count; + const struct sm6_phi *src_phi; -+ + +- if (!ins) +- return false; + for (i = 0; i < block->phi_count; ++i) + { + struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_dst_param *dst_param; -+ + +- memcpy(ins, block->instructions, block->instruction_count * sizeof(*block->instructions)); +- sm6->p.instructions.count += block->instruction_count; + src_phi = &block->phi[i]; + incoming_count = src_phi->incoming_count; -+ + +- sm6_parser_add_instruction(sm6, VKD3DSIH_RET); + ins = sm6_parser_add_instruction(sm6, VKD3DSIH_PHI); + if (!(src_params = instruction_src_params_alloc(ins, incoming_count * 2u, sm6))) + return; + if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) + return; -+ + +- return true; + for (j = 0; j < incoming_count; ++j) + { + const struct sm6_block *incoming_block = src_phi->incoming[j].block; @@ -5308,7 +6106,7 @@ index beb9ae574dc..8a31d03c531 100644 } static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const struct dxil_block *block, -@@ -4331,6 +5515,8 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st +@@ -4331,6 +5938,8 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st sm6->p.location.line = block->id; sm6->p.location.column = 0; @@ -5317,7 +6115,7 @@ index beb9ae574dc..8a31d03c531 100644 switch (block->id) { case CONSTANTS_BLOCK: -@@ -4370,6 +5556,48 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st +@@ -4370,6 +5979,48 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st return VKD3D_OK; } @@ -5366,7 +6164,7 @@ index beb9ae574dc..8a31d03c531 100644 static bool sm6_parser_allocate_named_metadata(struct sm6_parser *sm6) { struct dxil_block *block; -@@ -4644,8 +5872,10 @@ static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component +@@ -4644,8 +6295,10 @@ static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] = { [SEMANTIC_KIND_ARBITRARY] = VKD3D_SHADER_SV_NONE, @@ -5378,7 +6176,7 @@ index beb9ae574dc..8a31d03c531 100644 }; static enum vkd3d_shader_sysval_semantic sysval_semantic_from_dxil_semantic_kind(enum dxil_semantic_kind kind) -@@ -4727,6 +5957,288 @@ static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6, +@@ -4727,6 +6380,332 @@ static bool sm6_parser_resources_load_register_range(struct sm6_parser *sm6, return true; } @@ -5400,6 +6198,8 @@ index beb9ae574dc..8a31d03c531 100644 + switch (kind) + { + case RESOURCE_KIND_TYPEDBUFFER: ++ case RESOURCE_KIND_RAWBUFFER: ++ case RESOURCE_KIND_STRUCTUREDBUFFER: + return VKD3D_SHADER_RESOURCE_BUFFER; + default: + return VKD3D_SHADER_RESOURCE_NONE; @@ -5464,6 +6264,13 @@ index beb9ae574dc..8a31d03c531 100644 + } + ins->resource_type = resource_type; + ++ if (!m) ++ { ++ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; ++ ins->declaration.raw_resource.resource.reg.write_mask = 0; ++ return &ins->declaration.raw_resource.resource; ++ } ++ + if (!sm6_metadata_value_is_node(m)) + { + WARN("Resource metadata list is not a node.\n"); @@ -5518,6 +6325,39 @@ index beb9ae574dc..8a31d03c531 100644 + + return &ins->declaration.semantic.resource; + } ++ else if (dxil_resource_type == RESOURCE_TYPE_RAW_STRUCTURED) ++ { ++ if (kind == RESOURCE_KIND_RAWBUFFER) ++ { ++ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; ++ ins->declaration.raw_resource.resource.reg.write_mask = 0; ++ ++ return &ins->declaration.raw_resource.resource; ++ } ++ ++ if (kind != RESOURCE_KIND_STRUCTUREDBUFFER) ++ { ++ WARN("Unhandled resource kind %u.\n", kind); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, ++ "Resource kind %u for a raw or structured buffer is unhandled.", kind); ++ return NULL; ++ } ++ ++ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED; ++ ins->declaration.structured_resource.byte_stride = values[1]; ++ ins->declaration.structured_resource.resource.reg.write_mask = 0; ++ ++ /* TODO: 16-bit resources. */ ++ if (ins->declaration.structured_resource.byte_stride % 4u) ++ { ++ WARN("Byte stride %u is not a multiple of 4.\n", ins->declaration.structured_resource.byte_stride); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, ++ "Structured resource byte stride %u is not a multiple of 4.", ++ ins->declaration.structured_resource.byte_stride); ++ } ++ ++ return &ins->declaration.structured_resource.resource; ++ } + else + { + FIXME("Unhandled resource type %u.\n", dxil_resource_type); @@ -5584,7 +6424,8 @@ index beb9ae574dc..8a31d03c531 100644 + d->kind = kind; + d->reg_type = VKD3DSPR_RESOURCE; + d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_RESOURCE; -+ d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; ++ d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL) ++ ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; + + init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range); + @@ -5657,7 +6498,8 @@ index beb9ae574dc..8a31d03c531 100644 + d->kind = values[0]; + d->reg_type = VKD3DSPR_UAV; + d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_UAV; -+ d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; ++ d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL_UAV_TYPED) ++ ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; + + init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range); + @@ -5667,7 +6509,7 @@ index beb9ae574dc..8a31d03c531 100644 static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) { -@@ -4769,6 +6281,10 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, +@@ -4769,6 +6748,10 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, ins->declaration.cb.range = d->range; @@ -5678,7 +6520,7 @@ index beb9ae574dc..8a31d03c531 100644 return VKD3D_OK; } -@@ -4840,6 +6356,14 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, +@@ -4840,6 +6823,14 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0) return ret; break; @@ -5693,7 +6535,7 @@ index beb9ae574dc..8a31d03c531 100644 default: FIXME("Unsupported descriptor type %u.\n", type); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, -@@ -4848,7 +6372,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, +@@ -4848,7 +6839,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, } ++sm6->descriptor_count; @@ -5702,7 +6544,7 @@ index beb9ae574dc..8a31d03c531 100644 } return VKD3D_OK; -@@ -5198,9 +6722,9 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co +@@ -5198,9 +7189,9 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co unsigned int group_sizes[3]; unsigned int i; @@ -5714,7 +6556,7 @@ index beb9ae574dc..8a31d03c531 100644 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; -@@ -5285,7 +6809,7 @@ static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6) +@@ -5285,7 +7276,7 @@ static enum vkd3d_result sm6_parser_entry_point_init(struct sm6_parser *sm6) sm6->entry_point = value->u.function.name; if (!sm6_metadata_value_is_string(entry_node->operands[1]) @@ -5723,7 +6565,7 @@ index beb9ae574dc..8a31d03c531 100644 { WARN("Entry point function name %s mismatch.\n", sm6->entry_point); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_ENTRY_POINT_MISMATCH, -@@ -5419,9 +6943,20 @@ static void sm6_symtab_cleanup(struct sm6_symbol *symbols, size_t count) +@@ -5419,9 +7410,20 @@ static void sm6_symtab_cleanup(struct sm6_symbol *symbols, size_t count) vkd3d_free(symbols); } @@ -5744,7 +6586,7 @@ index beb9ae574dc..8a31d03c531 100644 vkd3d_free(block); } -@@ -5433,6 +6968,7 @@ static void sm6_functions_cleanup(struct sm6_function *functions, size_t count) +@@ -5433,6 +7435,7 @@ static void sm6_functions_cleanup(struct sm6_function *functions, size_t count) { for (j = 0; j < functions[i].block_count; ++j) sm6_block_destroy(functions[i].blocks[j]); @@ -5752,7 +6594,7 @@ index beb9ae574dc..8a31d03c531 100644 } vkd3d_free(functions); } -@@ -5443,7 +6979,7 @@ static void sm6_parser_destroy(struct vkd3d_shader_parser *parser) +@@ -5443,7 +7446,7 @@ static void sm6_parser_destroy(struct vkd3d_shader_parser *parser) dxil_block_destroy(&sm6->root_block); dxil_global_abbrevs_cleanup(sm6->abbrevs, sm6->abbrev_count); @@ -5761,7 +6603,7 @@ index beb9ae574dc..8a31d03c531 100644 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); -@@ -5463,7 +6999,7 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6 +@@ -5463,7 +7466,7 @@ static struct sm6_function *sm6_parser_get_function(const struct sm6_parser *sm6 { size_t i; for (i = 0; i < sm6->function_count; ++i) @@ -5770,7 +6612,7 @@ index beb9ae574dc..8a31d03c531 100644 return &sm6->functions[i]; return NULL; } -@@ -5538,7 +7074,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5538,7 +7541,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if ((magic = sm6->start[0]) != BITCODE_MAGIC) { WARN("Unknown magic number 0x%08x.\n", magic); @@ -5779,7 +6621,7 @@ index beb9ae574dc..8a31d03c531 100644 "DXIL bitcode chunk magic number 0x%08x is not the expected 0x%08x.", magic, BITCODE_MAGIC); } -@@ -5547,7 +7083,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5547,7 +7550,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if ((version.type = version_token >> 16) >= VKD3D_SHADER_TYPE_COUNT) { FIXME("Unknown shader type %#x.\n", version.type); @@ -5788,7 +6630,7 @@ index beb9ae574dc..8a31d03c531 100644 "Unknown shader type %#x.", version.type); } -@@ -5573,10 +7109,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5573,10 +7576,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if ((ret = dxil_block_init(block, NULL, sm6)) < 0) { if (ret == VKD3D_ERROR_OUT_OF_MEMORY) @@ -5801,7 +6643,7 @@ index beb9ae574dc..8a31d03c531 100644 "DXIL bitcode chunk has invalid bitcode."); else vkd3d_unreachable(); -@@ -5606,10 +7142,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5606,10 +7609,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if ((ret = sm6_parser_type_table_init(sm6)) < 0) { if (ret == VKD3D_ERROR_OUT_OF_MEMORY) @@ -5814,7 +6656,7 @@ index beb9ae574dc..8a31d03c531 100644 "DXIL type table is invalid."); else vkd3d_unreachable(); -@@ -5619,10 +7155,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5619,21 +7622,21 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if ((ret = sm6_parser_symtab_init(sm6)) < 0) { if (ret == VKD3D_ERROR_OUT_OF_MEMORY) @@ -5827,8 +6669,13 @@ index beb9ae574dc..8a31d03c531 100644 "DXIL value symbol table is invalid."); else vkd3d_unreachable(); -@@ -5633,7 +7169,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t - || !(sm6->input_params = shader_parser_get_dst_params(&sm6->p, input_signature->element_count))) + return ret; + } + +- if (!(sm6->output_params = shader_parser_get_dst_params(&sm6->p, output_signature->element_count)) +- || !(sm6->input_params = shader_parser_get_dst_params(&sm6->p, input_signature->element_count))) ++ if (!(sm6->output_params = vsir_program_get_dst_params(&sm6->p.program, output_signature->element_count)) ++ || !(sm6->input_params = vsir_program_get_dst_params(&sm6->p.program, input_signature->element_count))) { ERR("Failed to allocate input/output parameters.\n"); - vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, @@ -5836,7 +6683,7 @@ index beb9ae574dc..8a31d03c531 100644 "Out of memory allocating input/output parameters."); return VKD3D_ERROR_OUT_OF_MEMORY; } -@@ -5642,7 +7178,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5642,7 +7645,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if (!(sm6->functions = vkd3d_calloc(function_count, sizeof(*sm6->functions)))) { ERR("Failed to allocate function array.\n"); @@ -5845,7 +6692,7 @@ index beb9ae574dc..8a31d03c531 100644 "Out of memory allocating DXIL function array."); return VKD3D_ERROR_OUT_OF_MEMORY; } -@@ -5650,14 +7186,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5650,14 +7653,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if (sm6_parser_compute_max_value_count(sm6, &sm6->root_block, 0) == SIZE_MAX) { WARN("Value array count overflowed.\n"); @@ -5862,7 +6709,7 @@ index beb9ae574dc..8a31d03c531 100644 "Out of memory allocating DXIL value array."); return VKD3D_ERROR_OUT_OF_MEMORY; } -@@ -5684,7 +7220,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5684,7 +7687,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if (j == ARRAY_SIZE(sm6->metadata_tables)) { FIXME("Too many metadata tables.\n"); @@ -5871,7 +6718,7 @@ index beb9ae574dc..8a31d03c531 100644 "A metadata table count greater than %zu is unsupported.", ARRAY_SIZE(sm6->metadata_tables)); return VKD3D_ERROR_INVALID_SHADER; } -@@ -5702,24 +7238,22 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5702,24 +7705,22 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0) { if (ret == VKD3D_ERROR_OUT_OF_MEMORY) @@ -5900,7 +6747,7 @@ index beb9ae574dc..8a31d03c531 100644 if (!(fn = sm6_parser_get_function(sm6, sm6->entry_point))) { -@@ -5730,12 +7264,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t +@@ -5730,12 +7731,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t } assert(sm6->function_count == 1); @@ -5915,7 +6762,7 @@ index beb9ae574dc..8a31d03c531 100644 dxil_block_destroy(&sm6->root_block); -@@ -5786,7 +7316,7 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -5786,7 +7783,7 @@ int vkd3d_shader_sm6_parser_create(const struct vkd3d_shader_compile_info *compi vkd3d_free(byte_code); if (!sm6->p.failed && ret >= 0) @@ -7493,7 +8340,7 @@ index 0dde4c18587..8dc353e11c0 100644 $$ = $1; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 4a622185741..1fe141a346a 100644 +index 4a622185741..6ad60e4c6c2 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -32,6 +32,11 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str @@ -7700,7 +8547,187 @@ index 4a622185741..1fe141a346a 100644 if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc))) return false; -@@ -4973,6 +5012,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4084,13 +4123,46 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { +- if (var->is_uniform && var->last_read) ++ unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; ++ ++ if (!var->is_uniform || !var->last_read || reg_size == 0) ++ continue; ++ ++ if (var->reg_reservation.reg_type == 'c') + { +- unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; ++ unsigned int reg_idx = var->reg_reservation.reg_index; ++ unsigned int i; + +- if (reg_size == 0) +- continue; ++ assert(reg_size % 4 == 0); ++ for (i = 0; i < reg_size / 4; ++i) ++ { ++ if (get_available_writemask(&allocator, 1, UINT_MAX, reg_idx + i) != VKD3DSP_WRITEMASK_ALL) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, ++ "Overlapping register() reservations on 'c%u'.", reg_idx + i); ++ } ++ ++ record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX); ++ } ++ ++ var->regs[HLSL_REGSET_NUMERIC].id = reg_idx; ++ var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4; ++ var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL; ++ var->regs[HLSL_REGSET_NUMERIC].allocated = true; ++ TRACE("Allocated reserved %s to %s.\n", var->name, ++ debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); ++ } ++ } + ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; ++ ++ if (!var->is_uniform || !var->last_read || reg_size == 0) ++ continue; ++ ++ if (!var->regs[HLSL_REGSET_NUMERIC].allocated) ++ { + var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, &allocator, + 1, UINT_MAX, var->data_type); + TRACE("Allocated %s to %s.\n", var->name, +@@ -4230,45 +4302,52 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3 + return NULL; + } + +-static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) ++static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, bool register_reservation) + { + unsigned int var_reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; + enum hlsl_type_class var_class = var->data_type->class; + struct hlsl_buffer *buffer = var->buffer; + +- if (var->reg_reservation.offset_type == 'c') ++ if (register_reservation) ++ { ++ var->buffer_offset = 4 * var->reg_reservation.reg_index; ++ } ++ else + { +- if (var->reg_reservation.offset_index % 4) ++ if (var->reg_reservation.offset_type == 'c') + { +- if (var_class == HLSL_CLASS_MATRIX) +- { +- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, +- "packoffset() reservations with matrix types must be aligned with the beginning of a register."); +- } +- else if (var_class == HLSL_CLASS_ARRAY) ++ if (var->reg_reservation.offset_index % 4) + { +- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, +- "packoffset() reservations with array types must be aligned with the beginning of a register."); +- } +- else if (var_class == HLSL_CLASS_STRUCT) +- { +- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, +- "packoffset() reservations with struct types must be aligned with the beginning of a register."); +- } +- else if (var_class == HLSL_CLASS_VECTOR) +- { +- unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index); +- +- if (var->reg_reservation.offset_index != aligned_offset) ++ if (var_class == HLSL_CLASS_MATRIX) ++ { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, +- "packoffset() reservations with vector types cannot span multiple registers."); ++ "packoffset() reservations with matrix types must be aligned with the beginning of a register."); ++ } ++ else if (var_class == HLSL_CLASS_ARRAY) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, ++ "packoffset() reservations with array types must be aligned with the beginning of a register."); ++ } ++ else if (var_class == HLSL_CLASS_STRUCT) ++ { ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, ++ "packoffset() reservations with struct types must be aligned with the beginning of a register."); ++ } ++ else if (var_class == HLSL_CLASS_VECTOR) ++ { ++ unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index); ++ ++ if (var->reg_reservation.offset_index != aligned_offset) ++ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, ++ "packoffset() reservations with vector types cannot span multiple registers."); ++ } + } ++ var->buffer_offset = var->reg_reservation.offset_index; ++ } ++ else ++ { ++ var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size); + } +- var->buffer_offset = var->reg_reservation.offset_index; +- } +- else +- { +- var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size); + } + + TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name); +@@ -4337,6 +4416,11 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx) + } + } + ++static bool var_has_buffer_offset_register_reservation(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var) ++{ ++ return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; ++} ++ + static void allocate_buffers(struct hlsl_ctx *ctx) + { + struct hlsl_buffer *buffer; +@@ -4345,13 +4429,29 @@ static void allocate_buffers(struct hlsl_ctx *ctx) + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { +- if (var->is_uniform && !hlsl_type_is_resource(var->data_type)) +- { +- if (var->is_param) +- var->buffer = ctx->params_buffer; ++ if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) ++ continue; + +- calculate_buffer_offset(ctx, var); +- } ++ if (var->is_param) ++ var->buffer = ctx->params_buffer; ++ } ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) ++ continue; ++ ++ if (var_has_buffer_offset_register_reservation(ctx, var)) ++ calculate_buffer_offset(ctx, var, true); ++ } ++ ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) ++ continue; ++ ++ if (!var_has_buffer_offset_register_reservation(ctx, var)) ++ calculate_buffer_offset(ctx, var, false); + } + + validate_buffer_offsets(ctx); +@@ -4973,6 +5073,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry lower_ir(ctx, lower_abs, body); } @@ -7710,7 +8737,7 @@ index 4a622185741..1fe141a346a 100644 transform_derefs(ctx, replace_deref_path_with_offset, body); while (hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL)); diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 710811c6761..9079be48b4f 100644 +index 710811c6761..88634487482 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -18,15 +18,32 @@ @@ -7766,7 +8793,7 @@ index 710811c6761..9079be48b4f 100644 + } +} + -+static bool vsir_instruction_init_with_params(struct vkd3d_shader_parser *parser, ++static bool vsir_instruction_init_with_params(struct vsir_program *program, + struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, + enum vkd3d_shader_opcode handler_idx, unsigned int dst_count, unsigned int src_count) +{ @@ -7774,13 +8801,13 @@ index 710811c6761..9079be48b4f 100644 + ins->dst_count = dst_count; + ins->src_count = src_count; + -+ if (!(ins->dst = shader_parser_get_dst_params(parser, ins->dst_count))) ++ if (!(ins->dst = vsir_program_get_dst_params(program, ins->dst_count))) + { + ERR("Failed to allocate %u destination parameters.\n", dst_count); + return false; + } + -+ if (!(ins->src = shader_parser_get_src_params(parser, ins->src_count))) ++ if (!(ins->src = vsir_program_get_src_params(program, ins->src_count))) + { + ERR("Failed to allocate %u source parameters.\n", src_count); + return false; @@ -7816,7 +8843,7 @@ index 710811c6761..9079be48b4f 100644 + /* tmp = ins->dst[0] < 0 */ + + ins = &instructions->elements[i + 1]; -+ if (!vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2)) ++ if (!vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); @@ -7839,7 +8866,7 @@ index 710811c6761..9079be48b4f 100644 + for (k = 1; k < components_read; ++k) + { + ins = &instructions->elements[i + 1 + k]; -+ if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2))) ++ if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); @@ -7860,7 +8887,7 @@ index 710811c6761..9079be48b4f 100644 + /* discard_nz tmp.x */ + + ins = &instructions->elements[i + 1 + components_read]; -+ if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1))) ++ if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; + @@ -7923,7 +8950,7 @@ index 710811c6761..9079be48b4f 100644 return; if (normaliser->phase_body_idx == ~0u) -@@ -312,6 +434,21 @@ void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_reg +@@ -312,6 +434,61 @@ void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_reg reg->alignment = 0; } @@ -7935,26 +8962,66 @@ index 710811c6761..9079be48b4f 100644 + param->modifiers = VKD3DSPSM_NONE; +} + ++void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, ++ enum vkd3d_data_type data_type, unsigned int idx_count) ++{ ++ vsir_register_init(¶m->reg, reg_type, data_type, idx_count); ++ param->write_mask = VKD3DSP_WRITEMASK_0; ++ param->modifiers = VKD3DSPDM_NONE; ++ param->shift = 0; ++} ++ +void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id) +{ + vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UINT, 1); + param->reg.dimension = VSIR_DIMENSION_NONE; + param->reg.idx[0].offset = label_id; +} ++ ++static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx) ++{ ++ vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); ++ src->reg.idx[0].offset = idx; ++} ++ ++static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) ++{ ++ vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); ++ dst->reg.idx[0].offset = idx; ++} ++ ++static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx) ++{ ++ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ dst->reg.idx[0].offset = idx; ++ dst->write_mask = VKD3DSP_WRITEMASK_0; ++} ++ ++static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx) ++{ ++ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); ++ src->reg.idx[0].offset = idx; ++} ++ ++static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value) ++{ ++ vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); ++ src->reg.u.immconst_u32[0] = value; ++} + void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode handler_idx) { -@@ -320,6 +457,23 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk +@@ -320,6 +497,23 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk ins->handler_idx = handler_idx; } -+static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, -+ unsigned int label_id, void *parser) ++static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, ++ const struct vkd3d_shader_location *location, unsigned int label_id, struct vsir_program *program) +{ + struct vkd3d_shader_src_param *src_param; + -+ if (!(src_param = shader_parser_get_src_params(parser, 1))) ++ if (!(src_param = vsir_program_get_src_params(program, 1))) + return false; + + vsir_src_param_init_label(src_param, label_id); @@ -7969,7 +9036,7 @@ index 710811c6761..9079be48b4f 100644 static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd3d_shader_instruction_array *src_instructions) { struct hull_flattener flattener = {*src_instructions}; -@@ -339,9 +493,6 @@ static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd +@@ -339,9 +533,6 @@ static enum vkd3d_result instruction_array_flatten_hull_shader_phases(struct vkd if (flattener.phase != VKD3DSIH_INVALID) { @@ -7979,7 +9046,7 @@ index 710811c6761..9079be48b4f 100644 if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET); -@@ -463,6 +614,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -463,6 +654,7 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i struct vkd3d_shader_instruction_array *instructions; struct control_point_normaliser normaliser; unsigned int input_control_point_count; @@ -7987,7 +9054,7 @@ index 710811c6761..9079be48b4f 100644 struct vkd3d_shader_instruction *ins; enum vkd3d_result ret; unsigned int i, j; -@@ -488,10 +640,10 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -488,10 +680,10 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i normaliser.phase = ins->handler_idx; break; default: @@ -8000,7 +9067,7 @@ index 710811c6761..9079be48b4f 100644 break; } } -@@ -513,8 +665,10 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i +@@ -513,8 +705,10 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i return VKD3D_OK; case VKD3DSIH_HS_FORK_PHASE: case VKD3DSIH_HS_JOIN_PHASE: @@ -8012,7 +9079,7 @@ index 710811c6761..9079be48b4f 100644 *src_instructions = normaliser.instructions; return ret; default: -@@ -530,13 +684,11 @@ struct io_normaliser +@@ -530,13 +724,11 @@ struct io_normaliser { struct vkd3d_shader_instruction_array instructions; enum vkd3d_shader_type shader_type; @@ -8027,7 +9094,7 @@ index 710811c6761..9079be48b4f 100644 unsigned int instance_count; unsigned int phase_body_idx; enum vkd3d_shader_opcode phase; -@@ -567,7 +719,7 @@ static bool io_normaliser_is_in_control_point_phase(const struct io_normaliser * +@@ -567,7 +759,7 @@ static bool io_normaliser_is_in_control_point_phase(const struct io_normaliser * static unsigned int shader_signature_find_element_for_reg(const struct shader_signature *signature, unsigned int reg_idx, unsigned int write_mask) { @@ -8036,7 +9103,7 @@ index 710811c6761..9079be48b4f 100644 for (i = 0; i < signature->element_count; ++i) { -@@ -579,7 +731,14 @@ static unsigned int shader_signature_find_element_for_reg(const struct shader_si +@@ -579,7 +771,14 @@ static unsigned int shader_signature_find_element_for_reg(const struct shader_si } } @@ -8052,7 +9119,7 @@ index 710811c6761..9079be48b4f 100644 vkd3d_unreachable(); } -@@ -590,19 +749,19 @@ struct signature_element *vsir_signature_find_element_for_reg(const struct shade +@@ -590,19 +789,19 @@ struct signature_element *vsir_signature_find_element_for_reg(const struct shade } static unsigned int range_map_get_register_count(uint8_t range_map[][VKD3D_VEC4_SIZE], @@ -8077,7 +9144,7 @@ index 710811c6761..9079be48b4f 100644 assert(register_idx < MAX_REG_OUTPUT && MAX_REG_OUTPUT - register_idx >= register_count); -@@ -746,12 +905,58 @@ static int signature_element_index_compare(const void *a, const void *b) +@@ -746,12 +945,58 @@ static int signature_element_index_compare(const void *a, const void *b) return vkd3d_u32_compare(e->sort_index, f->sort_index); } @@ -8136,7 +9203,7 @@ index 710811c6761..9079be48b4f 100644 element_count = s->element_count; if (!(elements = vkd3d_malloc(element_count * sizeof(*elements)))) -@@ -772,14 +977,15 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map +@@ -772,14 +1017,15 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map if (range_map_get_register_count(range_map, e->register_index, e->mask) > 1) continue; @@ -8154,7 +9221,7 @@ index 710811c6761..9079be48b4f 100644 || range_map_get_register_count(range_map, f->register_index, f->mask) > 1) break; -@@ -790,6 +996,16 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map +@@ -790,6 +1036,16 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map e->mask |= f->mask; e->used_mask |= f->used_mask; e->semantic_index = min(e->semantic_index, f->semantic_index); @@ -8171,7 +9238,7 @@ index 710811c6761..9079be48b4f 100644 } } element_count = new_count; -@@ -816,6 +1032,7 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map +@@ -816,6 +1072,7 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map { TRACE("Merging %s, base reg %u, count %u.\n", e->semantic_name, e->register_index, register_count); e->register_count = register_count; @@ -8179,7 +9246,7 @@ index 710811c6761..9079be48b4f 100644 } } element_count = new_count; -@@ -840,6 +1057,13 @@ static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_sh +@@ -840,6 +1097,13 @@ static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_sh reg->idx[id_idx + 1].rel_addr = NULL; reg->idx[id_idx + 1].offset = reg->idx[id_idx].offset; reg->idx[id_idx].offset -= register_index; @@ -8193,7 +9260,7 @@ index 710811c6761..9079be48b4f 100644 ++id_idx; } /* Otherwise we have no address for the arrayed register, so insert one. This happens e.g. where -@@ -864,39 +1088,70 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par +@@ -864,39 +1128,70 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par const struct shader_signature *signature; const struct signature_element *e; @@ -8289,7 +9356,7 @@ index 710811c6761..9079be48b4f 100644 if (is_io_dcl) { /* Validated in the TPF reader. */ -@@ -979,27 +1234,43 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par +@@ -979,27 +1274,43 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par switch (reg->type) { case VKD3DSPR_PATCHCONST: @@ -8335,7 +9402,7 @@ index 710811c6761..9079be48b4f 100644 element_idx = shader_signature_find_element_for_reg(signature, reg_idx, write_mask); e = &signature->elements[element_idx]; -@@ -1008,10 +1279,10 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par +@@ -1008,10 +1319,10 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par reg->idx[id_idx].offset = element_idx; reg->idx_count = id_idx + 1; @@ -8348,7 +9415,7 @@ index 710811c6761..9079be48b4f 100644 src_param->swizzle -= component_idx << VKD3D_SHADER_SWIZZLE_SHIFT(i); } } -@@ -1062,32 +1333,34 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi +@@ -1062,32 +1373,34 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi memset(normaliser->pc_dcl_params, 0, sizeof(normaliser->pc_dcl_params)); break; default: @@ -8390,7 +9457,7 @@ index 710811c6761..9079be48b4f 100644 switch (ins->handler_idx) { -@@ -1130,7 +1403,7 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse +@@ -1130,7 +1443,7 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse || !shader_signature_merge(&parser->shader_desc.output_signature, normaliser.output_range_map, false) || !shader_signature_merge(&parser->shader_desc.patch_constant_signature, normaliser.pc_range_map, true)) { @@ -8399,7 +9466,7 @@ index 710811c6761..9079be48b4f 100644 return VKD3D_ERROR_OUT_OF_MEMORY; } -@@ -1138,8 +1411,8 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse +@@ -1138,8 +1451,8 @@ static enum vkd3d_result shader_normalise_io_registers(struct vkd3d_shader_parse for (i = 0; i < normaliser.instructions.count; ++i) shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser); @@ -8410,7 +9477,7 @@ index 710811c6761..9079be48b4f 100644 return VKD3D_OK; } -@@ -1152,7 +1425,6 @@ struct flat_constant_def +@@ -1152,7 +1465,6 @@ struct flat_constant_def struct flat_constants_normaliser { @@ -8418,7 +9485,7 @@ index 710811c6761..9079be48b4f 100644 struct flat_constant_def *defs; size_t def_count, defs_capacity; }; -@@ -1215,7 +1487,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par +@@ -1215,7 +1527,7 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par param->reg.idx_count = 0; param->reg.dimension = VSIR_DIMENSION_VEC4; for (j = 0; j < 4; ++j) @@ -8427,7 +9494,7 @@ index 710811c6761..9079be48b4f 100644 return; } } -@@ -1227,14 +1499,14 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par +@@ -1227,14 +1539,14 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par param->reg.idx_count = 3; } @@ -8446,7 +9513,7 @@ index 710811c6761..9079be48b4f 100644 if (ins->handler_idx == VKD3DSIH_DEF || ins->handler_idx == VKD3DSIH_DEFI || ins->handler_idx == VKD3DSIH_DEFB) { -@@ -1251,14 +1523,14 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d +@@ -1251,14 +1563,14 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d get_flat_constant_register_type((struct vkd3d_shader_register *)&ins->dst[0].reg, &def->set, &def->index); for (j = 0; j < 4; ++j) @@ -8463,7 +9530,7 @@ index 710811c6761..9079be48b4f 100644 } } -@@ -1266,14 +1538,14 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d +@@ -1266,14 +1578,14 @@ static enum vkd3d_result instruction_array_normalise_flat_constants(struct vkd3d return VKD3D_OK; } @@ -8481,7 +9548,7 @@ index 710811c6761..9079be48b4f 100644 switch (ins->handler_idx) { -@@ -1360,15 +1632,15 @@ static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser +@@ -1360,15 +1672,15 @@ static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser { unsigned int i; @@ -8500,7 +9567,7 @@ index 710811c6761..9079be48b4f 100644 return VKD3D_ERROR_OUT_OF_MEMORY; memset(srcs, 0, sizeof(*srcs) * 3); -@@ -1424,111 +1696,805 @@ static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser +@@ -1424,95 +1736,1420 @@ static enum vkd3d_result normalise_combined_samplers(struct vkd3d_shader_parser return VKD3D_OK; } @@ -8669,21 +9736,21 @@ index 710811c6761..9079be48b4f 100644 +static unsigned int cf_flattener_alloc_block_id(struct cf_flattener *flattener) { - unsigned int i, temp_count = ctx->temp_count; -- ++ return ++flattener->block_id; ++} + - /* SM1-3 shaders do not include a DCL_TEMPS instruction. */ - if (ctx->parser->shader_version.major <= 3) - temp_count = ctx->parser->shader_desc.temp_count; -+ return ++flattener->block_id; -+} ++static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, ++ unsigned int count, struct cf_flattener *flattener) ++{ ++ struct vkd3d_shader_src_param *params; - if (reg->type >= VKD3DSPR_COUNT) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.", - reg->type); -+static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, -+ unsigned int count, struct cf_flattener *flattener) -+{ -+ struct vkd3d_shader_src_param *params = shader_parser_get_src_params(flattener->parser, count); -+ if (!params) ++ if (!(params = vsir_program_get_src_params(&flattener->parser->program, count))) + { + flattener->allocation_failed = true; + return NULL; @@ -8692,28 +9759,19 @@ index 710811c6761..9079be48b4f 100644 + ins->src_count = count; + return params; +} - -- if (reg->precision >= VKD3D_SHADER_REGISTER_PRECISION_COUNT) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", -- reg->precision); ++ +static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int label_id) +{ + struct vkd3d_shader_instruction *ins; - -- if (reg->data_type >= VKD3D_DATA_COUNT) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.", -- reg->data_type); ++ + if (!(ins = cf_flattener_require_space(flattener, 1))) + return; -+ if (vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->parser)) ++ if (vsir_instruction_init_label(ins, &flattener->location, label_id, &flattener->parser->program)) + ++flattener->instruction_count; + else + flattener->allocation_failed = true; +} - -- if (reg->dimension >= VSIR_DIMENSION_COUNT) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid register dimension %#x.", -- reg->dimension); ++ +/* For conditional branches, this returns the false target branch parameter. */ +static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flattener *flattener, + unsigned int merge_block_id, unsigned int continue_block_id, @@ -8722,10 +9780,7 @@ index 710811c6761..9079be48b4f 100644 +{ + struct vkd3d_shader_src_param *src_params, *false_branch_param; + struct vkd3d_shader_instruction *ins; - -- if (reg->idx_count > ARRAY_SIZE(reg->idx)) -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid register index count %u.", -- reg->idx_count); ++ + if (!(ins = cf_flattener_require_space(flattener, 1))) + return NULL; + vsir_instruction_init(ins, &flattener->location, VKD3DSIH_BRANCH); @@ -9236,6 +10291,624 @@ index 710811c6761..9079be48b4f 100644 + return result; +} + ++static unsigned int label_from_src_param(const struct vkd3d_shader_src_param *param) ++{ ++ assert(param->reg.type == VKD3DSPR_LABEL); ++ return param->reg.idx[0].offset; ++} ++ ++static bool reserve_instructions(struct vkd3d_shader_instruction **instructions, size_t *capacity, size_t count) ++{ ++ if (!vkd3d_array_reserve((void **)instructions, capacity, count, sizeof(**instructions))) ++ { ++ ERR("Failed to allocate instructions.\n"); ++ return false; ++ } ++ ++ return true; ++} ++ ++/* A record represents replacing a jump from block `switch_label' to ++ * block `target_label' with a jump from block `if_label' to block ++ * `target_label'. */ ++struct lower_switch_to_if_ladder_block_mapping ++{ ++ unsigned int switch_label; ++ unsigned int if_label; ++ unsigned int target_label; ++}; ++ ++static bool lower_switch_to_if_ladder_add_block_mapping(struct lower_switch_to_if_ladder_block_mapping **block_map, ++ size_t *map_capacity, size_t *map_count, unsigned int switch_label, unsigned int if_label, unsigned int target_label) ++{ ++ if (!vkd3d_array_reserve((void **)block_map, map_capacity, *map_count + 1, sizeof(**block_map))) ++ { ++ ERR("Failed to allocate block mapping.\n"); ++ return false; ++ } ++ ++ (*block_map)[*map_count].switch_label = switch_label; ++ (*block_map)[*map_count].if_label = if_label; ++ (*block_map)[*map_count].target_label = target_label; ++ ++ *map_count += 1; ++ ++ return true; ++} ++ ++static enum vkd3d_result lower_switch_to_if_ladder(struct vsir_program *program) ++{ ++ unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label; ++ size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0; ++ struct vkd3d_shader_instruction *instructions = NULL; ++ struct lower_switch_to_if_ladder_block_mapping *block_map = NULL; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count)) ++ goto fail; ++ ++ /* First subpass: convert SWITCH_MONOLITHIC instructions to ++ * selection ladders, keeping a map between blocks before and ++ * after the subpass. */ ++ for (i = 0; i < program->instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; ++ unsigned int case_count, j, default_label; ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_LABEL: ++ current_label = label_from_src_param(&ins->src[0]); ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) ++ goto fail; ++ instructions[ins_count++] = *ins; ++ continue; ++ ++ case VKD3DSIH_SWITCH_MONOLITHIC: ++ break; ++ ++ default: ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) ++ goto fail; ++ instructions[ins_count++] = *ins; ++ continue; ++ } ++ ++ case_count = (ins->src_count - 3) / 2; ++ default_label = label_from_src_param(&ins->src[1]); ++ ++ /* In principle we can have a switch with no cases, and we ++ * just have to jump to the default label. */ ++ if (case_count == 0) ++ { ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) ++ goto fail; ++ ++ if (!vsir_instruction_init_with_params(program, &instructions[ins_count], ++ &ins->location, VKD3DSIH_BRANCH, 0, 1)) ++ goto fail; ++ vsir_src_param_init_label(&instructions[ins_count].src[0], default_label); ++ ++ins_count; ++ } ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3 * case_count - 1)) ++ goto fail; ++ ++ if_label = current_label; ++ ++ for (j = 0; j < case_count; ++j) ++ { ++ unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]); ++ ++ if (!vsir_instruction_init_with_params(program, ++ &instructions[ins_count], &ins->location, VKD3DSIH_IEQ, 1, 2)) ++ goto fail; ++ dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count); ++ instructions[ins_count].src[0] = ins->src[0]; ++ instructions[ins_count].src[1] = ins->src[3 + 2 * j]; ++ ++ins_count; ++ ++ /* For all cases except the last one we fall through to ++ * the following case; the last one has to jump to the ++ * default label. */ ++ if (j == case_count - 1) ++ fallthrough_label = default_label; ++ else ++ fallthrough_label = block_count + 1; ++ ++ if (!vsir_instruction_init_with_params(program, &instructions[ins_count], ++ &ins->location, VKD3DSIH_BRANCH, 0, 3)) ++ goto fail; ++ src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count); ++ vsir_src_param_init_label(&instructions[ins_count].src[1], case_label); ++ vsir_src_param_init_label(&instructions[ins_count].src[2], fallthrough_label); ++ ++ins_count; ++ ++ ++ssa_count; ++ ++ if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count, ++ current_label, if_label, case_label)) ++ goto fail; ++ ++ if (j == case_count - 1) ++ { ++ if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count, ++ current_label, if_label, default_label)) ++ goto fail; ++ } ++ else ++ { ++ if (!vsir_instruction_init_with_params(program, ++ &instructions[ins_count], &ins->location, VKD3DSIH_LABEL, 0, 1)) ++ goto fail; ++ vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count); ++ ++ins_count; ++ ++ if_label = block_count; ++ } ++ } ++ } ++ ++ /* Second subpass: creating new blocks might have broken ++ * references in PHI instructions, so we use the block map to fix ++ * them. */ ++ current_label = 0; ++ for (i = 0; i < ins_count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &instructions[i]; ++ struct vkd3d_shader_src_param *new_src; ++ unsigned int j, l, new_src_count = 0; ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_LABEL: ++ current_label = label_from_src_param(&ins->src[0]); ++ continue; ++ ++ case VKD3DSIH_PHI: ++ break; ++ ++ default: ++ continue; ++ } ++ ++ /* First count how many source parameters we need. */ ++ for (j = 0; j < ins->src_count; j += 2) ++ { ++ unsigned int source_label = label_from_src_param(&ins->src[j + 1]); ++ size_t k, match_count = 0; ++ ++ for (k = 0; k < map_count; ++k) ++ { ++ struct lower_switch_to_if_ladder_block_mapping *mapping = &block_map[k]; ++ ++ if (mapping->switch_label == source_label && mapping->target_label == current_label) ++ match_count += 1; ++ } ++ ++ new_src_count += (match_count != 0) ? 2 * match_count : 2; ++ } ++ ++ assert(new_src_count >= ins->src_count); ++ ++ /* Allocate more source parameters if needed. */ ++ if (new_src_count == ins->src_count) ++ { ++ new_src = ins->src; ++ } ++ else ++ { ++ if (!(new_src = vsir_program_get_src_params(program, new_src_count))) ++ { ++ ERR("Failed to allocate %u source parameters.\n", new_src_count); ++ goto fail; ++ } ++ } ++ ++ /* Then do the copy. */ ++ for (j = 0, l = 0; j < ins->src_count; j += 2) ++ { ++ unsigned int source_label = label_from_src_param(&ins->src[j + 1]); ++ size_t k, match_count = 0; ++ ++ for (k = 0; k < map_count; ++k) ++ { ++ struct lower_switch_to_if_ladder_block_mapping *mapping = &block_map[k]; ++ ++ if (mapping->switch_label == source_label && mapping->target_label == current_label) ++ { ++ match_count += 1; ++ ++ new_src[l] = ins->src[j]; ++ new_src[l + 1] = ins->src[j + 1]; ++ new_src[l + 1].reg.idx[0].offset = mapping->if_label; ++ l += 2; ++ } ++ } ++ ++ if (match_count == 0) ++ { ++ new_src[l] = ins->src[j]; ++ new_src[l + 1] = ins->src[j + 1]; ++ l += 2; ++ } ++ } ++ ++ assert(l == new_src_count); ++ ++ ins->src_count = new_src_count; ++ ins->src = new_src; ++ } ++ ++ vkd3d_free(program->instructions.elements); ++ vkd3d_free(block_map); ++ program->instructions.elements = instructions; ++ program->instructions.capacity = ins_capacity; ++ program->instructions.count = ins_count; ++ program->block_count = block_count; ++ program->ssa_count = ssa_count; ++ ++ return VKD3D_OK; ++ ++fail: ++ vkd3d_free(instructions); ++ vkd3d_free(block_map); ++ ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++} ++ ++static void materialize_ssas_to_temps_process_src_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_src_param *src); ++ ++/* This is idempotent: it can be safely applied more than once on the ++ * same register. */ ++static void materialize_ssas_to_temps_process_reg(struct vkd3d_shader_parser *parser, struct vkd3d_shader_register *reg) ++{ ++ unsigned int i; ++ ++ if (reg->type == VKD3DSPR_SSA) ++ { ++ reg->type = VKD3DSPR_TEMP; ++ reg->idx[0].offset += parser->program.temp_count; ++ } ++ ++ for (i = 0; i < reg->idx_count; ++i) ++ if (reg->idx[i].rel_addr) ++ materialize_ssas_to_temps_process_src_param(parser, reg->idx[i].rel_addr); ++} ++ ++static void materialize_ssas_to_temps_process_dst_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_dst_param *dst) ++{ ++ materialize_ssas_to_temps_process_reg(parser, &dst->reg); ++} ++ ++static void materialize_ssas_to_temps_process_src_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_src_param *src) ++{ ++ materialize_ssas_to_temps_process_reg(parser, &src->reg); ++} ++ ++static const struct vkd3d_shader_src_param *materialize_ssas_to_temps_compute_source(struct vkd3d_shader_instruction *ins, ++ unsigned int label) ++{ ++ unsigned int i; ++ ++ assert(ins->handler_idx == VKD3DSIH_PHI); ++ ++ for (i = 0; i < ins->src_count; i += 2) ++ { ++ if (label_from_src_param(&ins->src[i + 1]) == label) ++ return &ins->src[i]; ++ } ++ ++ vkd3d_unreachable(); ++} ++ ++static bool materialize_ssas_to_temps_synthesize_mov(struct vkd3d_shader_parser *parser, ++ struct vkd3d_shader_instruction *instruction, const struct vkd3d_shader_location *loc, ++ const struct vkd3d_shader_dst_param *dest, const struct vkd3d_shader_src_param *cond, ++ const struct vkd3d_shader_src_param *source, bool invert) ++{ ++ struct vkd3d_shader_src_param *src; ++ struct vkd3d_shader_dst_param *dst; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, instruction, loc, ++ cond ? VKD3DSIH_MOVC : VKD3DSIH_MOV, 1, cond ? 3 : 1)) ++ return false; ++ ++ dst = instruction->dst; ++ src = instruction->src; ++ ++ dst[0] = *dest; ++ materialize_ssas_to_temps_process_dst_param(parser, &dst[0]); ++ ++ assert(dst[0].write_mask == VKD3DSP_WRITEMASK_0); ++ assert(dst[0].modifiers == 0); ++ assert(dst[0].shift == 0); ++ ++ if (cond) ++ { ++ src[0] = *cond; ++ src[1 + invert] = *source; ++ memset(&src[2 - invert], 0, sizeof(src[2 - invert])); ++ src[2 - invert].reg = dst[0].reg; ++ materialize_ssas_to_temps_process_src_param(parser, &src[1]); ++ materialize_ssas_to_temps_process_src_param(parser, &src[2]); ++ } ++ else ++ { ++ src[0] = *source; ++ materialize_ssas_to_temps_process_src_param(parser, &src[0]); ++ } ++ ++ return true; ++} ++ ++static enum vkd3d_result materialize_ssas_to_temps(struct vkd3d_shader_parser *parser) ++{ ++ struct vkd3d_shader_instruction *instructions = NULL; ++ struct materialize_ssas_to_temps_block_data ++ { ++ size_t phi_begin; ++ size_t phi_count; ++ } *block_index = NULL; ++ size_t ins_capacity = 0, ins_count = 0, i; ++ unsigned int current_label = 0; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, parser->program.instructions.count)) ++ goto fail; ++ ++ if (!(block_index = vkd3d_calloc(parser->program.block_count, sizeof(*block_index)))) ++ { ++ ERR("Failed to allocate block index.\n"); ++ goto fail; ++ } ++ ++ for (i = 0; i < parser->program.instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_LABEL: ++ current_label = label_from_src_param(&ins->src[0]); ++ break; ++ ++ case VKD3DSIH_PHI: ++ assert(current_label != 0); ++ assert(i != 0); ++ if (block_index[current_label - 1].phi_begin == 0) ++ block_index[current_label - 1].phi_begin = i; ++ block_index[current_label - 1].phi_count += 1; ++ break; ++ ++ default: ++ current_label = 0; ++ break; ++ } ++ } ++ ++ for (i = 0; i < parser->program.instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; ++ size_t j; ++ ++ for (j = 0; j < ins->dst_count; ++j) ++ materialize_ssas_to_temps_process_dst_param(parser, &ins->dst[j]); ++ ++ for (j = 0; j < ins->src_count; ++j) ++ materialize_ssas_to_temps_process_src_param(parser, &ins->src[j]); ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_LABEL: ++ current_label = label_from_src_param(&ins->src[0]); ++ break; ++ ++ case VKD3DSIH_BRANCH: ++ { ++ if (vsir_register_is_label(&ins->src[0].reg)) ++ { ++ const struct materialize_ssas_to_temps_block_data *data = &block_index[label_from_src_param(&ins->src[0]) - 1]; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + data->phi_count)) ++ goto fail; ++ ++ for (j = data->phi_begin; j < data->phi_begin + data->phi_count; ++j) ++ { ++ const struct vkd3d_shader_src_param *source; ++ ++ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); ++ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, ++ &parser->program.instructions.elements[j].dst[0], NULL, source, false)) ++ goto fail; ++ ++ ++ins_count; ++ } ++ } ++ else ++ { ++ struct materialize_ssas_to_temps_block_data *data_true = &block_index[label_from_src_param(&ins->src[1]) - 1], ++ *data_false = &block_index[label_from_src_param(&ins->src[2]) - 1]; ++ const struct vkd3d_shader_src_param *cond = &ins->src[0]; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ++ ins_count + data_true->phi_count + data_false->phi_count)) ++ goto fail; ++ ++ for (j = data_true->phi_begin; j < data_true->phi_begin + data_true->phi_count; ++j) ++ { ++ const struct vkd3d_shader_src_param *source; ++ ++ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); ++ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, ++ &parser->program.instructions.elements[j].dst[0], cond, source, false)) ++ goto fail; ++ ++ ++ins_count; ++ } ++ ++ for (j = data_false->phi_begin; j < data_false->phi_begin + data_false->phi_count; ++j) ++ { ++ const struct vkd3d_shader_src_param *source; ++ ++ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); ++ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, ++ &parser->program.instructions.elements[j].dst[0], cond, source, true)) ++ goto fail; ++ ++ ++ins_count; ++ } ++ } ++ break; ++ } ++ ++ case VKD3DSIH_PHI: ++ continue; ++ ++ default: ++ break; ++ } ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) ++ goto fail; ++ ++ instructions[ins_count++] = *ins; ++ } ++ ++ vkd3d_free(parser->program.instructions.elements); ++ vkd3d_free(block_index); ++ parser->program.instructions.elements = instructions; ++ parser->program.instructions.capacity = ins_capacity; ++ parser->program.instructions.count = ins_count; ++ parser->program.temp_count += parser->program.ssa_count; ++ parser->program.ssa_count = 0; ++ ++ return VKD3D_OK; ++ ++fail: ++ vkd3d_free(instructions); ++ vkd3d_free(block_index); ++ ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++} ++ ++static enum vkd3d_result simple_structurizer_run(struct vkd3d_shader_parser *parser) ++{ ++ const unsigned int block_temp_idx = parser->program.temp_count; ++ struct vkd3d_shader_instruction *instructions = NULL; ++ const struct vkd3d_shader_location no_loc = {0}; ++ size_t ins_capacity = 0, ins_count = 0, i; ++ bool first_label_found = false; ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, parser->program.instructions.count)) ++ goto fail; ++ ++ for (i = 0; i < parser->program.instructions.count; ++i) ++ { ++ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; ++ ++ switch (ins->handler_idx) ++ { ++ case VKD3DSIH_PHI: ++ case VKD3DSIH_SWITCH_MONOLITHIC: ++ vkd3d_unreachable(); ++ ++ case VKD3DSIH_LABEL: ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 4)) ++ goto fail; ++ ++ if (!first_label_found) ++ { ++ first_label_found = true; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1)) ++ goto fail; ++ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); ++ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_LOOP, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_SWITCH, 0, 1)) ++ goto fail; ++ src_param_init_temp_uint(&instructions[ins_count].src[0], block_temp_idx); ++ ins_count++; ++ } ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_CASE, 0, 1)) ++ goto fail; ++ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); ++ ins_count++; ++ break; ++ ++ case VKD3DSIH_BRANCH: ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 2)) ++ goto fail; ++ ++ if (vsir_register_is_label(&ins->src[0].reg)) ++ { ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1)) ++ goto fail; ++ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); ++ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); ++ ins_count++; ++ } ++ else ++ { ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOVC, 1, 3)) ++ goto fail; ++ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); ++ instructions[ins_count].src[0] = ins->src[0]; ++ src_param_init_const_uint(&instructions[ins_count].src[1], label_from_src_param(&ins->src[1])); ++ src_param_init_const_uint(&instructions[ins_count].src[2], label_from_src_param(&ins->src[2])); ++ ins_count++; ++ } ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_BREAK, 0, 0)) ++ goto fail; ++ ins_count++; ++ break; ++ ++ case VKD3DSIH_RET: ++ default: ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) ++ goto fail; ++ ++ instructions[ins_count++] = *ins; ++ break; ++ } ++ } ++ ++ assert(first_label_found); ++ ++ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3)) ++ goto fail; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDSWITCH, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDLOOP, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_RET, 0, 0)) ++ goto fail; ++ ins_count++; ++ ++ vkd3d_free(parser->program.instructions.elements); ++ parser->program.instructions.elements = instructions; ++ parser->program.instructions.capacity = ins_capacity; ++ parser->program.instructions.count = ins_count; ++ parser->program.temp_count += 1; ++ ++ return VKD3D_OK; ++ ++fail: ++ vkd3d_free(instructions); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++} ++ +enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, + const struct vkd3d_shader_compile_info *compile_info) +{ @@ -9247,7 +10920,18 @@ index 710811c6761..9079be48b4f 100644 + if ((result = instruction_array_lower_texkills(parser)) < 0) + return result; + -+ if (!parser->shader_desc.is_dxil) ++ if (parser->shader_desc.is_dxil) ++ { ++ if ((result = lower_switch_to_if_ladder(&parser->program)) < 0) ++ return result; ++ ++ if ((result = materialize_ssas_to_temps(parser)) < 0) ++ return result; ++ ++ if ((result = simple_structurizer_run(parser)) < 0) ++ return result; ++ } ++ else + { + if (parser->program.shader_version.type != VKD3D_SHADER_TYPE_PIXEL) + { @@ -9273,13 +10957,13 @@ index 710811c6761..9079be48b4f 100644 + + remove_dead_code(&parser->program); + -+ if ((result = flatten_control_flow_constructs(parser)) < 0) -+ return result; -+ + if ((result = normalise_combined_samplers(parser)) < 0) + return result; + } + ++ if ((result = flatten_control_flow_constructs(parser)) < 0) ++ return result; ++ + if (TRACE_ON()) + vkd3d_shader_trace(&parser->program); + @@ -9317,6 +11001,7 @@ index 710811c6761..9079be48b4f 100644 + struct validation_context_ssa_data + { + enum vsir_dimension dimension; ++ enum vkd3d_data_type data_type; + size_t first_seen; + uint32_t write_mask; + uint32_t read_mask; @@ -9365,26 +11050,10 @@ index 710811c6761..9079be48b4f 100644 + if (reg->type >= VKD3DSPR_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, "Invalid register type %#x.", + reg->type); -+ -+ if (reg->precision >= VKD3D_SHADER_REGISTER_PRECISION_COUNT) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", -+ reg->precision); -+ -+ if (reg->data_type >= VKD3D_DATA_COUNT) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.", -+ reg->data_type); -+ -+ if (reg->dimension >= VSIR_DIMENSION_COUNT) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid register dimension %#x.", -+ reg->dimension); -+ -+ if (reg->idx_count > ARRAY_SIZE(reg->idx)) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, "Invalid register index count %u.", -+ reg->idx_count); - for (i = 0; i < min(reg->idx_count, ARRAY_SIZE(reg->idx)); ++i) - { -@@ -1540,16 +2506,128 @@ static void vsir_validate_register(struct validation_context *ctx, + if (reg->precision >= VKD3D_SHADER_REGISTER_PRECISION_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", +@@ -1540,16 +3177,135 @@ static void vsir_validate_register(struct validation_context *ctx, switch (reg->type) { case VKD3DSPR_TEMP: @@ -9472,13 +11141,20 @@ index 710811c6761..9079be48b4f 100644 + if (data->dimension == VSIR_DIMENSION_NONE) + { + data->dimension = reg->dimension; ++ data->data_type = reg->data_type; + data->first_seen = ctx->instruction_idx; + } -+ else if (data->dimension != reg->dimension) ++ else + { -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a SSA register: " -+ "it has already been seen with dimension %#x at instruction %zu.", -+ reg->dimension, data->dimension, data->first_seen); ++ if (data->dimension != reg->dimension) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a SSA register: " ++ "it has already been seen with dimension %#x at instruction %zu.", ++ reg->dimension, data->dimension, data->first_seen); ++ ++ if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type)) ++ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid data type %#x for a SSA register: " ++ "it has already been seen with data type %#x at instruction %zu.", ++ reg->data_type, data->data_type, data->first_seen); + } + break; + } @@ -9516,7 +11192,7 @@ index 710811c6761..9079be48b4f 100644 break; case VKD3DSPR_NULL: -@@ -1584,6 +2662,26 @@ static void vsir_validate_dst_param(struct validation_context *ctx, +@@ -1584,6 +3340,26 @@ static void vsir_validate_dst_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, "Destination has invalid write mask %#x.", dst->write_mask); @@ -9543,7 +11219,7 @@ index 710811c6761..9079be48b4f 100644 if (dst->modifiers & ~VKD3DSPDM_MASK) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.", dst->modifiers); -@@ -1603,6 +2701,41 @@ static void vsir_validate_dst_param(struct validation_context *ctx, +@@ -1603,6 +3379,41 @@ static void vsir_validate_dst_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SHIFT, "Destination has invalid shift %#x.", dst->shift); } @@ -9585,7 +11261,7 @@ index 710811c6761..9079be48b4f 100644 } static void vsir_validate_src_param(struct validation_context *ctx, -@@ -1614,9 +2747,30 @@ static void vsir_validate_src_param(struct validation_context *ctx, +@@ -1614,9 +3425,30 @@ static void vsir_validate_src_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SWIZZLE, "Source has invalid swizzle %#x.", src->swizzle); @@ -9616,7 +11292,7 @@ index 710811c6761..9079be48b4f 100644 } static void vsir_validate_dst_count(struct validation_context *ctx, -@@ -1637,11 +2791,64 @@ static void vsir_validate_src_count(struct validation_context *ctx, +@@ -1637,11 +3469,64 @@ static void vsir_validate_src_count(struct validation_context *ctx, instruction->src_count, instruction->handler_idx, count); } @@ -9682,7 +11358,7 @@ index 710811c6761..9079be48b4f 100644 ctx->parser->location = instruction->location; for (i = 0; i < instruction->dst_count; ++i) -@@ -1664,26 +2871,68 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -1664,26 +3549,68 @@ static void vsir_validate_instruction(struct validation_context *ctx) case VKD3DSIH_HS_JOIN_PHASE: vsir_validate_dst_count(ctx, instruction, 0); vsir_validate_src_count(ctx, instruction, 0); @@ -9757,7 +11433,7 @@ index 710811c6761..9079be48b4f 100644 switch (instruction->handler_idx) { case VKD3DSIH_DCL_TEMPS: -@@ -1691,14 +2940,15 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -1691,14 +3618,15 @@ static void vsir_validate_instruction(struct validation_context *ctx) vsir_validate_src_count(ctx, instruction, 0); if (ctx->dcl_temps_found) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_DUPLICATE_DCL_TEMPS, "Duplicate DCL_TEMPS instruction."); @@ -9777,7 +11453,7 @@ index 710811c6761..9079be48b4f 100644 vsir_validate_dst_count(ctx, instruction, 0); vsir_validate_src_count(ctx, instruction, 1); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) -@@ -1707,6 +2957,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -1707,6 +3635,7 @@ static void vsir_validate_instruction(struct validation_context *ctx) break; case VKD3DSIH_IFC: @@ -9785,7 +11461,7 @@ index 710811c6761..9079be48b4f 100644 vsir_validate_dst_count(ctx, instruction, 0); vsir_validate_src_count(ctx, instruction, 2); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) -@@ -1715,41 +2966,46 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -1715,41 +3644,46 @@ static void vsir_validate_instruction(struct validation_context *ctx) break; case VKD3DSIH_ELSE: @@ -9836,7 +11512,7 @@ index 710811c6761..9079be48b4f 100644 vsir_validate_dst_count(ctx, instruction, 0); vsir_validate_src_count(ctx, instruction, 1); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) -@@ -1758,15 +3014,17 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -1758,15 +3692,17 @@ static void vsir_validate_instruction(struct validation_context *ctx) break; case VKD3DSIH_ENDREP: @@ -9855,7 +11531,7 @@ index 710811c6761..9079be48b4f 100644 vsir_validate_dst_count(ctx, instruction, 0); vsir_validate_src_count(ctx, instruction, 1); if (!vkd3d_array_reserve((void **)&ctx->blocks, &ctx->blocks_capacity, ctx->depth + 1, sizeof(*ctx->blocks))) -@@ -1775,35 +3033,223 @@ static void vsir_validate_instruction(struct validation_context *ctx) +@@ -1775,35 +3711,223 @@ static void vsir_validate_instruction(struct validation_context *ctx) break; case VKD3DSIH_ENDSWITCH: @@ -10086,7 +11762,7 @@ index 710811c6761..9079be48b4f 100644 + return VKD3D_ERROR_OUT_OF_MEMORY; } diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index c8a43adbe03..a86ca583e63 100644 +index c8a43adbe03..6c92b03b216 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -133,7 +133,7 @@ static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, @@ -10128,7 +11804,24 @@ index c8a43adbe03..a86ca583e63 100644 #endif /* HAVE_SPIRV_TOOLS */ -@@ -851,20 +855,6 @@ static void vkd3d_spirv_end_function_stream_insertion(struct vkd3d_spirv_builder +@@ -219,16 +223,6 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d + } + } + +-static inline bool register_is_undef(const struct vkd3d_shader_register *reg) +-{ +- return reg->type == VKD3DSPR_UNDEF; +-} +- +-static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg) +-{ +- return register_is_constant(reg) || register_is_undef(reg); +-} +- + #define VKD3D_SPIRV_VERSION 0x00010000 + #define VKD3D_SPIRV_GENERATOR_ID 18 + #define VKD3D_SPIRV_GENERATOR_VERSION 10 +@@ -851,20 +845,6 @@ static void vkd3d_spirv_end_function_stream_insertion(struct vkd3d_spirv_builder builder->insertion_location = ~(size_t)0; } @@ -10149,7 +11842,7 @@ index c8a43adbe03..a86ca583e63 100644 static void vkd3d_spirv_build_op_capability(struct vkd3d_spirv_stream *stream, SpvCapability cap) { -@@ -1194,6 +1184,16 @@ static uint32_t vkd3d_spirv_get_op_constant64(struct vkd3d_spirv_builder *builde +@@ -1194,6 +1174,16 @@ static uint32_t vkd3d_spirv_get_op_constant64(struct vkd3d_spirv_builder *builde (const uint32_t *)&value, 2, vkd3d_spirv_build_op_constant64); } @@ -10166,7 +11859,7 @@ index c8a43adbe03..a86ca583e63 100644 static uint32_t vkd3d_spirv_build_op_constant_composite(struct vkd3d_spirv_builder *builder, uint32_t result_type, const uint32_t *constituents, unsigned int constituent_count) { -@@ -1515,6 +1515,25 @@ static uint32_t vkd3d_spirv_build_op_uless_than_equal(struct vkd3d_spirv_builder +@@ -1515,6 +1505,25 @@ static uint32_t vkd3d_spirv_build_op_uless_than_equal(struct vkd3d_spirv_builder SpvOpULessThanEqual, result_type, operand0, operand1); } @@ -10192,7 +11885,7 @@ index c8a43adbe03..a86ca583e63 100644 static uint32_t vkd3d_spirv_build_op_convert_utof(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t unsigned_value) { -@@ -1750,6 +1769,15 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder +@@ -1750,6 +1759,15 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder GLSLstd450NMax, operands, ARRAY_SIZE(operands)); } @@ -10208,7 +11901,7 @@ index c8a43adbe03..a86ca583e63 100644 static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t x, uint32_t min, uint32_t max) { -@@ -1783,6 +1811,8 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, +@@ -1783,6 +1801,8 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, break; case VKD3D_SHADER_COMPONENT_DOUBLE: return vkd3d_spirv_get_op_type_float(builder, 64); @@ -10217,7 +11910,7 @@ index c8a43adbe03..a86ca583e63 100644 default: FIXME("Unhandled component type %#x.\n", component_type); return 0; -@@ -1816,6 +1846,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder +@@ -1816,6 +1836,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder break; case VKD3D_DATA_DOUBLE: return vkd3d_spirv_get_op_type_float(builder, 64); @@ -10226,7 +11919,7 @@ index c8a43adbe03..a86ca583e63 100644 case VKD3D_DATA_BOOL: return vkd3d_spirv_get_op_type_bool(builder); default: -@@ -1858,8 +1890,6 @@ static void vkd3d_spirv_builder_begin_main_function(struct vkd3d_spirv_builder * +@@ -1858,8 +1880,6 @@ static void vkd3d_spirv_builder_begin_main_function(struct vkd3d_spirv_builder * vkd3d_spirv_build_op_function(builder, void_id, builder->main_function_id, SpvFunctionControlMaskNone, function_type_id); @@ -10235,7 +11928,7 @@ index c8a43adbe03..a86ca583e63 100644 } static void vkd3d_spirv_builder_free(struct vkd3d_spirv_builder *builder) -@@ -1922,6 +1952,8 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder, +@@ -1922,6 +1942,8 @@ static bool vkd3d_spirv_compile_module(struct vkd3d_spirv_builder *builder, vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_descriptor_indexing"); if (vkd3d_spirv_capability_is_enabled(builder, SpvCapabilityStencilExportEXT)) vkd3d_spirv_build_op_extension(&stream, "SPV_EXT_shader_stencil_export"); @@ -10244,7 +11937,7 @@ index c8a43adbe03..a86ca583e63 100644 if (builder->ext_instr_set_glsl_450) vkd3d_spirv_build_op_ext_inst_import(&stream, builder->ext_instr_set_glsl_450, "GLSL.std.450"); -@@ -2152,6 +2184,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, +@@ -2152,6 +2174,7 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, break; case VKD3DSPR_IMMCONSTBUFFER: @@ -10252,7 +11945,7 @@ index c8a43adbe03..a86ca583e63 100644 break; default: -@@ -2159,9 +2192,18 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, +@@ -2159,9 +2182,18 @@ static void vkd3d_symbol_make_register(struct vkd3d_symbol *symbol, } } @@ -10272,7 +11965,7 @@ index c8a43adbe03..a86ca583e63 100644 { symbol->id = val_id; symbol->descriptor_array = NULL; -@@ -2230,51 +2272,6 @@ static const char *debug_vkd3d_symbol(const struct vkd3d_symbol *symbol) +@@ -2230,51 +2262,6 @@ static const char *debug_vkd3d_symbol(const struct vkd3d_symbol *symbol) } } @@ -10324,7 +12017,7 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_push_constant_buffer_binding { struct vkd3d_shader_register reg; -@@ -2328,13 +2325,6 @@ struct spirv_compiler +@@ -2328,13 +2315,6 @@ struct spirv_compiler enum vkd3d_shader_type shader_type; @@ -10338,7 +12031,7 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_shader_interface_info shader_interface; struct vkd3d_shader_descriptor_offset_info offset_info; uint32_t descriptor_offsets_member_id; -@@ -2343,8 +2333,7 @@ struct spirv_compiler +@@ -2343,8 +2323,7 @@ struct spirv_compiler struct vkd3d_push_constant_buffer_binding *push_constants; const struct vkd3d_shader_spirv_target_info *spirv_target_info; @@ -10348,7 +12041,7 @@ index c8a43adbe03..a86ca583e63 100644 struct shader_signature input_signature; struct shader_signature output_signature; struct shader_signature patch_constant_signature; -@@ -2358,13 +2347,16 @@ struct spirv_compiler +@@ -2358,13 +2337,16 @@ struct spirv_compiler uint32_t private_output_variable[MAX_REG_OUTPUT + 1]; /* 1 entry for oDepth */ uint32_t private_output_variable_write_mask[MAX_REG_OUTPUT + 1]; /* 1 entry for oDepth */ uint32_t epilogue_function_id; @@ -10365,7 +12058,7 @@ index c8a43adbe03..a86ca583e63 100644 enum vkd3d_shader_opcode phase; bool emit_default_control_point_phase; -@@ -2376,12 +2368,21 @@ struct spirv_compiler +@@ -2376,12 +2358,21 @@ struct spirv_compiler struct vkd3d_shader_spec_constant *spec_constants; size_t spec_constants_size; enum vkd3d_shader_compile_option_formatting_flags formatting; @@ -10387,7 +12080,7 @@ index c8a43adbe03..a86ca583e63 100644 }; static bool is_in_default_phase(const struct spirv_compiler *compiler) -@@ -2400,6 +2401,9 @@ static bool is_in_fork_or_join_phase(const struct spirv_compiler *compiler) +@@ -2400,6 +2391,9 @@ static bool is_in_fork_or_join_phase(const struct spirv_compiler *compiler) } static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler); @@ -10397,7 +12090,7 @@ index c8a43adbe03..a86ca583e63 100644 static const char *spirv_compiler_get_entry_point_name(const struct spirv_compiler *compiler) { -@@ -2410,8 +2414,6 @@ static const char *spirv_compiler_get_entry_point_name(const struct spirv_compil +@@ -2410,8 +2404,6 @@ static const char *spirv_compiler_get_entry_point_name(const struct spirv_compil static void spirv_compiler_destroy(struct spirv_compiler *compiler) { @@ -10406,7 +12099,7 @@ index c8a43adbe03..a86ca583e63 100644 vkd3d_free(compiler->output_info); vkd3d_free(compiler->push_constants); -@@ -2430,6 +2432,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) +@@ -2430,6 +2422,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) shader_signature_cleanup(&compiler->patch_constant_signature); vkd3d_free(compiler->ssa_register_info); @@ -10414,7 +12107,7 @@ index c8a43adbe03..a86ca583e63 100644 vkd3d_free(compiler); } -@@ -2437,7 +2440,8 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) +@@ -2437,7 +2430,8 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_version *shader_version, struct vkd3d_shader_desc *shader_desc, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, @@ -10424,7 +12117,7 @@ index c8a43adbe03..a86ca583e63 100644 { const struct shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature; const struct shader_signature *output_signature = &shader_desc->output_signature; -@@ -2454,6 +2458,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve +@@ -2454,6 +2448,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve memset(compiler, 0, sizeof(*compiler)); compiler->message_context = message_context; compiler->location = *location; @@ -10432,7 +12125,7 @@ index c8a43adbe03..a86ca583e63 100644 if ((target_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO))) { -@@ -2509,6 +2514,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve +@@ -2509,6 +2504,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve break; case VKD3D_SHADER_COMPILE_OPTION_API_VERSION: @@ -10440,7 +12133,7 @@ index c8a43adbe03..a86ca583e63 100644 break; case VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV: -@@ -2533,12 +2539,20 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve +@@ -2533,12 +2529,20 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve WARN("Ignoring unrecognised value %#x for option %#x.\n", option->value, option->name); break; @@ -10461,7 +12154,7 @@ index c8a43adbe03..a86ca583e63 100644 rb_init(&compiler->symbol_table, vkd3d_symbol_compare); compiler->shader_type = shader_version->type; -@@ -2546,6 +2560,8 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve +@@ -2546,6 +2550,8 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve if ((shader_interface = vkd3d_find_struct(compile_info->next, INTERFACE_INFO))) { compiler->xfb_info = vkd3d_find_struct(compile_info->next, TRANSFORM_FEEDBACK_INFO); @@ -10470,7 +12163,7 @@ index c8a43adbe03..a86ca583e63 100644 compiler->shader_interface = *shader_interface; if (shader_interface->push_constant_buffer_count) -@@ -2759,6 +2775,14 @@ static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spi +@@ -2759,6 +2765,14 @@ static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spi return buffer; } @@ -10485,7 +12178,7 @@ index c8a43adbe03..a86ca583e63 100644 static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_binding( struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, -@@ -2955,7 +2979,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, +@@ -2955,7 +2969,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, assert(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); @@ -10494,7 +12187,7 @@ index c8a43adbe03..a86ca583e63 100644 { FIXME("Unhandled component_type %#x.\n", component_type); return vkd3d_spirv_get_op_undef(builder, type_id); -@@ -3015,14 +3039,21 @@ static uint32_t spirv_compiler_get_constant_double_vector(struct spirv_compiler +@@ -3015,14 +3029,21 @@ static uint32_t spirv_compiler_get_constant_double_vector(struct spirv_compiler component_count, (const uint64_t *)values); } @@ -10518,7 +12211,7 @@ index c8a43adbe03..a86ca583e63 100644 } static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler, -@@ -3317,7 +3348,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp +@@ -3317,7 +3338,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp } static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, @@ -10527,7 +12220,7 @@ index c8a43adbe03..a86ca583e63 100644 static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *compiler, const struct vkd3d_shader_register_index *reg_index) -@@ -3467,11 +3498,13 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi +@@ -3467,11 +3488,13 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi index_ids[0] = compiler->descriptor_offsets_member_id; index_ids[1] = spirv_compiler_get_constant_uint(compiler, push_constant_index); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPushConstant, type_id); @@ -10543,7 +12236,7 @@ index c8a43adbe03..a86ca583e63 100644 } index_id = vkd3d_spirv_build_op_iadd(builder, type_id, index_id, offset_id); } -@@ -3498,7 +3531,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp +@@ -3498,7 +3521,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp } else if (reg->type == VKD3DSPR_IMMCONSTBUFFER) { @@ -10552,7 +12245,7 @@ index c8a43adbe03..a86ca583e63 100644 } else if (reg->type == VKD3DSPR_IDXTEMP) { -@@ -3530,7 +3563,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp +@@ -3530,7 +3553,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp if (index_count) { @@ -10561,7 +12254,7 @@ index c8a43adbe03..a86ca583e63 100644 type_id = vkd3d_spirv_get_type_id(builder, register_info->component_type, component_count); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id); register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, -@@ -3556,30 +3589,29 @@ static uint32_t spirv_compiler_get_register_id(struct spirv_compiler *compiler, +@@ -3556,30 +3579,35 @@ static uint32_t spirv_compiler_get_register_id(struct spirv_compiler *compiler, SpvStorageClassPrivate, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); } @@ -10573,15 +12266,21 @@ index c8a43adbe03..a86ca583e63 100644 } -static bool vkd3d_swizzle_is_scalar(unsigned int swizzle) -+static bool vkd3d_swizzle_is_scalar(uint32_t swizzle) ++static bool vkd3d_swizzle_is_scalar(uint32_t swizzle, const struct vkd3d_shader_register *reg) { - unsigned int component_idx = vkd3d_swizzle_get_component(swizzle, 0); - return vkd3d_swizzle_get_component(swizzle, 1) == component_idx - && vkd3d_swizzle_get_component(swizzle, 2) == component_idx - && vkd3d_swizzle_get_component(swizzle, 3) == component_idx; + unsigned int component_idx = vsir_swizzle_get_component(swizzle, 0); -+ return vsir_swizzle_get_component(swizzle, 1) == component_idx -+ && vsir_swizzle_get_component(swizzle, 2) == component_idx ++ ++ if (vsir_swizzle_get_component(swizzle, 1) != component_idx) ++ return false; ++ ++ if (data_type_is_64_bit(reg->data_type)) ++ return true; ++ ++ return vsir_swizzle_get_component(swizzle, 2) == component_idx + && vsir_swizzle_get_component(swizzle, 3) == component_idx; } @@ -10602,7 +12301,7 @@ index c8a43adbe03..a86ca583e63 100644 if (component_count == val_component_count && (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask))) -@@ -3589,9 +3621,9 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, +@@ -3589,9 +3617,9 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, if (component_count == 1) { @@ -10615,7 +12314,7 @@ index c8a43adbe03..a86ca583e63 100644 return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx); } -@@ -3601,7 +3633,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, +@@ -3601,7 +3629,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, { if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) { @@ -10624,7 +12323,7 @@ index c8a43adbe03..a86ca583e63 100644 components[component_idx++] = val_id; } } -@@ -3611,14 +3643,14 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, +@@ -3611,14 +3639,14 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, for (i = 0, component_idx = 0; i < VKD3D_VEC4_SIZE; ++i) { if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) @@ -10641,7 +12340,7 @@ index c8a43adbe03..a86ca583e63 100644 enum vkd3d_shader_component_type component_type, unsigned int component_count) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -@@ -3631,9 +3663,9 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil +@@ -3631,9 +3659,9 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil for (i = 0; i < component_count; ++i) { if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) @@ -10653,9 +12352,77 @@ index c8a43adbe03..a86ca583e63 100644 } type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -@@ -3642,9 +3674,9 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil +@@ -3641,10 +3669,77 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil + type_id, vector1_id, vector2_id, components, component_count); } ++static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, ++ enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, ++ unsigned int component_count, uint32_t val_id) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id; ++ SpvOp op; ++ ++ assert(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); ++ ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; ++ return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, ++ data_type == VKD3D_DATA_UINT64 ++ ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) ++ : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); ++ false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, ++ component_count); ++ false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); ++ false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ ++static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compiler, ++ unsigned int component_count, uint32_t val_id, bool signedness) ++{ ++ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; ++ uint32_t type_id, true_id, false_id; ++ ++ true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); ++ false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); ++ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++} ++ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask) + const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) @@ -10665,7 +12432,7 @@ index c8a43adbe03..a86ca583e63 100644 uint32_t values[VKD3D_VEC4_SIZE] = {0}; unsigned int i, j; -@@ -3653,14 +3685,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile +@@ -3653,14 +3748,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile if (reg->dimension == VSIR_DIMENSION_SCALAR) { for (i = 0; i < component_count; ++i) @@ -10682,7 +12449,7 @@ index c8a43adbe03..a86ca583e63 100644 } } -@@ -3669,9 +3701,9 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile +@@ -3669,9 +3764,9 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile } static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compiler, @@ -10694,7 +12461,7 @@ index c8a43adbe03..a86ca583e63 100644 uint64_t values[VKD3D_DVEC2_SIZE] = {0}; unsigned int i, j; -@@ -3680,14 +3712,14 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi +@@ -3680,14 +3775,14 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi if (reg->dimension == VSIR_DIMENSION_SCALAR) { for (i = 0; i < component_count; ++i) @@ -10707,11 +12474,11 @@ index c8a43adbe03..a86ca583e63 100644 { if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) - values[j++] = reg->u.immconst_uint64[vkd3d_swizzle_get_component64(swizzle, i)]; -+ values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component64(swizzle, i)]; ++ values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component(swizzle, i)]; } } -@@ -3696,9 +3728,9 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi +@@ -3696,9 +3791,9 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi } static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, @@ -10723,7 +12490,7 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id; -@@ -3709,28 +3741,28 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, +@@ -3709,28 +3804,28 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, } static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, @@ -10760,7 +12527,29 @@ index c8a43adbe03..a86ca583e63 100644 { ERR("Invalid component_idx %u for register %#x, %u (write_mask %#x).\n", component_idx, reg->type, reg->idx[0].offset, reg_info->write_mask); -@@ -3756,6 +3788,69 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, +@@ -3749,13 +3844,89 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, + + if (component_type != reg_info->component_type) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); +- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) ++ { ++ if (reg_info->component_type != VKD3D_SHADER_COMPONENT_UINT) ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } ++ val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, ++ VKD3D_DATA_UINT, 1, val_id); ++ } ++ else ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } + } + return val_id; } @@ -10830,7 +12619,7 @@ index c8a43adbe03..a86ca583e63 100644 static const struct ssa_register_info *spirv_compiler_get_ssa_register_info(const struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg) { -@@ -3775,7 +3870,7 @@ static void spirv_compiler_set_ssa_register_info(const struct spirv_compiler *co +@@ -3775,7 +3946,7 @@ static void spirv_compiler_set_ssa_register_info(const struct spirv_compiler *co static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, enum vkd3d_shader_component_type component_type, @@ -10839,23 +12628,40 @@ index c8a43adbe03..a86ca583e63 100644 { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; enum vkd3d_shader_component_type reg_component_type; -@@ -3785,7 +3880,12 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler +@@ -3785,12 +3956,18 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler ssa = spirv_compiler_get_ssa_register_info(compiler, reg); val_id = ssa->id; - assert(val_id); +- assert(vkd3d_swizzle_is_scalar(swizzle)); + if (!val_id) + { + /* Should only be from a missing instruction implementation. */ + assert(compiler->failed); + return 0; + } - assert(vkd3d_swizzle_is_scalar(swizzle)); ++ assert(vkd3d_swizzle_is_scalar(swizzle, reg)); ++ ++ reg_component_type = vkd3d_component_type_from_data_type(ssa->data_type); if (reg->dimension == VSIR_DIMENSION_SCALAR) -@@ -3801,19 +3901,19 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler + { +- reg_component_type = vkd3d_component_type_from_data_type(ssa->data_type); + if (component_type != reg_component_type) + { + type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); +@@ -3800,20 +3977,28 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler + return val_id; } ++ if (component_type != reg_component_type) ++ { ++ /* Required for resource loads with sampled type int, because DXIL has no signedness. ++ * Only 128-bit vector sizes are used. */ ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - component_idx = vkd3d_swizzle_get_component(swizzle, 0); + component_idx = vsir_swizzle_get_component(swizzle, 0); @@ -10876,7 +12682,7 @@ index c8a43adbe03..a86ca583e63 100644 if (reg->type == VKD3DSPR_IMMCONST) return spirv_compiler_emit_load_constant(compiler, reg, swizzle, write_mask); -@@ -3822,7 +3922,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, +@@ -3822,7 +4007,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, else if (reg->type == VKD3DSPR_UNDEF) return spirv_compiler_emit_load_undef(compiler, reg, write_mask); @@ -10885,7 +12691,7 @@ index c8a43adbe03..a86ca583e63 100644 component_type = vkd3d_component_type_from_data_type(reg->data_type); if (reg->type == VKD3DSPR_SSA) -@@ -3836,21 +3936,21 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, +@@ -3836,31 +4021,45 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, assert(reg_info.component_type != VKD3D_SHADER_COMPONENT_DOUBLE); spirv_compiler_emit_dereference_register(compiler, reg, ®_info); @@ -10910,7 +12716,33 @@ index c8a43adbe03..a86ca583e63 100644 val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); } -@@ -3882,7 +3982,7 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler, ++ swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; + val_id = spirv_compiler_emit_swizzle(compiler, + val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask32); + + if (component_type != reg_info.component_type) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); +- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) ++ { ++ if (reg_info.component_type != VKD3D_SHADER_COMPONENT_UINT) ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } ++ val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, ++ VKD3D_DATA_UINT, component_count, val_id); ++ } ++ else ++ { ++ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); ++ } + } + + return val_id; +@@ -3882,7 +4081,7 @@ static void spirv_compiler_emit_execution_mode1(struct spirv_compiler *compiler, } static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler, @@ -10919,7 +12751,7 @@ index c8a43adbe03..a86ca583e63 100644 { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id; -@@ -3896,7 +3996,7 @@ static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler, +@@ -3896,7 +4095,7 @@ static uint32_t spirv_compiler_emit_abs(struct spirv_compiler *compiler, } static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, @@ -10928,7 +12760,7 @@ index c8a43adbe03..a86ca583e63 100644 { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id; -@@ -3904,7 +4004,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, +@@ -3904,7 +4103,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, type_id = spirv_compiler_get_type_id_for_reg(compiler, reg, write_mask); if (reg->data_type == VKD3D_DATA_FLOAT || reg->data_type == VKD3D_DATA_DOUBLE) return vkd3d_spirv_build_op_fnegate(builder, type_id, val_id); @@ -10937,7 +12769,7 @@ index c8a43adbe03..a86ca583e63 100644 return vkd3d_spirv_build_op_snegate(builder, type_id, val_id); FIXME("Unhandled data type %#x.\n", reg->data_type); -@@ -3912,7 +4012,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, +@@ -3912,7 +4111,7 @@ static uint32_t spirv_compiler_emit_neg(struct spirv_compiler *compiler, } static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler, @@ -10946,7 +12778,7 @@ index c8a43adbe03..a86ca583e63 100644 enum vkd3d_shader_src_modifier modifier, uint32_t val_id) { switch (modifier) -@@ -3935,7 +4035,7 @@ static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler +@@ -3935,7 +4134,7 @@ static uint32_t spirv_compiler_emit_src_modifier(struct spirv_compiler *compiler } static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, @@ -10955,7 +12787,7 @@ index c8a43adbe03..a86ca583e63 100644 { uint32_t val_id; -@@ -3944,7 +4044,7 @@ static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, +@@ -3944,7 +4143,7 @@ static uint32_t spirv_compiler_emit_load_src(struct spirv_compiler *compiler, } static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *compiler, @@ -10964,7 +12796,7 @@ index c8a43adbe03..a86ca583e63 100644 { struct vkd3d_shader_src_param src_param = *src; -@@ -3953,19 +4053,19 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co +@@ -3953,19 +4152,19 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co } static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, @@ -10989,7 +12821,7 @@ index c8a43adbe03..a86ca583e63 100644 index = spirv_compiler_get_constant_uint(compiler, component_idx); dst_id = vkd3d_spirv_build_op_in_bounds_access_chain1(builder, ptr_type_id, dst_id, index); } -@@ -3974,8 +4074,8 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, +@@ -3974,8 +4173,8 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, } static void spirv_compiler_emit_store(struct spirv_compiler *compiler, @@ -11000,7 +12832,7 @@ index c8a43adbe03..a86ca583e63 100644 { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int component_count, dst_component_count; -@@ -3985,14 +4085,14 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, +@@ -3985,14 +4184,14 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, assert(write_mask); @@ -11018,7 +12850,7 @@ index c8a43adbe03..a86ca583e63 100644 write_mask &= dst_write_mask; component_count = 1; } -@@ -4029,12 +4129,12 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, +@@ -4029,12 +4228,12 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, } static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, @@ -11033,7 +12865,7 @@ index c8a43adbe03..a86ca583e63 100644 uint32_t type_id; assert(!register_is_constant_or_undef(reg)); -@@ -4052,10 +4152,10 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, +@@ -4052,10 +4251,13 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, component_type = vkd3d_component_type_from_data_type(reg->data_type); if (component_type != reg_info.component_type) { @@ -11041,13 +12873,16 @@ index c8a43adbe03..a86ca583e63 100644 - src_write_mask = vkd3d_write_mask_32_from_64(write_mask); + if (data_type_is_64_bit(reg->data_type)) + src_write_mask = vsir_write_mask_32_from_64(write_mask); ++ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) ++ val_id = spirv_compiler_emit_bool_to_int(compiler, ++ vsir_write_mask_component_count(src_write_mask), val_id, false); type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, - vkd3d_write_mask_component_count(src_write_mask)); + vsir_write_mask_component_count(src_write_mask)); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); component_type = reg_info.component_type; } -@@ -4065,9 +4165,9 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, +@@ -4065,9 +4267,9 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, } static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, @@ -11059,7 +12894,7 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, zero_id, one_id; -@@ -4102,7 +4202,7 @@ static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, +@@ -4102,7 +4304,7 @@ static void spirv_compiler_emit_store_dst(struct spirv_compiler *compiler, static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, uint32_t val_id, @@ -11068,7 +12903,7 @@ index c8a43adbe03..a86ca583e63 100644 { struct vkd3d_shader_dst_param typed_dst = *dst; val_id = spirv_compiler_emit_swizzle(compiler, -@@ -4118,7 +4218,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp +@@ -4118,7 +4320,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp const struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_component_type component_type, uint32_t *component_ids) { @@ -11077,7 +12912,7 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, val_id; -@@ -4137,16 +4237,16 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp +@@ -4137,16 +4339,16 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp static void spirv_compiler_emit_store_dst_scalar(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst, uint32_t val_id, @@ -11098,7 +12933,7 @@ index c8a43adbe03..a86ca583e63 100644 ERR("Invalid swizzle %#x for scalar value, write mask %#x.\n", swizzle, dst->write_mask); component_ids[i] = val_id; -@@ -4169,10 +4269,58 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, +@@ -4169,10 +4371,58 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthReplacing, NULL, 0); break; case SpvBuiltInLayer: @@ -11159,7 +12994,7 @@ index c8a43adbe03..a86ca583e63 100644 break; case SpvBuiltInSampleId: vkd3d_spirv_enable_capability(builder, SpvCapabilitySampleRateShading); -@@ -4191,14 +4339,18 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, +@@ -4191,14 +4441,18 @@ static void spirv_compiler_decorate_builtin(struct spirv_compiler *compiler, } static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler *compiler, @@ -11180,48 +13015,116 @@ index c8a43adbe03..a86ca583e63 100644 case VKD3DSIM_CONSTANT: vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationFlat, NULL, 0); break; -@@ -4226,7 +4378,8 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler +@@ -4225,87 +4479,36 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler + } } - static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, +-static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - enum vkd3d_shader_conditional_op condition, unsigned int component_count, uint32_t val_id) -+ enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, -+ unsigned int component_count, uint32_t val_id) ++typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct spirv_compiler *compiler, ++ uint32_t val_id); ++ ++static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler *compiler, ++ uint32_t index_id, SpvBuiltIn base) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id; -@@ -4237,7 +4390,9 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); - op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; - return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, +- uint32_t type_id; +- SpvOp op; ++ uint32_t base_var_id, base_id, type_id; + +- assert(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); ++ vkd3d_spirv_enable_capability(builder, SpvCapabilityDrawParameters); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); +- op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; +- return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, - spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); -+ data_type == VKD3D_DATA_UINT64 -+ ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) -+ : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); +-} ++ base_var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, ++ SpvStorageClassInput, VKD3D_SHADER_COMPONENT_INT, 1); ++ vkd3d_spirv_add_iface_variable(builder, base_var_id); ++ spirv_compiler_decorate_builtin(compiler, base_var_id, base); + +-static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, +- unsigned int component_count, uint32_t val_id, bool signedness) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, true_id, false_id; ++ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); ++ base_id = vkd3d_spirv_build_op_load(builder, ++ type_id, base_var_id, SpvMemoryAccessMaskNone); + +- true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); +- false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); +- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); ++ return vkd3d_spirv_build_op_isub(builder, type_id, index_id, base_id); } - static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, -@@ -4252,6 +4407,19 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -+static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler, -+ unsigned int component_count, uint32_t val_id, bool signedness) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ uint32_t type_id, true_id, false_id; -+ -+ true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, -+ component_count); -+ false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); -+ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); -+} -+ - static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, - unsigned int component_count, uint32_t val_id, bool signedness) +-static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, +- unsigned int component_count, uint32_t val_id, bool signedness) ++/* Substitute "VertexIndex - BaseVertex" for SV_VertexID. */ ++static uint32_t sv_vertex_id_fixup(struct spirv_compiler *compiler, ++ uint32_t vertex_index_id) { -@@ -4422,9 +4590,9 @@ vkd3d_register_builtins[] = +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, true_id, false_id; +- +- true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); +- false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); +- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +-} +- +-static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compiler, +- unsigned int component_count, uint32_t val_id, bool signedness) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t type_id, true_id, false_id; +- +- true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); +- false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); +- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); +-} +- +-typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct spirv_compiler *compiler, +- uint32_t val_id); +- +-static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler *compiler, +- uint32_t index_id, SpvBuiltIn base) +-{ +- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- uint32_t base_var_id, base_id, type_id; +- +- vkd3d_spirv_enable_capability(builder, SpvCapabilityDrawParameters); +- +- base_var_id = spirv_compiler_emit_variable(compiler, &builder->global_stream, +- SpvStorageClassInput, VKD3D_SHADER_COMPONENT_INT, 1); +- vkd3d_spirv_add_iface_variable(builder, base_var_id); +- spirv_compiler_decorate_builtin(compiler, base_var_id, base); +- +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); +- base_id = vkd3d_spirv_build_op_load(builder, +- type_id, base_var_id, SpvMemoryAccessMaskNone); +- +- return vkd3d_spirv_build_op_isub(builder, type_id, index_id, base_id); +-} +- +-/* Substitute "VertexIndex - BaseVertex" for SV_VertexID. */ +-static uint32_t sv_vertex_id_fixup(struct spirv_compiler *compiler, +- uint32_t vertex_index_id) +-{ +- return spirv_compiler_emit_draw_parameter_fixup(compiler, +- vertex_index_id, SpvBuiltInBaseVertex); +-} ++ return spirv_compiler_emit_draw_parameter_fixup(compiler, ++ vertex_index_id, SpvBuiltInBaseVertex); ++} + + /* Substitute "InstanceIndex - BaseInstance" for SV_InstanceID. */ + static uint32_t sv_instance_id_fixup(struct spirv_compiler *compiler, +@@ -4422,9 +4625,9 @@ vkd3d_register_builtins[] = }; static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *compiler, @@ -11233,7 +13136,7 @@ index c8a43adbe03..a86ca583e63 100644 { case VKD3DSPR_DEPTHOUTGE: spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeDepthGreater, NULL, 0); -@@ -4437,9 +4605,9 @@ static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *c +@@ -4437,9 +4640,9 @@ static void spirv_compiler_emit_register_execution_mode(struct spirv_compiler *c VKD3D_SHADER_SPIRV_EXTENSION_EXT_STENCIL_EXPORT)) { FIXME("The target environment does not support stencil export.\n"); @@ -11246,7 +13149,7 @@ index c8a43adbe03..a86ca583e63 100644 } vkd3d_spirv_enable_capability(&compiler->spirv_builder, SpvCapabilityStencilExportEXT); spirv_compiler_emit_execution_mode(compiler, SpvExecutionModeStencilRefReplacingEXT, NULL, 0); -@@ -4635,7 +4803,7 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co +@@ -4635,7 +4838,7 @@ static uint32_t spirv_compiler_emit_builtin_variable_v(struct spirv_compiler *co assert(size_count <= ARRAY_SIZE(sizes)); memcpy(sizes, array_sizes, size_count * sizeof(sizes[0])); array_sizes = sizes; @@ -11255,7 +13158,7 @@ index c8a43adbe03..a86ca583e63 100644 id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, builtin->component_type, builtin->component_count, array_sizes, size_count); -@@ -4674,17 +4842,16 @@ static unsigned int shader_signature_next_location(const struct shader_signature +@@ -4674,17 +4877,16 @@ static unsigned int shader_signature_next_location(const struct shader_signature } static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, @@ -11275,15 +13178,15 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_symbol *symbol = NULL; uint32_t val_id, input_id, var_id; uint32_t type_id, float_type_id; -@@ -4693,31 +4860,26 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4693,31 +4895,26 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, struct rb_entry *entry = NULL; bool use_private_var = false; unsigned int array_sizes[2]; - unsigned int element_idx; - +- - assert(!reg->idx_count || !reg->idx[0].rel_addr); - assert(reg->idx_count < 2 || !reg->idx[1].rel_addr); -- + - shader_signature = reg->type == VKD3DSPR_PATCHCONST + shader_signature = reg_type == VKD3DSPR_PATCHCONST ? &compiler->patch_constant_signature : &compiler->input_signature; @@ -11314,7 +13217,7 @@ index c8a43adbe03..a86ca583e63 100644 } write_mask = signature_element->mask; -@@ -4731,8 +4893,8 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4731,8 +4928,8 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, else { component_type = signature_element->component_type; @@ -11325,7 +13228,7 @@ index c8a43adbe03..a86ca583e63 100644 } if (needs_private_io_variable(builtin)) -@@ -4742,13 +4904,13 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4742,13 +4939,13 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, } else { @@ -11341,7 +13244,7 @@ index c8a43adbe03..a86ca583e63 100644 if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) { -@@ -4756,7 +4918,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4756,7 +4953,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, * duplicate declarations are: a single register split into multiple declarations having * different components, which should have been merged, and declarations in one phase * being repeated in another (i.e. vcp/vocp), which should have been deleted. */ @@ -11350,7 +13253,7 @@ index c8a43adbe03..a86ca583e63 100644 FIXME("Duplicate input definition found.\n"); symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); return symbol->id; -@@ -4765,7 +4927,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4765,7 +4962,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, if (builtin) { input_id = spirv_compiler_emit_builtin_variable_v(compiler, builtin, storage_class, array_sizes, 2); @@ -11359,7 +13262,7 @@ index c8a43adbe03..a86ca583e63 100644 vkd3d_spirv_build_op_decorate(builder, input_id, SpvDecorationPatch, NULL, 0); } else -@@ -4775,7 +4937,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4775,7 +4972,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, input_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, component_type, input_component_count, array_sizes, 2); vkd3d_spirv_add_iface_variable(builder, input_id); @@ -11368,7 +13271,7 @@ index c8a43adbe03..a86ca583e63 100644 { vkd3d_spirv_build_op_decorate(builder, input_id, SpvDecorationPatch, NULL, 0); location += shader_signature_next_location(&compiler->input_signature); -@@ -4784,7 +4946,8 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4784,7 +4981,8 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, if (component_idx) vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx); @@ -11378,7 +13281,7 @@ index c8a43adbe03..a86ca583e63 100644 } var_id = input_id; -@@ -4802,12 +4965,14 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4802,12 +5000,14 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, assert(!builtin || !builtin->spirv_array_size || use_private_var || array_sizes[0] || array_sizes[1]); spirv_compiler_put_symbol(compiler, ®_symbol); @@ -11396,7 +13299,7 @@ index c8a43adbe03..a86ca583e63 100644 type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count); -@@ -4824,9 +4989,9 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4824,9 +5024,9 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, val_id = spirv_compiler_emit_swizzle(compiler, val_id, vkd3d_write_mask_from_component_count(input_component_count), @@ -11408,7 +13311,7 @@ index c8a43adbe03..a86ca583e63 100644 } return input_id; -@@ -4896,7 +5061,7 @@ static void calculate_clip_or_cull_distance_mask(const struct signature_element +@@ -4896,7 +5096,7 @@ static void calculate_clip_or_cull_distance_mask(const struct signature_element return; } @@ -11417,7 +13320,7 @@ index c8a43adbe03..a86ca583e63 100644 *mask |= (write_mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); } -@@ -4995,7 +5160,7 @@ static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler, +@@ -4995,7 +5195,7 @@ static void spirv_compiler_emit_output_register(struct spirv_compiler *compiler, SpvStorageClassOutput, builtin->component_type, write_mask); reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; spirv_compiler_put_symbol(compiler, ®_symbol); @@ -11426,7 +13329,7 @@ index c8a43adbe03..a86ca583e63 100644 spirv_compiler_emit_register_debug_name(builder, output_id, reg); } -@@ -5024,46 +5189,44 @@ static uint32_t spirv_compiler_emit_shader_phase_builtin_variable(struct spirv_c +@@ -5024,46 +5224,44 @@ static uint32_t spirv_compiler_emit_shader_phase_builtin_variable(struct spirv_c return id; } @@ -11484,7 +13387,7 @@ index c8a43adbe03..a86ca583e63 100644 if (builtin) { component_type = builtin->component_type; -@@ -5077,15 +5240,18 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st +@@ -5077,15 +5275,18 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st storage_class = SpvStorageClassOutput; @@ -11507,7 +13410,7 @@ index c8a43adbe03..a86ca583e63 100644 if (rb_get(&compiler->symbol_table, ®_symbol)) { -@@ -5094,7 +5260,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st +@@ -5094,7 +5295,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st return; } @@ -11516,7 +13419,7 @@ index c8a43adbe03..a86ca583e63 100644 { id = compiler->output_info[element_idx].id; } -@@ -5105,7 +5271,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st +@@ -5105,7 +5306,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st else id = spirv_compiler_emit_builtin_variable_v(compiler, builtin, storage_class, array_sizes, 2); @@ -11525,7 +13428,7 @@ index c8a43adbe03..a86ca583e63 100644 } else if (signature_element->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) { -@@ -5146,8 +5312,11 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st +@@ -5146,8 +5347,11 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st spirv_compiler_decorate_xfb_output(compiler, id, output_component_count, signature_element); @@ -11539,7 +13442,7 @@ index c8a43adbe03..a86ca583e63 100644 var_id = id; if (use_private_variable) -@@ -5165,8 +5334,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st +@@ -5165,8 +5369,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, const st spirv_compiler_put_symbol(compiler, ®_symbol); @@ -11549,7 +13452,7 @@ index c8a43adbe03..a86ca583e63 100644 if (use_private_variable) { -@@ -5198,9 +5366,9 @@ static uint32_t spirv_compiler_get_output_array_index(struct spirv_compiler *com +@@ -5198,9 +5401,9 @@ static uint32_t spirv_compiler_get_output_array_index(struct spirv_compiler *com static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compiler, const struct shader_signature *signature, const struct signature_element *output, const struct vkd3d_shader_output_info *output_info, @@ -11561,7 +13464,7 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, zero_id, ptr_type_id, chain_id, object_id; const struct signature_element *element; -@@ -5222,7 +5390,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi +@@ -5222,7 +5425,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi use_mask |= element->used_mask; } } @@ -11570,7 +13473,7 @@ index c8a43adbe03..a86ca583e63 100644 dst_write_mask >>= index; use_mask >>= index; write_mask &= dst_write_mask; -@@ -5246,7 +5414,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi +@@ -5246,7 +5449,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi output_info->component_type, VKD3D_VEC4_SIZE, 0); val_id = spirv_compiler_emit_vector_shuffle(compiler, zero_id, val_id, swizzle, uninit_mask, output_info->component_type, @@ -11579,7 +13482,7 @@ index c8a43adbe03..a86ca583e63 100644 } else { -@@ -5258,7 +5426,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi +@@ -5258,7 +5461,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi if (output_index_id) { type_id = vkd3d_spirv_get_type_id(builder, @@ -11588,7 +13491,7 @@ index c8a43adbe03..a86ca583e63 100644 ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id); } -@@ -5412,7 +5580,6 @@ static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *comp +@@ -5412,7 +5615,6 @@ static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *comp if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) { vkd3d_spirv_builder_begin_main_function(builder); @@ -11596,7 +13499,7 @@ index c8a43adbe03..a86ca583e63 100644 } } -@@ -5440,10 +5607,34 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler +@@ -5440,10 +5642,34 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler if (flags & (VKD3DSGF_ENABLE_DOUBLE_PRECISION_FLOAT_OPS | VKD3DSGF_ENABLE_11_1_DOUBLE_EXTENSIONS)) { @@ -11632,7 +13535,7 @@ index c8a43adbe03..a86ca583e63 100644 if (flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_ENABLE_RAW_AND_STRUCTURED_BUFFERS)) FIXME("Unhandled global flags %#"PRIx64".\n", (uint64_t)flags); else -@@ -5493,39 +5684,43 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil +@@ -5493,39 +5719,43 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil { const struct vkd3d_shader_indexable_temp *temp = &instruction->declaration.indexable_temp; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -11689,7 +13592,7 @@ index c8a43adbe03..a86ca583e63 100644 spirv_compiler_put_symbol(compiler, ®_symbol); } -@@ -5743,34 +5938,24 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi +@@ -5743,34 +5973,24 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_immediate_constant_buffer *icb = instruction->declaration.icb; @@ -11731,7 +13634,7 @@ index c8a43adbe03..a86ca583e63 100644 spirv_compiler_put_symbol(compiler, ®_symbol); } -@@ -6052,6 +6237,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp +@@ -6052,6 +6272,9 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); @@ -11741,7 +13644,7 @@ index c8a43adbe03..a86ca583e63 100644 if (d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER) { assert(structure_stride); /* counters are valid only for structured buffers */ -@@ -6147,37 +6335,22 @@ static void spirv_compiler_emit_dcl_input(struct spirv_compiler *compiler, +@@ -6147,37 +6370,22 @@ static void spirv_compiler_emit_dcl_input(struct spirv_compiler *compiler, { const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst; @@ -11784,7 +13687,7 @@ index c8a43adbe03..a86ca583e63 100644 static void spirv_compiler_emit_dcl_stream(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { -@@ -6256,7 +6429,7 @@ static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compi +@@ -6256,7 +6464,7 @@ static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compi { case VKD3D_PT_POINTLIST: mode = SpvExecutionModeOutputPoints; @@ -11793,7 +13696,7 @@ index c8a43adbe03..a86ca583e63 100644 break; case VKD3D_PT_LINESTRIP: mode = SpvExecutionModeOutputLineStrip; -@@ -6377,7 +6550,6 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile +@@ -6377,7 +6585,6 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) { @@ -11801,7 +13704,7 @@ index c8a43adbe03..a86ca583e63 100644 struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; if (is_in_control_point_phase(compiler) && compiler->emit_default_control_point_phase) -@@ -6395,7 +6567,6 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) +@@ -6395,7 +6602,6 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) /* Fork and join phases share output registers (patch constants). * Control point phase has separate output registers. */ @@ -11809,7 +13712,7 @@ index c8a43adbe03..a86ca583e63 100644 memset(compiler->private_output_variable, 0, sizeof(compiler->private_output_variable)); memset(compiler->private_output_variable_write_mask, 0, sizeof(compiler->private_output_variable_write_mask)); } -@@ -6420,35 +6591,59 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, +@@ -6420,35 +6626,59 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, vkd3d_spirv_build_op_function(builder, void_id, function_id, SpvFunctionControlMaskNone, function_type_id); @@ -11876,7 +13779,7 @@ index c8a43adbe03..a86ca583e63 100644 invocation_id = spirv_compiler_emit_load_invocation_id(compiler); memset(&invocation, 0, sizeof(invocation)); -@@ -6466,6 +6661,8 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile +@@ -6466,6 +6696,8 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile { const struct signature_element *output = &output_signature->elements[i]; const struct signature_element *input = &input_signature->elements[i]; @@ -11885,7 +13788,7 @@ index c8a43adbe03..a86ca583e63 100644 assert(input->mask == output->mask); assert(input->component_type == output->component_type); -@@ -6473,22 +6670,16 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile +@@ -6473,22 +6705,16 @@ static void spirv_compiler_emit_default_control_point_phase(struct spirv_compile input_reg.idx[1].offset = i; input_id = spirv_compiler_get_register_id(compiler, &input_reg); @@ -11915,7 +13818,7 @@ index c8a43adbe03..a86ca583e63 100644 vkd3d_spirv_build_op_copy_memory(builder, dst_id, input_id, SpvMemoryAccessMaskNone); } -@@ -6547,7 +6738,11 @@ static void spirv_compiler_emit_hull_shader_main(struct spirv_compiler *compiler +@@ -6547,7 +6773,11 @@ static void spirv_compiler_emit_hull_shader_main(struct spirv_compiler *compiler struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t void_id; @@ -11927,7 +13830,7 @@ index c8a43adbe03..a86ca583e63 100644 void_id = vkd3d_spirv_get_op_type_void(builder); -@@ -6591,14 +6786,18 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru +@@ -6591,14 +6821,18 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru {VKD3DSIH_INEG, SpvOpSNegate}, {VKD3DSIH_ISHL, SpvOpShiftLeftLogical}, {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic}, @@ -11946,7 +13849,7 @@ index c8a43adbe03..a86ca583e63 100644 {VKD3DSIH_XOR, SpvOpBitwiseXor}, }; unsigned int i; -@@ -6650,6 +6849,10 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, +@@ -6650,6 +6884,10 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, { val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->handler_idx == VKD3DSIH_ITOI); } @@ -11957,7 +13860,7 @@ index c8a43adbe03..a86ca583e63 100644 else { WARN("Unhandled data type %u.\n", dst->reg.data_type); -@@ -6715,11 +6918,11 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -6715,11 +6953,11 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil * Microsoft fxc will compile immediate constants larger than 5 bits. * Fixing up the constants would be more elegant, but the simplest way is * to let this handle constants too. */ @@ -11972,7 +13875,7 @@ index c8a43adbe03..a86ca583e63 100644 src_ids[1] = vkd3d_spirv_build_op_and(builder, type_id, src_ids[1], mask_id); } -@@ -6732,6 +6935,23 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil +@@ -6732,6 +6970,23 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil return VKD3D_OK; } @@ -11996,7 +13899,27 @@ index c8a43adbe03..a86ca583e63 100644 static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( const struct vkd3d_shader_instruction *instruction) { -@@ -6762,6 +6982,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( +@@ -6742,6 +6997,9 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( + } + glsl_insts[] = + { ++ {VKD3DSIH_ACOS, GLSLstd450Acos}, ++ {VKD3DSIH_ASIN, GLSLstd450Asin}, ++ {VKD3DSIH_ATAN, GLSLstd450Atan}, + {VKD3DSIH_DFMA, GLSLstd450Fma}, + {VKD3DSIH_DMAX, GLSLstd450NMax}, + {VKD3DSIH_DMIN, GLSLstd450NMin}, +@@ -6750,6 +7008,9 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( + {VKD3DSIH_FIRSTBIT_LO, GLSLstd450FindILsb}, + {VKD3DSIH_FIRSTBIT_SHI, GLSLstd450FindSMsb}, + {VKD3DSIH_FRC, GLSLstd450Fract}, ++ {VKD3DSIH_HCOS, GLSLstd450Cosh}, ++ {VKD3DSIH_HSIN, GLSLstd450Sinh}, ++ {VKD3DSIH_HTAN, GLSLstd450Tanh}, + {VKD3DSIH_IMAX, GLSLstd450SMax}, + {VKD3DSIH_IMIN, GLSLstd450SMin}, + {VKD3DSIH_LOG, GLSLstd450Log2}, +@@ -6762,6 +7023,7 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( {VKD3DSIH_ROUND_Z, GLSLstd450Trunc}, {VKD3DSIH_RSQ, GLSLstd450InverseSqrt}, {VKD3DSIH_SQRT, GLSLstd450Sqrt}, @@ -12004,7 +13927,7 @@ index c8a43adbe03..a86ca583e63 100644 {VKD3DSIH_UMAX, GLSLstd450UMax}, {VKD3DSIH_UMIN, GLSLstd450UMin}, }; -@@ -6779,13 +7000,13 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( +@@ -6779,13 +7041,13 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -12020,7 +13943,7 @@ index c8a43adbe03..a86ca583e63 100644 glsl_inst = spirv_compiler_map_ext_glsl_instruction(instruction); if (glsl_inst == GLSLstd450Bad) -@@ -6811,8 +7032,13 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp +@@ -6811,8 +7073,13 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp || instruction->handler_idx == VKD3DSIH_FIRSTBIT_SHI) { /* In D3D bits are numbered from the most significant bit. */ @@ -12036,25 +13959,42 @@ index c8a43adbe03..a86ca583e63 100644 } spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -6849,7 +7075,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, +@@ -6821,11 +7088,11 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp + static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, + const struct vkd3d_shader_instruction *instruction) + { ++ uint32_t val_id, dst_val_id, type_id, dst_id, src_id, write_mask32, swizzle32; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + struct vkd3d_shader_register_info dst_reg_info, src_reg_info; + const struct vkd3d_shader_dst_param *dst = instruction->dst; + const struct vkd3d_shader_src_param *src = instruction->src; +- uint32_t val_id, dst_val_id, type_id, dst_id, src_id; + uint32_t components[VKD3D_VEC4_SIZE]; + unsigned int i, component_count; + +@@ -6849,7 +7116,9 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, return; } - component_count = vkd3d_write_mask_component_count(dst->write_mask); -+ component_count = vsir_write_mask_component_count(dst->write_mask); ++ write_mask32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_write_mask_32_from_64(dst->write_mask) : dst->write_mask; ++ swizzle32 = data_type_is_64_bit(src->reg.data_type) ? vsir_swizzle_32_from_64(src->swizzle) : src->swizzle; ++ component_count = vsir_write_mask_component_count(write_mask32); if (component_count != 1 && component_count != VKD3D_VEC4_SIZE && dst_reg_info.write_mask == VKD3DSP_WRITEMASK_ALL) { -@@ -6863,7 +7089,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, +@@ -6862,8 +7131,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, + for (i = 0; i < ARRAY_SIZE(components); ++i) { - if (dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)) +- if (dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)) - components[i] = VKD3D_VEC4_SIZE + vkd3d_swizzle_get_component(src->swizzle, i); -+ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(src->swizzle, i); ++ if (write_mask32 & (VKD3DSP_WRITEMASK_0 << i)) ++ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle32, i); else components[i] = i; } -@@ -6877,6 +7103,11 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, +@@ -6877,6 +7146,11 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, general_implementation: val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); @@ -12066,7 +14006,7 @@ index c8a43adbe03..a86ca583e63 100644 spirv_compiler_emit_store_dst(compiler, dst, val_id); } -@@ -6893,12 +7124,12 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, +@@ -6893,12 +7167,12 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); @@ -12081,7 +14021,7 @@ index c8a43adbe03..a86ca583e63 100644 val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src1_id, src2_id); spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -6919,11 +7150,11 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, +@@ -6919,11 +7193,11 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); @@ -12095,7 +14035,7 @@ index c8a43adbe03..a86ca583e63 100644 val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, src2_id, src1_id); spirv_compiler_emit_store_dst(compiler, &dst[0], val_id); -@@ -6940,9 +7171,9 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, +@@ -6940,9 +7214,9 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type; uint32_t type_id, val_id, src_ids[2]; unsigned int component_count, i; @@ -12107,7 +14047,7 @@ index c8a43adbe03..a86ca583e63 100644 component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); if (instruction->handler_idx == VKD3DSIH_DP4) -@@ -6980,7 +7211,7 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, +@@ -6980,7 +7254,7 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, uint32_t type_id, src_id, val_id, div_id; unsigned int component_count; @@ -12116,7 +14056,7 @@ index c8a43adbe03..a86ca583e63 100644 type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); -@@ -7060,7 +7291,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, +@@ -7060,7 +7334,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, uint32_t type_id, val_id, src_ids[3]; unsigned int i, component_count; @@ -12125,7 +14065,7 @@ index c8a43adbe03..a86ca583e63 100644 type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, component_count); for (i = 0; i < ARRAY_SIZE(src_ids); ++i) -@@ -7087,16 +7318,18 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, +@@ -7087,16 +7361,18 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, if (dst[0].reg.type != VKD3DSPR_NULL) { @@ -12148,7 +14088,7 @@ index c8a43adbe03..a86ca583e63 100644 val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id); /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ -@@ -7109,16 +7342,18 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, +@@ -7109,16 +7385,18 @@ static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, { if (!component_count || dst[0].write_mask != dst[1].write_mask) { @@ -12171,7 +14111,7 @@ index c8a43adbe03..a86ca583e63 100644 } val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id); -@@ -7147,7 +7382,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, +@@ -7147,7 +7425,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, * as a signed integer, but Direct3D expects the result to saturate, * and for NaN to yield zero. */ @@ -12180,7 +14120,7 @@ index c8a43adbe03..a86ca583e63 100644 src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask); dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); -@@ -7200,7 +7435,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, +@@ -7200,7 +7478,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, * as an unsigned integer, but Direct3D expects the result to saturate, * and for NaN to yield zero. */ @@ -12189,7 +14129,7 @@ index c8a43adbe03..a86ca583e63 100644 src_type_id = spirv_compiler_get_type_id_for_reg(compiler, &src->reg, dst->write_mask); dst_type_id = spirv_compiler_get_type_id_for_dst(compiler, dst); src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); -@@ -7232,13 +7467,13 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, +@@ -7232,13 +7510,13 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -12199,21 +14139,25 @@ index c8a43adbe03..a86ca583e63 100644 const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; enum vkd3d_shader_component_type component_type; - unsigned int i, j, k, src_count; +- unsigned int i, j, k, src_count; - DWORD write_mask; ++ unsigned int i, j, k, src_count, size; + uint32_t write_mask; SpvOp op; src_count = instruction->src_count; -@@ -7247,6 +7482,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp +@@ -7246,7 +7524,9 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp + component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - mask_id = spirv_compiler_get_constant_uint(compiler, 0x1f); -+ size_id = spirv_compiler_get_constant_uint(compiler, 0x20); +- mask_id = spirv_compiler_get_constant_uint(compiler, 0x1f); ++ size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20; ++ mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); ++ size_id = spirv_compiler_get_constant_uint(compiler, size); switch (instruction->handler_idx) { -@@ -7275,6 +7511,9 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp +@@ -7275,6 +7555,9 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp { src_ids[j] = vkd3d_spirv_build_op_and(builder, type_id, src_ids[j], mask_id); } @@ -12223,7 +14167,7 @@ index c8a43adbe03..a86ca583e63 100644 constituents[k++] = vkd3d_spirv_build_op_trv(builder, &builder->function_stream, op, type_id, src_ids, src_count); -@@ -7291,8 +7530,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, +@@ -7291,8 +7574,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t components[VKD3D_VEC4_SIZE]; @@ -12233,7 +14177,7 @@ index c8a43adbe03..a86ca583e63 100644 instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -@@ -7324,8 +7563,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, +@@ -7324,8 +7607,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t components[VKD3D_VEC4_SIZE]; @@ -12243,7 +14187,7 @@ index c8a43adbe03..a86ca583e63 100644 instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -@@ -7387,7 +7626,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co +@@ -7387,7 +7670,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co return; } @@ -12252,7 +14196,7 @@ index c8a43adbe03..a86ca583e63 100644 src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); -@@ -7409,7 +7648,7 @@ static uint32_t spirv_compiler_emit_conditional_branch(struct spirv_compiler *co +@@ -7409,7 +7692,7 @@ static uint32_t spirv_compiler_emit_conditional_branch(struct spirv_compiler *co uint32_t condition_id, merge_block_id; condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); @@ -12261,7 +14205,7 @@ index c8a43adbe03..a86ca583e63 100644 merge_block_id = vkd3d_spirv_alloc_id(builder); -@@ -7445,16 +7684,39 @@ static void spirv_compiler_emit_retc(struct spirv_compiler *compiler, +@@ -7445,16 +7728,39 @@ static void spirv_compiler_emit_retc(struct spirv_compiler *compiler, vkd3d_spirv_build_op_label(builder, merge_block_id); } @@ -12307,7 +14251,7 @@ index c8a43adbe03..a86ca583e63 100644 if (spirv_compiler_is_target_extension_supported(compiler, VKD3D_SHADER_SPIRV_EXTENSION_EXT_DEMOTE_TO_HELPER_INVOCATION)) -@@ -7469,381 +7731,151 @@ static void spirv_compiler_emit_kill(struct spirv_compiler *compiler, +@@ -7469,381 +7775,158 @@ static void spirv_compiler_emit_kill(struct spirv_compiler *compiler, } vkd3d_spirv_build_op_label(builder, merge_block_id); @@ -12585,7 +14529,8 @@ index c8a43adbe03..a86ca583e63 100644 - break; - - case VKD3DSIH_CASE: -- { ++ if (instruction->src_count > 1) + { - uint32_t label_id, value; - - assert(compiler->control_flow_depth); @@ -12680,8 +14625,7 @@ index c8a43adbe03..a86ca583e63 100644 - } - - case VKD3DSIH_CONTINUE: -+ if (instruction->src_count > 1) - { +- { - struct vkd3d_control_flow_info *loop_cf_info; - - assert(compiler->control_flow_depth); @@ -12697,7 +14641,10 @@ index c8a43adbe03..a86ca583e63 100644 - cf_info->inside_block = false; - break; + /* Loop merge only. Must have a merge block and a continue block. */ -+ spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset); ++ if (instruction->src_count == 3) ++ spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset); ++ else ++ ERR("Invalid branch with %u sources.\n", instruction->src_count); } + vkd3d_spirv_build_op_branch(builder, spirv_compiler_get_label_id(compiler, src[0].reg.idx[0].offset)); + return; @@ -12712,7 +14659,7 @@ index c8a43adbe03..a86ca583e63 100644 - ERR("Invalid 'continuec' instruction outside loop.\n"); - return VKD3D_ERROR_INVALID_SHADER; - } -+ if (!vkd3d_swizzle_is_scalar(src->swizzle)) ++ if (!vkd3d_swizzle_is_scalar(src->swizzle, &src->reg)) + { + WARN("Unexpected src swizzle %#x.\n", src->swizzle); + spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE, @@ -12725,11 +14672,15 @@ index c8a43adbe03..a86ca583e63 100644 - break; - } + condition_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); -+ condition_id = spirv_compiler_emit_int_to_bool(compiler, -+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id); ++ if (src[0].reg.data_type != VKD3D_DATA_BOOL) ++ condition_id = spirv_compiler_emit_int_to_bool(compiler, ++ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id); + /* Emit the merge immediately before the branch instruction. */ -+ spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset, -+ (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0); ++ if (instruction->src_count >= 4) ++ spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset, ++ (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0); ++ else ++ ERR("Invalid branch with %u sources.\n", instruction->src_count); + vkd3d_spirv_build_op_branch_conditional(builder, condition_id, + spirv_compiler_get_label_id(compiler, src[1].reg.idx[0].offset), + spirv_compiler_get_label_id(compiler, src[2].reg.idx[0].offset)); @@ -12751,7 +14702,7 @@ index c8a43adbe03..a86ca583e63 100644 - else - compiler->main_block_open = false; - break; -+ if (!vkd3d_swizzle_is_scalar(src[0].swizzle)) ++ if (!vkd3d_swizzle_is_scalar(src[0].swizzle, &src[0].reg)) + { + WARN("Unexpected src swizzle %#x.\n", src[0].swizzle); + spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE, @@ -12795,7 +14746,7 @@ index c8a43adbe03..a86ca583e63 100644 } static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compiler, -@@ -8090,7 +8122,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, +@@ -8090,7 +8173,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, unsigned int image_operand_count = 0; struct vkd3d_shader_image image; uint32_t image_operands[2]; @@ -12804,7 +14755,7 @@ index c8a43adbe03..a86ca583e63 100644 bool multisample; multisample = instruction->handler_idx == VKD3DSIH_LD2DMS; -@@ -8164,7 +8196,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, +@@ -8164,7 +8247,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, unsigned int image_operand_count = 0; struct vkd3d_shader_image image; uint32_t image_operands[3]; @@ -12813,7 +14764,7 @@ index c8a43adbe03..a86ca583e63 100644 SpvOp op; resource = &src[1]; -@@ -8280,7 +8312,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, +@@ -8280,7 +8363,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, struct vkd3d_shader_image image; unsigned int component_idx; uint32_t image_operands[1]; @@ -12822,7 +14773,7 @@ index c8a43adbe03..a86ca583e63 100644 bool extended_offset; if (instruction->handler_idx == VKD3DSIH_GATHER4_C -@@ -8325,7 +8357,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, +@@ -8325,7 +8408,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, } else { @@ -12831,7 +14782,7 @@ index c8a43adbe03..a86ca583e63 100644 /* Nvidia driver requires signed integer type. */ component_id = spirv_compiler_get_constant(compiler, VKD3D_SHADER_COMPONENT_INT, 1, &component_idx); -@@ -8340,13 +8372,13 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, +@@ -8340,13 +8423,13 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, static uint32_t spirv_compiler_emit_raw_structured_addressing( struct spirv_compiler *compiler, uint32_t type_id, unsigned int stride, @@ -12848,7 +14799,7 @@ index c8a43adbe03..a86ca583e63 100644 if (stride) { -@@ -8403,7 +8435,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler +@@ -8403,7 +8486,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) continue; @@ -12857,7 +14808,7 @@ index c8a43adbe03..a86ca583e63 100644 coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, -@@ -8435,7 +8467,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler +@@ -8435,7 +8518,7 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) continue; @@ -12866,7 +14817,7 @@ index c8a43adbe03..a86ca583e63 100644 coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, -@@ -8447,7 +8479,6 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler +@@ -8447,7 +8530,6 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler type_id, val_id, 0); } } @@ -12874,7 +14825,7 @@ index c8a43adbe03..a86ca583e63 100644 spirv_compiler_emit_store_dst_components(compiler, dst, VKD3D_SHADER_COMPONENT_UINT, constituents); } -@@ -8479,7 +8510,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, +@@ -8479,7 +8561,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, if (!(dst->write_mask & (VKD3DSP_WRITEMASK_0 << i))) continue; @@ -12883,7 +14834,7 @@ index c8a43adbe03..a86ca583e63 100644 coordinate_id = base_coordinate_id; if (component_idx) coordinate_id = vkd3d_spirv_build_op_iadd(builder, type_id, -@@ -8540,7 +8571,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * +@@ -8540,7 +8622,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * assert(data->reg.data_type == VKD3D_DATA_UINT); val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); @@ -12892,7 +14843,7 @@ index c8a43adbe03..a86ca583e63 100644 for (component_idx = 0; component_idx < component_count; ++component_idx) { data_id = component_count > 1 ? -@@ -8569,7 +8600,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * +@@ -8569,7 +8651,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * assert(data->reg.data_type == VKD3D_DATA_UINT); val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); @@ -12901,7 +14852,7 @@ index c8a43adbe03..a86ca583e63 100644 for (component_idx = 0; component_idx < component_count; ++component_idx) { /* Mesa Vulkan drivers require the texel parameter to be a vector. */ -@@ -8613,7 +8644,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, +@@ -8613,7 +8695,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, assert(data->reg.data_type == VKD3D_DATA_UINT); val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask); @@ -12910,7 +14861,7 @@ index c8a43adbe03..a86ca583e63 100644 for (component_idx = 0; component_idx < component_count; ++component_idx) { data_id = component_count > 1 ? -@@ -8655,7 +8686,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, +@@ -8655,7 +8737,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src = instruction->src; const struct vkd3d_symbol *resource_symbol; struct vkd3d_shader_image image; @@ -12919,7 +14870,7 @@ index c8a43adbe03..a86ca583e63 100644 uint32_t indices[2]; resource_symbol = spirv_compiler_find_resource(compiler, &src[1].reg); -@@ -8698,7 +8729,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, +@@ -8698,7 +8780,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src = instruction->src; const struct vkd3d_symbol *resource_symbol; struct vkd3d_shader_image image; @@ -12928,7 +14879,7 @@ index c8a43adbe03..a86ca583e63 100644 uint32_t indices[2]; resource_symbol = spirv_compiler_find_resource(compiler, &dst->reg); -@@ -8864,7 +8895,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil +@@ -8864,7 +8946,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil struct vkd3d_shader_register_info reg_info; struct vkd3d_shader_image image; unsigned int structure_stride; @@ -12937,7 +14888,7 @@ index c8a43adbe03..a86ca583e63 100644 uint32_t operands[6]; unsigned int i = 0; SpvScope scope; -@@ -9275,7 +9306,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, +@@ -9275,7 +9357,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, } type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, @@ -12946,7 +14897,7 @@ index c8a43adbe03..a86ca583e63 100644 instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, op, src_ids, src_count); -@@ -9296,9 +9327,9 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, +@@ -9296,9 +9378,9 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { unsigned int memory_semantics = SpvMemorySemanticsAcquireReleaseMask; @@ -12957,7 +14908,7 @@ index c8a43adbe03..a86ca583e63 100644 if (flags & VKD3DSSF_GROUP_SHARED_MEMORY) { -@@ -9313,11 +9344,20 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, +@@ -9313,11 +9395,20 @@ static void spirv_compiler_emit_sync(struct spirv_compiler *compiler, flags &= ~VKD3DSSF_THREAD_GROUP; } @@ -12982,7 +14933,7 @@ index c8a43adbe03..a86ca583e63 100644 } if (flags) -@@ -9382,28 +9422,15 @@ static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler) +@@ -9382,28 +9473,15 @@ static void spirv_compiler_emit_main_prolog(struct spirv_compiler *compiler) { spirv_compiler_emit_push_constant_buffers(compiler); @@ -13012,7 +14963,7 @@ index c8a43adbe03..a86ca583e63 100644 switch (instruction->handler_idx) { case VKD3DSIH_DCL_GLOBAL_FLAGS: -@@ -9425,18 +9452,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9425,18 +9503,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DCL_INPUT: spirv_compiler_emit_dcl_input(compiler, instruction); break; @@ -13031,7 +14982,7 @@ index c8a43adbe03..a86ca583e63 100644 case VKD3DSIH_DCL_STREAM: spirv_compiler_emit_dcl_stream(compiler, instruction); break; -@@ -9500,6 +9518,8 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9500,6 +9569,8 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_INEG: case VKD3DSIH_ISHL: case VKD3DSIH_ISHR: @@ -13040,17 +14991,23 @@ index c8a43adbe03..a86ca583e63 100644 case VKD3DSIH_ITOD: case VKD3DSIH_ITOF: case VKD3DSIH_ITOI: -@@ -9513,6 +9533,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9513,6 +9584,15 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_XOR: ret = spirv_compiler_emit_alu_instruction(compiler, instruction); break; + case VKD3DSIH_ISFINITE: + spirv_compiler_emit_isfinite(compiler, instruction); + break; ++ case VKD3DSIH_ACOS: ++ case VKD3DSIH_ASIN: ++ case VKD3DSIH_ATAN: ++ case VKD3DSIH_HCOS: ++ case VKD3DSIH_HSIN: ++ case VKD3DSIH_HTAN: case VKD3DSIH_DFMA: case VKD3DSIH_DMAX: case VKD3DSIH_DMIN: -@@ -9533,6 +9556,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9533,6 +9613,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_ROUND_Z: case VKD3DSIH_RSQ: case VKD3DSIH_SQRT: @@ -13058,7 +15015,7 @@ index c8a43adbe03..a86ca583e63 100644 case VKD3DSIH_UMAX: case VKD3DSIH_UMIN: spirv_compiler_emit_ext_glsl_instruction(compiler, instruction); -@@ -9599,24 +9623,23 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9599,24 +9680,23 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_F32TOF16: spirv_compiler_emit_f32tof16(compiler, instruction); break; @@ -13098,7 +15055,7 @@ index c8a43adbe03..a86ca583e63 100644 break; case VKD3DSIH_DSX: case VKD3DSIH_DSX_COARSE: -@@ -9719,10 +9742,14 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9719,10 +9799,14 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DCL_CONSTANT_BUFFER: case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: @@ -13114,7 +15071,7 @@ index c8a43adbe03..a86ca583e63 100644 case VKD3DSIH_DCL_UAV_RAW: case VKD3DSIH_DCL_UAV_STRUCTURED: case VKD3DSIH_DCL_UAV_TYPED: -@@ -9740,6 +9767,30 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9740,6 +9824,30 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, return ret; } @@ -13145,7 +15102,7 @@ index c8a43adbe03..a86ca583e63 100644 static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler) { unsigned int i; -@@ -9793,24 +9844,28 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -9793,24 +9901,28 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; struct vkd3d_shader_desc *shader_desc = &parser->shader_desc; struct vkd3d_shader_instruction_array instructions; @@ -13182,7 +15139,7 @@ index c8a43adbe03..a86ca583e63 100644 compiler->input_signature = shader_desc->input_signature; compiler->output_signature = shader_desc->output_signature; -@@ -9818,10 +9873,12 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -9818,10 +9930,12 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, memset(&shader_desc->input_signature, 0, sizeof(shader_desc->input_signature)); memset(&shader_desc->output_signature, 0, sizeof(shader_desc->output_signature)); memset(&shader_desc->patch_constant_signature, 0, sizeof(shader_desc->patch_constant_signature)); @@ -13198,7 +15155,7 @@ index c8a43adbe03..a86ca583e63 100644 if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) spirv_compiler_emit_shader_signature_outputs(compiler); -@@ -9837,9 +9894,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -9837,9 +9951,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (result < 0) return result; @@ -13208,7 +15165,7 @@ index c8a43adbe03..a86ca583e63 100644 if (!is_in_default_phase(compiler)) spirv_compiler_leave_shader_phase(compiler); else -@@ -9862,6 +9916,9 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -9862,6 +9973,9 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, } } @@ -13218,7 +15175,7 @@ index c8a43adbe03..a86ca583e63 100644 if (compiler->epilogue_function_id) { vkd3d_spirv_build_op_name(builder, compiler->epilogue_function_id, "epilogue"); -@@ -9874,11 +9931,28 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -9874,11 +9988,28 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (!vkd3d_spirv_compile_module(builder, spirv, spirv_compiler_get_entry_point_name(compiler))) return VKD3D_ERROR; @@ -13250,7 +15207,15 @@ index c8a43adbe03..a86ca583e63 100644 } if (compiler->failed) -@@ -9904,8 +9978,8 @@ int spirv_compile(struct vkd3d_shader_parser *parser, +@@ -9890,6 +10021,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler); + if (vkd3d_spirv_binary_to_text(spirv, environment, compiler->formatting, &text) != VKD3D_OK) + return VKD3D_ERROR; ++ vkd3d_shader_free_shader_code(spirv); + *spirv = text; + } + +@@ -9904,8 +10036,8 @@ int spirv_compile(struct vkd3d_shader_parser *parser, struct spirv_compiler *spirv_compiler; int ret; @@ -13262,7 +15227,7 @@ index c8a43adbe03..a86ca583e63 100644 ERR("Failed to create SPIR-V compiler.\n"); return VKD3D_ERROR; diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 80f8ab98c08..50146c2c7c9 100644 +index 80f8ab98c08..adfddd32036 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -711,7 +711,7 @@ static struct vkd3d_shader_sm4_parser *vkd3d_shader_sm4_parser(struct vkd3d_shad @@ -13465,6 +15430,15 @@ index 80f8ab98c08..50146c2c7c9 100644 free_shader_desc(&parser->shader_desc); vkd3d_free(sm4); } +@@ -1730,7 +1742,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const + { + if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) + { +- struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&priv->p, 1); ++ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&priv->p.program, 1); + + if (!(reg_idx->rel_addr = rel_addr)) + { @@ -1759,11 +1771,11 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui const struct vkd3d_sm4_register_type_info *register_type_info; enum vkd3d_shader_register_type vsir_register_type; @@ -13602,7 +15576,17 @@ index 80f8ab98c08..50146c2c7c9 100644 if (*ptr >= end) { -@@ -2153,7 +2174,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons +@@ -2140,6 +2161,9 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons + break; + } + ++ if (data_type_is_64_bit(data_type)) ++ src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); ++ + if (register_is_input_output(&src_param->reg) && !shader_sm4_validate_input_output_register(priv, + &src_param->reg, mask_from_swizzle(src_param->swizzle))) + return false; +@@ -2153,7 +2177,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons enum vkd3d_sm4_swizzle_type swizzle_type; enum vkd3d_shader_src_modifier modifier; unsigned int dimension, swizzle; @@ -13611,7 +15595,7 @@ index 80f8ab98c08..50146c2c7c9 100644 if (*ptr >= end) { -@@ -2219,7 +2240,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons +@@ -2219,7 +2243,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons } if (data_type == VKD3D_DATA_DOUBLE) @@ -13620,7 +15604,7 @@ index 80f8ab98c08..50146c2c7c9 100644 /* Some scalar registers are declared with no write mask in shader bytecode. */ if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg)) dst_param->write_mask = VKD3DSP_WRITEMASK_0; -@@ -2233,7 +2254,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons +@@ -2233,7 +2257,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons return true; } @@ -13629,7 +15613,7 @@ index 80f8ab98c08..50146c2c7c9 100644 { enum vkd3d_sm4_instruction_modifier modifier_type = modifier & VKD3D_SM4_MODIFIER_MASK; -@@ -2241,7 +2262,7 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh +@@ -2241,7 +2265,7 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh { case VKD3D_SM4_MODIFIER_AOFFIMMI: { @@ -13638,7 +15622,7 @@ index 80f8ab98c08..50146c2c7c9 100644 | VKD3D_SM4_MODIFIER_MASK | VKD3D_SM4_AOFFIMMI_U_MASK | VKD3D_SM4_AOFFIMMI_V_MASK -@@ -2269,7 +2290,7 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh +@@ -2269,7 +2293,7 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh case VKD3D_SM5_MODIFIER_DATA_TYPE: { @@ -13647,7 +15631,13 @@ index 80f8ab98c08..50146c2c7c9 100644 unsigned int i; for (i = 0; i < VKD3D_VEC4_SIZE; i++) -@@ -2325,9 +2346,9 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str +@@ -2320,14 +2344,15 @@ static void shader_sm4_read_instruction_modifier(DWORD modifier, struct vkd3d_sh + static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins) + { + const struct vkd3d_sm4_opcode_info *opcode_info; ++ struct vsir_program *program = &sm4->p.program; + uint32_t opcode_token, opcode, previous_token; + struct vkd3d_shader_dst_param *dst_params; struct vkd3d_shader_src_param *src_params; const uint32_t **ptr = &sm4->ptr; unsigned int i, len; @@ -13659,7 +15649,25 @@ index 80f8ab98c08..50146c2c7c9 100644 if (*ptr >= sm4->end) { -@@ -2533,6 +2554,16 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t +@@ -2378,7 +2403,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str + ins->predicate = NULL; + ins->dst_count = strnlen(opcode_info->dst_info, SM4_MAX_DST_COUNT); + ins->src_count = strnlen(opcode_info->src_info, SM4_MAX_SRC_COUNT); +- ins->src = src_params = shader_parser_get_src_params(&sm4->p, ins->src_count); ++ ins->src = src_params = vsir_program_get_src_params(program, ins->src_count); + if (!src_params && ins->src_count) + { + ERR("Failed to allocate src parameters.\n"); +@@ -2420,7 +2445,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str + precise = (opcode_token & VKD3D_SM5_PRECISE_MASK) >> VKD3D_SM5_PRECISE_SHIFT; + ins->flags |= precise << VKD3DSI_PRECISE_SHIFT; + +- ins->dst = dst_params = shader_parser_get_dst_params(&sm4->p, ins->dst_count); ++ ins->dst = dst_params = vsir_program_get_dst_params(program, ins->dst_count); + if (!dst_params && ins->dst_count) + { + ERR("Failed to allocate dst parameters.\n"); +@@ -2533,6 +2558,16 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t return true; } @@ -13676,7 +15684,7 @@ index 80f8ab98c08..50146c2c7c9 100644 static bool shader_sm4_parser_validate_signature(struct vkd3d_shader_sm4_parser *sm4, const struct shader_signature *signature, unsigned int *masks, const char *name) { -@@ -2628,6 +2659,12 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -2628,6 +2663,12 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -13689,7 +15697,7 @@ index 80f8ab98c08..50146c2c7c9 100644 if (!shader_sm4_parser_validate_signature(sm4, &shader_desc->input_signature, sm4->input_register_masks, "Input") || !shader_sm4_parser_validate_signature(sm4, &shader_desc->output_signature, -@@ -2639,7 +2676,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -2639,7 +2680,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi return VKD3D_ERROR_INVALID_SHADER; } @@ -13698,7 +15706,7 @@ index 80f8ab98c08..50146c2c7c9 100644 while (sm4->ptr != sm4->end) { if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) -@@ -2660,7 +2697,8 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -2660,7 +2701,8 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi } ++instructions->count; } @@ -13708,7 +15716,7 @@ index 80f8ab98c08..50146c2c7c9 100644 shader_sm4_validate_default_phase_index_ranges(sm4); if (!sm4->p.failed) -@@ -2769,6 +2807,8 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant +@@ -2769,6 +2811,8 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant {"position", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_POSITION}, {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_POSITION}, {"sv_isfrontface", false, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_IS_FRONT_FACE}, @@ -13717,7 +15725,7 @@ index 80f8ab98c08..50146c2c7c9 100644 {"color", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_TARGET}, {"depth", true, VKD3D_SHADER_TYPE_PIXEL, D3D_NAME_DEPTH}, -@@ -2777,9 +2817,12 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant +@@ -2777,9 +2821,12 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant {"sv_position", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_UNDEFINED}, {"sv_vertexid", false, VKD3D_SHADER_TYPE_VERTEX, D3D_NAME_VERTEX_ID}, @@ -13730,7 +15738,7 @@ index 80f8ab98c08..50146c2c7c9 100644 }; bool needs_compat_mapping = ascii_strncasecmp(semantic->name, "sv_", 3); -@@ -3842,7 +3885,7 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src, +@@ -3842,7 +3889,7 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src, if (width == 1) { src->reg.dimension = VSIR_DIMENSION_SCALAR; @@ -13739,7 +15747,7 @@ index 80f8ab98c08..50146c2c7c9 100644 } else { -@@ -3852,9 +3895,9 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src, +@@ -3852,9 +3899,9 @@ static void sm4_src_from_constant_value(struct vkd3d_shader_src_param *src, for (i = 0; i < 4; ++i) { if ((map_writemask & (1u << i)) && (j < width)) @@ -13751,7 +15759,7 @@ index 80f8ab98c08..50146c2c7c9 100644 } } } -@@ -4049,12 +4092,12 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vk +@@ -4049,12 +4096,12 @@ static void sm4_write_src_register(const struct tpf_writer *tpf, const struct vk if (src->reg.type == VKD3DSPR_IMMCONST) { @@ -13768,7 +15776,7 @@ index 80f8ab98c08..50146c2c7c9 100644 } } } -@@ -4589,7 +4632,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node +@@ -4589,7 +4636,7 @@ static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node memset(&instr.srcs[2], 0, sizeof(instr.srcs[2])); reg->type = VKD3DSPR_IMMCONST; reg->dimension = VSIR_DIMENSION_SCALAR; @@ -13777,7 +15785,7 @@ index 80f8ab98c08..50146c2c7c9 100644 } else if (tpf->ctx->profile->major_version == 4 && tpf->ctx->profile->minor_version == 0) { -@@ -4750,7 +4793,7 @@ static void write_sm4_cast_from_bool(const struct tpf_writer *tpf, const struct +@@ -4750,7 +4797,7 @@ static void write_sm4_cast_from_bool(const struct tpf_writer *tpf, const struct sm4_src_from_node(tpf, &instr.srcs[0], arg, instr.dsts[0].write_mask); instr.srcs[1].reg.type = VKD3DSPR_IMMCONST; instr.srcs[1].reg.dimension = VSIR_DIMENSION_SCALAR; @@ -13786,7 +15794,7 @@ index 80f8ab98c08..50146c2c7c9 100644 instr.src_count = 2; write_sm4_instruction(tpf, &instr); -@@ -5460,7 +5503,7 @@ static void write_sm4_loop(const struct tpf_writer *tpf, const struct hlsl_ir_lo +@@ -5460,7 +5507,7 @@ static void write_sm4_loop(const struct tpf_writer *tpf, const struct hlsl_ir_lo static void write_sm4_gather(const struct tpf_writer *tpf, const struct hlsl_ir_node *dst, const struct hlsl_deref *resource, const struct hlsl_deref *sampler, @@ -13796,7 +15804,7 @@ index 80f8ab98c08..50146c2c7c9 100644 struct vkd3d_shader_src_param *src; struct sm4_instruction instr; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 8fd8945151f..1b7ea8dde9a 100644 +index 8fd8945151f..d0fd6b047b1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -23,6 +23,8 @@ @@ -13825,7 +15833,7 @@ index 8fd8945151f..1b7ea8dde9a 100644 void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format, va_list args) { -@@ -371,13 +383,42 @@ size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *byte +@@ -371,24 +383,53 @@ size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *byte return offset; } @@ -13871,6 +15879,19 @@ index 8fd8945151f..1b7ea8dde9a 100644 } static void vkd3d_shader_dump_blob(const char *path, const char *profile, + const char *suffix, const void *data, size_t size) + { +- static LONG shader_id = 0; ++ static unsigned int shader_id = 0; + char filename[1024]; + unsigned int id; + FILE *f; + +- id = InterlockedIncrement(&shader_id) - 1; ++ id = vkd3d_atomic_increment_u32(&shader_id) - 1; + + if (profile) + snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%u-%s.%s", path, id, profile, suffix); @@ -498,10 +539,9 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, parser->location.source_name = source_name; parser->location.line = 1; @@ -14136,7 +16157,7 @@ index 8fd8945151f..1b7ea8dde9a 100644 struct vkd3d_shader_immediate_constant_buffer *icb) { diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index a93fa7160f7..fd0f2f0f34a 100644 +index a93fa7160f7..acfd39b7643 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -91,13 +91,15 @@ enum vkd3d_shader_error @@ -14174,7 +16195,19 @@ index a93fa7160f7..fd0f2f0f34a 100644 VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300, }; -@@ -235,6 +239,7 @@ enum vkd3d_shader_opcode +@@ -221,8 +225,11 @@ enum vkd3d_shader_error + enum vkd3d_shader_opcode + { + VKD3DSIH_ABS, ++ VKD3DSIH_ACOS, + VKD3DSIH_ADD, + VKD3DSIH_AND, ++ VKD3DSIH_ASIN, ++ VKD3DSIH_ATAN, + VKD3DSIH_ATOMIC_AND, + VKD3DSIH_ATOMIC_CMP_STORE, + VKD3DSIH_ATOMIC_IADD, +@@ -235,6 +242,7 @@ enum vkd3d_shader_opcode VKD3DSIH_BEM, VKD3DSIH_BFI, VKD3DSIH_BFREV, @@ -14182,7 +16215,21 @@ index a93fa7160f7..fd0f2f0f34a 100644 VKD3DSIH_BREAK, VKD3DSIH_BREAKC, VKD3DSIH_BREAKP, -@@ -388,8 +393,11 @@ enum vkd3d_shader_opcode +@@ -358,10 +366,13 @@ enum vkd3d_shader_opcode + VKD3DSIH_GATHER4_S, + VKD3DSIH_GEO, + VKD3DSIH_GEU, ++ VKD3DSIH_HCOS, + VKD3DSIH_HS_CONTROL_POINT_PHASE, + VKD3DSIH_HS_DECLS, + VKD3DSIH_HS_FORK_PHASE, + VKD3DSIH_HS_JOIN_PHASE, ++ VKD3DSIH_HSIN, ++ VKD3DSIH_HTAN, + VKD3DSIH_IADD, + VKD3DSIH_IBFE, + VKD3DSIH_IDIV, +@@ -388,8 +399,11 @@ enum vkd3d_shader_opcode VKD3DSIH_IMUL, VKD3DSIH_INE, VKD3DSIH_INEG, @@ -14194,7 +16241,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 VKD3DSIH_ITOD, VKD3DSIH_ITOF, VKD3DSIH_ITOI, -@@ -432,6 +440,7 @@ enum vkd3d_shader_opcode +@@ -432,6 +446,7 @@ enum vkd3d_shader_opcode VKD3DSIH_NRM, VKD3DSIH_OR, VKD3DSIH_PHASE, @@ -14202,7 +16249,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 VKD3DSIH_POW, VKD3DSIH_RCP, VKD3DSIH_REP, -@@ -469,7 +478,9 @@ enum vkd3d_shader_opcode +@@ -469,7 +484,9 @@ enum vkd3d_shader_opcode VKD3DSIH_SUB, VKD3DSIH_SWAPC, VKD3DSIH_SWITCH, @@ -14212,7 +16259,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 VKD3DSIH_TEX, VKD3DSIH_TEXBEM, VKD3DSIH_TEXBEML, -@@ -618,6 +629,11 @@ static inline bool data_type_is_bool(enum vkd3d_data_type data_type) +@@ -618,6 +635,11 @@ static inline bool data_type_is_bool(enum vkd3d_data_type data_type) return data_type == VKD3D_DATA_BOOL; } @@ -14224,7 +16271,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 enum vsir_dimension { VSIR_DIMENSION_NONE, -@@ -716,6 +732,7 @@ enum vkd3d_shader_sync_flags +@@ -716,6 +738,7 @@ enum vkd3d_shader_sync_flags { VKD3DSSF_THREAD_GROUP = 0x1, VKD3DSSF_GROUP_SHARED_MEMORY = 0x2, @@ -14232,7 +16279,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 VKD3DSSF_GLOBAL_UAV = 0x8, }; -@@ -740,6 +757,7 @@ enum vkd3d_tessellator_domain +@@ -740,6 +763,7 @@ enum vkd3d_tessellator_domain #define VKD3DSI_RESINFO_UINT 0x2 #define VKD3DSI_SAMPLE_INFO_UINT 0x1 #define VKD3DSI_SAMPLER_COMPARISON_MODE 0x1 @@ -14240,7 +16287,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 #define VKD3DSI_PRECISE_X 0x100 #define VKD3DSI_PRECISE_Y 0x200 -@@ -793,10 +811,12 @@ struct vkd3d_shader_version +@@ -793,10 +817,12 @@ struct vkd3d_shader_version struct vkd3d_shader_immediate_constant_buffer { @@ -14253,7 +16300,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 uint32_t data[]; }; -@@ -807,12 +827,13 @@ struct vkd3d_shader_indexable_temp +@@ -807,12 +833,13 @@ struct vkd3d_shader_indexable_temp unsigned int alignment; enum vkd3d_data_type data_type; unsigned int component_count; @@ -14268,7 +16315,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 unsigned int offset; /* address is known to fall within the object (for optimisation) */ bool is_in_bounds; -@@ -831,10 +852,10 @@ struct vkd3d_shader_register +@@ -831,10 +858,10 @@ struct vkd3d_shader_register unsigned int alignment; union { @@ -14283,7 +16330,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 unsigned fp_body_idx; } u; }; -@@ -861,17 +882,21 @@ struct vkd3d_shader_dst_param +@@ -861,17 +888,23 @@ struct vkd3d_shader_dst_param { struct vkd3d_shader_register reg; uint32_t write_mask; @@ -14303,12 +16350,14 @@ index a93fa7160f7..fd0f2f0f34a 100644 +void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, + enum vkd3d_data_type data_type, unsigned int idx_count); ++void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, ++ enum vkd3d_data_type data_type, unsigned int idx_count); +void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id); + struct vkd3d_shader_index_range { struct vkd3d_shader_dst_param dst; -@@ -945,6 +970,9 @@ enum vkd3d_shader_input_sysval_semantic +@@ -945,6 +978,9 @@ enum vkd3d_shader_input_sysval_semantic VKD3D_SIV_LINE_DENSITY_TESS_FACTOR = 22, }; @@ -14318,7 +16367,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 #define SIGNATURE_TARGET_LOCATION_UNUSED (~0u) struct signature_element -@@ -998,17 +1026,10 @@ struct vkd3d_shader_desc +@@ -998,17 +1034,10 @@ struct vkd3d_shader_desc struct shader_signature output_signature; struct shader_signature patch_constant_signature; @@ -14336,7 +16385,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 }; struct vkd3d_shader_register_semantic -@@ -1110,11 +1131,11 @@ struct vkd3d_shader_instruction +@@ -1110,11 +1139,11 @@ struct vkd3d_shader_instruction { struct vkd3d_shader_location location; enum vkd3d_shader_opcode handler_idx; @@ -14351,10 +16400,20 @@ index a93fa7160f7..fd0f2f0f34a 100644 struct vkd3d_shader_texel_offset texel_offset; enum vkd3d_shader_resource_type resource_type; unsigned int resource_stride; -@@ -1171,6 +1192,22 @@ static inline bool register_is_constant(const struct vkd3d_shader_register *reg) +@@ -1171,6 +1200,32 @@ static inline bool register_is_constant(const struct vkd3d_shader_register *reg) return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); } ++static inline bool register_is_undef(const struct vkd3d_shader_register *reg) ++{ ++ return reg->type == VKD3DSPR_UNDEF; ++} ++ ++static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg) ++{ ++ return register_is_constant(reg) || register_is_undef(reg); ++} ++ +static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg) +{ + return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR @@ -14374,7 +16433,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 struct vkd3d_shader_param_node { struct vkd3d_shader_param_node *next; -@@ -1217,6 +1254,8 @@ struct vkd3d_shader_instruction_array +@@ -1217,6 +1272,8 @@ 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); @@ -14383,7 +16442,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 bool 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, -@@ -1228,6 +1267,24 @@ enum vkd3d_shader_config_flags +@@ -1228,6 +1285,36 @@ enum vkd3d_shader_config_flags VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, }; @@ -14404,11 +16463,23 @@ index a93fa7160f7..fd0f2f0f34a 100644 + +bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve); +void vsir_program_cleanup(struct vsir_program *program); ++ ++static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params( ++ struct vsir_program *program, unsigned int count) ++{ ++ return shader_dst_param_allocator_get(&program->instructions.dst_params, count); ++} ++ ++static inline struct vkd3d_shader_src_param *vsir_program_get_src_params( ++ struct vsir_program *program, unsigned int count) ++{ ++ return shader_src_param_allocator_get(&program->instructions.src_params, count); ++} + struct vkd3d_shader_parser { struct vkd3d_shader_message_context *message_context; -@@ -1235,9 +1292,8 @@ struct vkd3d_shader_parser +@@ -1235,9 +1322,8 @@ struct vkd3d_shader_parser bool failed; struct vkd3d_shader_desc shader_desc; @@ -14419,23 +16490,26 @@ index a93fa7160f7..fd0f2f0f34a 100644 uint64_t config_flags; }; -@@ -1259,13 +1315,13 @@ void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, - static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params( - struct vkd3d_shader_parser *parser, unsigned int count) - { +@@ -1256,18 +1342,6 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, + void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); + +-static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params( +- struct vkd3d_shader_parser *parser, unsigned int count) +-{ - return shader_dst_param_allocator_get(&parser->instructions.dst_params, count); -+ return shader_dst_param_allocator_get(&parser->program.instructions.dst_params, count); - } - - static inline struct vkd3d_shader_src_param *shader_parser_get_src_params( - struct vkd3d_shader_parser *parser, unsigned int count) - { +-} +- +-static inline struct vkd3d_shader_src_param *shader_parser_get_src_params( +- struct vkd3d_shader_parser *parser, unsigned int count) +-{ - return shader_src_param_allocator_get(&parser->instructions.src_params, count); -+ return shader_src_param_allocator_get(&parser->program.instructions.src_params, count); - } - +-} +- static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) -@@ -1286,6 +1342,7 @@ struct vkd3d_shader_descriptor_info1 + { + parser->ops->parser_destroy(parser); +@@ -1286,6 +1360,7 @@ struct vkd3d_shader_descriptor_info1 unsigned int buffer_size; unsigned int structure_stride; unsigned int count; @@ -14443,7 +16517,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 }; struct vkd3d_shader_scan_descriptor_info1 -@@ -1294,8 +1351,7 @@ struct vkd3d_shader_scan_descriptor_info1 +@@ -1294,8 +1369,7 @@ struct vkd3d_shader_scan_descriptor_info1 unsigned int descriptor_count; }; @@ -14453,7 +16527,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 const char *shader_get_type_prefix(enum vkd3d_shader_type type); -@@ -1311,9 +1367,15 @@ struct vkd3d_string_buffer_cache +@@ -1311,9 +1385,15 @@ struct vkd3d_string_buffer_cache size_t count, max_count, capacity; }; @@ -14472,7 +16546,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer); struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list); void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer); -@@ -1338,7 +1400,9 @@ struct vkd3d_bytecode_buffer +@@ -1338,7 +1418,9 @@ struct vkd3d_bytecode_buffer /* Align to the next 4-byte offset, and return that offset. */ size_t bytecode_align(struct vkd3d_bytecode_buffer *buffer); size_t bytecode_put_bytes(struct vkd3d_bytecode_buffer *buffer, const void *bytes, size_t size); @@ -14482,7 +16556,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 static inline size_t put_u32(struct vkd3d_bytecode_buffer *buffer, uint32_t value) { -@@ -1382,6 +1446,8 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str +@@ -1382,6 +1464,8 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str enum vkd3d_shader_error error, const char *format, va_list args); void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_log_level level, const char *format, va_list args); @@ -14491,7 +16565,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format, va_list args); -@@ -1409,7 +1475,7 @@ struct vkd3d_glsl_generator; +@@ -1409,7 +1493,7 @@ struct vkd3d_glsl_generator; struct vkd3d_glsl_generator *vkd3d_glsl_generator_create(const struct vkd3d_shader_version *version, struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location); int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *generator, @@ -14500,7 +16574,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator); #define SPIRV_MAX_SRC_COUNT 6 -@@ -1427,7 +1493,7 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, +@@ -1427,7 +1511,7 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); @@ -14509,7 +16583,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vkd3d_data_type data_type) -@@ -1444,6 +1510,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty +@@ -1444,6 +1528,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty return VKD3D_SHADER_COMPONENT_INT; case VKD3D_DATA_DOUBLE: return VKD3D_SHADER_COMPONENT_DOUBLE; @@ -14518,7 +16592,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 case VKD3D_DATA_BOOL: return VKD3D_SHADER_COMPONENT_BOOL; default: -@@ -1505,7 +1573,7 @@ static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum +@@ -1505,7 +1591,7 @@ static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum return vkd3d_siv_from_sysval_indexed(sysval, 0); } @@ -14527,7 +16601,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 { unsigned int i; -@@ -1520,7 +1588,7 @@ static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask) +@@ -1520,7 +1606,7 @@ static inline unsigned int vkd3d_write_mask_get_component_idx(DWORD write_mask) return 0; } @@ -14536,7 +16610,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 { unsigned int count = vkd3d_popcount(write_mask & VKD3DSP_WRITEMASK_ALL); assert(1 <= count && count <= VKD3D_VEC4_SIZE); -@@ -1533,32 +1601,30 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co +@@ -1533,32 +1619,94 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co return (VKD3DSP_WRITEMASK_0 << component_count) - 1; } @@ -14544,31 +16618,100 @@ index a93fa7160f7..fd0f2f0f34a 100644 +static inline uint32_t vsir_write_mask_64_from_32(uint32_t write_mask32) { - unsigned int write_mask64 = write_mask32 | (write_mask32 >> 1); -+ uint32_t write_mask64 = write_mask32 | (write_mask32 >> 1); - return (write_mask64 & VKD3DSP_WRITEMASK_0) | ((write_mask64 & VKD3DSP_WRITEMASK_2) >> 1); +- return (write_mask64 & VKD3DSP_WRITEMASK_0) | ((write_mask64 & VKD3DSP_WRITEMASK_2) >> 1); ++ switch (write_mask32) ++ { ++ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1: ++ return VKD3DSP_WRITEMASK_0; ++ ++ case VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3: ++ return VKD3DSP_WRITEMASK_1; ++ ++ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3: ++ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; ++ ++ default: ++ ERR("Invalid 32 bit writemask when converting to 64 bit: %#x.\n", write_mask32); ++ return VKD3DSP_WRITEMASK_0; ++ } } -static inline unsigned int vkd3d_write_mask_32_from_64(unsigned int write_mask64) +static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64) { - unsigned int write_mask32 = (write_mask64 | (write_mask64 << 1)) -+ uint32_t write_mask32 = (write_mask64 | (write_mask64 << 1)) - & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2); - return write_mask32 | (write_mask32 << 1); +- & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2); +- return write_mask32 | (write_mask32 << 1); ++ switch (write_mask64) ++ { ++ case VKD3DSP_WRITEMASK_0: ++ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; ++ ++ case VKD3DSP_WRITEMASK_1: ++ return VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; ++ ++ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1: ++ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; ++ ++ default: ++ ERR("Invalid 64 bit writemask: %#x.\n", write_mask64); ++ return VKD3DSP_WRITEMASK_0; ++ } } -static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle, - unsigned int idx) -+static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx) ++static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32) { - return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK; +- return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK; ++ switch (swizzle32) ++ { ++ case VKD3D_SHADER_SWIZZLE(X, Y, X, Y): ++ return VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ++ case VKD3D_SHADER_SWIZZLE(X, Y, Z, W): ++ return VKD3D_SHADER_SWIZZLE(X, Y, X, X); ++ ++ case VKD3D_SHADER_SWIZZLE(Z, W, X, Y): ++ return VKD3D_SHADER_SWIZZLE(Y, X, X, X); ++ ++ case VKD3D_SHADER_SWIZZLE(Z, W, Z, W): ++ return VKD3D_SHADER_SWIZZLE(Y, Y, X, X); ++ ++ default: ++ ERR("Invalid 32 bit swizzle when converting to 64 bit: %#x.\n", swizzle32); ++ return VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ } } -static inline unsigned int vkd3d_swizzle_get_component64(DWORD swizzle, - unsigned int idx) -+static inline unsigned int vsir_swizzle_get_component64(uint32_t swizzle, unsigned int idx) ++static inline uint32_t vsir_swizzle_32_from_64(uint32_t swizzle64) { - return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u; +- return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u; ++ switch (swizzle64) ++ { ++ case VKD3D_SHADER_SWIZZLE(X, X, X, X): ++ return VKD3D_SHADER_SWIZZLE(X, Y, X, Y); ++ ++ case VKD3D_SHADER_SWIZZLE(X, Y, X, X): ++ return VKD3D_SHADER_SWIZZLE(X, Y, Z, W); ++ ++ case VKD3D_SHADER_SWIZZLE(Y, X, X, X): ++ return VKD3D_SHADER_SWIZZLE(Z, W, X, Y); ++ ++ case VKD3D_SHADER_SWIZZLE(Y, Y, X, X): ++ return VKD3D_SHADER_SWIZZLE(Z, W, Z, W); ++ ++ default: ++ ERR("Invalid 64 bit swizzle: %#x.\n", swizzle64); ++ return VKD3D_SHADER_SWIZZLE(X, Y, X, Y); ++ } ++} ++ ++static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx) ++{ ++ return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK; } -static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned int write_mask) @@ -14576,7 +16719,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 { unsigned int i, compacted_swizzle = 0; -@@ -1567,7 +1633,7 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned +@@ -1567,7 +1715,7 @@ static inline unsigned int vkd3d_compact_swizzle(unsigned int swizzle, unsigned if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) { compacted_swizzle <<= VKD3D_SHADER_SWIZZLE_SHIFT(1); @@ -14586,7 +16729,7 @@ index a93fa7160f7..fd0f2f0f34a 100644 } diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index 15c8317b191..3cf58e06d40 100644 +index 15c8317b191..8a47dc494f7 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -313,7 +313,7 @@ static void vkd3d_wait_for_gpu_fence(struct vkd3d_fence_worker *worker, @@ -14679,6 +16822,21 @@ index 15c8317b191..3cf58e06d40 100644 TRACE("%p decreasing refcount to %u.\n", allocator, refcount); +@@ -1921,12 +1921,12 @@ HRESULT d3d12_command_allocator_create(struct d3d12_device *device, + + static void d3d12_command_signature_incref(struct d3d12_command_signature *signature) + { +- vkd3d_atomic_increment(&signature->internal_refcount); ++ vkd3d_atomic_increment_u32(&signature->internal_refcount); + } + + static void d3d12_command_signature_decref(struct d3d12_command_signature *signature) + { +- unsigned int refcount = vkd3d_atomic_decrement(&signature->internal_refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&signature->internal_refcount); + + if (!refcount) + { @@ -2320,7 +2320,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_QueryInterface(ID3D12Graphic static ULONG STDMETHODCALLTYPE d3d12_command_list_AddRef(ID3D12GraphicsCommandList5 *iface) { @@ -14734,6 +16892,92 @@ index 15c8317b191..3cf58e06d40 100644 return; } +@@ -4494,8 +4499,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I + { + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + +- TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", +- iface, root_parameter_index, base_descriptor.ptr); ++ TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n", ++ iface, root_parameter_index, debug_gpu_handle(base_descriptor)); + + d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_COMPUTE, + root_parameter_index, base_descriptor); +@@ -4506,8 +4511,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable( + { + struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); + +- TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", +- iface, root_parameter_index, base_descriptor.ptr); ++ TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n", ++ iface, root_parameter_index, debug_gpu_handle(base_descriptor)); + + d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_GRAPHICS, + root_parameter_index, base_descriptor); +@@ -5127,8 +5132,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra + struct VkAttachmentDescription attachment_desc; + struct VkAttachmentReference ds_reference; + +- TRACE("iface %p, dsv %#lx, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p.\n", +- iface, dsv.ptr, flags, depth, stencil, rect_count, rects); ++ TRACE("iface %p, dsv %s, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p.\n", ++ iface, debug_cpu_handle(dsv), flags, depth, stencil, rect_count, rects); + + d3d12_command_list_track_resource_usage(list, dsv_desc->resource); + +@@ -5175,8 +5180,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra + struct VkAttachmentReference color_reference; + VkClearValue clear_value; + +- TRACE("iface %p, rtv %#lx, color %p, rect_count %u, rects %p.\n", +- iface, rtv.ptr, color, rect_count, rects); ++ TRACE("iface %p, rtv %s, color %p, rect_count %u, rects %p.\n", ++ iface, debug_cpu_handle(rtv), color, rect_count, rects); + + d3d12_command_list_track_resource_usage(list, rtv_desc->resource); + +@@ -5427,8 +5432,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID + struct d3d12_resource *resource_impl; + VkClearColorValue colour; + +- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %lx, resource %p, values %p, rect_count %u, rects %p.\n", +- iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects); ++ TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", ++ iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); + + resource_impl = unsafe_impl_from_ID3D12Resource(resource); + if (!(descriptor = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) +@@ -5491,8 +5496,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I + VkClearColorValue colour; + struct vkd3d_view *view; + +- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %lx, resource %p, values %p, rect_count %u, rects %p.\n", +- iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects); ++ TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", ++ iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); + + resource_impl = unsafe_impl_from_ID3D12Resource(resource); + if (!(view = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) +@@ -5958,15 +5963,15 @@ static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCom + static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) + { +- FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, +- meta_command, parameters_data, data_size_in_bytes); ++ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface, ++ meta_command, parameters_data, (uintptr_t)data_size_in_bytes); + } + + static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList5 *iface, + ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) + { +- FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, +- meta_command, parameters_data, data_size_in_bytes); ++ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface, ++ meta_command, parameters_data, (uintptr_t)data_size_in_bytes); + } + + static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface, @@ -6225,7 +6230,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_QueryInterface(ID3D12Comman static ULONG STDMETHODCALLTYPE d3d12_command_queue_AddRef(ID3D12CommandQueue *iface) { @@ -14797,7 +17041,7 @@ index 15c8317b191..3cf58e06d40 100644 TRACE("%p decreasing refcount to %u.\n", signature, refcount); diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index 5c801ca4676..2b8558175e0 100644 +index 5c801ca4676..90272818b3d 100644 --- a/libs/vkd3d/libs/vkd3d/device.c +++ b/libs/vkd3d/libs/vkd3d/device.c @@ -94,9 +94,11 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = @@ -14882,6 +17126,24 @@ index 5c801ca4676..2b8558175e0 100644 if (instance->vk_procs.vkDestroyInstance) instance->vk_procs.vkDestroyInstance(vk_instance, NULL); if (instance->libvulkan) +@@ -718,7 +750,7 @@ static void vkd3d_destroy_instance(struct vkd3d_instance *instance) + + ULONG vkd3d_instance_incref(struct vkd3d_instance *instance) + { +- ULONG refcount = InterlockedIncrement(&instance->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&instance->refcount); + + TRACE("%p increasing refcount to %u.\n", instance, refcount); + +@@ -727,7 +759,7 @@ ULONG vkd3d_instance_incref(struct vkd3d_instance *instance) + + ULONG vkd3d_instance_decref(struct vkd3d_instance *instance) + { +- ULONG refcount = InterlockedDecrement(&instance->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&instance->refcount); + + TRACE("%p decreasing refcount to %u.\n", instance, refcount); + @@ -763,6 +795,7 @@ struct vkd3d_physical_device_info VkPhysicalDeviceTransformFeedbackFeaturesEXT xfb_features; VkPhysicalDeviceVertexAttributeDivisorFeaturesEXT vertex_divisor_features; @@ -14953,6 +17215,24 @@ index 5c801ca4676..2b8558175e0 100644 /* Disable unused Vulkan features. */ features->shaderTessellationAndGeometryPointSize = VK_FALSE; +@@ -1926,7 +1969,7 @@ static HRESULT vkd3d_select_queues(const struct vkd3d_instance *vkd3d_instance, + * which applies to resources of a total size of 4 MiB or less. */ + static bool d3d12_is_64k_msaa_supported(struct d3d12_device *device) + { +- D3D12_RESOURCE_ALLOCATION_INFO info; ++ struct vkd3d_resource_allocation_info info; + D3D12_RESOURCE_DESC resource_desc; + + memset(&resource_desc, 0, sizeof(resource_desc)); +@@ -1943,7 +1986,7 @@ static bool d3d12_is_64k_msaa_supported(struct d3d12_device *device) + * resources, which must have 0x10000 in their description, so we might + * reasonably return true here for 0x20000 or 0x40000. */ + return SUCCEEDED(vkd3d_get_image_allocation_info(device, &resource_desc, &info)) +- && info.Alignment <= 0x10000; ++ && info.alignment <= 0x10000; + } + + static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, @@ -2028,7 +2071,7 @@ static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, if (FAILED(hr = vkd3d_load_vk_device_procs(&device->vk_procs, vk_procs, vk_device))) @@ -14989,12 +17269,107 @@ index 5c801ca4676..2b8558175e0 100644 } #define VKD3D_VA_FALLBACK_BASE 0x8000000000000000ull -@@ -2495,6 +2538,28 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface) +@@ -2090,7 +2133,7 @@ static void d3d12_device_destroy_pipeline_cache(struct d3d12_device *device) + #define VKD3D_VA_SLAB_COUNT (64 * 1024) + + static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_slab(struct vkd3d_gpu_va_allocator *allocator, +- size_t aligned_size, void *ptr) ++ uint64_t aligned_size, void *ptr) + { + struct vkd3d_gpu_va_slab *slab; + D3D12_GPU_VIRTUAL_ADDRESS address; +@@ -2106,13 +2149,13 @@ static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_slab(struct vkd + slab_idx = slab - allocator->slabs; + address = VKD3D_VA_SLAB_BASE + slab_idx * VKD3D_VA_SLAB_SIZE; + +- TRACE("Allocated address %#"PRIx64", slab %u, size %zu.\n", address, slab_idx, aligned_size); ++ TRACE("Allocated address %#"PRIx64", slab %u, size %"PRIu64".\n", address, slab_idx, aligned_size); + + return address; + } + + static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_fallback(struct vkd3d_gpu_va_allocator *allocator, +- size_t alignment, size_t aligned_size, void *ptr) ++ size_t alignment, uint64_t aligned_size, void *ptr) + { + struct vkd3d_gpu_va_allocation *allocation; + D3D12_GPU_VIRTUAL_ADDRESS base, ceiling; +@@ -2138,17 +2181,17 @@ static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_fallback(struct + * only fail once we have exhausted 63 bits of address space. */ + allocator->fallback_floor = base + aligned_size; + +- TRACE("Allocated address %#"PRIx64", size %zu.\n", base, aligned_size); ++ TRACE("Allocated address %#"PRIx64", size %"PRIu64".\n", base, aligned_size); + + return base; + } + + D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, +- size_t alignment, size_t size, void *ptr) ++ size_t alignment, uint64_t size, void *ptr) + { + D3D12_GPU_VIRTUAL_ADDRESS address; + +- if (size > ~(size_t)0 - (alignment - 1)) ++ if (size > ~(uint64_t)0 - (alignment - 1)) + return 0; + size = align(size, alignment); + +@@ -2184,7 +2227,7 @@ static void *vkd3d_gpu_va_allocator_dereference_slab(struct vkd3d_gpu_va_allocat + base_offset -= slab_idx * VKD3D_VA_SLAB_SIZE; + if (base_offset >= slab->size) + { +- ERR("Address %#"PRIx64" is %#"PRIx64" bytes into slab %u of size %zu.\n", ++ ERR("Address %#"PRIx64" is %#"PRIx64" bytes into slab %u of size %"PRIu64".\n", + address, base_offset, slab_idx, slab->size); + return NULL; + } +@@ -2455,17 +2498,19 @@ static void vkd3d_desc_object_cache_cleanup(struct vkd3d_desc_object_cache *cach + } + + /* ID3D12Device */ +-static inline struct d3d12_device *impl_from_ID3D12Device5(ID3D12Device5 *iface) ++static inline struct d3d12_device *impl_from_ID3D12Device7(ID3D12Device7 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device5_iface); ++ return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device7_iface); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device7 *iface, + REFIID riid, void **object) + { + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + +- if (IsEqualGUID(riid, &IID_ID3D12Device5) ++ if (IsEqualGUID(riid, &IID_ID3D12Device7) ++ || IsEqualGUID(riid, &IID_ID3D12Device6) ++ || IsEqualGUID(riid, &IID_ID3D12Device5) + || IsEqualGUID(riid, &IID_ID3D12Device4) + || IsEqualGUID(riid, &IID_ID3D12Device3) + || IsEqualGUID(riid, &IID_ID3D12Device2) +@@ -2485,20 +2530,42 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *ifac + return E_NOINTERFACE; + } + +-static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface) ++static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device7 *iface) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); +- ULONG refcount = InterlockedIncrement(&device->refcount); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&device->refcount); + + TRACE("%p increasing refcount to %u.\n", device, refcount); + return refcount; } +-static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) +static HRESULT device_worker_stop(struct d3d12_device *device) -+{ + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); +- ULONG refcount = InterlockedDecrement(&device->refcount); + HRESULT hr; + + TRACE("device %p.\n", device); @@ -15015,10 +17390,14 @@ index 5c801ca4676..2b8558175e0 100644 + return S_OK; +} + - static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) - { - struct d3d12_device *device = impl_from_ID3D12Device5(iface); -@@ -2520,6 +2585,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) ++static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device7 *iface) ++{ ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&device->refcount); + + TRACE("%p decreasing refcount to %u.\n", device, refcount); + +@@ -2520,6 +2587,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) d3d12_device_destroy_vkd3d_queues(device); vkd3d_desc_object_cache_cleanup(&device->view_desc_cache); vkd3d_desc_object_cache_cleanup(&device->cbuffer_desc_cache); @@ -15028,10 +17407,1077 @@ index 5c801ca4676..2b8558175e0 100644 VK_CALL(vkDestroyDevice(device->vk_device, NULL)); if (device->parent) IUnknown_Release(device->parent); -@@ -4251,6 +4319,40 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface) - return impl_from_ID3D12Device5(iface); +@@ -2531,10 +2601,10 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) + return refcount; } +-static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device7 *iface, + REFGUID guid, UINT *data_size, void *data) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); +@@ -2542,10 +2612,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device5 *ifac + return vkd3d_get_private_data(&device->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device7 *iface, + REFGUID guid, UINT data_size, const void *data) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); +@@ -2553,19 +2623,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device5 *ifac + return vkd3d_set_private_data(&device->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device7 *iface, + REFGUID guid, const IUnknown *data) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); + + return vkd3d_set_private_data_interface(&device->private_store, guid, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device5 *iface, const WCHAR *name) ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device7 *iface, const WCHAR *name) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size)); + +@@ -2573,17 +2643,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device5 *iface, cons + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name); + } + +-static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device5 *iface) ++static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device7 *iface) + { + TRACE("iface %p.\n", iface); + + return 1; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device7 *iface, + const D3D12_COMMAND_QUEUE_DESC *desc, REFIID riid, void **command_queue) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_command_queue *object; + HRESULT hr; + +@@ -2597,10 +2667,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device5 * + riid, command_queue); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device7 *iface, + D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **command_allocator) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_command_allocator *object; + HRESULT hr; + +@@ -2614,10 +2684,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic + riid, command_allocator); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device7 *iface, + const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_pipeline_state *object; + HRESULT hr; + +@@ -2631,10 +2701,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12 + &IID_ID3D12PipelineState, riid, pipeline_state); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device7 *iface, + const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_pipeline_state *object; + HRESULT hr; + +@@ -2648,11 +2718,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12D + &IID_ID3D12PipelineState, riid, pipeline_state); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device7 *iface, + UINT node_mask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *command_allocator, + ID3D12PipelineState *initial_pipeline_state, REFIID riid, void **command_list) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_command_list *object; + HRESULT hr; + +@@ -2775,10 +2845,10 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) + return true; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device7 *iface, + D3D12_FEATURE feature, void *feature_data, UINT feature_data_size) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n", + iface, feature, feature_data, feature_data_size); +@@ -3278,16 +3348,101 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device5 + return S_OK; + } + ++ case D3D12_FEATURE_D3D12_OPTIONS6: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS6 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->AdditionalShadingRatesSupported = FALSE; ++ data->PerPrimitiveShadingRateSupportedWithViewportIndexing = FALSE; ++ data->VariableShadingRateTier = D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED; ++ data->ShadingRateImageTileSize = 0; ++ data->BackgroundProcessingSupported = FALSE; ++ ++ TRACE("Additional shading rates support %#x.\n", data->AdditionalShadingRatesSupported); ++ TRACE("Per-primitive shading rates with viewport indexing %#x.\n", ++ data->PerPrimitiveShadingRateSupportedWithViewportIndexing); ++ TRACE("Variable shading rate tier %#x.\n", data->VariableShadingRateTier); ++ TRACE("Shading rate image tile size %#x.\n", data->ShadingRateImageTileSize); ++ TRACE("Background processing support %#x.\n", data->BackgroundProcessingSupported); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS7: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS7 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->MeshShaderTier = D3D12_MESH_SHADER_TIER_NOT_SUPPORTED; ++ data->SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED; ++ ++ TRACE("Mesh shading tier %#x.\n", data->MeshShaderTier); ++ TRACE("Sampler feedback tier %#x.\n", data->SamplerFeedbackTier); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS8: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS8 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->UnalignedBlockTexturesSupported = FALSE; ++ ++ TRACE("Unaligned block texture support %#x.\n", data->UnalignedBlockTexturesSupported); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS9: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS9 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->MeshShaderPipelineStatsSupported = FALSE; ++ data->MeshShaderSupportsFullRangeRenderTargetArrayIndex = FALSE; ++ data->AtomicInt64OnTypedResourceSupported = FALSE; ++ data->AtomicInt64OnGroupSharedSupported = FALSE; ++ data->DerivativesInMeshAndAmplificationShadersSupported = FALSE; ++ data->WaveMMATier = D3D12_WAVE_MMA_TIER_NOT_SUPPORTED; ++ ++ TRACE("Mesh shader pipeline stats support %#x.\n", data->MeshShaderPipelineStatsSupported); ++ TRACE("Mesh shader RT array index full range %#x.\n", data->MeshShaderSupportsFullRangeRenderTargetArrayIndex); ++ TRACE("Atomic int64 on typed resource %#x.\n", data->AtomicInt64OnTypedResourceSupported); ++ TRACE("Atomic int64 on group shared mem %#x.\n", data->AtomicInt64OnGroupSharedSupported); ++ TRACE("Derivatives in mesh and amp shaders %#x.\n", data->DerivativesInMeshAndAmplificationShadersSupported); ++ TRACE("Wave MMA tier %#x.\n", data->WaveMMATier); ++ return S_OK; ++ } ++ + default: + FIXME("Unhandled feature %#x.\n", feature); + return E_NOTIMPL; + } + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device7 *iface, + const D3D12_DESCRIPTOR_HEAP_DESC *desc, REFIID riid, void **descriptor_heap) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_descriptor_heap *object; + HRESULT hr; + +@@ -3301,7 +3456,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device5 + &IID_ID3D12DescriptorHeap, riid, descriptor_heap); + } + +-static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device5 *iface, ++static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device7 *iface, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) + { + TRACE("iface %p, descriptor_heap_type %#x.\n", iface, descriptor_heap_type); +@@ -3324,16 +3479,16 @@ static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D + } + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device7 *iface, + UINT node_mask, const void *bytecode, SIZE_T bytecode_length, + REFIID riid, void **root_signature) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_root_signature *object; + HRESULT hr; + +- TRACE("iface %p, node_mask 0x%08x, bytecode %p, bytecode_length %lu, riid %s, root_signature %p.\n", +- iface, node_mask, bytecode, bytecode_length, debugstr_guid(riid), root_signature); ++ TRACE("iface %p, node_mask 0x%08x, bytecode %p, bytecode_length %"PRIuPTR", riid %s, root_signature %p.\n", ++ iface, node_mask, bytecode, (uintptr_t)bytecode_length, debugstr_guid(riid), root_signature); + + debug_ignored_node_mask(node_mask); + +@@ -3344,89 +3499,89 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device5 + &IID_ID3D12RootSignature, riid, root_signature); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device7 *iface, + const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_desc tmp = {0}; + +- TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); ++ TRACE("iface %p, desc %p, descriptor %s.\n", iface, desc, debug_cpu_handle(descriptor)); + + d3d12_desc_create_cbv(&tmp, device, desc); + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device7 *iface, + ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_desc tmp = {0}; + +- TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", +- iface, resource, desc, descriptor.ptr); ++ TRACE("iface %p, resource %p, desc %p, descriptor %s.\n", ++ iface, resource, desc, debug_cpu_handle(descriptor)); + + d3d12_desc_create_srv(&tmp, device, unsafe_impl_from_ID3D12Resource(resource), desc); + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device7 *iface, + ID3D12Resource *resource, ID3D12Resource *counter_resource, + const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_desc tmp = {0}; + +- TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n", +- iface, resource, counter_resource, desc, descriptor.ptr); ++ TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %s.\n", ++ iface, resource, counter_resource, desc, debug_cpu_handle(descriptor)); + + d3d12_desc_create_uav(&tmp, device, unsafe_impl_from_ID3D12Resource(resource), + unsafe_impl_from_ID3D12Resource(counter_resource), desc); + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device7 *iface, + ID3D12Resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", +- iface, resource, desc, descriptor.ptr); ++ TRACE("iface %p, resource %p, desc %p, descriptor %s.\n", ++ iface, resource, desc, debug_cpu_handle(descriptor)); + + d3d12_rtv_desc_create_rtv(d3d12_rtv_desc_from_cpu_handle(descriptor), +- impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc); ++ impl_from_ID3D12Device7(iface), unsafe_impl_from_ID3D12Resource(resource), desc); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device7 *iface, + ID3D12Resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", +- iface, resource, desc, descriptor.ptr); ++ TRACE("iface %p, resource %p, desc %p, descriptor %s.\n", ++ iface, resource, desc, debug_cpu_handle(descriptor)); + + d3d12_dsv_desc_create_dsv(d3d12_dsv_desc_from_cpu_handle(descriptor), +- impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc); ++ impl_from_ID3D12Device7(iface), unsafe_impl_from_ID3D12Resource(resource), desc); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device7 *iface, + const D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_desc tmp = {0}; + +- TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); ++ TRACE("iface %p, desc %p, descriptor %s.\n", iface, desc, debug_cpu_handle(descriptor)); + + d3d12_desc_create_sampler(&tmp, device, desc); + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device7 *iface, + UINT dst_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets, + const UINT *dst_descriptor_range_sizes, + UINT src_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets, + const UINT *src_descriptor_range_sizes, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx; + unsigned int dst_range_size, src_range_size; + struct d3d12_descriptor_heap *dst_heap; +@@ -3482,101 +3637,126 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device5 *iface, + } + } + +-static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device7 *iface, + UINT descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE dst_descriptor_range_offset, + const D3D12_CPU_DESCRIPTOR_HANDLE src_descriptor_range_offset, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) + { +- TRACE("iface %p, descriptor_count %u, dst_descriptor_range_offset %#lx, " +- "src_descriptor_range_offset %#lx, descriptor_heap_type %#x.\n", +- iface, descriptor_count, dst_descriptor_range_offset.ptr, src_descriptor_range_offset.ptr, +- descriptor_heap_type); ++ TRACE("iface %p, descriptor_count %u, dst_descriptor_range_offset %s, " ++ "src_descriptor_range_offset %s, descriptor_heap_type %#x.\n", ++ iface, descriptor_count, debug_cpu_handle(dst_descriptor_range_offset), ++ debug_cpu_handle(src_descriptor_range_offset), descriptor_heap_type); + + d3d12_device_CopyDescriptors(iface, 1, &dst_descriptor_range_offset, &descriptor_count, + 1, &src_descriptor_range_offset, &descriptor_count, descriptor_heap_type); + } + +-static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo( +- ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, +- UINT count, const D3D12_RESOURCE_DESC *resource_descs) ++static void d3d12_resource_allocation_info1_from_vkd3d(D3D12_RESOURCE_ALLOCATION_INFO1 *result, ++ const struct vkd3d_resource_allocation_info *info) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ result->Offset = info->offset; ++ result->Alignment = info->alignment; ++ result->SizeInBytes = info->size_in_bytes; ++} ++ ++static void d3d12_device_get_resource_allocation_info(struct d3d12_device *device, ++ D3D12_RESOURCE_ALLOCATION_INFO1 *infos1, unsigned int count, const D3D12_RESOURCE_DESC *resource_descs, ++ D3D12_RESOURCE_ALLOCATION_INFO *result) ++{ ++ struct vkd3d_resource_allocation_info info; + const D3D12_RESOURCE_DESC *desc; + uint64_t requested_alignment; ++ unsigned int i; + +- TRACE("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p.\n", +- iface, info, visible_mask, count, resource_descs); +- +- debug_ignored_node_mask(visible_mask); +- +- info->SizeInBytes = 0; +- info->Alignment = 0; ++ result->Alignment = 0; ++ result->SizeInBytes = 0; + +- if (count != 1) +- { +- FIXME("Multiple resource descriptions not supported.\n"); +- return info; +- } ++ info.offset = 0; + +- desc = &resource_descs[0]; +- +- if (FAILED(d3d12_resource_validate_desc(desc, device))) ++ for (i = 0; i < count; ++i) + { +- WARN("Invalid resource desc.\n"); +- goto invalid; +- } ++ desc = &resource_descs[i]; + +- if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) +- { +- info->SizeInBytes = align(desc->Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); +- info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; +- } +- else +- { +- if (FAILED(vkd3d_get_image_allocation_info(device, desc, info))) ++ if (FAILED(d3d12_resource_validate_desc(desc, device))) + { +- WARN("Failed to get allocation info for texture.\n"); ++ WARN("Invalid resource desc.\n"); + goto invalid; + } + +- requested_alignment = desc->Alignment +- ? desc->Alignment : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; +- info->Alignment = max(info->Alignment, requested_alignment); ++ if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) ++ { ++ info.alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; ++ info.offset = align(info.offset, info.alignment); ++ info.size_in_bytes = align(desc->Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); ++ } ++ else ++ { ++ if (FAILED(vkd3d_get_image_allocation_info(device, desc, &info))) ++ { ++ WARN("Failed to get allocation info for texture.\n"); ++ goto invalid; ++ } + +- info->SizeInBytes = align(info->SizeInBytes, info->Alignment); ++ requested_alignment = desc->Alignment ++ ? desc->Alignment : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; ++ info.alignment = max(info.alignment, requested_alignment); ++ info.size_in_bytes = align(info.size_in_bytes, info.alignment); + +- /* Pad by the maximum heap offset increase which may be needed to align to a higher +- * Vulkan requirement an offset supplied by the calling application. This allows +- * us to return the standard D3D12 alignment and adjust resource placement later. */ +- if (info->Alignment > requested_alignment) +- { +- info->SizeInBytes += info->Alignment - requested_alignment; +- info->Alignment = requested_alignment; ++ /* Pad by the maximum heap offset increase which may be needed to align to a higher ++ * Vulkan requirement an offset supplied by the calling application. This allows ++ * us to return the standard D3D12 alignment and adjust resource placement later. */ ++ if (info.alignment > requested_alignment) ++ { ++ info.size_in_bytes += info.alignment - requested_alignment; ++ info.alignment = requested_alignment; ++ } ++ ++ info.offset = align(info.offset, info.alignment); + } +- } + +- TRACE("Size %#"PRIx64", alignment %#"PRIx64".\n", info->SizeInBytes, info->Alignment); ++ if (infos1) ++ d3d12_resource_allocation_info1_from_vkd3d(&infos1[i], &info); + +- return info; ++ info.offset += info.size_in_bytes; ++ ++ result->Alignment = max(result->Alignment, info.alignment); ++ result->SizeInBytes = info.offset; ++ } ++ ++ return; + + invalid: +- info->SizeInBytes = ~(uint64_t)0; ++ result->SizeInBytes = UINT64_MAX; + +- /* FIXME: Should we support D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT for small MSSA resources? */ ++ /* FIXME: Should we support D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT for small MSAA resources? */ + if (desc->SampleDesc.Count != 1) +- info->Alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT; ++ result->Alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT; + else +- info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; ++ result->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; ++ ++ TRACE("Alignment %#"PRIx64".\n", result->Alignment); ++} ++ ++static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo( ++ ID3D12Device7 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, ++ UINT count, const D3D12_RESOURCE_DESC *resource_descs) ++{ ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + +- TRACE("Alignment %#"PRIx64".\n", info->Alignment); ++ TRACE("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p.\n", ++ iface, info, visible_mask, count, resource_descs); ++ ++ debug_ignored_node_mask(visible_mask); ++ ++ d3d12_device_get_resource_allocation_info(device, NULL, count, resource_descs, info); + + return info; + } + +-static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device5 *iface, ++static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device7 *iface, + D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + bool coherent; + + TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n", +@@ -3616,12 +3796,12 @@ static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapPrope + return heap_properties; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device7 *iface, + 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, REFIID iid, void **resource) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_resource *object; + HRESULT hr; + +@@ -3640,10 +3820,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi + return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device7 *iface, + const D3D12_HEAP_DESC *desc, REFIID iid, void **heap) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_heap *object; + HRESULT hr; + +@@ -3659,12 +3839,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device5 *iface, + return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device7 *iface, + ID3D12Heap *heap, UINT64 heap_offset, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_heap *heap_object; + struct d3d12_resource *object; + HRESULT hr; +@@ -3683,11 +3863,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device5 + return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device7 *iface, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_resource *object; + HRESULT hr; + +@@ -3701,11 +3881,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Devic + return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device7 *iface, + ID3D12DeviceChild *object, const SECURITY_ATTRIBUTES *attributes, DWORD access, + const WCHAR *name, HANDLE *handle) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n", + iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle); +@@ -3713,7 +3893,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device5 * + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device7 *iface, + HANDLE handle, REFIID riid, void **object) + { + FIXME("iface %p, handle %p, riid %s, object %p stub!\n", +@@ -3722,10 +3902,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device5 *if + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device7 *iface, + const WCHAR *name, DWORD access, HANDLE *handle) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + FIXME("iface %p, name %s, access %#x, handle %p stub!\n", + iface, debugstr_w(name, device->wchar_size), access, handle); +@@ -3733,7 +3913,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device7 *iface, + UINT object_count, ID3D12Pageable * const *objects) + { + ID3D12Fence *fence; +@@ -3741,17 +3921,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device5 *iface, + + TRACE("iface %p, object_count %u, objects %p.\n", iface, object_count, objects); + +- if (FAILED(hr = ID3D12Device5_CreateFence(iface, 0, 0, &IID_ID3D12Fence, (void **)&fence))) ++ if (FAILED(hr = ID3D12Device7_CreateFence(iface, 0, 0, &IID_ID3D12Fence, (void **)&fence))) + return hr; + +- hr = ID3D12Device5_EnqueueMakeResident(iface, 0, object_count, objects, fence, 1); ++ hr = ID3D12Device7_EnqueueMakeResident(iface, 0, object_count, objects, fence, 1); + if (SUCCEEDED(hr)) + ID3D12Fence_SetEventOnCompletion(fence, 1, NULL); + ID3D12Fence_Release(fence); + return hr; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device7 *iface, + UINT object_count, ID3D12Pageable * const *objects) + { + FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", +@@ -3760,10 +3940,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device5 *iface, + return S_OK; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device7 *iface, + UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_fence *object; + HRESULT hr; + +@@ -3776,21 +3956,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device5 *iface, + return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device5 *iface) ++static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device7 *iface) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p.\n", iface); + + return device->removed_reason; + } + +-static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device7 *iface, + const D3D12_RESOURCE_DESC *desc, UINT first_sub_resource, UINT sub_resource_count, + UINT64 base_offset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, + UINT *row_counts, UINT64 *row_sizes, UINT64 *total_bytes) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + unsigned int i, sub_resource_idx, miplevel_idx, row_count, row_size, row_pitch; + unsigned int width, height, depth, plane_count, sub_resources_per_plane; +@@ -3870,10 +4050,10 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device5 * + *total_bytes = total; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device7 *iface, + const D3D12_QUERY_HEAP_DESC *desc, REFIID iid, void **heap) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_query_heap *object; + HRESULT hr; + +@@ -3886,18 +4066,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device5 *ifa + return return_interface(&object->ID3D12QueryHeap_iface, &IID_ID3D12QueryHeap, iid, heap); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device5 *iface, BOOL enable) ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device7 *iface, BOOL enable) + { + FIXME("iface %p, enable %#x stub!\n", iface, enable); + + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device7 *iface, + const D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *root_signature, + REFIID iid, void **command_signature) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_command_signature *object; + HRESULT hr; + +@@ -3911,14 +4091,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic + &IID_ID3D12CommandSignature, iid, command_signature); + } + +-static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device7 *iface, + ID3D12Resource *resource, UINT *total_tile_count, + D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, + UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling, + D3D12_SUBRESOURCE_TILING *sub_resource_tilings) + { + const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource); +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " + "standard_title_shape %p, sub_resource_tiling_count %p, " +@@ -3931,9 +4111,9 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device5 *ifac + sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); + } + +-static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device5 *iface, LUID *luid) ++static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device7 *iface, LUID *luid) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + TRACE("iface %p, luid %p.\n", iface, luid); + +@@ -3942,15 +4122,16 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device5 *iface + return luid; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device7 *iface, + const void *blob, SIZE_T blob_size, REFIID iid, void **lib) + { +- FIXME("iface %p, blob %p, blob_size %lu, iid %s, lib %p stub!\n", iface, blob, blob_size, debugstr_guid(iid), lib); ++ FIXME("iface %p, blob %p, blob_size %"PRIuPTR", iid %s, lib %p stub!\n", ++ iface, blob, (uintptr_t)blob_size, debugstr_guid(iid), lib); + + return DXGI_ERROR_UNSUPPORTED; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device7 *iface, + ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count, + D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event) + { +@@ -3960,7 +4141,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion( + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device7 *iface, + UINT object_count, ID3D12Pageable *const *objects, const D3D12_RESIDENCY_PRIORITY *priorities) + { + FIXME_ONCE("iface %p, object_count %u, objects %p, priorities %p stub!\n", iface, object_count, objects, priorities); +@@ -3968,10 +4149,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device5 + return S_OK; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device7 *iface, + const D3D12_PIPELINE_STATE_STREAM_DESC *desc, REFIID iid, void **pipeline_state) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_pipeline_state *object; + HRESULT hr; + +@@ -3983,7 +4164,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device5 + return return_interface(&object->ID3D12PipelineState_iface, &IID_ID3D12PipelineState, iid, pipeline_state); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12Device7 *iface, + const void *address, REFIID iid, void **heap) + { + FIXME("iface %p, address %p, iid %s, heap %p stub!\n", iface, address, debugstr_guid(iid), heap); +@@ -3991,7 +4172,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12 + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID3D12Device7 *iface, + HANDLE file_mapping, REFIID iid, void **heap) + { + FIXME("iface %p, file_mapping %p, iid %s, heap %p stub!\n", iface, file_mapping, debugstr_guid(iid), heap); +@@ -3999,7 +4180,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device7 *iface, + D3D12_RESIDENCY_FLAGS flags, UINT num_objects, ID3D12Pageable *const *objects, + ID3D12Fence *fence, UINT64 fence_value) + { +@@ -4010,7 +4191,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device5 + return S_OK; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device7 *iface, + UINT node_mask, D3D12_COMMAND_LIST_TYPE type, D3D12_COMMAND_LIST_FLAGS flags, + REFIID iid, void **command_list) + { +@@ -4020,7 +4201,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device5 * + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device7 *iface, + const D3D12_PROTECTED_RESOURCE_SESSION_DESC *desc, REFIID iid, void **session) + { + FIXME("iface %p, desc %p, iid %s, session %p stub!\n", iface, desc, debugstr_guid(iid), session); +@@ -4028,13 +4209,13 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3 + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Device7 *iface, + 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, + ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_resource *object; + HRESULT hr; + +@@ -4053,11 +4234,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Dev + return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device7 *iface, + const D3D12_HEAP_DESC *desc, ID3D12ProtectedResourceSession *protected_session, + REFIID iid, void **heap) + { +- struct d3d12_device *device = impl_from_ID3D12Device5(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); + struct d3d12_heap *object; + HRESULT hr; + +@@ -4073,7 +4254,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface, + return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Device7 *iface, + const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, + const D3D12_CLEAR_VALUE *optimized_clear_value, + ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource) +@@ -4087,17 +4268,23 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Devi + } + + static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo1( +- ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, ++ ID3D12Device7 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, + UINT count, const D3D12_RESOURCE_DESC *resource_descs, + D3D12_RESOURCE_ALLOCATION_INFO1 *info1) + { +- FIXME("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p, info1 %p stub!\n", ++ struct d3d12_device *device = impl_from_ID3D12Device7(iface); ++ ++ TRACE("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p, info1 %p.\n", + iface, info, visible_mask, count, resource_descs, info1); + ++ debug_ignored_node_mask(visible_mask); ++ ++ d3d12_device_get_resource_allocation_info(device, info1, count, resource_descs, info); ++ + return info; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device7 *iface, + ID3D12LifetimeOwner *owner, REFIID iid, void **tracker) + { + FIXME("iface %p, owner %p, iid %s, tracker %p stub!\n", iface, owner, debugstr_guid(iid), tracker); +@@ -4105,12 +4292,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device + return E_NOTIMPL; + } + +-static void STDMETHODCALLTYPE d3d12_device_RemoveDevice(ID3D12Device5 *iface) ++static void STDMETHODCALLTYPE d3d12_device_RemoveDevice(ID3D12Device7 *iface) + { + FIXME("iface %p stub!\n", iface); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device7 *iface, + UINT *num_meta_commands, D3D12_META_COMMAND_DESC *command_desc) + { + FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface, +@@ -4119,7 +4306,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device7 *iface, + REFGUID command_id, D3D12_META_COMMAND_PARAMETER_STAGE stage, + UINT *size_in_bytes, UINT *parameter_count, + D3D12_META_COMMAND_PARAMETER_DESC *parameter_desc) +@@ -4131,19 +4318,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3 + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device7 *iface, + REFGUID command_id, UINT node_mask, const void *parameters_data, + SIZE_T data_size_in_bytes, REFIID iid, void **meta_command) + { + FIXME("iface %p, command_id %s, node_mask %#x, parameters_data %p, " +- "data_size_in_bytes %lu, iid %s, meta_command %p stub!\n", iface, ++ "data_size_in_bytes %"PRIuPTR", iid %s, meta_command %p stub!\n", iface, + debugstr_guid(command_id), node_mask, parameters_data, +- data_size_in_bytes, debugstr_guid(iid), meta_command); ++ (uintptr_t)data_size_in_bytes, debugstr_guid(iid), meta_command); + + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device5 *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device7 *iface, + const D3D12_STATE_OBJECT_DESC *desc, REFIID iid, void **state_object) + { + FIXME("iface %p, desc %p, iid %s, state_object %p stub!\n", iface, desc, debugstr_guid(iid), state_object); +@@ -4151,14 +4338,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device5 *i + return E_NOTIMPL; + } + +-static void STDMETHODCALLTYPE d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo(ID3D12Device5 *iface, ++static void STDMETHODCALLTYPE d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo(ID3D12Device7 *iface, + const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *desc, + D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO *info) + { + FIXME("iface %p, desc %p, info %p stub!\n", iface, desc, info); + } + +-static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_CheckDriverMatchingIdentifier(ID3D12Device5 *iface, ++static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_CheckDriverMatchingIdentifier(ID3D12Device7 *iface, + D3D12_SERIALIZED_DATA_TYPE data_type, const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *identifier) + { + FIXME("iface %p, data_type %u, identifier %p stub!\n", iface, data_type, identifier); +@@ -4166,7 +4353,35 @@ static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_Ch + return D3D12_DRIVER_MATCHING_IDENTIFIER_UNRECOGNIZED; + } + +-static const struct ID3D12Device5Vtbl d3d12_device_vtbl = ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetBackgroundProcessingMode(ID3D12Device7 *iface, ++ D3D12_BACKGROUND_PROCESSING_MODE mode, D3D12_MEASUREMENTS_ACTION action, HANDLE event, ++ BOOL *further_measurements_desired) ++{ ++ FIXME("iface %p, mode %#x, action %#x, event %p, further_measurements_desired %p stub!\n", ++ iface, mode, action, event, further_measurements_desired); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT STDMETHODCALLTYPE d3d12_device_AddToStateObject(ID3D12Device7 *iface, ++ const D3D12_STATE_OBJECT_DESC *addition, ID3D12StateObject *state_object_to_grow_from, ++ REFIID riid, void **new_state_object) ++{ ++ FIXME("iface %p, addition %p, state_object_to_grow_from %p, riid %s, new_state_object %p stub!\n", ++ iface, addition, state_object_to_grow_from, debugstr_guid(riid), new_state_object); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession1(ID3D12Device7 *iface, ++ const D3D12_PROTECTED_RESOURCE_SESSION_DESC1 *desc, REFIID riid, void **session) ++{ ++ FIXME("iface %p, desc %p, riid %s, session %p stub!\n", iface, desc, debugstr_guid(riid), session); ++ ++ return E_NOTIMPL; ++} ++ ++static const struct ID3D12Device7Vtbl d3d12_device_vtbl = + { + /* IUnknown methods */ + d3d12_device_QueryInterface, +@@ -4241,14 +4456,53 @@ static const struct ID3D12Device5Vtbl d3d12_device_vtbl = + d3d12_device_CreateStateObject, + d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo, + d3d12_device_CheckDriverMatchingIdentifier, ++ /* ID3D12Device6 methods */ ++ d3d12_device_SetBackgroundProcessingMode, ++ /* ID3D12Device7 methods */ ++ d3d12_device_AddToStateObject, ++ d3d12_device_CreateProtectedResourceSession1, + }; + +-struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface) ++struct d3d12_device *unsafe_impl_from_ID3D12Device7(ID3D12Device7 *iface) + { + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d12_device_vtbl); +- return impl_from_ID3D12Device5(iface); ++ return impl_from_ID3D12Device7(iface); ++} ++ +static void *device_worker_main(void *arg) +{ + struct d3d12_descriptor_heap *heap; @@ -15064,12 +18510,19 @@ index 5c801ca4676..2b8558175e0 100644 + vkd3d_mutex_unlock(&device->worker_mutex); + + return NULL; -+} -+ + } + static HRESULT d3d12_device_init(struct d3d12_device *device, - struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info) - { -@@ -4270,6 +4372,14 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, +@@ -4257,7 +4511,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, + const struct vkd3d_vk_device_procs *vk_procs; + HRESULT hr; + +- device->ID3D12Device5_iface.lpVtbl = &d3d12_device_vtbl; ++ device->ID3D12Device7_iface.lpVtbl = &d3d12_device_vtbl; + device->refcount = 1; + + vkd3d_instance_incref(device->vkd3d_instance = instance); +@@ -4270,6 +4524,14 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, device->vk_device = VK_NULL_HANDLE; @@ -15084,7 +18537,7 @@ index 5c801ca4676..2b8558175e0 100644 if (FAILED(hr = vkd3d_create_vk_device(device, create_info))) goto out_free_instance; -@@ -4291,6 +4401,13 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, +@@ -4291,6 +4553,13 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, if (FAILED(hr = vkd3d_vk_descriptor_heap_layouts_init(device))) goto out_cleanup_uav_clear_state; @@ -15098,7 +18551,7 @@ index 5c801ca4676..2b8558175e0 100644 vkd3d_render_pass_cache_init(&device->render_pass_cache); vkd3d_gpu_va_allocator_init(&device->gpu_va_allocator); vkd3d_time_domains_init(device); -@@ -4308,6 +4425,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, +@@ -4308,6 +4577,8 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, return S_OK; @@ -15107,7 +18560,16 @@ index 5c801ca4676..2b8558175e0 100644 out_cleanup_uav_clear_state: vkd3d_uav_clear_state_cleanup(&device->uav_clear_state, device); out_destroy_null_resources: -@@ -4361,6 +4480,40 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason, +@@ -4354,13 +4625,47 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason, + va_list args; + + va_start(args, message); +- WARN("Device %p is lost (reason %#x, \"%s\").\n", +- device, reason, vkd3d_dbg_vsprintf(message, args)); ++ WARN("Device %p is lost (reason %s, \"%s\").\n", ++ device, debugstr_hresult(reason), vkd3d_dbg_vsprintf(message, args)); + va_end(args); + device->removed_reason = reason; } @@ -15148,7 +18610,7 @@ index 5c801ca4676..2b8558175e0 100644 #ifdef _WIN32 struct thread_data -@@ -4403,7 +4556,7 @@ HRESULT vkd3d_create_thread(struct vkd3d_instance *instance, +@@ -4403,7 +4708,7 @@ HRESULT vkd3d_create_thread(struct vkd3d_instance *instance, thread_data->data = data; if (!(thread->handle = CreateThread(NULL, 0, call_thread_main, thread_data, 0, NULL))) { @@ -15157,7 +18619,7 @@ index 5c801ca4676..2b8558175e0 100644 vkd3d_free(thread_data); hr = E_FAIL; } -@@ -4429,7 +4582,7 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha +@@ -4429,7 +4734,7 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha if (instance->join_thread) { if (FAILED(hr = instance->join_thread(thread->handle))) @@ -15166,8 +18628,41 @@ index 5c801ca4676..2b8558175e0 100644 } else { +@@ -4454,28 +4759,28 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha + + IUnknown *vkd3d_get_device_parent(ID3D12Device *device) + { +- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); + + return d3d12_device->parent; + } + + VkDevice vkd3d_get_vk_device(ID3D12Device *device) + { +- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); + + return d3d12_device->vk_device; + } + + VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device) + { +- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); + + return d3d12_device->vk_physical_device; + } + + struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device) + { +- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); + + return d3d12_device->vkd3d_instance; + } diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index abbdfbe2015..a360b0ef4dd 100644 +index abbdfbe2015..8f4d18358d2 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -22,7 +22,7 @@ @@ -15179,6 +18674,151 @@ index abbdfbe2015..a360b0ef4dd 100644 static inline bool is_cpu_accessible_heap(const D3D12_HEAP_PROPERTIES *properties) { +@@ -308,7 +308,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_heap_QueryInterface(ID3D12Heap *iface, + static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface) + { + struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); +- ULONG refcount = InterlockedIncrement(&heap->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount); + + TRACE("%p increasing refcount to %u.\n", heap, refcount); + +@@ -345,7 +345,7 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap) + static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) + { + struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); +- ULONG refcount = InterlockedDecrement(&heap->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount); + + TRACE("%p decreasing refcount to %u.\n", heap, refcount); + +@@ -358,7 +358,7 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) + + static void d3d12_heap_resource_destroyed(struct d3d12_heap *heap) + { +- if (!InterlockedDecrement(&heap->resource_count) && (!heap->refcount || heap->is_private)) ++ if (!vkd3d_atomic_decrement_u32(&heap->resource_count) && (!heap->refcount || heap->is_private)) + d3d12_heap_destroy(heap); + } + +@@ -940,7 +940,7 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device, + } + + HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, +- const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info) ++ const D3D12_RESOURCE_DESC *desc, struct vkd3d_resource_allocation_info *allocation_info) + { + static const D3D12_HEAP_PROPERTIES heap_properties = {D3D12_HEAP_TYPE_DEFAULT}; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; +@@ -968,8 +968,8 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, + VK_CALL(vkGetImageMemoryRequirements(device->vk_device, vk_image, &requirements)); + VK_CALL(vkDestroyImage(device->vk_device, vk_image, NULL)); + +- allocation_info->SizeInBytes = requirements.size; +- allocation_info->Alignment = requirements.alignment; ++ allocation_info->size_in_bytes = requirements.size; ++ allocation_info->alignment = requirements.alignment; + } + + return hr; +@@ -1003,7 +1003,7 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 + + static ULONG d3d12_resource_incref(struct d3d12_resource *resource) + { +- ULONG refcount = InterlockedIncrement(&resource->internal_refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&resource->internal_refcount); + + TRACE("%p increasing refcount to %u.\n", resource, refcount); + +@@ -1012,7 +1012,7 @@ static ULONG d3d12_resource_incref(struct d3d12_resource *resource) + + static ULONG d3d12_resource_decref(struct d3d12_resource *resource) + { +- ULONG refcount = InterlockedDecrement(&resource->internal_refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->internal_refcount); + + TRACE("%p decreasing refcount to %u.\n", resource, refcount); + +@@ -1284,7 +1284,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource1 * + static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface) + { + struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface); +- ULONG refcount = InterlockedIncrement(&resource->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&resource->refcount); + + TRACE("%p increasing refcount to %u.\n", resource, refcount); + +@@ -1302,7 +1302,7 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface) + static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource1 *iface) + { + struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface); +- ULONG refcount = InterlockedDecrement(&resource->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->refcount); + + TRACE("%p decreasing refcount to %u.\n", resource, refcount); + +@@ -2174,7 +2174,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, + { + resource->heap = heap; + resource->heap_offset = heap_offset; +- InterlockedIncrement(&heap->resource_count); ++ vkd3d_atomic_increment_u32(&heap->resource_count); + } + else + { +@@ -2239,7 +2239,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device, + HRESULT vkd3d_create_image_resource(ID3D12Device *device, + const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource) + { +- struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device5((ID3D12Device5 *)device); ++ struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device7((ID3D12Device7 *)device); + struct d3d12_resource *object; + HRESULT hr; + +@@ -2314,14 +2314,14 @@ static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache) + + STATIC_ASSERT(!(ARRAY_SIZE(cache->heads) & HEAD_INDEX_MASK)); + +- i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; ++ i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK; + for (;;) + { + if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) + { + if ((u.object = cache->heads[i].head)) + { +- vkd3d_atomic_decrement(&cache->free_count); ++ vkd3d_atomic_decrement_u32(&cache->free_count); + cache->heads[i].head = u.header->next; + vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); + return u.object; +@@ -2345,7 +2345,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, + + /* Using the same index as above may result in a somewhat uneven distribution, + * but the main objective is to avoid costly spinlock contention. */ +- i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; ++ i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK; + for (;;) + { + if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) +@@ -2357,7 +2357,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, + u.header->next = head; + cache->heads[i].head = u.object; + vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); +- vkd3d_atomic_increment(&cache->free_count); ++ vkd3d_atomic_increment_u32(&cache->free_count); + } + + #undef HEAD_INDEX_MASK +@@ -2429,7 +2429,7 @@ void vkd3d_view_decref(void *view, struct d3d12_device *device) + { + union d3d12_desc_object u = {view}; + +- if (vkd3d_atomic_decrement(&u.header->refcount)) ++ if (vkd3d_atomic_decrement_u32(&u.header->refcount)) + return; + + if (u.header->magic != VKD3D_DESCRIPTOR_MAGIC_CBV) @@ -2470,12 +2470,14 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; @@ -15349,6 +18989,24 @@ index abbdfbe2015..a360b0ef4dd 100644 return hresult_from_vk_result(vr); } +@@ -3966,7 +4010,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_descriptor_heap_QueryInterface(ID3D12Desc + static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap *iface) + { + struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface); +- ULONG refcount = InterlockedIncrement(&heap->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount); + + TRACE("%p increasing refcount to %u.\n", heap, refcount); + +@@ -3976,7 +4020,7 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap + static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHeap *iface) + { + struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface); +- ULONG refcount = InterlockedDecrement(&heap->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount); + + TRACE("%p decreasing refcount to %u.\n", heap, refcount); + @@ -3997,6 +4041,9 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHea { struct d3d12_desc *descriptors = (struct d3d12_desc *)heap->descriptors; @@ -15412,6 +19070,24 @@ index abbdfbe2015..a360b0ef4dd 100644 } else { +@@ -4364,7 +4429,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_query_heap_QueryInterface(ID3D12QueryHeap + static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface) + { + struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface); +- ULONG refcount = InterlockedIncrement(&heap->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount); + + TRACE("%p increasing refcount to %u.\n", heap, refcount); + +@@ -4374,7 +4439,7 @@ static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface) + static ULONG STDMETHODCALLTYPE d3d12_query_heap_Release(ID3D12QueryHeap *iface) + { + struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface); +- ULONG refcount = InterlockedDecrement(&heap->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount); + + TRACE("%p decreasing refcount to %u.\n", heap, refcount); + @@ -4858,7 +4923,7 @@ HRESULT vkd3d_init_null_resources(struct vkd3d_null_resources *null_resources, return vkd3d_init_null_resources_data(null_resources, device); @@ -15422,9 +19098,27 @@ index abbdfbe2015..a360b0ef4dd 100644 return hr; } diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index fc3187f4bea..5f383d256cc 100644 +index fc3187f4bea..3428742dd7f 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c +@@ -52,7 +52,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_root_signature_QueryInterface(ID3D12RootS + static ULONG STDMETHODCALLTYPE d3d12_root_signature_AddRef(ID3D12RootSignature *iface) + { + struct d3d12_root_signature *root_signature = impl_from_ID3D12RootSignature(iface); +- ULONG refcount = InterlockedIncrement(&root_signature->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&root_signature->refcount); + + TRACE("%p increasing refcount to %u.\n", root_signature, refcount); + +@@ -110,7 +110,7 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa + static ULONG STDMETHODCALLTYPE d3d12_root_signature_Release(ID3D12RootSignature *iface) + { + struct d3d12_root_signature *root_signature = impl_from_ID3D12RootSignature(iface); +- ULONG refcount = InterlockedDecrement(&root_signature->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&root_signature->refcount); + + TRACE("%p decreasing refcount to %u.\n", root_signature, refcount); + @@ -515,7 +515,7 @@ static HRESULT d3d12_root_signature_init_push_constants(struct d3d12_root_signat assert(p->ShaderVisibility <= D3D12_SHADER_VISIBILITY_PIXEL); push_constants[p->ShaderVisibility].stageFlags = use_vk_heaps ? VK_SHADER_STAGE_ALL @@ -15499,6 +19193,24 @@ index fc3187f4bea..5f383d256cc 100644 return hr; } +@@ -1965,7 +1984,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_pipeline_state_QueryInterface(ID3D12Pipel + static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_AddRef(ID3D12PipelineState *iface) + { + struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); +- ULONG refcount = InterlockedIncrement(&state->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&state->refcount); + + TRACE("%p increasing refcount to %u.\n", state, refcount); + +@@ -2008,7 +2027,7 @@ static void d3d12_pipeline_uav_counter_state_cleanup(struct d3d12_pipeline_uav_c + static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState *iface) + { + struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); +- ULONG refcount = InterlockedDecrement(&state->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&state->refcount); + + TRACE("%p decreasing refcount to %u.\n", state, refcount); + @@ -2129,6 +2148,18 @@ static inline unsigned int typed_uav_compile_option(const struct d3d12_device *d : VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV_READ_FORMAT_R32; } @@ -15616,7 +19328,7 @@ index fc3187f4bea..5f383d256cc 100644 } } diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c -index 9b28068be51..751971220e7 100644 +index 9b28068be51..ac79ae5ddff 100644 --- a/libs/vkd3d/libs/vkd3d/utils.c +++ b/libs/vkd3d/libs/vkd3d/utils.c @@ -539,6 +539,7 @@ bool is_valid_feature_level(D3D_FEATURE_LEVEL feature_level) @@ -15635,7 +19347,31 @@ index 9b28068be51..751971220e7 100644 }; unsigned int i; -@@ -681,7 +683,7 @@ const char *debug_vk_extent_3d(VkExtent3D extent) +@@ -630,6 +632,11 @@ HRESULT return_interface(void *iface, REFIID iface_iid, + return hr; + } + ++const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle) ++{ ++ return vkd3d_dbg_sprintf("{%#"PRIxPTR"}", (uintptr_t)handle.ptr); ++} ++ + const char *debug_d3d12_box(const D3D12_BOX *box) + { + if (!box) +@@ -671,6 +678,11 @@ const char *debug_d3d12_shader_component_mapping(unsigned int mapping) + debug_d3d12_shader_component(D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(3, mapping))); + } + ++const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle) ++{ ++ return vkd3d_dbg_sprintf("{%#"PRIx64"}", handle.ptr); ++} ++ + const char *debug_vk_extent_3d(VkExtent3D extent) + { + return vkd3d_dbg_sprintf("(%u, %u, %u)", +@@ -681,7 +693,7 @@ const char *debug_vk_extent_3d(VkExtent3D extent) const char *debug_vk_queue_flags(VkQueueFlags flags) { @@ -15644,7 +19380,7 @@ index 9b28068be51..751971220e7 100644 buffer[0] = '\0'; #define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; } -@@ -689,6 +691,10 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) +@@ -689,6 +701,10 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) FLAG_TO_STR(VK_QUEUE_COMPUTE_BIT) FLAG_TO_STR(VK_QUEUE_TRANSFER_BIT) FLAG_TO_STR(VK_QUEUE_SPARSE_BINDING_BIT) @@ -15655,7 +19391,7 @@ index 9b28068be51..751971220e7 100644 #undef FLAG_TO_STR if (flags) FIXME("Unrecognized flag(s) %#x.\n", flags); -@@ -727,10 +733,8 @@ const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags) +@@ -727,10 +743,8 @@ const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags) FLAG_TO_STR(VK_MEMORY_PROPERTY_HOST_CACHED_BIT) FLAG_TO_STR(VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) FLAG_TO_STR(VK_MEMORY_PROPERTY_PROTECTED_BIT) @@ -15669,7 +19405,7 @@ index 9b28068be51..751971220e7 100644 if (flags) FIXME("Unrecognized flag(s) %#x.\n", flags); diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c -index 245edb5aeac..0139de5dd23 100644 +index 245edb5aeac..7919b7d8760 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c +++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c @@ -60,7 +60,7 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, @@ -15681,6 +19417,95 @@ index 245edb5aeac..0139de5dd23 100644 return E_FAIL; } +@@ -71,18 +71,18 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, + + if (!device) + { +- ID3D12Device_Release(&object->ID3D12Device5_iface); ++ ID3D12Device_Release(&object->ID3D12Device7_iface); + return S_FALSE; + } + +- return return_interface(&object->ID3D12Device5_iface, &IID_ID3D12Device, iid, device); ++ return return_interface(&object->ID3D12Device7_iface, &IID_ID3D12Device, iid, device); + } + + /* ID3D12RootSignatureDeserializer */ + struct d3d12_root_signature_deserializer + { + ID3D12RootSignatureDeserializer ID3D12RootSignatureDeserializer_iface; +- LONG refcount; ++ unsigned int refcount; + + union + { +@@ -123,7 +123,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_root_signature_deserializer_QueryInterfac + static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_AddRef(ID3D12RootSignatureDeserializer *iface) + { + struct d3d12_root_signature_deserializer *deserializer = impl_from_ID3D12RootSignatureDeserializer(iface); +- ULONG refcount = InterlockedIncrement(&deserializer->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&deserializer->refcount); + + TRACE("%p increasing refcount to %u.\n", deserializer, refcount); + +@@ -133,7 +133,7 @@ static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_AddRef(ID3D12Ro + static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_Release(ID3D12RootSignatureDeserializer *iface) + { + struct d3d12_root_signature_deserializer *deserializer = impl_from_ID3D12RootSignatureDeserializer(iface); +- ULONG refcount = InterlockedDecrement(&deserializer->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&deserializer->refcount); + + TRACE("%p decreasing refcount to %u.\n", deserializer, refcount); + +@@ -222,8 +222,8 @@ HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_s + struct d3d12_root_signature_deserializer *object; + HRESULT hr; + +- TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", +- data, data_size, debugstr_guid(iid), deserializer); ++ TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", ++ data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); + + if (!(object = vkd3d_malloc(sizeof(*object)))) + return E_OUTOFMEMORY; +@@ -242,7 +242,7 @@ HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_s + struct d3d12_versioned_root_signature_deserializer + { + ID3D12VersionedRootSignatureDeserializer ID3D12VersionedRootSignatureDeserializer_iface; +- LONG refcount; ++ unsigned int refcount; + + union + { +@@ -284,7 +284,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_Que + static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_AddRef(ID3D12VersionedRootSignatureDeserializer *iface) + { + struct d3d12_versioned_root_signature_deserializer *deserializer = impl_from_ID3D12VersionedRootSignatureDeserializer(iface); +- ULONG refcount = InterlockedIncrement(&deserializer->refcount); ++ unsigned int refcount = vkd3d_atomic_increment_u32(&deserializer->refcount); + + TRACE("%p increasing refcount to %u.\n", deserializer, refcount); + +@@ -294,7 +294,7 @@ static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_AddRe + static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_Release(ID3D12VersionedRootSignatureDeserializer *iface) + { + struct d3d12_versioned_root_signature_deserializer *deserializer = impl_from_ID3D12VersionedRootSignatureDeserializer(iface); +- ULONG refcount = InterlockedDecrement(&deserializer->refcount); ++ unsigned int refcount = vkd3d_atomic_decrement_u32(&deserializer->refcount); + + TRACE("%p decreasing refcount to %u.\n", deserializer, refcount); + +@@ -406,8 +406,8 @@ HRESULT vkd3d_create_versioned_root_signature_deserializer(const void *data, SIZ + struct vkd3d_shader_code dxbc = {data, data_size}; + HRESULT hr; + +- TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", +- data, data_size, debugstr_guid(iid), deserializer); ++ TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", ++ data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); + + if (!(object = vkd3d_malloc(sizeof(*object)))) + return E_OUTOFMEMORY; @@ -456,7 +456,7 @@ HRESULT vkd3d_serialize_root_signature(const D3D12_ROOT_SIGNATURE_DESC *desc, if (error_blob && messages) { @@ -15718,7 +19543,7 @@ index 245edb5aeac..0139de5dd23 100644 } return hr; diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index f06f564d6ea..a6d5b94b778 100644 +index f06f564d6ea..78f4f3514e2 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -55,7 +55,7 @@ @@ -15751,7 +19576,16 @@ index f06f564d6ea..a6d5b94b778 100644 bool EXT_texel_buffer_alignment; bool EXT_transform_feedback; bool EXT_vertex_attribute_divisor; -@@ -248,7 +250,7 @@ static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond) +@@ -190,7 +192,7 @@ struct vkd3d_instance + + uint64_t host_ticks_per_second; + +- LONG refcount; ++ unsigned int refcount; + }; + + #ifdef _WIN32 +@@ -248,23 +250,13 @@ static inline void vkd3d_cond_broadcast(struct vkd3d_cond *cond) static inline void vkd3d_cond_wait(struct vkd3d_cond *cond, struct vkd3d_mutex *lock) { if (!SleepConditionVariableCS(&cond->cond, &lock->lock, INFINITE)) @@ -15760,7 +19594,73 @@ index f06f564d6ea..a6d5b94b778 100644 } static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) -@@ -619,8 +621,8 @@ struct vkd3d_signaled_semaphore + { + } + +-static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) +-{ +- return InterlockedIncrement((LONG volatile *)x); +-} +- +-static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) +-{ +- return InterlockedDecrement((LONG volatile *)x); +-} +- + static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg) + { + return InterlockedCompareExchange((LONG volatile *)x, xchg, cmp) == cmp; +@@ -387,24 +379,6 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) + ERR("Could not destroy the condition variable, error %d.\n", ret); + } + +-# if HAVE_SYNC_SUB_AND_FETCH +-static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) +-{ +- return __sync_sub_and_fetch(x, 1); +-} +-# else +-# error "vkd3d_atomic_decrement() not implemented for this platform" +-# endif /* HAVE_SYNC_SUB_AND_FETCH */ +- +-# if HAVE_SYNC_ADD_AND_FETCH +-static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) +-{ +- return __sync_add_and_fetch(x, 1); +-} +-# else +-# error "vkd3d_atomic_increment() not implemented for this platform" +-# endif /* HAVE_SYNC_ADD_AND_FETCH */ +- + # if HAVE_SYNC_BOOL_COMPARE_AND_SWAP + static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg) + { +@@ -491,13 +465,13 @@ struct vkd3d_fence_worker + struct vkd3d_gpu_va_allocation + { + D3D12_GPU_VIRTUAL_ADDRESS base; +- size_t size; ++ uint64_t size; + void *ptr; + }; + + struct vkd3d_gpu_va_slab + { +- size_t size; ++ uint64_t size; + void *ptr; + }; + +@@ -515,7 +489,7 @@ struct vkd3d_gpu_va_allocator + }; + + D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, +- size_t alignment, size_t size, void *ptr); ++ size_t alignment, uint64_t size, void *ptr); + void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address); + void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address); + +@@ -619,8 +593,8 @@ struct vkd3d_signaled_semaphore struct d3d12_fence { ID3D12Fence1 ID3D12Fence1_iface; @@ -15771,7 +19671,88 @@ index f06f564d6ea..a6d5b94b778 100644 D3D12_FENCE_FLAGS flags; -@@ -1363,7 +1365,7 @@ struct vkd3d_buffer +@@ -663,8 +637,8 @@ VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint + struct d3d12_heap + { + ID3D12Heap ID3D12Heap_iface; +- LONG refcount; +- LONG resource_count; ++ unsigned int refcount; ++ unsigned int resource_count; + + bool is_private; + D3D12_HEAP_DESC desc; +@@ -719,8 +693,8 @@ struct d3d12_resource_tile_info + struct d3d12_resource + { + ID3D12Resource1 ID3D12Resource1_iface; +- LONG refcount; +- LONG internal_refcount; ++ unsigned int refcount; ++ unsigned int internal_refcount; + + D3D12_RESOURCE_DESC desc; + const struct vkd3d_format *format; +@@ -768,6 +742,13 @@ static inline bool d3d12_resource_is_texture(const struct d3d12_resource *resour + return resource->desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER; + } + ++struct vkd3d_resource_allocation_info ++{ ++ uint64_t offset; ++ uint64_t alignment; ++ uint64_t size_in_bytes; ++}; ++ + bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource); + HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device); + void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, +@@ -795,7 +776,7 @@ HRESULT vkd3d_create_buffer(struct d3d12_device *device, + const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, + const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer); + HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, +- const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info); ++ const D3D12_RESOURCE_DESC *desc, struct vkd3d_resource_allocation_info *allocation_info); + + enum vkd3d_view_type + { +@@ -1044,7 +1025,7 @@ struct d3d12_descriptor_heap_vk_set + struct d3d12_descriptor_heap + { + ID3D12DescriptorHeap ID3D12DescriptorHeap_iface; +- LONG refcount; ++ unsigned int refcount; + uint64_t serial_id; + + D3D12_DESCRIPTOR_HEAP_DESC desc; +@@ -1083,7 +1064,7 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device, + struct d3d12_query_heap + { + ID3D12QueryHeap ID3D12QueryHeap_iface; +- LONG refcount; ++ unsigned int refcount; + + VkQueryPool vk_query_pool; + +@@ -1170,7 +1151,7 @@ struct d3d12_descriptor_set_layout + struct d3d12_root_signature + { + ID3D12RootSignature ID3D12RootSignature_iface; +- LONG refcount; ++ unsigned int refcount; + + VkPipelineLayout vk_pipeline_layout; + struct d3d12_descriptor_set_layout descriptor_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS]; +@@ -1279,7 +1260,7 @@ struct d3d12_pipeline_uav_counter_state + struct d3d12_pipeline_state + { + ID3D12PipelineState ID3D12PipelineState_iface; +- LONG refcount; ++ unsigned int refcount; + + union + { +@@ -1363,7 +1344,7 @@ struct vkd3d_buffer struct d3d12_command_allocator { ID3D12CommandAllocator ID3D12CommandAllocator_iface; @@ -15780,7 +19761,7 @@ index f06f564d6ea..a6d5b94b778 100644 D3D12_COMMAND_LIST_TYPE type; VkQueueFlags vk_queue_flags; -@@ -1464,7 +1466,7 @@ enum vkd3d_pipeline_bind_point +@@ -1464,7 +1445,7 @@ enum vkd3d_pipeline_bind_point struct d3d12_command_list { ID3D12GraphicsCommandList5 ID3D12GraphicsCommandList5_iface; @@ -15789,7 +19770,7 @@ index f06f564d6ea..a6d5b94b778 100644 D3D12_COMMAND_LIST_TYPE type; VkQueueFlags vk_queue_flags; -@@ -1620,7 +1622,7 @@ struct d3d12_command_queue_op_array +@@ -1620,7 +1601,7 @@ struct d3d12_command_queue_op_array struct d3d12_command_queue { ID3D12CommandQueue ID3D12CommandQueue_iface; @@ -15798,7 +19779,7 @@ index f06f564d6ea..a6d5b94b778 100644 D3D12_COMMAND_QUEUE_DESC desc; -@@ -1655,7 +1657,7 @@ HRESULT d3d12_command_queue_create(struct d3d12_device *device, +@@ -1655,7 +1636,7 @@ HRESULT d3d12_command_queue_create(struct d3d12_device *device, struct d3d12_command_signature { ID3D12CommandSignature ID3D12CommandSignature_iface; @@ -15807,7 +19788,18 @@ index f06f564d6ea..a6d5b94b778 100644 unsigned int internal_refcount; D3D12_COMMAND_SIGNATURE_DESC desc; -@@ -1757,9 +1759,23 @@ struct d3d12_device +@@ -1746,8 +1727,8 @@ struct vkd3d_desc_object_cache + /* ID3D12Device */ + struct d3d12_device + { +- ID3D12Device5 ID3D12Device5_iface; +- LONG refcount; ++ ID3D12Device7 ID3D12Device7_iface; ++ unsigned int refcount; + + VkDevice vk_device; + VkPhysicalDevice vk_physical_device; +@@ -1757,9 +1738,23 @@ struct d3d12_device struct vkd3d_gpu_va_allocator gpu_va_allocator; @@ -15832,7 +19824,7 @@ index f06f564d6ea..a6d5b94b778 100644 struct vkd3d_render_pass_cache render_pass_cache; VkPipelineCache vk_pipeline_cache; -@@ -1799,11 +1815,6 @@ struct d3d12_device +@@ -1799,11 +1794,6 @@ struct d3d12_device const struct vkd3d_format_compatibility_list *format_compatibility_lists; struct vkd3d_null_resources null_resources; struct vkd3d_uav_clear_state uav_clear_state; @@ -15844,15 +19836,52 @@ index f06f564d6ea..a6d5b94b778 100644 }; HRESULT d3d12_device_create(struct vkd3d_instance *instance, -@@ -1813,6 +1824,8 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent); +@@ -1812,27 +1802,29 @@ struct vkd3d_queue *d3d12_device_get_vkd3d_queue(struct d3d12_device *device, D3 + bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent); void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason, const char *message, ...) VKD3D_PRINTF_FUNC(3, 4); - struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface); +-struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface); ++struct d3d12_device *unsafe_impl_from_ID3D12Device7(ID3D12Device7 *iface); +HRESULT d3d12_device_add_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap); +void d3d12_device_remove_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap); static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object) { +- return ID3D12Device5_QueryInterface(&device->ID3D12Device5_iface, iid, object); ++ return ID3D12Device7_QueryInterface(&device->ID3D12Device7_iface, iid, object); + } + + static inline ULONG d3d12_device_add_ref(struct d3d12_device *device) + { +- return ID3D12Device5_AddRef(&device->ID3D12Device5_iface); ++ return ID3D12Device7_AddRef(&device->ID3D12Device7_iface); + } + + static inline ULONG d3d12_device_release(struct d3d12_device *device) + { +- return ID3D12Device5_Release(&device->ID3D12Device5_iface); ++ return ID3D12Device7_Release(&device->ID3D12Device7_iface); + } + + static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type) + { +- return ID3D12Device5_GetDescriptorHandleIncrementSize(&device->ID3D12Device5_iface, descriptor_type); ++ return ID3D12Device7_GetDescriptorHandleIncrementSize(&device->ID3D12Device7_iface, descriptor_type); + } + + /* utils */ +@@ -1940,8 +1932,10 @@ bool is_write_resource_state(D3D12_RESOURCE_STATES state); + + HRESULT return_interface(void *iface, REFIID iface_iid, REFIID requested_iid, void **object); + ++const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle); + const char *debug_d3d12_box(const D3D12_BOX *box); + const char *debug_d3d12_shader_component_mapping(unsigned int mapping); ++const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle); + const char *debug_vk_extent_3d(VkExtent3D extent); + const char *debug_vk_memory_heap_flags(VkMemoryHeapFlags flags); + const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags); -- 2.43.0 diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-628acb6b96eaae24861402dfa2be641c44c.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-628acb6b96eaae24861402dfa2be641c44c.patch new file mode 100644 index 00000000..91d95ab3 --- /dev/null +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-628acb6b96eaae24861402dfa2be641c44c.patch @@ -0,0 +1,638 @@ +From 07e19d3baeaa0d5296084d12f003fff95f0655ce Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Thu, 15 Feb 2024 11:01:11 +1100 +Subject: [PATCH] Updated vkd3d to 628acb6b96eaae24861402dfa2be641c44ce2480. + +--- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 221 ++++++++++++++++-- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 18 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 7 +- + libs/vkd3d/libs/vkd3d/device.c | 85 ++++++- + 4 files changed, 304 insertions(+), 27 deletions(-) + +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index a001f6f0642..33d30aef08e 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -33,7 +33,7 @@ static const uint64_t ALLOCA_FLAG_IN_ALLOCA = 0x20; + static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE = 0x40; + static const uint64_t ALLOCA_ALIGNMENT_MASK = ALLOCA_FLAG_IN_ALLOCA - 1; + static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4; +-static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 5; ++static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 11; + + static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64}; + +@@ -228,6 +228,13 @@ enum dxil_component_type + COMPONENT_TYPE_PACKEDU8X32 = 18, + }; + ++enum dxil_sampler_kind ++{ ++ SAMPLER_KIND_DEFAULT = 0, ++ SAMPLER_KIND_COMPARISON = 1, ++ SAMPLER_KIND_MONO = 2, ++}; ++ + enum dxil_semantic_kind + { + SEMANTIC_KIND_ARBITRARY = 0, +@@ -369,6 +376,8 @@ enum dx_intrinsic_opcode + DX_UBFE = 52, + DX_CREATE_HANDLE = 57, + DX_CBUFFER_LOAD_LEGACY = 59, ++ DX_SAMPLE = 60, ++ DX_SAMPLE_GRAD = 63, + DX_TEXTURE_LOAD = 66, + DX_TEXTURE_STORE = 67, + DX_BUFFER_LOAD = 68, +@@ -2421,6 +2430,26 @@ static bool sm6_value_validate_is_texture_handle(const struct sm6_value *value, + return true; + } + ++static bool sm6_value_validate_is_sampler_handle(const struct sm6_value *value, enum dx_intrinsic_opcode op, ++ struct sm6_parser *sm6) ++{ ++ enum dxil_resource_kind kind; ++ ++ if (!sm6_value_validate_is_handle(value, sm6)) ++ return false; ++ ++ kind = value->u.handle.d->kind; ++ if (kind != RESOURCE_KIND_SAMPLER) ++ { ++ WARN("Resource kind %u for op %u is not a sampler.\n", kind, op); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE, ++ "Resource kind %u for sample operation %u is not a sampler.", kind, op); ++ return false; ++ } ++ ++ return true; ++} ++ + static bool sm6_value_validate_is_pointer(const struct sm6_value *value, struct sm6_parser *sm6) + { + if (!sm6_type_is_pointer(value->type)) +@@ -3500,7 +3529,8 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco + "Ignoring flags %#"PRIx64" for a binary operation.", flags); + } + +- src_params = instruction_src_params_alloc(ins, 2, sm6); ++ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) ++ return; + src_param_init_from_value(&src_params[0], a); + src_param_init_from_value(&src_params[1], b); + if (code == BINOP_SUB) +@@ -3654,11 +3684,10 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st + } + + static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, +- const struct sm6_value *z_operand, struct function_emission_state *state, ++ unsigned int max_operands, const struct sm6_value *z_operand, struct function_emission_state *state, + struct vkd3d_shader_register *reg) + { + const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; +- const unsigned int max_operands = 3; + unsigned int component_count; + + for (component_count = 0; component_count < max_operands; ++component_count) +@@ -3751,7 +3780,8 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o + struct vkd3d_shader_src_param *src_param; + + vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op)); +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param_init_from_value(src_param, operands[0]); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +@@ -3785,7 +3815,8 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ + struct vkd3d_shader_src_param *src_params; + + vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type)); +- src_params = instruction_src_params_alloc(ins, 2, sm6); ++ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) ++ return; + src_param_init_from_value(&src_params[0], operands[0]); + src_param_init_from_value(&src_params[1], operands[1]); + +@@ -3807,7 +3838,8 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); + register_index_address_init(&src_param->reg.idx[2], operands[1], sm6); + assert(src_param->reg.idx_count == 3); +@@ -3903,7 +3935,8 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi + unsigned int i; + + vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_tertiary_op(op)); +- src_params = instruction_src_params_alloc(ins, 3, sm6); ++ if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) ++ return; + for (i = 0; i < 3; ++i) + src_param_init_from_value(&src_params[i], operands[i]); + +@@ -3934,7 +3967,8 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin + } + e = &signature->elements[row_index]; + +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param->reg = sm6->input_params[row_index].reg; + src_param_init_scalar(src_param, column_index); + if (e->register_count > 1) +@@ -4013,7 +4047,8 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri + instruction_init_with_resource(ins, (resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + ? VKD3DSIH_LD_UAV_TYPED : VKD3DSIH_LD, resource, sm6); + +- src_params = instruction_src_params_alloc(ins, 2, sm6); ++ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) ++ return; + src_param_init_from_value(&src_params[0], operands[1]); + if (!sm6_value_is_undef(operands[2])) + { +@@ -4040,6 +4075,71 @@ static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, + ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); + } + ++static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, ++ const struct sm6_value **operands, struct function_emission_state *state) ++{ ++ struct vkd3d_shader_register coord, ddx, ddy; ++ const struct sm6_value *resource, *sampler; ++ struct vkd3d_shader_src_param *src_params; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int clamp_idx; ++ ++ resource = operands[0]; ++ sampler = operands[1]; ++ if (!sm6_value_validate_is_texture_handle(resource, op, sm6) ++ || !sm6_value_validate_is_sampler_handle(sampler, op, sm6)) ++ { ++ return; ++ } ++ ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], VKD3D_VEC4_SIZE, NULL, state, &coord)) ++ return; ++ ++ if (op == DX_SAMPLE_GRAD) ++ { ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[9], 3, NULL, state, &ddx)) ++ return; ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[12], 3, NULL, state, &ddy)) ++ return; ++ } ++ ++ ins = state->ins; ++ switch (op) ++ { ++ case DX_SAMPLE: ++ instruction_init_with_resource(ins, VKD3DSIH_SAMPLE, resource, sm6); ++ src_params = instruction_src_params_alloc(ins, 3, sm6); ++ clamp_idx = 9; ++ break; ++ case DX_SAMPLE_GRAD: ++ instruction_init_with_resource(ins, VKD3DSIH_SAMPLE_GRAD, resource, sm6); ++ src_params = instruction_src_params_alloc(ins, 5, sm6); ++ src_param_init_vector_from_reg(&src_params[3], &ddx); ++ src_param_init_vector_from_reg(&src_params[4], &ddy); ++ clamp_idx = 15; ++ break; ++ default: ++ vkd3d_unreachable(); ++ } ++ ++ if (!src_params) ++ return; ++ ++ if (!sm6_value_is_undef(operands[clamp_idx])) ++ { ++ FIXME("Ignoring LOD clamp value.\n"); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, ++ "Ignoring LOD clamp value for a sample operation."); ++ } ++ ++ src_param_init_vector_from_reg(&src_params[0], &coord); ++ src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); ++ src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); ++ instruction_set_texel_offset(ins, &operands[6], sm6); ++ ++ instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); ++} ++ + static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +@@ -4050,7 +4150,8 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ + unsigned int index; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS); +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param_init_from_value(src_param, operands[0]); + + index = op == DX_COS; +@@ -4069,7 +4170,8 @@ static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intr + struct vkd3d_shader_src_param *src_param; + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param_init_from_value(src_param, operands[0]); + + instruction_dst_param_init_ssa_vector(ins, 2, sm6); +@@ -4150,7 +4252,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr + is_uav = resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; + + mip_level_or_sample_count = (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) ? operands[1] : NULL; +- if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3, + is_multisample ? NULL : mip_level_or_sample_count, state, &coord)) + { + return; +@@ -4164,7 +4266,8 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr + for (i = 0; i < VKD3D_VEC4_SIZE; ++i) + ins->resource_data_type[i] = resource->u.handle.d->resource_data_type; + +- src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6); ++ if (!(src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6))) ++ return; + src_param_init_vector_from_reg(&src_params[0], &coord); + src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); + if (is_multisample) +@@ -4187,7 +4290,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int + if (!sm6_value_validate_is_texture_handle(resource, op, sm6)) + return; + +- if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], NULL, state, &coord)) ++ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], 3, NULL, state, &coord)) + return; + + write_mask = sm6_value_get_constant_uint(operands[8]); +@@ -4290,6 +4393,8 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = + [DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary}, + [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, ++ [DX_SAMPLE ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample}, ++ [DX_SAMPLE_GRAD ] = {"o", "HHffffiiifffffff", sm6_parser_emit_dx_sample}, + [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, + [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, + [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, +@@ -4661,7 +4766,8 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor + return; + } + +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param_init_from_value(src_param, value); + + instruction_dst_param_init_ssa_scalar(ins, sm6); +@@ -4797,7 +4903,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor + "Ignoring flags %#"PRIx64" for a comparison operation.", flags); + } + +- src_params = instruction_src_params_alloc(ins, 2, sm6); ++ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) ++ return; + src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a); + src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b); + +@@ -4855,7 +4962,8 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param->reg = src->u.reg; + src_param_init_scalar(src_param, elem_idx); + +@@ -5006,7 +5114,8 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param_init_from_value(&src_param[0], ptr); + src_param->reg.alignment = alignment; + +@@ -5165,7 +5274,8 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + +- src_param = instruction_src_params_alloc(ins, 1, sm6); ++ if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ return; + src_param_init_from_value(&src_param[0], src); + + dst_param = instruction_dst_params_alloc(ins, 1, sm6); +@@ -5285,7 +5395,8 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re + + vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOVC); + +- src_params = instruction_src_params_alloc(ins, 3, sm6); ++ if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) ++ return; + for (i = 0; i < 3; ++i) + src_param_init_from_value(&src_params[i], src[i]); + +@@ -6755,6 +6866,70 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, + return VKD3D_OK; + } + ++static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm6, ++ const struct sm6_metadata_node *node, struct sm6_descriptor_info *d, struct vkd3d_shader_instruction *ins) ++{ ++ struct vkd3d_shader_register *reg; ++ unsigned int kind; ++ ++ 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 sampler 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 sampler descriptor.", node->operand_count - 7); ++ } ++ ++ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_SAMPLER); ++ ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; ++ ++ if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind)) ++ { ++ WARN("Failed to load sampler mode.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, ++ "Sampler mode metadata value is not an integer."); ++ return VKD3D_ERROR_INVALID_SHADER; ++ } ++ switch (kind) ++ { ++ case SAMPLER_KIND_DEFAULT: ++ break; ++ case SAMPLER_KIND_COMPARISON: ++ ins->flags = VKD3DSI_SAMPLER_COMPARISON_MODE; ++ break; ++ default: ++ FIXME("Ignoring sampler kind %u.\n", kind); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, ++ "Ignoring sampler kind %u.", kind); ++ break; ++ } ++ ++ ins->declaration.sampler.src.swizzle = VKD3D_SHADER_NO_SWIZZLE; ++ ins->declaration.sampler.src.modifiers = VKD3DSPSM_NONE; ++ ++ reg = &ins->declaration.sampler.src.reg; ++ vsir_register_init(reg, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 3); ++ reg->idx[0].offset = d->id; ++ reg->idx[1].offset = d->range.first; ++ reg->idx[2].offset = d->range.last; ++ ++ ins->declaration.sampler.range = d->range; ++ ++ d->resource_type = ins->resource_type; ++ d->kind = RESOURCE_KIND_SAMPLER; ++ d->reg_type = VKD3DSPR_SAMPLER; ++ d->reg_data_type = VKD3D_DATA_UNUSED; ++ d->resource_data_type = VKD3D_DATA_UNUSED; ++ ++ 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) + { +@@ -6831,6 +7006,10 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, + if ((ret = sm6_parser_resources_load_uav(sm6, node, d, ins)) < 0) + return ret; + break; ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: ++ if ((ret = sm6_parser_resources_load_sampler(sm6, node, d, 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, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 8dc353e11c0..5f6334a4d19 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -5572,11 +5572,11 @@ attribute: + $$->name = $2; + hlsl_block_init(&$$->instrs); + hlsl_block_add_block(&$$->instrs, $4.instrs); +- vkd3d_free($4.instrs); + $$->loc = @$; + $$->args_count = $4.args_count; + for (i = 0; i < $4.args_count; ++i) + hlsl_src_from_node(&$$->args[i], $4.args[i]); ++ free_parse_initializer(&$4); + } + + attribute_list: +@@ -5807,7 +5807,11 @@ func_prototype: + } + else + { +- free($1.attrs); ++ unsigned int i; ++ ++ for (i = 0; i < $1.count; ++i) ++ hlsl_free_attribute((void *)$1.attrs[i]); ++ vkd3d_free($1.attrs); + } + $$ = $2; + } +@@ -6992,8 +6996,10 @@ primary_expr: + if (!(var = hlsl_get_var(ctx->cur_scope, $1))) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable \"%s\" is not defined.", $1); ++ vkd3d_free($1); + YYABORT; + } ++ vkd3d_free($1); + if (!(load = hlsl_new_var_load(ctx, var, &@1))) + YYABORT; + if (!($$ = make_block(ctx, &load->node))) +@@ -7067,12 +7073,17 @@ postfix_expr: + if (!(field = get_struct_field(type->e.record.fields, type->e.record.field_count, $3))) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3); ++ vkd3d_free($3); + YYABORT; + } + + field_idx = field - type->e.record.fields; + if (!add_record_access(ctx, $1, node, field_idx, &@2)) ++ { ++ vkd3d_free($3); + YYABORT; ++ } ++ vkd3d_free($3); + $$ = $1; + } + else if (hlsl_is_numeric_type(node->data_type)) +@@ -7082,14 +7093,17 @@ postfix_expr: + if (!(swizzle = get_swizzle(ctx, node, $3, &@3))) + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle \"%s\".", $3); ++ vkd3d_free($3); + YYABORT; + } + hlsl_block_add_instr($1, swizzle); ++ vkd3d_free($3); + $$ = $1; + } + else + { + hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3); ++ vkd3d_free($3); + YYABORT; + } + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index d0fd6b047b1..1557fb3ea7f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -2048,9 +2048,12 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, + + if (count > allocator->count - allocator->index) + { +- struct vkd3d_shader_param_node *next = shader_param_allocator_node_create(allocator); ++ struct vkd3d_shader_param_node *next; + +- if (!next) ++ /* Monolithic switch has no definite parameter count limit. */ ++ allocator->count = max(allocator->count, count); ++ ++ if (!(next = shader_param_allocator_node_create(allocator))) + return NULL; + if (allocator->current) + allocator->current->next = next; +diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c +index 90272818b3d..f5a57ad31b7 100644 +--- a/libs/vkd3d/libs/vkd3d/device.c ++++ b/libs/vkd3d/libs/vkd3d/device.c +@@ -3433,6 +3433,87 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device7 + return S_OK; + } + ++ case D3D12_FEATURE_D3D12_OPTIONS10: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS10 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->VariableRateShadingSumCombinerSupported = FALSE; ++ data->MeshShaderPerPrimitiveShadingRateSupported = FALSE; ++ ++ TRACE("Variable rate shading sum combiner %#x.\n", data->VariableRateShadingSumCombinerSupported); ++ TRACE("Mesh shader per primitive shading rate %#x.\n", data->MeshShaderPerPrimitiveShadingRateSupported); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS11: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS11 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->AtomicInt64OnDescriptorHeapResourceSupported = FALSE; ++ ++ TRACE("Atomic int64 on descriptor heap resource %#x.\n", data->AtomicInt64OnDescriptorHeapResourceSupported); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS12: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS12 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->MSPrimitivesPipelineStatisticIncludesCulledPrimitives = D3D12_TRI_STATE_UNKNOWN; ++ data->EnhancedBarriersSupported = FALSE; ++ data->RelaxedFormatCastingSupported = FALSE; ++ ++ TRACE("Mesh shader primitives pipeline stats include cull primitives %#x.\n", ++ data->MSPrimitivesPipelineStatisticIncludesCulledPrimitives); ++ TRACE("Enhanced barriers %#x.\n", data->EnhancedBarriersSupported); ++ TRACE("Relaxed format casting %#x.\n", data->RelaxedFormatCastingSupported); ++ return S_OK; ++ } ++ ++ case D3D12_FEATURE_D3D12_OPTIONS13: ++ { ++ D3D12_FEATURE_DATA_D3D12_OPTIONS13 *data = feature_data; ++ ++ if (feature_data_size != sizeof(*data)) ++ { ++ WARN("Invalid size %u.\n", feature_data_size); ++ return E_INVALIDARG; ++ } ++ ++ data->UnrestrictedBufferTextureCopyPitchSupported = FALSE; ++ data->UnrestrictedVertexElementAlignmentSupported = FALSE; ++ data->InvertedViewportHeightFlipsYSupported = FALSE; ++ data->InvertedViewportDepthFlipsZSupported = FALSE; ++ data->TextureCopyBetweenDimensionsSupported = FALSE; ++ data->AlphaBlendFactorSupported = FALSE; ++ ++ TRACE("Unrestricted buffer-texture copy pitch %#x.\n", data->UnrestrictedBufferTextureCopyPitchSupported); ++ TRACE("Unrestricted vertex element alignment %#x.\n", data->UnrestrictedVertexElementAlignmentSupported); ++ TRACE("Inverted viewport height flips Y %#x.\n", data->InvertedViewportHeightFlipsYSupported); ++ TRACE("Inverted viewport depth flips Z %#x.\n", data->InvertedViewportDepthFlipsZSupported); ++ TRACE("Texture copy between dimensions %#x.\n", data->TextureCopyBetweenDimensionsSupported); ++ TRACE("Alpha blend factor support %#x.\n", data->AlphaBlendFactorSupported); ++ return S_OK; ++ } ++ + default: + FIXME("Unhandled feature %#x.\n", feature); + return E_NOTIMPL; +@@ -3888,7 +3969,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device7 * + struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n", +- iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle); ++ iface, object, attributes, (uint32_t)access, debugstr_w(name, device->wchar_size), handle); + + return E_NOTIMPL; + } +@@ -3908,7 +3989,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic + struct d3d12_device *device = impl_from_ID3D12Device7(iface); + + FIXME("iface %p, name %s, access %#x, handle %p stub!\n", +- iface, debugstr_w(name, device->wchar_size), access, handle); ++ iface, debugstr_w(name, device->wchar_size), (uint32_t)access, handle); + + return E_NOTIMPL; + } +-- +2.43.0 + diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch deleted file mode 100644 index 12713e18..00000000 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-6dea3d08b1e9453bfc51dfec827cf1a25c2.patch +++ /dev/null @@ -1,1766 +0,0 @@ -From 512ffa3af40d1fab9d76cfff8b26d6b60c4481ac Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 1 Feb 2024 12:20:04 +1100 -Subject: [PATCH 2/5] Updated vkd3d to - 6dea3d08b1e9453bfc51dfec827cf1a25c2729df. - ---- - libs/vkd3d/include/private/vkd3d_debug.h | 4 + - libs/vkd3d/include/vkd3d_d3dcompiler.h | 4 + - libs/vkd3d/include/vkd3d_shader.h | 8 +- - libs/vkd3d/include/vkd3d_utils.h | 2 + - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 17 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 15 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 170 ++++++++- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 137 +++++-- - libs/vkd3d/libs/vkd3d-shader/ir.c | 334 +++++++++++++++++- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 56 ++- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 10 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 4 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 108 ++++-- - libs/vkd3d/libs/vkd3d/device.c | 12 +- - libs/vkd3d/libs/vkd3d/resource.c | 24 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 16 +- - 16 files changed, 767 insertions(+), 154 deletions(-) - -diff --git a/libs/vkd3d/include/private/vkd3d_debug.h b/libs/vkd3d/include/private/vkd3d_debug.h -index 663fc311adf..c5b6ccedf81 100644 ---- a/libs/vkd3d/include/private/vkd3d_debug.h -+++ b/libs/vkd3d/include/private/vkd3d_debug.h -@@ -89,6 +89,10 @@ const char *debugstr_w(const WCHAR *wstr, size_t wchar_size); - #define TRACE_ON() (vkd3d_dbg_get_level() == VKD3D_DBG_LEVEL_TRACE) - #endif - -+#ifndef WARN_ON -+#define WARN_ON() (vkd3d_dbg_get_level() >= VKD3D_DBG_LEVEL_WARN) -+#endif -+ - #define FIXME_ONCE VKD3D_DBG_LOG_ONCE(FIXME, WARN) - - #define VKD3D_DEBUG_ENV_NAME(name) const char *const vkd3d_dbg_env_name = name -diff --git a/libs/vkd3d/include/vkd3d_d3dcompiler.h b/libs/vkd3d/include/vkd3d_d3dcompiler.h -index 1975f4f980a..872a90bbc4b 100644 ---- a/libs/vkd3d/include/vkd3d_d3dcompiler.h -+++ b/libs/vkd3d/include/vkd3d_d3dcompiler.h -@@ -79,6 +79,7 @@ HRESULT WINAPI D3DCompile2(const void *data, SIZE_T data_size, const char *filen - const void *secondary_data, SIZE_T secondary_data_size, ID3DBlob **shader, - ID3DBlob **error_messages); - HRESULT WINAPI D3DCreateBlob(SIZE_T size, ID3DBlob **blob); -+HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob); - HRESULT WINAPI D3DGetBlobPart(const void *data, SIZE_T data_size, D3D_BLOB_PART part, UINT flags, ID3DBlob **blob); - HRESULT WINAPI D3DGetDebugInfo(const void *data, SIZE_T data_size, ID3DBlob **blob); - HRESULT WINAPI D3DGetInputAndOutputSignatureBlob(const void *data, SIZE_T data_size, ID3DBlob **blob); -@@ -89,5 +90,8 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename - HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection); - HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob); - -+typedef HRESULT (WINAPI *pD3DDisassemble)(const void *data, SIZE_T data_size, -+ UINT flags, const char *comments, ID3DBlob **blob); -+ - #endif /* __D3DCOMPILER_H__ */ - #endif /* __VKD3D_D3DCOMPILER_H */ -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index a8cc3a336a3..2f4478a7983 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -1777,10 +1777,10 @@ struct vkd3d_shader_dxbc_desc - * \endcode - */ - #define VKD3D_SHADER_SWIZZLE(x, y, z, w) \ -- vkd3d_shader_create_swizzle(VKD3D_SHADER_SWIZZLE_ ## x, \ -- VKD3D_SHADER_SWIZZLE_ ## y, \ -- VKD3D_SHADER_SWIZZLE_ ## z, \ -- VKD3D_SHADER_SWIZZLE_ ## w) -+ (VKD3D_SHADER_SWIZZLE_ ## x << VKD3D_SHADER_SWIZZLE_SHIFT(0) \ -+ | VKD3D_SHADER_SWIZZLE_ ## y << VKD3D_SHADER_SWIZZLE_SHIFT(1) \ -+ | VKD3D_SHADER_SWIZZLE_ ## z << VKD3D_SHADER_SWIZZLE_SHIFT(2) \ -+ | VKD3D_SHADER_SWIZZLE_ ## w << VKD3D_SHADER_SWIZZLE_SHIFT(3)) - - /** The identity swizzle ".xyzw". */ - #define VKD3D_SHADER_NO_SWIZZLE VKD3D_SHADER_SWIZZLE(X, Y, Z, W) -diff --git a/libs/vkd3d/include/vkd3d_utils.h b/libs/vkd3d/include/vkd3d_utils.h -index adcac5fcf64..7616a3f3c46 100644 ---- a/libs/vkd3d/include/vkd3d_utils.h -+++ b/libs/vkd3d/include/vkd3d_utils.h -@@ -117,6 +117,8 @@ VKD3D_UTILS_API HRESULT WINAPI D3DGetOutputSignatureBlob(const void *data, SIZE_ - VKD3D_UTILS_API HRESULT WINAPI D3DStripShader(const void *data, SIZE_T data_size, UINT flags, ID3DBlob **blob); - - /** \since 1.11 */ -+VKD3D_UTILS_API HRESULT WINAPI D3DDisassemble(const void *data, -+ SIZE_T data_size, UINT flags, const char *comments, ID3DBlob **blob); - VKD3D_UTILS_API HRESULT WINAPI D3DReflect(const void *data, SIZE_T data_size, REFIID iid, void **reflection); - - #ifdef __cplusplus -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index af939396a08..dd96b7fa50b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -1389,7 +1389,7 @@ static void shader_dump_dst_param(struct vkd3d_d3d_asm_compiler *compiler, - { - static const char write_mask_chars[] = "xyzw"; - -- if (param->reg.data_type == VKD3D_DATA_DOUBLE) -+ if (data_type_is_64_bit(param->reg.data_type)) - write_mask = vsir_write_mask_32_from_64(write_mask); - - shader_addline(buffer, ".%s", compiler->colours.write_mask); -@@ -1454,13 +1454,18 @@ static void shader_dump_src_param(struct vkd3d_d3d_asm_compiler *compiler, - if (param->reg.type != VKD3DSPR_IMMCONST && param->reg.type != VKD3DSPR_IMMCONST64 - && param->reg.dimension == VSIR_DIMENSION_VEC4) - { -- unsigned int swizzle_x = vsir_swizzle_get_component(swizzle, 0); -- unsigned int swizzle_y = vsir_swizzle_get_component(swizzle, 1); -- unsigned int swizzle_z = vsir_swizzle_get_component(swizzle, 2); -- unsigned int swizzle_w = vsir_swizzle_get_component(swizzle, 3); -- - static const char swizzle_chars[] = "xyzw"; - -+ unsigned int swizzle_x, swizzle_y, swizzle_z, swizzle_w; -+ -+ if (data_type_is_64_bit(param->reg.data_type)) -+ swizzle = vsir_swizzle_32_from_64(swizzle); -+ -+ swizzle_x = vsir_swizzle_get_component(swizzle, 0); -+ swizzle_y = vsir_swizzle_get_component(swizzle, 1); -+ swizzle_z = vsir_swizzle_get_component(swizzle, 2); -+ swizzle_w = vsir_swizzle_get_component(swizzle, 3); -+ - if (swizzle_x == swizzle_y - && swizzle_x == swizzle_z - && swizzle_x == swizzle_w) -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 4ba001ea4cd..9ad9f735dd1 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -587,7 +587,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, - - if (!(element = find_signature_element_by_register_index(signature, register_index))) - { -- vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC, -+ vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_UNDECLARED_SEMANTIC, - "%s register %u was used without being declared.", output ? "Output" : "Input", register_index); - return; - } -@@ -899,7 +899,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const - shader_sm1_read_param(sm1, ptr, &token, &addr_token); - if (has_relative_address(token)) - { -- if (!(src_rel_addr = shader_parser_get_src_params(&sm1->p, 1))) -+ if (!(src_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1))) - { - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, - "Out of memory."); -@@ -920,7 +920,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const - shader_sm1_read_param(sm1, ptr, &token, &addr_token); - if (has_relative_address(token)) - { -- if (!(dst_rel_addr = shader_parser_get_src_params(&sm1->p, 1))) -+ if (!(dst_rel_addr = vsir_program_get_src_params(&sm1->p.program, 1))) - { - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, - "Out of memory."); -@@ -1089,6 +1089,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - { - struct vkd3d_shader_src_param *src_params, *predicate; - const struct vkd3d_sm1_opcode_info *opcode_info; -+ struct vsir_program *program = &sm1->p.program; - struct vkd3d_shader_dst_param *dst_param; - const uint32_t **ptr = &sm1->ptr; - uint32_t opcode_token; -@@ -1111,7 +1112,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, - "Invalid opcode %#x (token 0x%08x, shader version %u.%u).", - opcode_token & VKD3D_SM1_OPCODE_MASK, opcode_token, -- sm1->p.program.shader_version.major, sm1->p.program.shader_version.minor); -+ program->shader_version.major, program->shader_version.minor); - goto fail; - } - -@@ -1121,11 +1122,11 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - ins->raw = false; - ins->structured = false; - predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED); -- ins->predicate = predicate = predicated ? shader_parser_get_src_params(&sm1->p, 1) : NULL; -+ ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL; - ins->dst_count = opcode_info->dst_count; -- ins->dst = dst_param = shader_parser_get_dst_params(&sm1->p, ins->dst_count); -+ ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count); - ins->src_count = opcode_info->src_count; -- ins->src = src_params = shader_parser_get_src_params(&sm1->p, ins->src_count); -+ ins->src = src_params = vsir_program_get_src_params(program, ins->src_count); - if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count)) - { - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 8a31d03c531..0358dbb6e06 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -36,6 +36,10 @@ static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4; - - static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64}; - -+#define VKD3D_SHADER_SWIZZLE_64_MASK \ -+ (VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(0) \ -+ | VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(1)) -+ - enum bitcode_block_id - { - BLOCKINFO_BLOCK = 0, -@@ -354,6 +358,8 @@ enum dx_intrinsic_opcode - DX_IMIN = 38, - DX_UMAX = 39, - DX_UMIN = 40, -+ DX_IBFE = 51, -+ DX_UBFE = 52, - DX_CREATE_HANDLE = 57, - DX_CBUFFER_LOAD_LEGACY = 59, - DX_BUFFER_LOAD = 68, -@@ -363,6 +369,7 @@ enum dx_intrinsic_opcode - DX_DERIV_FINEY = 86, - DX_LEGACY_F32TOF16 = 130, - DX_LEGACY_F16TOF32 = 131, -+ DX_RAW_BUFFER_LOAD = 139, - }; - - enum dxil_cast_code -@@ -2078,13 +2085,16 @@ static void instruction_init_with_resource(struct vkd3d_shader_instruction *ins, - { - vsir_instruction_init(ins, &sm6->p.location, handler_idx); - ins->resource_type = resource->u.handle.d->resource_type; -+ ins->raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; -+ ins->structured = resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER; - } - - static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, - unsigned int count, struct sm6_parser *sm6) - { -- struct vkd3d_shader_src_param *params = shader_parser_get_src_params(&sm6->p, count); -- if (!params) -+ struct vkd3d_shader_src_param *params; -+ -+ if (!(params = vsir_program_get_src_params(&sm6->p.program, count))) - { - ERR("Failed to allocate src params.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -2099,8 +2109,9 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ - static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_shader_instruction *ins, - unsigned int count, struct sm6_parser *sm6) - { -- struct vkd3d_shader_dst_param *params = shader_parser_get_dst_params(&sm6->p, count); -- if (!params) -+ struct vkd3d_shader_dst_param *params; -+ -+ if (!(params = vsir_program_get_dst_params(&sm6->p.program, count))) - { - ERR("Failed to allocate dst params.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -2211,6 +2222,8 @@ static inline void src_param_init(struct vkd3d_shader_src_param *param) - static void src_param_init_scalar(struct vkd3d_shader_src_param *param, unsigned int component_idx) - { - param->swizzle = vkd3d_shader_create_swizzle(component_idx, component_idx, component_idx, component_idx); -+ if (data_type_is_64_bit(param->reg.data_type)) -+ param->swizzle &= VKD3D_SHADER_SWIZZLE_64_MASK; - param->modifiers = VKD3DSPSM_NONE; - } - -@@ -2241,7 +2254,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, - } - else - { -- struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&sm6->p, 1); -+ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&sm6->p.program, 1); - if (rel_addr) - src_param_init_from_value(rel_addr, address); - idx->offset = 0; -@@ -3100,6 +3113,15 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, - param->reg.dimension = VSIR_DIMENSION_VEC4; - } - -+static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, -+ const struct sm6_value **operands, unsigned int count) -+{ -+ unsigned int i; -+ -+ for (i = 0; i < count; ++i) -+ src_param_init_from_value(&src_params[i], operands[i]); -+} -+ - static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, - enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) - { -@@ -3624,6 +3646,8 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr - type = sm6_type_get_scalar_type(dst->type, 0); - assert(type); - src_param->reg.data_type = vkd3d_data_type_from_sm6_type(type); -+ if (data_type_is_64_bit(src_param->reg.data_type)) -+ src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); - - instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); - } -@@ -3689,6 +3713,34 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int - ins->handler_idx = VKD3DSIH_NOP; - } - -+static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode op) -+{ -+ switch (op) -+ { -+ case DX_IBFE: -+ return VKD3DSIH_IBFE; -+ case DX_UBFE: -+ return VKD3DSIH_UBFE; -+ default: -+ vkd3d_unreachable(); -+ } -+} -+ -+static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -+ const struct sm6_value **operands, struct function_emission_state *state) -+{ -+ struct vkd3d_shader_instruction *ins = state->ins; -+ struct vkd3d_shader_src_param *src_params; -+ unsigned int i; -+ -+ vsir_instruction_init(ins, &sm6->p.location, sm6_dx_map_tertiary_op(op)); -+ src_params = instruction_src_params_alloc(ins, 3, sm6); -+ for (i = 0; i < 3; ++i) -+ src_param_init_from_value(&src_params[i], operands[i]); -+ -+ instruction_dst_param_init_ssa_scalar(ins, sm6); -+} -+ - static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -@@ -3722,6 +3774,49 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin - instruction_dst_param_init_ssa_scalar(ins, sm6); - } - -+static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -+ const struct sm6_value **operands, struct function_emission_state *state) -+{ -+ unsigned int operand_count, write_mask, component_count = VKD3D_VEC4_SIZE; -+ struct vkd3d_shader_instruction *ins = state->ins; -+ struct vkd3d_shader_src_param *src_params; -+ const struct sm6_value *resource; -+ bool raw; -+ -+ resource = operands[0]; -+ if (!sm6_value_validate_is_handle(resource, sm6)) -+ return; -+ raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER; -+ -+ if (op == DX_RAW_BUFFER_LOAD) -+ { -+ write_mask = sm6_value_get_constant_uint(operands[3]); -+ if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) -+ { -+ WARN("Invalid write mask %#x.\n", write_mask); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Write mask %#x for a raw/structured buffer load operation is invalid.", write_mask); -+ return; -+ } -+ else if (write_mask & (write_mask + 1)) -+ { -+ FIXME("Unhandled write mask %#x.\n", write_mask); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Write mask %#x for a raw/structured buffer load operation is unhandled.", write_mask); -+ } -+ component_count = vsir_write_mask_component_count(write_mask); -+ } -+ -+ instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6); -+ operand_count = 2 + !raw; -+ if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) -+ return; -+ src_params_init_from_operands(src_params, &operands[1], operand_count - 1); -+ src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg); -+ -+ instruction_dst_param_init_ssa_vector(ins, component_count, sm6); -+} -+ - static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -@@ -3733,6 +3828,12 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri - if (!sm6_value_validate_is_handle(resource, sm6)) - return; - -+ if (resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER -+ || resource->u.handle.d->kind == RESOURCE_KIND_STRUCTUREDBUFFER) -+ { -+ return sm6_parser_emit_dx_raw_buffer_load(sm6, op, operands, state); -+ } -+ - if (resource->u.handle.d->kind != RESOURCE_KIND_TYPEDBUFFER) - { - WARN("Resource is not a typed buffer.\n"); -@@ -3875,6 +3976,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = - [DX_FMAX ] = {"g", "RR", sm6_parser_emit_dx_binary}, - [DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary}, - [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, - [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, - [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, - [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary}, -@@ -3884,6 +3986,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = - [DX_LEGACY_F32TOF16 ] = {"i", "f", sm6_parser_emit_dx_unary}, - [DX_LOAD_INPUT ] = {"o", "ii8i", sm6_parser_emit_dx_load_input}, - [DX_LOG ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_RAW_BUFFER_LOAD ] = {"o", "Hii8i", sm6_parser_emit_dx_raw_buffer_load}, - [DX_ROUND_NE ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_ROUND_NI ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_ROUND_PI ] = {"g", "R", sm6_parser_emit_dx_unary}, -@@ -3893,6 +3996,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = - [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, - [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, - [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, - [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, - }; -@@ -4444,8 +4548,8 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); - - src_param = instruction_src_params_alloc(ins, 1, sm6); -- src_param_init_from_value(src_param, src); -- src_param->swizzle = vkd3d_shader_create_swizzle(elem_idx, elem_idx, elem_idx, elem_idx); -+ src_param_init_scalar(src_param, elem_idx); -+ src_param->reg = src->u.reg; - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -5975,6 +6079,8 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k - switch (kind) - { - case RESOURCE_KIND_TYPEDBUFFER: -+ case RESOURCE_KIND_RAWBUFFER: -+ case RESOURCE_KIND_STRUCTUREDBUFFER: - return VKD3D_SHADER_RESOURCE_BUFFER; - default: - return VKD3D_SHADER_RESOURCE_NONE; -@@ -6039,6 +6145,13 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc - } - ins->resource_type = resource_type; - -+ if (!m) -+ { -+ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; -+ ins->declaration.raw_resource.resource.reg.write_mask = 0; -+ return &ins->declaration.raw_resource.resource; -+ } -+ - if (!sm6_metadata_value_is_node(m)) - { - WARN("Resource metadata list is not a node.\n"); -@@ -6093,6 +6206,39 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc - - return &ins->declaration.semantic.resource; - } -+ else if (dxil_resource_type == RESOURCE_TYPE_RAW_STRUCTURED) -+ { -+ if (kind == RESOURCE_KIND_RAWBUFFER) -+ { -+ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; -+ ins->declaration.raw_resource.resource.reg.write_mask = 0; -+ -+ return &ins->declaration.raw_resource.resource; -+ } -+ -+ if (kind != RESOURCE_KIND_STRUCTUREDBUFFER) -+ { -+ WARN("Unhandled resource kind %u.\n", kind); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, -+ "Resource kind %u for a raw or structured buffer is unhandled.", kind); -+ return NULL; -+ } -+ -+ ins->handler_idx = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED; -+ ins->declaration.structured_resource.byte_stride = values[1]; -+ ins->declaration.structured_resource.resource.reg.write_mask = 0; -+ -+ /* TODO: 16-bit resources. */ -+ if (ins->declaration.structured_resource.byte_stride % 4u) -+ { -+ WARN("Byte stride %u is not a multiple of 4.\n", ins->declaration.structured_resource.byte_stride); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, -+ "Structured resource byte stride %u is not a multiple of 4.", -+ ins->declaration.structured_resource.byte_stride); -+ } -+ -+ return &ins->declaration.structured_resource.resource; -+ } - else - { - FIXME("Unhandled resource type %u.\n", dxil_resource_type); -@@ -6159,7 +6305,8 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, - d->kind = kind; - d->reg_type = VKD3DSPR_RESOURCE; - d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_RESOURCE; -- d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; -+ d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL) -+ ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; - - init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range); - -@@ -6232,7 +6379,8 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, - d->kind = values[0]; - d->reg_type = VKD3DSPR_UAV; - d->reg_data_type = (ins->resource_type == VKD3D_SHADER_RESOURCE_BUFFER) ? VKD3D_DATA_UINT : VKD3D_DATA_UAV; -- d->resource_data_type = ins->declaration.semantic.resource_data_type[0]; -+ d->resource_data_type = (ins->handler_idx == VKD3DSIH_DCL_UAV_TYPED) -+ ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; - - init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range); - -@@ -7165,8 +7313,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t - return ret; - } - -- if (!(sm6->output_params = shader_parser_get_dst_params(&sm6->p, output_signature->element_count)) -- || !(sm6->input_params = shader_parser_get_dst_params(&sm6->p, input_signature->element_count))) -+ if (!(sm6->output_params = vsir_program_get_dst_params(&sm6->p.program, output_signature->element_count)) -+ || !(sm6->input_params = vsir_program_get_dst_params(&sm6->p.program, input_signature->element_count))) - { - ERR("Failed to allocate input/output parameters.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 1fe141a346a..6ad60e4c6c2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -4123,13 +4123,46 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { -- if (var->is_uniform && var->last_read) -+ unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; -+ -+ if (!var->is_uniform || !var->last_read || reg_size == 0) -+ continue; -+ -+ if (var->reg_reservation.reg_type == 'c') - { -- unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; -+ unsigned int reg_idx = var->reg_reservation.reg_index; -+ unsigned int i; - -- if (reg_size == 0) -- continue; -+ assert(reg_size % 4 == 0); -+ for (i = 0; i < reg_size / 4; ++i) -+ { -+ if (get_available_writemask(&allocator, 1, UINT_MAX, reg_idx + i) != VKD3DSP_WRITEMASK_ALL) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -+ "Overlapping register() reservations on 'c%u'.", reg_idx + i); -+ } -+ -+ record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX); -+ } -+ -+ var->regs[HLSL_REGSET_NUMERIC].id = reg_idx; -+ var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4; -+ var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL; -+ var->regs[HLSL_REGSET_NUMERIC].allocated = true; -+ TRACE("Allocated reserved %s to %s.\n", var->name, -+ debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); -+ } -+ } -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ unsigned int reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; - -+ if (!var->is_uniform || !var->last_read || reg_size == 0) -+ continue; -+ -+ if (!var->regs[HLSL_REGSET_NUMERIC].allocated) -+ { - var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, &allocator, - 1, UINT_MAX, var->data_type); - TRACE("Allocated %s to %s.\n", var->name, -@@ -4269,45 +4302,52 @@ static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, uint3 - return NULL; - } - --static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) -+static void calculate_buffer_offset(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, bool register_reservation) - { - unsigned int var_reg_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC]; - enum hlsl_type_class var_class = var->data_type->class; - struct hlsl_buffer *buffer = var->buffer; - -- if (var->reg_reservation.offset_type == 'c') -+ if (register_reservation) - { -- if (var->reg_reservation.offset_index % 4) -+ var->buffer_offset = 4 * var->reg_reservation.reg_index; -+ } -+ else -+ { -+ if (var->reg_reservation.offset_type == 'c') - { -- if (var_class == HLSL_CLASS_MATRIX) -+ if (var->reg_reservation.offset_index % 4) - { -- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -- "packoffset() reservations with matrix types must be aligned with the beginning of a register."); -- } -- else if (var_class == HLSL_CLASS_ARRAY) -- { -- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -- "packoffset() reservations with array types must be aligned with the beginning of a register."); -- } -- else if (var_class == HLSL_CLASS_STRUCT) -- { -- hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -- "packoffset() reservations with struct types must be aligned with the beginning of a register."); -- } -- else if (var_class == HLSL_CLASS_VECTOR) -- { -- unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index); -- -- if (var->reg_reservation.offset_index != aligned_offset) -+ if (var_class == HLSL_CLASS_MATRIX) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -+ "packoffset() reservations with matrix types must be aligned with the beginning of a register."); -+ } -+ else if (var_class == HLSL_CLASS_ARRAY) -+ { -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -+ "packoffset() reservations with array types must be aligned with the beginning of a register."); -+ } -+ else if (var_class == HLSL_CLASS_STRUCT) -+ { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -- "packoffset() reservations with vector types cannot span multiple registers."); -+ "packoffset() reservations with struct types must be aligned with the beginning of a register."); -+ } -+ else if (var_class == HLSL_CLASS_VECTOR) -+ { -+ unsigned int aligned_offset = hlsl_type_get_sm4_offset(var->data_type, var->reg_reservation.offset_index); -+ -+ if (var->reg_reservation.offset_index != aligned_offset) -+ hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, -+ "packoffset() reservations with vector types cannot span multiple registers."); -+ } - } -+ var->buffer_offset = var->reg_reservation.offset_index; -+ } -+ else -+ { -+ var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size); - } -- var->buffer_offset = var->reg_reservation.offset_index; -- } -- else -- { -- var->buffer_offset = hlsl_type_get_sm4_offset(var->data_type, buffer->size); - } - - TRACE("Allocated buffer offset %u to %s.\n", var->buffer_offset, var->name); -@@ -4376,6 +4416,11 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx) - } - } - -+static bool var_has_buffer_offset_register_reservation(struct hlsl_ctx *ctx, const struct hlsl_ir_var *var) -+{ -+ return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; -+} -+ - static void allocate_buffers(struct hlsl_ctx *ctx) - { - struct hlsl_buffer *buffer; -@@ -4384,13 +4429,29 @@ static void allocate_buffers(struct hlsl_ctx *ctx) - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { -- if (var->is_uniform && !hlsl_type_is_resource(var->data_type)) -- { -- if (var->is_param) -- var->buffer = ctx->params_buffer; -+ if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) -+ continue; - -- calculate_buffer_offset(ctx, var); -- } -+ if (var->is_param) -+ var->buffer = ctx->params_buffer; -+ } -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) -+ continue; -+ -+ if (var_has_buffer_offset_register_reservation(ctx, var)) -+ calculate_buffer_offset(ctx, var, true); -+ } -+ -+ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) -+ { -+ if (!var->is_uniform || hlsl_type_is_resource(var->data_type)) -+ continue; -+ -+ if (!var_has_buffer_offset_register_reservation(ctx, var)) -+ calculate_buffer_offset(ctx, var, false); - } - - validate_buffer_offsets(ctx); -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 9079be48b4f..a0d6212cbf5 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -66,7 +66,7 @@ static void remove_dcl_temps(struct vsir_program *program) - } - } - --static bool vsir_instruction_init_with_params(struct vkd3d_shader_parser *parser, -+static bool vsir_instruction_init_with_params(struct vsir_program *program, - struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, - enum vkd3d_shader_opcode handler_idx, unsigned int dst_count, unsigned int src_count) - { -@@ -74,13 +74,13 @@ static bool vsir_instruction_init_with_params(struct vkd3d_shader_parser *parser - ins->dst_count = dst_count; - ins->src_count = src_count; - -- if (!(ins->dst = shader_parser_get_dst_params(parser, ins->dst_count))) -+ if (!(ins->dst = vsir_program_get_dst_params(program, ins->dst_count))) - { - ERR("Failed to allocate %u destination parameters.\n", dst_count); - return false; - } - -- if (!(ins->src = shader_parser_get_src_params(parser, ins->src_count))) -+ if (!(ins->src = vsir_program_get_src_params(program, ins->src_count))) - { - ERR("Failed to allocate %u source parameters.\n", src_count); - return false; -@@ -116,7 +116,7 @@ static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_pa - /* tmp = ins->dst[0] < 0 */ - - ins = &instructions->elements[i + 1]; -- if (!vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2)) -+ if (!vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_LTO, 1, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -@@ -139,7 +139,7 @@ static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_pa - for (k = 1; k < components_read; ++k) - { - ins = &instructions->elements[i + 1 + k]; -- if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2))) -+ if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_OR, 1, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; - - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -@@ -160,7 +160,7 @@ static enum vkd3d_result instruction_array_lower_texkills(struct vkd3d_shader_pa - /* discard_nz tmp.x */ - - ins = &instructions->elements[i + 1 + components_read]; -- if (!(vsir_instruction_init_with_params(parser, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1))) -+ if (!(vsir_instruction_init_with_params(program, ins, &texkill_ins->location, VKD3DSIH_DISCARD, 0, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ; - -@@ -442,6 +442,15 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader - param->modifiers = VKD3DSPSM_NONE; - } - -+void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, -+ enum vkd3d_data_type data_type, unsigned int idx_count) -+{ -+ vsir_register_init(¶m->reg, reg_type, data_type, idx_count); -+ param->write_mask = VKD3DSP_WRITEMASK_0; -+ param->modifiers = VKD3DSPDM_NONE; -+ param->shift = 0; -+} -+ - void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id) - { - vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UINT, 1); -@@ -449,6 +458,18 @@ void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned in - param->reg.idx[0].offset = label_id; - } - -+static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx) -+{ -+ vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); -+ src->reg.idx[0].offset = idx; -+} -+ -+static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) -+{ -+ vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); -+ dst->reg.idx[0].offset = idx; -+} -+ - void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, - enum vkd3d_shader_opcode handler_idx) - { -@@ -457,12 +478,12 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk - ins->handler_idx = handler_idx; - } - --static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, -- unsigned int label_id, void *parser) -+static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, -+ const struct vkd3d_shader_location *location, unsigned int label_id, struct vsir_program *program) - { - struct vkd3d_shader_src_param *src_param; - -- if (!(src_param = shader_parser_get_src_params(parser, 1))) -+ if (!(src_param = vsir_program_get_src_params(program, 1))) - return false; - - vsir_src_param_init_label(src_param, label_id); -@@ -1808,8 +1829,9 @@ static unsigned int cf_flattener_alloc_block_id(struct cf_flattener *flattener) - static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_shader_instruction *ins, - unsigned int count, struct cf_flattener *flattener) - { -- struct vkd3d_shader_src_param *params = shader_parser_get_src_params(flattener->parser, count); -- if (!params) -+ struct vkd3d_shader_src_param *params; -+ -+ if (!(params = vsir_program_get_src_params(&flattener->parser->program, count))) - { - flattener->allocation_failed = true; - return NULL; -@@ -1825,7 +1847,7 @@ static void cf_flattener_emit_label(struct cf_flattener *flattener, unsigned int - - if (!(ins = cf_flattener_require_space(flattener, 1))) - return; -- if (vsir_instruction_init_label(ins, &flattener->location, label_id, flattener->parser)) -+ if (vsir_instruction_init_label(ins, &flattener->location, label_id, &flattener->parser->program)) - ++flattener->instruction_count; - else - flattener->allocation_failed = true; -@@ -2350,6 +2372,271 @@ static enum vkd3d_result flatten_control_flow_constructs(struct vkd3d_shader_par - return result; - } - -+static unsigned int label_from_src_param(const struct vkd3d_shader_src_param *param) -+{ -+ assert(param->reg.type == VKD3DSPR_LABEL); -+ return param->reg.idx[0].offset; -+} -+ -+static bool reserve_instructions(struct vkd3d_shader_instruction **instructions, size_t *capacity, size_t count) -+{ -+ if (!vkd3d_array_reserve((void **)instructions, capacity, count, sizeof(**instructions))) -+ { -+ ERR("Failed to allocate instructions.\n"); -+ return false; -+ } -+ -+ return true; -+} -+ -+/* A record represents replacing a jump from block `switch_label' to -+ * block `target_label' with a jump from block `if_label' to block -+ * `target_label'. */ -+struct lower_switch_to_if_ladder_block_mapping -+{ -+ unsigned int switch_label; -+ unsigned int if_label; -+ unsigned int target_label; -+}; -+ -+static bool lower_switch_to_if_ladder_add_block_mapping(struct lower_switch_to_if_ladder_block_mapping **block_map, -+ size_t *map_capacity, size_t *map_count, unsigned int switch_label, unsigned int if_label, unsigned int target_label) -+{ -+ if (!vkd3d_array_reserve((void **)block_map, map_capacity, *map_count + 1, sizeof(**block_map))) -+ { -+ ERR("Failed to allocate block mapping.\n"); -+ return false; -+ } -+ -+ (*block_map)[*map_count].switch_label = switch_label; -+ (*block_map)[*map_count].if_label = if_label; -+ (*block_map)[*map_count].target_label = target_label; -+ -+ *map_count += 1; -+ -+ return true; -+} -+ -+static enum vkd3d_result lower_switch_to_if_ladder(struct vsir_program *program) -+{ -+ unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label; -+ size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0; -+ struct vkd3d_shader_instruction *instructions = NULL; -+ struct lower_switch_to_if_ladder_block_mapping *block_map = NULL; -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count)) -+ goto fail; -+ -+ /* First subpass: convert SWITCH_MONOLITHIC instructions to -+ * selection ladders, keeping a map between blocks before and -+ * after the subpass. */ -+ for (i = 0; i < program->instructions.count; ++i) -+ { -+ struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -+ unsigned int case_count, j, default_label; -+ -+ switch (ins->handler_idx) -+ { -+ case VKD3DSIH_LABEL: -+ current_label = label_from_src_param(&ins->src[0]); -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) -+ goto fail; -+ instructions[ins_count++] = *ins; -+ continue; -+ -+ case VKD3DSIH_SWITCH_MONOLITHIC: -+ break; -+ -+ default: -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) -+ goto fail; -+ instructions[ins_count++] = *ins; -+ continue; -+ } -+ -+ case_count = (ins->src_count - 3) / 2; -+ default_label = label_from_src_param(&ins->src[1]); -+ -+ /* In principle we can have a switch with no cases, and we -+ * just have to jump to the default label. */ -+ if (case_count == 0) -+ { -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) -+ goto fail; -+ -+ if (!vsir_instruction_init_with_params(program, &instructions[ins_count], -+ &ins->location, VKD3DSIH_BRANCH, 0, 1)) -+ goto fail; -+ vsir_src_param_init_label(&instructions[ins_count].src[0], default_label); -+ ++ins_count; -+ } -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3 * case_count - 1)) -+ goto fail; -+ -+ if_label = current_label; -+ -+ for (j = 0; j < case_count; ++j) -+ { -+ unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]); -+ -+ if (!vsir_instruction_init_with_params(program, -+ &instructions[ins_count], &ins->location, VKD3DSIH_IEQ, 1, 2)) -+ goto fail; -+ dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count); -+ instructions[ins_count].src[0] = ins->src[0]; -+ instructions[ins_count].src[1] = ins->src[3 + 2 * j]; -+ ++ins_count; -+ -+ /* For all cases except the last one we fall through to -+ * the following case; the last one has to jump to the -+ * default label. */ -+ if (j == case_count - 1) -+ fallthrough_label = default_label; -+ else -+ fallthrough_label = block_count + 1; -+ -+ if (!vsir_instruction_init_with_params(program, &instructions[ins_count], -+ &ins->location, VKD3DSIH_BRANCH, 0, 3)) -+ goto fail; -+ src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count); -+ vsir_src_param_init_label(&instructions[ins_count].src[1], case_label); -+ vsir_src_param_init_label(&instructions[ins_count].src[2], fallthrough_label); -+ ++ins_count; -+ -+ ++ssa_count; -+ -+ if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count, -+ current_label, if_label, case_label)) -+ goto fail; -+ -+ if (j == case_count - 1) -+ { -+ if (!lower_switch_to_if_ladder_add_block_mapping(&block_map, &map_capacity, &map_count, -+ current_label, if_label, default_label)) -+ goto fail; -+ } -+ else -+ { -+ if (!vsir_instruction_init_with_params(program, -+ &instructions[ins_count], &ins->location, VKD3DSIH_LABEL, 0, 1)) -+ goto fail; -+ vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count); -+ ++ins_count; -+ -+ if_label = block_count; -+ } -+ } -+ } -+ -+ /* Second subpass: creating new blocks might have broken -+ * references in PHI instructions, so we use the block map to fix -+ * them. */ -+ current_label = 0; -+ for (i = 0; i < ins_count; ++i) -+ { -+ struct vkd3d_shader_instruction *ins = &instructions[i]; -+ struct vkd3d_shader_src_param *new_src; -+ unsigned int j, l, new_src_count = 0; -+ -+ switch (ins->handler_idx) -+ { -+ case VKD3DSIH_LABEL: -+ current_label = label_from_src_param(&ins->src[0]); -+ continue; -+ -+ case VKD3DSIH_PHI: -+ break; -+ -+ default: -+ continue; -+ } -+ -+ /* First count how many source parameters we need. */ -+ for (j = 0; j < ins->src_count; j += 2) -+ { -+ unsigned int source_label = label_from_src_param(&ins->src[j + 1]); -+ size_t k, match_count = 0; -+ -+ for (k = 0; k < map_count; ++k) -+ { -+ struct lower_switch_to_if_ladder_block_mapping *mapping = &block_map[k]; -+ -+ if (mapping->switch_label == source_label && mapping->target_label == current_label) -+ match_count += 1; -+ } -+ -+ new_src_count += (match_count != 0) ? 2 * match_count : 2; -+ } -+ -+ assert(new_src_count >= ins->src_count); -+ -+ /* Allocate more source parameters if needed. */ -+ if (new_src_count == ins->src_count) -+ { -+ new_src = ins->src; -+ } -+ else -+ { -+ if (!(new_src = vsir_program_get_src_params(program, new_src_count))) -+ { -+ ERR("Failed to allocate %u source parameters.\n", new_src_count); -+ goto fail; -+ } -+ } -+ -+ /* Then do the copy. */ -+ for (j = 0, l = 0; j < ins->src_count; j += 2) -+ { -+ unsigned int source_label = label_from_src_param(&ins->src[j + 1]); -+ size_t k, match_count = 0; -+ -+ for (k = 0; k < map_count; ++k) -+ { -+ struct lower_switch_to_if_ladder_block_mapping *mapping = &block_map[k]; -+ -+ if (mapping->switch_label == source_label && mapping->target_label == current_label) -+ { -+ match_count += 1; -+ -+ new_src[l] = ins->src[j]; -+ new_src[l + 1] = ins->src[j + 1]; -+ new_src[l + 1].reg.idx[0].offset = mapping->if_label; -+ l += 2; -+ } -+ } -+ -+ if (match_count == 0) -+ { -+ new_src[l] = ins->src[j]; -+ new_src[l + 1] = ins->src[j + 1]; -+ l += 2; -+ } -+ } -+ -+ assert(l == new_src_count); -+ -+ ins->src_count = new_src_count; -+ ins->src = new_src; -+ } -+ -+ vkd3d_free(program->instructions.elements); -+ vkd3d_free(block_map); -+ program->instructions.elements = instructions; -+ program->instructions.capacity = ins_capacity; -+ program->instructions.count = ins_count; -+ program->block_count = block_count; -+ program->ssa_count = ssa_count; -+ -+ return VKD3D_OK; -+ -+fail: -+ vkd3d_free(instructions); -+ vkd3d_free(block_map); -+ -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+} -+ - enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, - const struct vkd3d_shader_compile_info *compile_info) - { -@@ -2361,7 +2648,12 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, - if ((result = instruction_array_lower_texkills(parser)) < 0) - return result; - -- if (!parser->shader_desc.is_dxil) -+ if (parser->shader_desc.is_dxil) -+ { -+ if ((result = lower_switch_to_if_ladder(&parser->program)) < 0) -+ return result; -+ } -+ else - { - if (parser->program.shader_version.type != VKD3D_SHADER_TYPE_PIXEL) - { -@@ -2431,6 +2723,7 @@ struct validation_context - struct validation_context_ssa_data - { - enum vsir_dimension dimension; -+ enum vkd3d_data_type data_type; - size_t first_seen; - uint32_t write_mask; - uint32_t read_mask; -@@ -2587,13 +2880,20 @@ static void vsir_validate_register(struct validation_context *ctx, - if (data->dimension == VSIR_DIMENSION_NONE) - { - data->dimension = reg->dimension; -+ data->data_type = reg->data_type; - data->first_seen = ctx->instruction_idx; - } -- else if (data->dimension != reg->dimension) -+ else - { -- validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a SSA register: " -- "it has already been seen with dimension %#x at instruction %zu.", -- reg->dimension, data->dimension, data->first_seen); -+ if (data->dimension != reg->dimension) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a SSA register: " -+ "it has already been seen with dimension %#x at instruction %zu.", -+ reg->dimension, data->dimension, data->first_seen); -+ -+ if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type)) -+ validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid data type %#x for a SSA register: " -+ "it has already been seen with data type %#x at instruction %zu.", -+ reg->data_type, data->data_type, data->first_seen); - } - break; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index a86ca583e63..aedbfc24a93 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -3594,11 +3594,17 @@ static bool vkd3d_swizzle_is_equal(uint32_t dst_write_mask, uint32_t swizzle, ui - return vkd3d_compact_swizzle(VKD3D_SHADER_NO_SWIZZLE, dst_write_mask) == vkd3d_compact_swizzle(swizzle, write_mask); - } - --static bool vkd3d_swizzle_is_scalar(uint32_t swizzle) -+static bool vkd3d_swizzle_is_scalar(uint32_t swizzle, const struct vkd3d_shader_register *reg) - { - unsigned int component_idx = vsir_swizzle_get_component(swizzle, 0); -- return vsir_swizzle_get_component(swizzle, 1) == component_idx -- && vsir_swizzle_get_component(swizzle, 2) == component_idx -+ -+ if (vsir_swizzle_get_component(swizzle, 1) != component_idx) -+ return false; -+ -+ if (data_type_is_64_bit(reg->data_type)) -+ return true; -+ -+ return vsir_swizzle_get_component(swizzle, 2) == component_idx - && vsir_swizzle_get_component(swizzle, 3) == component_idx; - } - -@@ -3719,7 +3725,7 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi - for (i = 0, j = 0; i < VKD3D_DVEC2_SIZE; ++i) - { - if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) -- values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component64(swizzle, i)]; -+ values[j++] = reg->u.immconst_u64[vsir_swizzle_get_component(swizzle, i)]; - } - } - -@@ -3886,7 +3892,7 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler - assert(compiler->failed); - return 0; - } -- assert(vkd3d_swizzle_is_scalar(swizzle)); -+ assert(vkd3d_swizzle_is_scalar(swizzle, reg)); - - if (reg->dimension == VSIR_DIMENSION_SCALAR) - { -@@ -3954,6 +3960,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); - } - -+ swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; - val_id = spirv_compiler_emit_swizzle(compiler, - val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask32); - -@@ -7047,11 +7054,11 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp - static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) - { -+ uint32_t val_id, dst_val_id, type_id, dst_id, src_id, write_mask32, swizzle32; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - struct vkd3d_shader_register_info dst_reg_info, src_reg_info; - const struct vkd3d_shader_dst_param *dst = instruction->dst; - const struct vkd3d_shader_src_param *src = instruction->src; -- uint32_t val_id, dst_val_id, type_id, dst_id, src_id; - uint32_t components[VKD3D_VEC4_SIZE]; - unsigned int i, component_count; - -@@ -7075,7 +7082,9 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, - return; - } - -- component_count = vsir_write_mask_component_count(dst->write_mask); -+ write_mask32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_write_mask_32_from_64(dst->write_mask) : dst->write_mask; -+ swizzle32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_swizzle_32_from_64(src->swizzle) : src->swizzle; -+ component_count = vsir_write_mask_component_count(write_mask32); - if (component_count != 1 && component_count != VKD3D_VEC4_SIZE - && dst_reg_info.write_mask == VKD3DSP_WRITEMASK_ALL) - { -@@ -7088,8 +7097,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, - - for (i = 0; i < ARRAY_SIZE(components); ++i) - { -- if (dst->write_mask & (VKD3DSP_WRITEMASK_0 << i)) -- components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(src->swizzle, i); -+ if (write_mask32 & (VKD3DSP_WRITEMASK_0 << i)) -+ components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle32, i); - else - components[i] = i; - } -@@ -7472,7 +7481,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - const struct vkd3d_shader_dst_param *dst = instruction->dst; - const struct vkd3d_shader_src_param *src = instruction->src; - enum vkd3d_shader_component_type component_type; -- unsigned int i, j, k, src_count; -+ unsigned int i, j, k, src_count, size; - uint32_t write_mask; - SpvOp op; - -@@ -7481,8 +7490,9 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - - component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -- mask_id = spirv_compiler_get_constant_uint(compiler, 0x1f); -- size_id = spirv_compiler_get_constant_uint(compiler, 0x20); -+ size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20; -+ mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); -+ size_id = spirv_compiler_get_constant_uint(compiler, size); - - switch (instruction->handler_idx) - { -@@ -7813,13 +7823,16 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, - if (instruction->src_count > 1) - { - /* Loop merge only. Must have a merge block and a continue block. */ -- spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset); -+ if (instruction->src_count == 3) -+ spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset); -+ else -+ ERR("Invalid branch with %u sources.\n", instruction->src_count); - } - vkd3d_spirv_build_op_branch(builder, spirv_compiler_get_label_id(compiler, src[0].reg.idx[0].offset)); - return; - } - -- if (!vkd3d_swizzle_is_scalar(src->swizzle)) -+ if (!vkd3d_swizzle_is_scalar(src->swizzle, &src->reg)) - { - WARN("Unexpected src swizzle %#x.\n", src->swizzle); - spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE, -@@ -7827,11 +7840,15 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, - } - - condition_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); -- condition_id = spirv_compiler_emit_int_to_bool(compiler, -- VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id); -+ if (src[0].reg.data_type != VKD3D_DATA_BOOL) -+ condition_id = spirv_compiler_emit_int_to_bool(compiler, -+ VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id); - /* Emit the merge immediately before the branch instruction. */ -- spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset, -- (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0); -+ if (instruction->src_count >= 4) -+ spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset, -+ (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0); -+ else -+ ERR("Invalid branch with %u sources.\n", instruction->src_count); - vkd3d_spirv_build_op_branch_conditional(builder, condition_id, - spirv_compiler_get_label_id(compiler, src[1].reg.idx[0].offset), - spirv_compiler_get_label_id(compiler, src[2].reg.idx[0].offset)); -@@ -7846,7 +7863,7 @@ static void spirv_compiler_emit_switch(struct spirv_compiler *compiler, - unsigned int i, word_count; - uint32_t *cases; - -- if (!vkd3d_swizzle_is_scalar(src[0].swizzle)) -+ if (!vkd3d_swizzle_is_scalar(src[0].swizzle, &src[0].reg)) - { - WARN("Unexpected src swizzle %#x.\n", src[0].swizzle); - spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE, -@@ -9964,6 +9981,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - enum vkd3d_shader_spirv_environment environment = spirv_compiler_get_target_environment(compiler); - if (vkd3d_spirv_binary_to_text(spirv, environment, compiler->formatting, &text) != VKD3D_OK) - return VKD3D_ERROR; -+ vkd3d_shader_free_shader_code(spirv); - *spirv = text; - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 50146c2c7c9..adfddd32036 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -1742,7 +1742,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const - { - if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) - { -- struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&priv->p, 1); -+ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(&priv->p.program, 1); - - if (!(reg_idx->rel_addr = rel_addr)) - { -@@ -2161,6 +2161,9 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons - break; - } - -+ if (data_type_is_64_bit(data_type)) -+ src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); -+ - if (register_is_input_output(&src_param->reg) && !shader_sm4_validate_input_output_register(priv, - &src_param->reg, mask_from_swizzle(src_param->swizzle))) - return false; -@@ -2341,6 +2344,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d - static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins) - { - const struct vkd3d_sm4_opcode_info *opcode_info; -+ struct vsir_program *program = &sm4->p.program; - uint32_t opcode_token, opcode, previous_token; - struct vkd3d_shader_dst_param *dst_params; - struct vkd3d_shader_src_param *src_params; -@@ -2399,7 +2403,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str - ins->predicate = NULL; - ins->dst_count = strnlen(opcode_info->dst_info, SM4_MAX_DST_COUNT); - ins->src_count = strnlen(opcode_info->src_info, SM4_MAX_SRC_COUNT); -- ins->src = src_params = shader_parser_get_src_params(&sm4->p, ins->src_count); -+ ins->src = src_params = vsir_program_get_src_params(program, ins->src_count); - if (!src_params && ins->src_count) - { - ERR("Failed to allocate src parameters.\n"); -@@ -2441,7 +2445,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str - precise = (opcode_token & VKD3D_SM5_PRECISE_MASK) >> VKD3D_SM5_PRECISE_SHIFT; - ins->flags |= precise << VKD3DSI_PRECISE_SHIFT; - -- ins->dst = dst_params = shader_parser_get_dst_params(&sm4->p, ins->dst_count); -+ ins->dst = dst_params = vsir_program_get_dst_params(program, ins->dst_count); - if (!dst_params && ins->dst_count) - { - ERR("Failed to allocate dst parameters.\n"); -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 1b7ea8dde9a..d0fd6b047b1 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -424,12 +424,12 @@ void set_string(struct vkd3d_bytecode_buffer *buffer, size_t offset, const char - static void vkd3d_shader_dump_blob(const char *path, const char *profile, - const char *suffix, const void *data, size_t size) - { -- static LONG shader_id = 0; -+ static unsigned int shader_id = 0; - char filename[1024]; - unsigned int id; - FILE *f; - -- id = InterlockedIncrement(&shader_id) - 1; -+ id = vkd3d_atomic_increment_u32(&shader_id) - 1; - - if (profile) - snprintf(filename, ARRAY_SIZE(filename), "%s/vkd3d-shader-%u-%s.%s", path, id, profile, suffix); -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index fd0f2f0f34a..0ba7e71922a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -895,6 +895,8 @@ struct vkd3d_shader_src_param - - void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count); -+void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, -+ enum vkd3d_data_type data_type, unsigned int idx_count); - void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id); - - struct vkd3d_shader_index_range -@@ -1285,6 +1287,18 @@ struct vsir_program - bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_version *version, unsigned int reserve); - void vsir_program_cleanup(struct vsir_program *program); - -+static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params( -+ struct vsir_program *program, unsigned int count) -+{ -+ return shader_dst_param_allocator_get(&program->instructions.dst_params, count); -+} -+ -+static inline struct vkd3d_shader_src_param *vsir_program_get_src_params( -+ struct vsir_program *program, unsigned int count) -+{ -+ return shader_src_param_allocator_get(&program->instructions.src_params, count); -+} -+ - struct vkd3d_shader_parser - { - struct vkd3d_shader_message_context *message_context; -@@ -1312,18 +1326,6 @@ bool vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, - void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, - enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); - --static inline struct vkd3d_shader_dst_param *shader_parser_get_dst_params( -- struct vkd3d_shader_parser *parser, unsigned int count) --{ -- return shader_dst_param_allocator_get(&parser->program.instructions.dst_params, count); --} -- --static inline struct vkd3d_shader_src_param *shader_parser_get_src_params( -- struct vkd3d_shader_parser *parser, unsigned int count) --{ -- return shader_src_param_allocator_get(&parser->program.instructions.src_params, count); --} -- - static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parser) - { - parser->ops->parser_destroy(parser); -@@ -1603,25 +1605,89 @@ static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int co - - static inline uint32_t vsir_write_mask_64_from_32(uint32_t write_mask32) - { -- uint32_t write_mask64 = write_mask32 | (write_mask32 >> 1); -- return (write_mask64 & VKD3DSP_WRITEMASK_0) | ((write_mask64 & VKD3DSP_WRITEMASK_2) >> 1); -+ switch (write_mask32) -+ { -+ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1: -+ return VKD3DSP_WRITEMASK_0; -+ -+ case VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3: -+ return VKD3DSP_WRITEMASK_1; -+ -+ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3: -+ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; -+ -+ default: -+ ERR("Invalid 32 bit writemask when converting to 64 bit: %#x.\n", write_mask32); -+ return VKD3DSP_WRITEMASK_0; -+ } - } - - static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64) - { -- uint32_t write_mask32 = (write_mask64 | (write_mask64 << 1)) -- & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_2); -- return write_mask32 | (write_mask32 << 1); -+ switch (write_mask64) -+ { -+ case VKD3DSP_WRITEMASK_0: -+ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; -+ -+ case VKD3DSP_WRITEMASK_1: -+ return VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; -+ -+ case VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1: -+ return VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; -+ -+ default: -+ ERR("Invalid 64 bit writemask: %#x.\n", write_mask64); -+ return VKD3DSP_WRITEMASK_0; -+ } -+} -+ -+static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32) -+{ -+ switch (swizzle32) -+ { -+ case VKD3D_SHADER_SWIZZLE(X, Y, X, Y): -+ return VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ -+ case VKD3D_SHADER_SWIZZLE(X, Y, Z, W): -+ return VKD3D_SHADER_SWIZZLE(X, Y, X, X); -+ -+ case VKD3D_SHADER_SWIZZLE(Z, W, X, Y): -+ return VKD3D_SHADER_SWIZZLE(Y, X, X, X); -+ -+ case VKD3D_SHADER_SWIZZLE(Z, W, Z, W): -+ return VKD3D_SHADER_SWIZZLE(Y, Y, X, X); -+ -+ default: -+ ERR("Invalid 32 bit swizzle when converting to 64 bit: %#x.\n", swizzle32); -+ return VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ } - } - --static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx) -+static inline uint32_t vsir_swizzle_32_from_64(uint32_t swizzle64) - { -- return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK; -+ switch (swizzle64) -+ { -+ case VKD3D_SHADER_SWIZZLE(X, X, X, X): -+ return VKD3D_SHADER_SWIZZLE(X, Y, X, Y); -+ -+ case VKD3D_SHADER_SWIZZLE(X, Y, X, X): -+ return VKD3D_SHADER_SWIZZLE(X, Y, Z, W); -+ -+ case VKD3D_SHADER_SWIZZLE(Y, X, X, X): -+ return VKD3D_SHADER_SWIZZLE(Z, W, X, Y); -+ -+ case VKD3D_SHADER_SWIZZLE(Y, Y, X, X): -+ return VKD3D_SHADER_SWIZZLE(Z, W, Z, W); -+ -+ default: -+ ERR("Invalid 64 bit swizzle: %#x.\n", swizzle64); -+ return VKD3D_SHADER_SWIZZLE(X, Y, X, Y); -+ } - } - --static inline unsigned int vsir_swizzle_get_component64(uint32_t swizzle, unsigned int idx) -+static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned int idx) - { -- return ((swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx * 2)) & VKD3D_SHADER_SWIZZLE_MASK) / 2u; -+ return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK; - } - - static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask) -diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index 2b8558175e0..e45072b9367 100644 ---- a/libs/vkd3d/libs/vkd3d/device.c -+++ b/libs/vkd3d/libs/vkd3d/device.c -@@ -750,7 +750,7 @@ static void vkd3d_destroy_instance(struct vkd3d_instance *instance) - - ULONG vkd3d_instance_incref(struct vkd3d_instance *instance) - { -- ULONG refcount = InterlockedIncrement(&instance->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&instance->refcount); - - TRACE("%p increasing refcount to %u.\n", instance, refcount); - -@@ -759,7 +759,7 @@ ULONG vkd3d_instance_incref(struct vkd3d_instance *instance) - - ULONG vkd3d_instance_decref(struct vkd3d_instance *instance) - { -- ULONG refcount = InterlockedDecrement(&instance->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&instance->refcount); - - TRACE("%p decreasing refcount to %u.\n", instance, refcount); - -@@ -2531,7 +2531,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *ifac - static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface) - { - struct d3d12_device *device = impl_from_ID3D12Device5(iface); -- ULONG refcount = InterlockedIncrement(&device->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&device->refcount); - - TRACE("%p increasing refcount to %u.\n", device, refcount); - -@@ -2563,7 +2563,7 @@ static HRESULT device_worker_stop(struct d3d12_device *device) - static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) - { - struct d3d12_device *device = impl_from_ID3D12Device5(iface); -- ULONG refcount = InterlockedDecrement(&device->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&device->refcount); - - TRACE("%p decreasing refcount to %u.\n", device, refcount); - -@@ -4473,8 +4473,8 @@ void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason, - va_list args; - - va_start(args, message); -- WARN("Device %p is lost (reason %#x, \"%s\").\n", -- device, reason, vkd3d_dbg_vsprintf(message, args)); -+ WARN("Device %p is lost (reason %s, \"%s\").\n", -+ device, debugstr_hresult(reason), vkd3d_dbg_vsprintf(message, args)); - va_end(args); - - device->removed_reason = reason; -diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index a360b0ef4dd..cd2f9af0e39 100644 ---- a/libs/vkd3d/libs/vkd3d/resource.c -+++ b/libs/vkd3d/libs/vkd3d/resource.c -@@ -308,7 +308,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_heap_QueryInterface(ID3D12Heap *iface, - static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface) - { - struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); -- ULONG refcount = InterlockedIncrement(&heap->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount); - - TRACE("%p increasing refcount to %u.\n", heap, refcount); - -@@ -345,7 +345,7 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap) - static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) - { - struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); -- ULONG refcount = InterlockedDecrement(&heap->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount); - - TRACE("%p decreasing refcount to %u.\n", heap, refcount); - -@@ -358,7 +358,7 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) - - static void d3d12_heap_resource_destroyed(struct d3d12_heap *heap) - { -- if (!InterlockedDecrement(&heap->resource_count) && (!heap->refcount || heap->is_private)) -+ if (!vkd3d_atomic_decrement_u32(&heap->resource_count) && (!heap->refcount || heap->is_private)) - d3d12_heap_destroy(heap); - } - -@@ -1003,7 +1003,7 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 - - static ULONG d3d12_resource_incref(struct d3d12_resource *resource) - { -- ULONG refcount = InterlockedIncrement(&resource->internal_refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&resource->internal_refcount); - - TRACE("%p increasing refcount to %u.\n", resource, refcount); - -@@ -1012,7 +1012,7 @@ static ULONG d3d12_resource_incref(struct d3d12_resource *resource) - - static ULONG d3d12_resource_decref(struct d3d12_resource *resource) - { -- ULONG refcount = InterlockedDecrement(&resource->internal_refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->internal_refcount); - - TRACE("%p decreasing refcount to %u.\n", resource, refcount); - -@@ -1284,7 +1284,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_resource_QueryInterface(ID3D12Resource1 * - static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface) - { - struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface); -- ULONG refcount = InterlockedIncrement(&resource->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&resource->refcount); - - TRACE("%p increasing refcount to %u.\n", resource, refcount); - -@@ -1302,7 +1302,7 @@ static ULONG STDMETHODCALLTYPE d3d12_resource_AddRef(ID3D12Resource1 *iface) - static ULONG STDMETHODCALLTYPE d3d12_resource_Release(ID3D12Resource1 *iface) - { - struct d3d12_resource *resource = impl_from_ID3D12Resource1(iface); -- ULONG refcount = InterlockedDecrement(&resource->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&resource->refcount); - - TRACE("%p decreasing refcount to %u.\n", resource, refcount); - -@@ -2174,7 +2174,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, - { - resource->heap = heap; - resource->heap_offset = heap_offset; -- InterlockedIncrement(&heap->resource_count); -+ vkd3d_atomic_increment_u32(&heap->resource_count); - } - else - { -@@ -4010,7 +4010,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_descriptor_heap_QueryInterface(ID3D12Desc - static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap *iface) - { - struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface); -- ULONG refcount = InterlockedIncrement(&heap->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount); - - TRACE("%p increasing refcount to %u.\n", heap, refcount); - -@@ -4020,7 +4020,7 @@ static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_AddRef(ID3D12DescriptorHeap - static ULONG STDMETHODCALLTYPE d3d12_descriptor_heap_Release(ID3D12DescriptorHeap *iface) - { - struct d3d12_descriptor_heap *heap = impl_from_ID3D12DescriptorHeap(iface); -- ULONG refcount = InterlockedDecrement(&heap->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount); - - TRACE("%p decreasing refcount to %u.\n", heap, refcount); - -@@ -4429,7 +4429,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_query_heap_QueryInterface(ID3D12QueryHeap - static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface) - { - struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface); -- ULONG refcount = InterlockedIncrement(&heap->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount); - - TRACE("%p increasing refcount to %u.\n", heap, refcount); - -@@ -4439,7 +4439,7 @@ static ULONG STDMETHODCALLTYPE d3d12_query_heap_AddRef(ID3D12QueryHeap *iface) - static ULONG STDMETHODCALLTYPE d3d12_query_heap_Release(ID3D12QueryHeap *iface) - { - struct d3d12_query_heap *heap = impl_from_ID3D12QueryHeap(iface); -- ULONG refcount = InterlockedDecrement(&heap->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&heap->refcount); - - TRACE("%p decreasing refcount to %u.\n", heap, refcount); - -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index a6d5b94b778..92840871631 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -@@ -192,7 +192,7 @@ struct vkd3d_instance - - uint64_t host_ticks_per_second; - -- LONG refcount; -+ unsigned int refcount; - }; - - #ifdef _WIN32 -@@ -665,8 +665,8 @@ VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint - struct d3d12_heap - { - ID3D12Heap ID3D12Heap_iface; -- LONG refcount; -- LONG resource_count; -+ unsigned int refcount; -+ unsigned int resource_count; - - bool is_private; - D3D12_HEAP_DESC desc; -@@ -721,8 +721,8 @@ struct d3d12_resource_tile_info - struct d3d12_resource - { - ID3D12Resource1 ID3D12Resource1_iface; -- LONG refcount; -- LONG internal_refcount; -+ unsigned int refcount; -+ unsigned int internal_refcount; - - D3D12_RESOURCE_DESC desc; - const struct vkd3d_format *format; -@@ -1046,7 +1046,7 @@ struct d3d12_descriptor_heap_vk_set - struct d3d12_descriptor_heap - { - ID3D12DescriptorHeap ID3D12DescriptorHeap_iface; -- LONG refcount; -+ unsigned int refcount; - uint64_t serial_id; - - D3D12_DESCRIPTOR_HEAP_DESC desc; -@@ -1085,7 +1085,7 @@ HRESULT d3d12_descriptor_heap_create(struct d3d12_device *device, - struct d3d12_query_heap - { - ID3D12QueryHeap ID3D12QueryHeap_iface; -- LONG refcount; -+ unsigned int refcount; - - VkQueryPool vk_query_pool; - -@@ -1749,7 +1749,7 @@ struct vkd3d_desc_object_cache - struct d3d12_device - { - ID3D12Device5 ID3D12Device5_iface; -- LONG refcount; -+ unsigned int refcount; - - VkDevice vk_device; - VkPhysicalDevice vk_physical_device; --- -2.43.0 - diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch deleted file mode 100644 index 18b34a0b..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-06ddb10c4008adde7d81e1ece4fdce7a2b2.patch +++ /dev/null @@ -1,1877 +0,0 @@ -From 29082a5f01e6e1fb631668d6f29b2615300e481e Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 7 Feb 2024 13:39:16 +1100 -Subject: [PATCH 3/5] Updated vkd3d to - 06ddb10c4008adde7d81e1ece4fdce7a2b267870. - ---- - libs/vkd3d/include/private/vkd3d_common.h | 2 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 181 ++++++- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 21 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 10 + - libs/vkd3d/libs/vkd3d/command.c | 16 +- - libs/vkd3d/libs/vkd3d/device.c | 444 ++++++++++-------- - libs/vkd3d/libs/vkd3d/resource.c | 8 +- - libs/vkd3d/libs/vkd3d/state.c | 8 +- - libs/vkd3d/libs/vkd3d/utils.c | 5 + - libs/vkd3d/libs/vkd3d/vkd3d_main.c | 16 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 32 +- - 11 files changed, 505 insertions(+), 238 deletions(-) - -diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h -index 979676c4d5a..666bb80faf9 100644 ---- a/libs/vkd3d/include/private/vkd3d_common.h -+++ b/libs/vkd3d/include/private/vkd3d_common.h -@@ -71,7 +71,7 @@ - #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) -+static inline uint64_t align(uint64_t addr, size_t alignment) - { - return (addr + (alignment - 1)) & ~(alignment - 1); - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 0358dbb6e06..ba951a6e51b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -33,6 +33,7 @@ static const uint64_t ALLOCA_FLAG_IN_ALLOCA = 0x20; - static const uint64_t ALLOCA_FLAG_EXPLICIT_TYPE = 0x40; - static const uint64_t ALLOCA_ALIGNMENT_MASK = ALLOCA_FLAG_IN_ALLOCA - 1; - static const unsigned int SHADER_DESCRIPTOR_TYPE_COUNT = 4; -+static const size_t MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION = 5; - - static const unsigned int dx_max_thread_group_size[3] = {1024, 1024, 64}; - -@@ -362,11 +363,13 @@ enum dx_intrinsic_opcode - DX_UBFE = 52, - DX_CREATE_HANDLE = 57, - DX_CBUFFER_LOAD_LEGACY = 59, -+ DX_TEXTURE_LOAD = 66, - DX_BUFFER_LOAD = 68, - DX_DERIV_COARSEX = 83, - DX_DERIV_COARSEY = 84, - DX_DERIV_FINEX = 85, - DX_DERIV_FINEY = 86, -+ DX_SPLIT_DOUBLE = 102, - DX_LEGACY_F32TOF16 = 130, - DX_LEGACY_F16TOF32 = 131, - DX_RAW_BUFFER_LOAD = 139, -@@ -1732,6 +1735,11 @@ static bool sm6_type_is_f16_f32(const struct sm6_type *type) - return type->class == TYPE_CLASS_FLOAT && (type->u.width == 16 || type->u.width == 32); - } - -+static bool sm6_type_is_double(const struct sm6_type *type) -+{ -+ return type->class == TYPE_CLASS_FLOAT && type->u.width == 64; -+} -+ - static inline bool sm6_type_is_floating_point(const struct sm6_type *type) - { - return type->class == TYPE_CLASS_FLOAT; -@@ -2371,6 +2379,26 @@ static bool sm6_value_validate_is_handle(const struct sm6_value *value, struct s - return true; - } - -+static bool sm6_value_validate_is_texture_handle(const struct sm6_value *value, enum dx_intrinsic_opcode op, -+ struct sm6_parser *sm6) -+{ -+ enum dxil_resource_kind kind; -+ -+ if (!sm6_value_validate_is_handle(value, sm6)) -+ return false; -+ -+ kind = value->u.handle.d->kind; -+ if (kind < RESOURCE_KIND_TEXTURE1D || kind > RESOURCE_KIND_TEXTURECUBEARRAY) -+ { -+ WARN("Resource kind %u for op %u is not a texture.\n", kind, op); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE, -+ "Resource kind %u for texture operation %u is not a texture.", kind, op); -+ return false; -+ } -+ -+ return true; -+} -+ - static bool sm6_value_validate_is_pointer(const struct sm6_value *value, struct sm6_parser *sm6) - { - if (!sm6_type_is_pointer(value->type)) -@@ -3199,6 +3227,7 @@ struct function_emission_state - { - struct sm6_block *code_block; - struct vkd3d_shader_instruction *ins; -+ unsigned int temp_idx; - }; - - static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record, -@@ -3518,6 +3547,72 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record - ins->handler_idx = VKD3DSIH_NOP; - } - -+static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, -+ const struct sm6_value *z_operand, struct function_emission_state *state, -+ struct vkd3d_shader_register *reg) -+{ -+ const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; -+ struct vkd3d_shader_instruction *ins = state->ins; -+ struct vkd3d_shader_src_param *src_params; -+ struct vkd3d_shader_dst_param *dst_param; -+ const unsigned int max_operands = 3; -+ unsigned int i, component_count; -+ bool all_constant = true; -+ -+ for (component_count = 0; component_count < max_operands; ++component_count) -+ { -+ if (!z_operand && operands[component_count]->is_undefined) -+ break; -+ operand_regs[component_count] = &operands[component_count]->u.reg; -+ all_constant &= register_is_constant_or_undef(operand_regs[component_count]); -+ } -+ if (z_operand) -+ { -+ all_constant &= register_is_constant(&z_operand->u.reg); -+ operand_regs[component_count++] = &z_operand->u.reg; -+ } -+ -+ if (component_count == 1) -+ { -+ *reg = operands[0]->u.reg; -+ return true; -+ } -+ -+ if (all_constant) -+ { -+ vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0]->data_type, 0); -+ reg->dimension = VSIR_DIMENSION_VEC4; -+ for (i = 0; i < component_count; ++i) -+ reg->u.immconst_u32[i] = operand_regs[i]->u.immconst_u32[0]; -+ return true; -+ } -+ -+ register_init_with_id(reg, VKD3DSPR_TEMP, operands[0]->u.reg.data_type, state->temp_idx++); -+ reg->dimension = VSIR_DIMENSION_VEC4; -+ -+ for (i = 0; i < component_count; ++i, ++ins) -+ { -+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ -+ if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) -+ return false; -+ -+ src_param_init(&src_params[0]); -+ src_params[0].reg = *operand_regs[i]; -+ -+ if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) -+ return false; -+ -+ dst_param_init_scalar(dst_param, i); -+ dst_param->reg = *reg; -+ } -+ -+ state->ins = ins; -+ state->code_block->instruction_count += component_count; -+ -+ return true; -+} -+ - static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) - { - switch (op) -@@ -3858,6 +3953,19 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri - instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); - } - -+static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value) -+{ -+ return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value); -+} -+ -+static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, -+ const struct sm6_value **operands, struct sm6_parser *sm6) -+{ -+ ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]); -+ ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]); -+ ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); -+} -+ - static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -@@ -3880,6 +3988,19 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ - dst->u.reg = dst_params[index].reg; - } - -+static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -+ const struct sm6_value **operands, struct function_emission_state *state) -+{ -+ struct vkd3d_shader_instruction *ins = state->ins; -+ struct vkd3d_shader_src_param *src_param; -+ -+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); -+ src_param = instruction_src_params_alloc(ins, 1, sm6); -+ src_param_init_from_value(src_param, operands[0]); -+ -+ instruction_dst_param_init_ssa_vector(ins, 2, sm6); -+} -+ - static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -@@ -3934,6 +4055,50 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr - src_param_init_from_value(src_param, value); - } - -+static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -+ const struct sm6_value **operands, struct function_emission_state *state) -+{ -+ const struct sm6_value *resource, *mip_level_or_sample_count; -+ enum vkd3d_shader_resource_type resource_type; -+ struct vkd3d_shader_src_param *src_params; -+ struct vkd3d_shader_instruction *ins; -+ struct vkd3d_shader_register coord; -+ bool is_multisample, is_uav; -+ unsigned int i; -+ -+ resource = operands[0]; -+ if (!sm6_value_validate_is_texture_handle(resource, op, sm6)) -+ return; -+ -+ resource_type = resource->u.handle.d->resource_type; -+ is_multisample = resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS -+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY; -+ is_uav = resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; -+ -+ mip_level_or_sample_count = (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) ? operands[1] : NULL; -+ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], -+ is_multisample ? NULL : mip_level_or_sample_count, state, &coord)) -+ { -+ return; -+ } -+ -+ ins = state->ins; -+ instruction_init_with_resource(ins, is_uav ? VKD3DSIH_LD_UAV_TYPED -+ : is_multisample ? VKD3DSIH_LD2DMS : VKD3DSIH_LD, resource, sm6); -+ instruction_set_texel_offset(ins, &operands[5], sm6); -+ -+ for (i = 0; i < VKD3D_VEC4_SIZE; ++i) -+ ins->resource_data_type[i] = resource->u.handle.d->resource_data_type; -+ -+ src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6); -+ src_param_init_vector_from_reg(&src_params[0], &coord); -+ src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); -+ if (is_multisample) -+ src_param_init_from_value(&src_params[2], mip_level_or_sample_count); -+ -+ instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); -+} -+ - struct sm6_dx_opcode_info - { - const char *ret_type; -@@ -3947,12 +4112,15 @@ struct sm6_dx_opcode_info - 8 -> int8 - b -> constant int1 - c -> constant int8/16/32 -+ C -> constant or undefined int8/16/32 - i -> int32 - m -> int16/32/64 - f -> float -+ d -> double - e -> half/float - g -> half/float/double - H -> handle -+ S -> splitdouble - v -> void - o -> overloaded - R -> matches the return type -@@ -3993,9 +4161,11 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = - [DX_ROUND_Z ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_RSQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, -+ [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, - [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, - [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load}, - [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, - [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, - [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, -@@ -4023,18 +4193,25 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc - case 'c': - return sm6_value_is_constant(value) && sm6_type_is_integer(type) && type->u.width >= 8 - && type->u.width <= 32; -+ case 'C': -+ return (sm6_value_is_constant(value) || sm6_value_is_undef(value)) -+ && sm6_type_is_integer(type) && type->u.width >= 8 && type->u.width <= 32; - case 'i': - return sm6_type_is_i32(type); - case 'm': - return sm6_type_is_i16_i32_i64(type); - case 'f': - return sm6_type_is_float(type); -+ case 'd': -+ return sm6_type_is_double(type); - case 'e': - return sm6_type_is_f16_f32(type); - case 'g': - return sm6_type_is_floating_point(type); - case 'H': - return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type; -+ case 'S': -+ return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.splitdouble"); - case 'v': - return !type; - case 'o': -@@ -5380,7 +5557,8 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - - /* Some instructions can emit >1 IR instruction, so extra may be used. */ - if (!vkd3d_array_reserve((void **)&code_block->instructions, &code_block->instruction_capacity, -- code_block->instruction_count + 1, sizeof(*code_block->instructions))) -+ code_block->instruction_count + MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION, -+ sizeof(*code_block->instructions))) - { - ERR("Failed to allocate instructions.\n"); - return VKD3D_ERROR_OUT_OF_MEMORY; -@@ -5411,6 +5589,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - { - struct function_emission_state state = {code_block, ins}; - sm6_parser_emit_call(sm6, record, &state, dst); -+ sm6->p.program.temp_count = max(sm6->p.program.temp_count, state.temp_idx); - break; - } - case FUNC_CODE_INST_CAST: -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index aedbfc24a93..9b6ce742976 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -223,16 +223,6 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d - } - } - --static inline bool register_is_undef(const struct vkd3d_shader_register *reg) --{ -- return reg->type == VKD3DSPR_UNDEF; --} -- --static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg) --{ -- return register_is_constant(reg) || register_is_undef(reg); --} -- - #define VKD3D_SPIRV_VERSION 0x00010000 - #define VKD3D_SPIRV_GENERATOR_ID 18 - #define VKD3D_SPIRV_GENERATOR_VERSION 10 -@@ -3894,9 +3884,10 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler - } - assert(vkd3d_swizzle_is_scalar(swizzle, reg)); - -+ reg_component_type = vkd3d_component_type_from_data_type(ssa->data_type); -+ - if (reg->dimension == VSIR_DIMENSION_SCALAR) - { -- reg_component_type = vkd3d_component_type_from_data_type(ssa->data_type); - if (component_type != reg_component_type) - { - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -@@ -3906,6 +3897,14 @@ static uint32_t spirv_compiler_emit_load_ssa_reg(struct spirv_compiler *compiler - return val_id; - } - -+ if (component_type != reg_component_type) -+ { -+ /* Required for resource loads with sampled type int, because DXIL has no signedness. -+ * Only 128-bit vector sizes are used. */ -+ type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); -+ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -+ } -+ - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - component_idx = vsir_swizzle_get_component(swizzle, 0); - return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx); -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 0ba7e71922a..a709121f1a1 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1194,6 +1194,16 @@ static inline bool register_is_constant(const struct vkd3d_shader_register *reg) - return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); - } - -+static inline bool register_is_undef(const struct vkd3d_shader_register *reg) -+{ -+ return reg->type == VKD3DSPR_UNDEF; -+} -+ -+static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg) -+{ -+ return register_is_constant(reg) || register_is_undef(reg); -+} -+ - static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg) - { - return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR -diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index 3cf58e06d40..f9940b3d383 100644 ---- a/libs/vkd3d/libs/vkd3d/command.c -+++ b/libs/vkd3d/libs/vkd3d/command.c -@@ -5132,8 +5132,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra - struct VkAttachmentDescription attachment_desc; - struct VkAttachmentReference ds_reference; - -- TRACE("iface %p, dsv %#lx, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p.\n", -- iface, dsv.ptr, flags, depth, stencil, rect_count, rects); -+ TRACE("iface %p, dsv %s, flags %#x, depth %.8e, stencil 0x%02x, rect_count %u, rects %p.\n", -+ iface, debug_cpu_handle(dsv), flags, depth, stencil, rect_count, rects); - - d3d12_command_list_track_resource_usage(list, dsv_desc->resource); - -@@ -5180,8 +5180,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra - struct VkAttachmentReference color_reference; - VkClearValue clear_value; - -- TRACE("iface %p, rtv %#lx, color %p, rect_count %u, rects %p.\n", -- iface, rtv.ptr, color, rect_count, rects); -+ TRACE("iface %p, rtv %s, color %p, rect_count %u, rects %p.\n", -+ iface, debug_cpu_handle(rtv), color, rect_count, rects); - - d3d12_command_list_track_resource_usage(list, rtv_desc->resource); - -@@ -5432,8 +5432,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID - struct d3d12_resource *resource_impl; - VkClearColorValue colour; - -- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %lx, resource %p, values %p, rect_count %u, rects %p.\n", -- iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects); -+ TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", -+ iface, gpu_handle.ptr, debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); - - resource_impl = unsafe_impl_from_ID3D12Resource(resource); - if (!(descriptor = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) -@@ -5496,8 +5496,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I - VkClearColorValue colour; - struct vkd3d_view *view; - -- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %lx, resource %p, values %p, rect_count %u, rects %p.\n", -- iface, gpu_handle.ptr, cpu_handle.ptr, resource, values, rect_count, rects); -+ TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", -+ iface, gpu_handle.ptr, debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); - - resource_impl = unsafe_impl_from_ID3D12Resource(resource); - if (!(view = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) -diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index e45072b9367..cf8b506fdf5 100644 ---- a/libs/vkd3d/libs/vkd3d/device.c -+++ b/libs/vkd3d/libs/vkd3d/device.c -@@ -1969,7 +1969,7 @@ static HRESULT vkd3d_select_queues(const struct vkd3d_instance *vkd3d_instance, - * which applies to resources of a total size of 4 MiB or less. */ - static bool d3d12_is_64k_msaa_supported(struct d3d12_device *device) - { -- D3D12_RESOURCE_ALLOCATION_INFO info; -+ struct vkd3d_resource_allocation_info info; - D3D12_RESOURCE_DESC resource_desc; - - memset(&resource_desc, 0, sizeof(resource_desc)); -@@ -1986,7 +1986,7 @@ static bool d3d12_is_64k_msaa_supported(struct d3d12_device *device) - * resources, which must have 0x10000 in their description, so we might - * reasonably return true here for 0x20000 or 0x40000. */ - return SUCCEEDED(vkd3d_get_image_allocation_info(device, &resource_desc, &info)) -- && info.Alignment <= 0x10000; -+ && info.alignment <= 0x10000; - } - - static HRESULT vkd3d_create_vk_device(struct d3d12_device *device, -@@ -2133,7 +2133,7 @@ static void d3d12_device_destroy_pipeline_cache(struct d3d12_device *device) - #define VKD3D_VA_SLAB_COUNT (64 * 1024) - - static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_slab(struct vkd3d_gpu_va_allocator *allocator, -- size_t aligned_size, void *ptr) -+ uint64_t aligned_size, void *ptr) - { - struct vkd3d_gpu_va_slab *slab; - D3D12_GPU_VIRTUAL_ADDRESS address; -@@ -2149,13 +2149,13 @@ static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_slab(struct vkd - slab_idx = slab - allocator->slabs; - address = VKD3D_VA_SLAB_BASE + slab_idx * VKD3D_VA_SLAB_SIZE; - -- TRACE("Allocated address %#"PRIx64", slab %u, size %zu.\n", address, slab_idx, aligned_size); -+ TRACE("Allocated address %#"PRIx64", slab %u, size %"PRIu64".\n", address, slab_idx, aligned_size); - - return address; - } - - static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_fallback(struct vkd3d_gpu_va_allocator *allocator, -- size_t alignment, size_t aligned_size, void *ptr) -+ size_t alignment, uint64_t aligned_size, void *ptr) - { - struct vkd3d_gpu_va_allocation *allocation; - D3D12_GPU_VIRTUAL_ADDRESS base, ceiling; -@@ -2181,17 +2181,17 @@ static D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate_fallback(struct - * only fail once we have exhausted 63 bits of address space. */ - allocator->fallback_floor = base + aligned_size; - -- TRACE("Allocated address %#"PRIx64", size %zu.\n", base, aligned_size); -+ TRACE("Allocated address %#"PRIx64", size %"PRIu64".\n", base, aligned_size); - - return base; - } - - D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, -- size_t alignment, size_t size, void *ptr) -+ size_t alignment, uint64_t size, void *ptr) - { - D3D12_GPU_VIRTUAL_ADDRESS address; - -- if (size > ~(size_t)0 - (alignment - 1)) -+ if (size > ~(uint64_t)0 - (alignment - 1)) - return 0; - size = align(size, alignment); - -@@ -2227,7 +2227,7 @@ static void *vkd3d_gpu_va_allocator_dereference_slab(struct vkd3d_gpu_va_allocat - base_offset -= slab_idx * VKD3D_VA_SLAB_SIZE; - if (base_offset >= slab->size) - { -- ERR("Address %#"PRIx64" is %#"PRIx64" bytes into slab %u of size %zu.\n", -+ ERR("Address %#"PRIx64" is %#"PRIx64" bytes into slab %u of size %"PRIu64".\n", - address, base_offset, slab_idx, slab->size); - return NULL; - } -@@ -2498,17 +2498,19 @@ static void vkd3d_desc_object_cache_cleanup(struct vkd3d_desc_object_cache *cach - } - - /* ID3D12Device */ --static inline struct d3d12_device *impl_from_ID3D12Device5(ID3D12Device5 *iface) -+static inline struct d3d12_device *impl_from_ID3D12Device7(ID3D12Device7 *iface) - { -- return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device5_iface); -+ return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device7_iface); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device7 *iface, - REFIID riid, void **object) - { - TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); - -- if (IsEqualGUID(riid, &IID_ID3D12Device5) -+ if (IsEqualGUID(riid, &IID_ID3D12Device7) -+ || IsEqualGUID(riid, &IID_ID3D12Device6) -+ || IsEqualGUID(riid, &IID_ID3D12Device5) - || IsEqualGUID(riid, &IID_ID3D12Device4) - || IsEqualGUID(riid, &IID_ID3D12Device3) - || IsEqualGUID(riid, &IID_ID3D12Device2) -@@ -2528,9 +2530,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device5 *ifac - return E_NOINTERFACE; - } - --static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device5 *iface) -+static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device7 *iface) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - unsigned int refcount = vkd3d_atomic_increment_u32(&device->refcount); - - TRACE("%p increasing refcount to %u.\n", device, refcount); -@@ -2560,9 +2562,9 @@ static HRESULT device_worker_stop(struct d3d12_device *device) - return S_OK; - } - --static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) -+static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device7 *iface) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - unsigned int refcount = vkd3d_atomic_decrement_u32(&device->refcount); - - TRACE("%p decreasing refcount to %u.\n", device, refcount); -@@ -2599,10 +2601,10 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device5 *iface) - return refcount; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device7 *iface, - REFGUID guid, UINT *data_size, void *data) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p, guid %s, data_size %p, data %p.\n", - iface, debugstr_guid(guid), data_size, data); -@@ -2610,10 +2612,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device5 *ifac - return vkd3d_get_private_data(&device->private_store, guid, data_size, data); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device7 *iface, - REFGUID guid, UINT data_size, const void *data) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p, guid %s, data_size %u, data %p.\n", - iface, debugstr_guid(guid), data_size, data); -@@ -2621,19 +2623,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device5 *ifac - return vkd3d_set_private_data(&device->private_store, guid, data_size, data); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device7 *iface, - REFGUID guid, const IUnknown *data) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p, guid %s, data %p.\n", iface, debugstr_guid(guid), data); - - return vkd3d_set_private_data_interface(&device->private_store, guid, data); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device5 *iface, const WCHAR *name) -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device7 *iface, const WCHAR *name) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size)); - -@@ -2641,17 +2643,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device5 *iface, cons - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name); - } - --static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device5 *iface) -+static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device7 *iface) - { - TRACE("iface %p.\n", iface); - - return 1; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device7 *iface, - const D3D12_COMMAND_QUEUE_DESC *desc, REFIID riid, void **command_queue) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_command_queue *object; - HRESULT hr; - -@@ -2665,10 +2667,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device5 * - riid, command_queue); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device7 *iface, - D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **command_allocator) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_command_allocator *object; - HRESULT hr; - -@@ -2682,10 +2684,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic - riid, command_allocator); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device7 *iface, - const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_pipeline_state *object; - HRESULT hr; - -@@ -2699,10 +2701,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12 - &IID_ID3D12PipelineState, riid, pipeline_state); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device7 *iface, - const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_pipeline_state *object; - HRESULT hr; - -@@ -2716,11 +2718,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12D - &IID_ID3D12PipelineState, riid, pipeline_state); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device7 *iface, - UINT node_mask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator *command_allocator, - ID3D12PipelineState *initial_pipeline_state, REFIID riid, void **command_list) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_command_list *object; - HRESULT hr; - -@@ -2843,10 +2845,10 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) - return true; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device7 *iface, - D3D12_FEATURE feature, void *feature_data, UINT feature_data_size) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n", - iface, feature, feature_data, feature_data_size); -@@ -3352,10 +3354,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device5 - } - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device7 *iface, - const D3D12_DESCRIPTOR_HEAP_DESC *desc, REFIID riid, void **descriptor_heap) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_descriptor_heap *object; - HRESULT hr; - -@@ -3369,7 +3371,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device5 - &IID_ID3D12DescriptorHeap, riid, descriptor_heap); - } - --static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device5 *iface, -+static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device7 *iface, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) - { - TRACE("iface %p, descriptor_heap_type %#x.\n", iface, descriptor_heap_type); -@@ -3392,11 +3394,11 @@ static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D - } - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device7 *iface, - UINT node_mask, const void *bytecode, SIZE_T bytecode_length, - REFIID riid, void **root_signature) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_root_signature *object; - HRESULT hr; - -@@ -3412,89 +3414,89 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device5 - &IID_ID3D12RootSignature, riid, root_signature); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device7 *iface, - const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_desc tmp = {0}; - -- TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); -+ TRACE("iface %p, desc %p, descriptor %s.\n", iface, desc, debug_cpu_handle(descriptor)); - - d3d12_desc_create_cbv(&tmp, device, desc); - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device7 *iface, - ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_desc tmp = {0}; - -- TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", -- iface, resource, desc, descriptor.ptr); -+ TRACE("iface %p, resource %p, desc %p, descriptor %s.\n", -+ iface, resource, desc, debug_cpu_handle(descriptor)); - - d3d12_desc_create_srv(&tmp, device, unsafe_impl_from_ID3D12Resource(resource), desc); - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device7 *iface, - ID3D12Resource *resource, ID3D12Resource *counter_resource, - const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_desc tmp = {0}; - -- TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n", -- iface, resource, counter_resource, desc, descriptor.ptr); -+ TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %s.\n", -+ iface, resource, counter_resource, desc, debug_cpu_handle(descriptor)); - - d3d12_desc_create_uav(&tmp, device, unsafe_impl_from_ID3D12Resource(resource), - unsafe_impl_from_ID3D12Resource(counter_resource), desc); - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device7 *iface, - ID3D12Resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", -- iface, resource, desc, descriptor.ptr); -+ TRACE("iface %p, resource %p, desc %p, descriptor %s.\n", -+ iface, resource, desc, debug_cpu_handle(descriptor)); - - d3d12_rtv_desc_create_rtv(d3d12_rtv_desc_from_cpu_handle(descriptor), -- impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc); -+ impl_from_ID3D12Device7(iface), unsafe_impl_from_ID3D12Resource(resource), desc); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device7 *iface, - ID3D12Resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", -- iface, resource, desc, descriptor.ptr); -+ TRACE("iface %p, resource %p, desc %p, descriptor %s.\n", -+ iface, resource, desc, debug_cpu_handle(descriptor)); - - d3d12_dsv_desc_create_dsv(d3d12_dsv_desc_from_cpu_handle(descriptor), -- impl_from_ID3D12Device5(iface), unsafe_impl_from_ID3D12Resource(resource), desc); -+ impl_from_ID3D12Device7(iface), unsafe_impl_from_ID3D12Resource(resource), desc); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device7 *iface, - const D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_desc tmp = {0}; - -- TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); -+ TRACE("iface %p, desc %p, descriptor %s.\n", iface, desc, debug_cpu_handle(descriptor)); - - d3d12_desc_create_sampler(&tmp, device, desc); - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device7 *iface, - UINT dst_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *dst_descriptor_range_offsets, - const UINT *dst_descriptor_range_sizes, - UINT src_descriptor_range_count, const D3D12_CPU_DESCRIPTOR_HANDLE *src_descriptor_range_offsets, - const UINT *src_descriptor_range_sizes, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx; - unsigned int dst_range_size, src_range_size; - struct d3d12_descriptor_heap *dst_heap; -@@ -3550,101 +3552,126 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device5 *iface, - } - } - --static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device7 *iface, - UINT descriptor_count, const D3D12_CPU_DESCRIPTOR_HANDLE dst_descriptor_range_offset, - const D3D12_CPU_DESCRIPTOR_HANDLE src_descriptor_range_offset, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) - { -- TRACE("iface %p, descriptor_count %u, dst_descriptor_range_offset %#lx, " -- "src_descriptor_range_offset %#lx, descriptor_heap_type %#x.\n", -- iface, descriptor_count, dst_descriptor_range_offset.ptr, src_descriptor_range_offset.ptr, -- descriptor_heap_type); -+ TRACE("iface %p, descriptor_count %u, dst_descriptor_range_offset %s, " -+ "src_descriptor_range_offset %s, descriptor_heap_type %#x.\n", -+ iface, descriptor_count, debug_cpu_handle(dst_descriptor_range_offset), -+ debug_cpu_handle(src_descriptor_range_offset), descriptor_heap_type); - - d3d12_device_CopyDescriptors(iface, 1, &dst_descriptor_range_offset, &descriptor_count, - 1, &src_descriptor_range_offset, &descriptor_count, descriptor_heap_type); - } - --static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo( -- ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, -- UINT count, const D3D12_RESOURCE_DESC *resource_descs) -+static void d3d12_resource_allocation_info1_from_vkd3d(D3D12_RESOURCE_ALLOCATION_INFO1 *result, -+ const struct vkd3d_resource_allocation_info *info) -+{ -+ result->Offset = info->offset; -+ result->Alignment = info->alignment; -+ result->SizeInBytes = info->size_in_bytes; -+} -+ -+static void d3d12_device_get_resource_allocation_info(struct d3d12_device *device, -+ D3D12_RESOURCE_ALLOCATION_INFO1 *infos1, unsigned int count, const D3D12_RESOURCE_DESC *resource_descs, -+ D3D12_RESOURCE_ALLOCATION_INFO *result) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct vkd3d_resource_allocation_info info; - const D3D12_RESOURCE_DESC *desc; - uint64_t requested_alignment; -+ unsigned int i; - -- TRACE("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p.\n", -- iface, info, visible_mask, count, resource_descs); -- -- debug_ignored_node_mask(visible_mask); -- -- info->SizeInBytes = 0; -- info->Alignment = 0; -- -- if (count != 1) -- { -- FIXME("Multiple resource descriptions not supported.\n"); -- return info; -- } -+ result->Alignment = 0; -+ result->SizeInBytes = 0; - -- desc = &resource_descs[0]; -+ info.offset = 0; - -- if (FAILED(d3d12_resource_validate_desc(desc, device))) -+ for (i = 0; i < count; ++i) - { -- WARN("Invalid resource desc.\n"); -- goto invalid; -- } -+ desc = &resource_descs[i]; - -- if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) -- { -- info->SizeInBytes = align(desc->Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); -- info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; -- } -- else -- { -- if (FAILED(vkd3d_get_image_allocation_info(device, desc, info))) -+ if (FAILED(d3d12_resource_validate_desc(desc, device))) - { -- WARN("Failed to get allocation info for texture.\n"); -+ WARN("Invalid resource desc.\n"); - goto invalid; - } - -- requested_alignment = desc->Alignment -- ? desc->Alignment : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; -- info->Alignment = max(info->Alignment, requested_alignment); -+ if (desc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) -+ { -+ info.alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; -+ info.offset = align(info.offset, info.alignment); -+ info.size_in_bytes = align(desc->Width, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT); -+ } -+ else -+ { -+ if (FAILED(vkd3d_get_image_allocation_info(device, desc, &info))) -+ { -+ WARN("Failed to get allocation info for texture.\n"); -+ goto invalid; -+ } - -- info->SizeInBytes = align(info->SizeInBytes, info->Alignment); -+ requested_alignment = desc->Alignment -+ ? desc->Alignment : D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; -+ info.alignment = max(info.alignment, requested_alignment); -+ info.size_in_bytes = align(info.size_in_bytes, info.alignment); - -- /* Pad by the maximum heap offset increase which may be needed to align to a higher -- * Vulkan requirement an offset supplied by the calling application. This allows -- * us to return the standard D3D12 alignment and adjust resource placement later. */ -- if (info->Alignment > requested_alignment) -- { -- info->SizeInBytes += info->Alignment - requested_alignment; -- info->Alignment = requested_alignment; -+ /* Pad by the maximum heap offset increase which may be needed to align to a higher -+ * Vulkan requirement an offset supplied by the calling application. This allows -+ * us to return the standard D3D12 alignment and adjust resource placement later. */ -+ if (info.alignment > requested_alignment) -+ { -+ info.size_in_bytes += info.alignment - requested_alignment; -+ info.alignment = requested_alignment; -+ } -+ -+ info.offset = align(info.offset, info.alignment); - } -- } - -- TRACE("Size %#"PRIx64", alignment %#"PRIx64".\n", info->SizeInBytes, info->Alignment); -+ if (infos1) -+ d3d12_resource_allocation_info1_from_vkd3d(&infos1[i], &info); - -- return info; -+ info.offset += info.size_in_bytes; -+ -+ result->Alignment = max(result->Alignment, info.alignment); -+ result->SizeInBytes = info.offset; -+ } -+ -+ return; - - invalid: -- info->SizeInBytes = ~(uint64_t)0; -+ result->SizeInBytes = UINT64_MAX; - -- /* FIXME: Should we support D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT for small MSSA resources? */ -+ /* FIXME: Should we support D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT for small MSAA resources? */ - if (desc->SampleDesc.Count != 1) -- info->Alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT; -+ result->Alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT; - else -- info->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; -+ result->Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; - -- TRACE("Alignment %#"PRIx64".\n", info->Alignment); -+ TRACE("Alignment %#"PRIx64".\n", result->Alignment); -+} -+ -+static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo( -+ ID3D12Device7 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, -+ UINT count, const D3D12_RESOURCE_DESC *resource_descs) -+{ -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); -+ -+ TRACE("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p.\n", -+ iface, info, visible_mask, count, resource_descs); -+ -+ debug_ignored_node_mask(visible_mask); -+ -+ d3d12_device_get_resource_allocation_info(device, NULL, count, resource_descs, info); - - return info; - } - --static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device5 *iface, -+static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device7 *iface, - D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - bool coherent; - - TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n", -@@ -3684,12 +3711,12 @@ static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapPrope - return heap_properties; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device7 *iface, - 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, REFIID iid, void **resource) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_resource *object; - HRESULT hr; - -@@ -3708,10 +3735,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi - return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device7 *iface, - const D3D12_HEAP_DESC *desc, REFIID iid, void **heap) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_heap *object; - HRESULT hr; - -@@ -3727,12 +3754,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device5 *iface, - return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device7 *iface, - ID3D12Heap *heap, UINT64 heap_offset, - const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, - const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_heap *heap_object; - struct d3d12_resource *object; - HRESULT hr; -@@ -3751,11 +3778,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device5 - return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device7 *iface, - const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, - const D3D12_CLEAR_VALUE *optimized_clear_value, REFIID iid, void **resource) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_resource *object; - HRESULT hr; - -@@ -3769,11 +3796,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Devic - return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device7 *iface, - ID3D12DeviceChild *object, const SECURITY_ATTRIBUTES *attributes, DWORD access, - const WCHAR *name, HANDLE *handle) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n", - iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle); -@@ -3781,7 +3808,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device5 * - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device7 *iface, - HANDLE handle, REFIID riid, void **object) - { - FIXME("iface %p, handle %p, riid %s, object %p stub!\n", -@@ -3790,10 +3817,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device5 *if - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device7 *iface, - const WCHAR *name, DWORD access, HANDLE *handle) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - FIXME("iface %p, name %s, access %#x, handle %p stub!\n", - iface, debugstr_w(name, device->wchar_size), access, handle); -@@ -3801,7 +3828,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device7 *iface, - UINT object_count, ID3D12Pageable * const *objects) - { - ID3D12Fence *fence; -@@ -3809,17 +3836,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device5 *iface, - - TRACE("iface %p, object_count %u, objects %p.\n", iface, object_count, objects); - -- if (FAILED(hr = ID3D12Device5_CreateFence(iface, 0, 0, &IID_ID3D12Fence, (void **)&fence))) -+ if (FAILED(hr = ID3D12Device7_CreateFence(iface, 0, 0, &IID_ID3D12Fence, (void **)&fence))) - return hr; - -- hr = ID3D12Device5_EnqueueMakeResident(iface, 0, object_count, objects, fence, 1); -+ hr = ID3D12Device7_EnqueueMakeResident(iface, 0, object_count, objects, fence, 1); - if (SUCCEEDED(hr)) - ID3D12Fence_SetEventOnCompletion(fence, 1, NULL); - ID3D12Fence_Release(fence); - return hr; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device7 *iface, - UINT object_count, ID3D12Pageable * const *objects) - { - FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", -@@ -3828,10 +3855,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device5 *iface, - return S_OK; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device7 *iface, - UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_fence *object; - HRESULT hr; - -@@ -3844,21 +3871,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device5 *iface, - return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device5 *iface) -+static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device7 *iface) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p.\n", iface); - - return device->removed_reason; - } - --static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device7 *iface, - const D3D12_RESOURCE_DESC *desc, UINT first_sub_resource, UINT sub_resource_count, - UINT64 base_offset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT *layouts, - UINT *row_counts, UINT64 *row_sizes, UINT64 *total_bytes) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - unsigned int i, sub_resource_idx, miplevel_idx, row_count, row_size, row_pitch; - unsigned int width, height, depth, plane_count, sub_resources_per_plane; -@@ -3938,10 +3965,10 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device5 * - *total_bytes = total; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device7 *iface, - const D3D12_QUERY_HEAP_DESC *desc, REFIID iid, void **heap) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_query_heap *object; - HRESULT hr; - -@@ -3954,18 +3981,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device5 *ifa - return return_interface(&object->ID3D12QueryHeap_iface, &IID_ID3D12QueryHeap, iid, heap); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device5 *iface, BOOL enable) -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device7 *iface, BOOL enable) - { - FIXME("iface %p, enable %#x stub!\n", iface, enable); - - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device7 *iface, - const D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *root_signature, - REFIID iid, void **command_signature) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_command_signature *object; - HRESULT hr; - -@@ -3979,14 +4006,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic - &IID_ID3D12CommandSignature, iid, command_signature); - } - --static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device7 *iface, - ID3D12Resource *resource, UINT *total_tile_count, - D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, - UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling, - D3D12_SUBRESOURCE_TILING *sub_resource_tilings) - { - const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource); -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " - "standard_title_shape %p, sub_resource_tiling_count %p, " -@@ -3999,9 +4026,9 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device5 *ifac - sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); - } - --static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device5 *iface, LUID *luid) -+static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device7 *iface, LUID *luid) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - TRACE("iface %p, luid %p.\n", iface, luid); - -@@ -4010,7 +4037,7 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device5 *iface - return luid; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device7 *iface, - const void *blob, SIZE_T blob_size, REFIID iid, void **lib) - { - FIXME("iface %p, blob %p, blob_size %lu, iid %s, lib %p stub!\n", iface, blob, blob_size, debugstr_guid(iid), lib); -@@ -4018,7 +4045,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device - return DXGI_ERROR_UNSUPPORTED; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device7 *iface, - ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count, - D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event) - { -@@ -4028,7 +4055,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion( - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device7 *iface, - UINT object_count, ID3D12Pageable *const *objects, const D3D12_RESIDENCY_PRIORITY *priorities) - { - FIXME_ONCE("iface %p, object_count %u, objects %p, priorities %p stub!\n", iface, object_count, objects, priorities); -@@ -4036,10 +4063,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device5 - return S_OK; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device7 *iface, - const D3D12_PIPELINE_STATE_STREAM_DESC *desc, REFIID iid, void **pipeline_state) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_pipeline_state *object; - HRESULT hr; - -@@ -4051,7 +4078,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineState(ID3D12Device5 - return return_interface(&object->ID3D12PipelineState_iface, &IID_ID3D12PipelineState, iid, pipeline_state); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12Device7 *iface, - const void *address, REFIID iid, void **heap) - { - FIXME("iface %p, address %p, iid %s, heap %p stub!\n", iface, address, debugstr_guid(iid), heap); -@@ -4059,7 +4086,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromAddress(ID3D12 - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID3D12Device7 *iface, - HANDLE file_mapping, REFIID iid, void **heap) - { - FIXME("iface %p, file_mapping %p, iid %s, heap %p stub!\n", iface, file_mapping, debugstr_guid(iid), heap); -@@ -4067,7 +4094,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenExistingHeapFromFileMapping(ID - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device7 *iface, - D3D12_RESIDENCY_FLAGS flags, UINT num_objects, ID3D12Pageable *const *objects, - ID3D12Fence *fence, UINT64 fence_value) - { -@@ -4078,7 +4105,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnqueueMakeResident(ID3D12Device5 - return S_OK; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device7 *iface, - UINT node_mask, D3D12_COMMAND_LIST_TYPE type, D3D12_COMMAND_LIST_FLAGS flags, - REFIID iid, void **command_list) - { -@@ -4088,7 +4115,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList1(ID3D12Device5 * - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3D12Device7 *iface, - const D3D12_PROTECTED_RESOURCE_SESSION_DESC *desc, REFIID iid, void **session) - { - FIXME("iface %p, desc %p, iid %s, session %p stub!\n", iface, desc, debugstr_guid(iid), session); -@@ -4096,13 +4123,13 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession(ID3 - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Device7 *iface, - 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, - ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_resource *object; - HRESULT hr; - -@@ -4121,11 +4148,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource1(ID3D12Dev - return return_interface(&object->ID3D12Resource1_iface, &IID_ID3D12Resource1, iid, resource); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device7 *iface, - const D3D12_HEAP_DESC *desc, ID3D12ProtectedResourceSession *protected_session, - REFIID iid, void **heap) - { -- struct d3d12_device *device = impl_from_ID3D12Device5(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); - struct d3d12_heap *object; - HRESULT hr; - -@@ -4141,7 +4168,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap1(ID3D12Device5 *iface, - return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Device7 *iface, - const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_STATES initial_state, - const D3D12_CLEAR_VALUE *optimized_clear_value, - ID3D12ProtectedResourceSession *protected_session, REFIID iid, void **resource) -@@ -4155,17 +4182,23 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource1(ID3D12Devi - } - - static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo1( -- ID3D12Device5 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, -+ ID3D12Device7 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, - UINT count, const D3D12_RESOURCE_DESC *resource_descs, - D3D12_RESOURCE_ALLOCATION_INFO1 *info1) - { -- FIXME("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p, info1 %p stub!\n", -+ struct d3d12_device *device = impl_from_ID3D12Device7(iface); -+ -+ TRACE("iface %p, info %p, visible_mask 0x%08x, count %u, resource_descs %p, info1 %p.\n", - iface, info, visible_mask, count, resource_descs, info1); - -+ debug_ignored_node_mask(visible_mask); -+ -+ d3d12_device_get_resource_allocation_info(device, info1, count, resource_descs, info); -+ - return info; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device7 *iface, - ID3D12LifetimeOwner *owner, REFIID iid, void **tracker) - { - FIXME("iface %p, owner %p, iid %s, tracker %p stub!\n", iface, owner, debugstr_guid(iid), tracker); -@@ -4173,12 +4206,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateLifetimeTracker(ID3D12Device - return E_NOTIMPL; - } - --static void STDMETHODCALLTYPE d3d12_device_RemoveDevice(ID3D12Device5 *iface) -+static void STDMETHODCALLTYPE d3d12_device_RemoveDevice(ID3D12Device7 *iface) - { - FIXME("iface %p stub!\n", iface); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device7 *iface, - UINT *num_meta_commands, D3D12_META_COMMAND_DESC *command_desc) - { - FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface, -@@ -4187,7 +4220,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device7 *iface, - REFGUID command_id, D3D12_META_COMMAND_PARAMETER_STAGE stage, - UINT *size_in_bytes, UINT *parameter_count, - D3D12_META_COMMAND_PARAMETER_DESC *parameter_desc) -@@ -4199,7 +4232,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3 - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device7 *iface, - REFGUID command_id, UINT node_mask, const void *parameters_data, - SIZE_T data_size_in_bytes, REFIID iid, void **meta_command) - { -@@ -4211,7 +4244,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device5 *i - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device5 *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device7 *iface, - const D3D12_STATE_OBJECT_DESC *desc, REFIID iid, void **state_object) - { - FIXME("iface %p, desc %p, iid %s, state_object %p stub!\n", iface, desc, debugstr_guid(iid), state_object); -@@ -4219,14 +4252,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateStateObject(ID3D12Device5 *i - return E_NOTIMPL; - } - --static void STDMETHODCALLTYPE d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo(ID3D12Device5 *iface, -+static void STDMETHODCALLTYPE d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo(ID3D12Device7 *iface, - const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS *desc, - D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO *info) - { - FIXME("iface %p, desc %p, info %p stub!\n", iface, desc, info); - } - --static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_CheckDriverMatchingIdentifier(ID3D12Device5 *iface, -+static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_CheckDriverMatchingIdentifier(ID3D12Device7 *iface, - D3D12_SERIALIZED_DATA_TYPE data_type, const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER *identifier) - { - FIXME("iface %p, data_type %u, identifier %p stub!\n", iface, data_type, identifier); -@@ -4234,7 +4267,35 @@ static D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS STDMETHODCALLTYPE d3d12_device_Ch - return D3D12_DRIVER_MATCHING_IDENTIFIER_UNRECOGNIZED; - } - --static const struct ID3D12Device5Vtbl d3d12_device_vtbl = -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetBackgroundProcessingMode(ID3D12Device7 *iface, -+ D3D12_BACKGROUND_PROCESSING_MODE mode, D3D12_MEASUREMENTS_ACTION action, HANDLE event, -+ BOOL *further_measurements_desired) -+{ -+ FIXME("iface %p, mode %#x, action %#x, event %p, further_measurements_desired %p stub!\n", -+ iface, mode, action, event, further_measurements_desired); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT STDMETHODCALLTYPE d3d12_device_AddToStateObject(ID3D12Device7 *iface, -+ const D3D12_STATE_OBJECT_DESC *addition, ID3D12StateObject *state_object_to_grow_from, -+ REFIID riid, void **new_state_object) -+{ -+ FIXME("iface %p, addition %p, state_object_to_grow_from %p, riid %s, new_state_object %p stub!\n", -+ iface, addition, state_object_to_grow_from, debugstr_guid(riid), new_state_object); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateProtectedResourceSession1(ID3D12Device7 *iface, -+ const D3D12_PROTECTED_RESOURCE_SESSION_DESC1 *desc, REFIID riid, void **session) -+{ -+ FIXME("iface %p, desc %p, riid %s, session %p stub!\n", iface, desc, debugstr_guid(riid), session); -+ -+ return E_NOTIMPL; -+} -+ -+static const struct ID3D12Device7Vtbl d3d12_device_vtbl = - { - /* IUnknown methods */ - d3d12_device_QueryInterface, -@@ -4309,14 +4370,19 @@ static const struct ID3D12Device5Vtbl d3d12_device_vtbl = - d3d12_device_CreateStateObject, - d3d12_device_GetRaytracingAccelerationStructurePrebuildInfo, - d3d12_device_CheckDriverMatchingIdentifier, -+ /* ID3D12Device6 methods */ -+ d3d12_device_SetBackgroundProcessingMode, -+ /* ID3D12Device7 methods */ -+ d3d12_device_AddToStateObject, -+ d3d12_device_CreateProtectedResourceSession1, - }; - --struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface) -+struct d3d12_device *unsafe_impl_from_ID3D12Device7(ID3D12Device7 *iface) - { - if (!iface) - return NULL; - assert(iface->lpVtbl == &d3d12_device_vtbl); -- return impl_from_ID3D12Device5(iface); -+ return impl_from_ID3D12Device7(iface); - } - - static void *device_worker_main(void *arg) -@@ -4359,7 +4425,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, - const struct vkd3d_vk_device_procs *vk_procs; - HRESULT hr; - -- device->ID3D12Device5_iface.lpVtbl = &d3d12_device_vtbl; -+ device->ID3D12Device7_iface.lpVtbl = &d3d12_device_vtbl; - device->refcount = 1; - - vkd3d_instance_incref(device->vkd3d_instance = instance); -@@ -4607,28 +4673,28 @@ HRESULT vkd3d_join_thread(struct vkd3d_instance *instance, union vkd3d_thread_ha - - IUnknown *vkd3d_get_device_parent(ID3D12Device *device) - { -- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); - - return d3d12_device->parent; - } - - VkDevice vkd3d_get_vk_device(ID3D12Device *device) - { -- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); - - return d3d12_device->vk_device; - } - - VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device) - { -- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); - - return d3d12_device->vk_physical_device; - } - - struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device) - { -- struct d3d12_device *d3d12_device = impl_from_ID3D12Device5((ID3D12Device5 *)device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device7((ID3D12Device7 *)device); - - return d3d12_device->vkd3d_instance; - } -diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index cd2f9af0e39..c04f48702a0 100644 ---- a/libs/vkd3d/libs/vkd3d/resource.c -+++ b/libs/vkd3d/libs/vkd3d/resource.c -@@ -940,7 +940,7 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device, - } - - HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, -- const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info) -+ const D3D12_RESOURCE_DESC *desc, struct vkd3d_resource_allocation_info *allocation_info) - { - static const D3D12_HEAP_PROPERTIES heap_properties = {D3D12_HEAP_TYPE_DEFAULT}; - const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; -@@ -968,8 +968,8 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, - VK_CALL(vkGetImageMemoryRequirements(device->vk_device, vk_image, &requirements)); - VK_CALL(vkDestroyImage(device->vk_device, vk_image, NULL)); - -- allocation_info->SizeInBytes = requirements.size; -- allocation_info->Alignment = requirements.alignment; -+ allocation_info->size_in_bytes = requirements.size; -+ allocation_info->alignment = requirements.alignment; - } - - return hr; -@@ -2239,7 +2239,7 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device, - HRESULT vkd3d_create_image_resource(ID3D12Device *device, - const struct vkd3d_image_resource_create_info *create_info, ID3D12Resource **resource) - { -- struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device5((ID3D12Device5 *)device); -+ struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device7((ID3D12Device7 *)device); - struct d3d12_resource *object; - HRESULT hr; - -diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 5f383d256cc..3428742dd7f 100644 ---- a/libs/vkd3d/libs/vkd3d/state.c -+++ b/libs/vkd3d/libs/vkd3d/state.c -@@ -52,7 +52,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_root_signature_QueryInterface(ID3D12RootS - static ULONG STDMETHODCALLTYPE d3d12_root_signature_AddRef(ID3D12RootSignature *iface) - { - struct d3d12_root_signature *root_signature = impl_from_ID3D12RootSignature(iface); -- ULONG refcount = InterlockedIncrement(&root_signature->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&root_signature->refcount); - - TRACE("%p increasing refcount to %u.\n", root_signature, refcount); - -@@ -110,7 +110,7 @@ static void d3d12_root_signature_cleanup(struct d3d12_root_signature *root_signa - static ULONG STDMETHODCALLTYPE d3d12_root_signature_Release(ID3D12RootSignature *iface) - { - struct d3d12_root_signature *root_signature = impl_from_ID3D12RootSignature(iface); -- ULONG refcount = InterlockedDecrement(&root_signature->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&root_signature->refcount); - - TRACE("%p decreasing refcount to %u.\n", root_signature, refcount); - -@@ -1984,7 +1984,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_pipeline_state_QueryInterface(ID3D12Pipel - static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_AddRef(ID3D12PipelineState *iface) - { - struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); -- ULONG refcount = InterlockedIncrement(&state->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&state->refcount); - - TRACE("%p increasing refcount to %u.\n", state, refcount); - -@@ -2027,7 +2027,7 @@ static void d3d12_pipeline_uav_counter_state_cleanup(struct d3d12_pipeline_uav_c - static ULONG STDMETHODCALLTYPE d3d12_pipeline_state_Release(ID3D12PipelineState *iface) - { - struct d3d12_pipeline_state *state = impl_from_ID3D12PipelineState(iface); -- ULONG refcount = InterlockedDecrement(&state->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&state->refcount); - - TRACE("%p decreasing refcount to %u.\n", state, refcount); - -diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c -index 751971220e7..28913a83e8c 100644 ---- a/libs/vkd3d/libs/vkd3d/utils.c -+++ b/libs/vkd3d/libs/vkd3d/utils.c -@@ -632,6 +632,11 @@ HRESULT return_interface(void *iface, REFIID iface_iid, - return hr; - } - -+const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle) -+{ -+ return vkd3d_dbg_sprintf("{%#"PRIxPTR"}", (uintptr_t)handle.ptr); -+} -+ - const char *debug_d3d12_box(const D3D12_BOX *box) - { - if (!box) -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c -index 0139de5dd23..f71b370137f 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c -@@ -71,18 +71,18 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, - - if (!device) - { -- ID3D12Device_Release(&object->ID3D12Device5_iface); -+ ID3D12Device_Release(&object->ID3D12Device7_iface); - return S_FALSE; - } - -- return return_interface(&object->ID3D12Device5_iface, &IID_ID3D12Device, iid, device); -+ return return_interface(&object->ID3D12Device7_iface, &IID_ID3D12Device, iid, device); - } - - /* ID3D12RootSignatureDeserializer */ - struct d3d12_root_signature_deserializer - { - ID3D12RootSignatureDeserializer ID3D12RootSignatureDeserializer_iface; -- LONG refcount; -+ unsigned int refcount; - - union - { -@@ -123,7 +123,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_root_signature_deserializer_QueryInterfac - static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_AddRef(ID3D12RootSignatureDeserializer *iface) - { - struct d3d12_root_signature_deserializer *deserializer = impl_from_ID3D12RootSignatureDeserializer(iface); -- ULONG refcount = InterlockedIncrement(&deserializer->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&deserializer->refcount); - - TRACE("%p increasing refcount to %u.\n", deserializer, refcount); - -@@ -133,7 +133,7 @@ static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_AddRef(ID3D12Ro - static ULONG STDMETHODCALLTYPE d3d12_root_signature_deserializer_Release(ID3D12RootSignatureDeserializer *iface) - { - struct d3d12_root_signature_deserializer *deserializer = impl_from_ID3D12RootSignatureDeserializer(iface); -- ULONG refcount = InterlockedDecrement(&deserializer->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&deserializer->refcount); - - TRACE("%p decreasing refcount to %u.\n", deserializer, refcount); - -@@ -242,7 +242,7 @@ HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_s - struct d3d12_versioned_root_signature_deserializer - { - ID3D12VersionedRootSignatureDeserializer ID3D12VersionedRootSignatureDeserializer_iface; -- LONG refcount; -+ unsigned int refcount; - - union - { -@@ -284,7 +284,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_Que - static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_AddRef(ID3D12VersionedRootSignatureDeserializer *iface) - { - struct d3d12_versioned_root_signature_deserializer *deserializer = impl_from_ID3D12VersionedRootSignatureDeserializer(iface); -- ULONG refcount = InterlockedIncrement(&deserializer->refcount); -+ unsigned int refcount = vkd3d_atomic_increment_u32(&deserializer->refcount); - - TRACE("%p increasing refcount to %u.\n", deserializer, refcount); - -@@ -294,7 +294,7 @@ static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_AddRe - static ULONG STDMETHODCALLTYPE d3d12_versioned_root_signature_deserializer_Release(ID3D12VersionedRootSignatureDeserializer *iface) - { - struct d3d12_versioned_root_signature_deserializer *deserializer = impl_from_ID3D12VersionedRootSignatureDeserializer(iface); -- ULONG refcount = InterlockedDecrement(&deserializer->refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&deserializer->refcount); - - TRACE("%p decreasing refcount to %u.\n", deserializer, refcount); - -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index 92840871631..8ecf6764ab6 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -@@ -493,13 +493,13 @@ struct vkd3d_fence_worker - struct vkd3d_gpu_va_allocation - { - D3D12_GPU_VIRTUAL_ADDRESS base; -- size_t size; -+ uint64_t size; - void *ptr; - }; - - struct vkd3d_gpu_va_slab - { -- size_t size; -+ uint64_t size; - void *ptr; - }; - -@@ -517,7 +517,7 @@ struct vkd3d_gpu_va_allocator - }; - - D3D12_GPU_VIRTUAL_ADDRESS vkd3d_gpu_va_allocator_allocate(struct vkd3d_gpu_va_allocator *allocator, -- size_t alignment, size_t size, void *ptr); -+ size_t alignment, uint64_t size, void *ptr); - void *vkd3d_gpu_va_allocator_dereference(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address); - void vkd3d_gpu_va_allocator_free(struct vkd3d_gpu_va_allocator *allocator, D3D12_GPU_VIRTUAL_ADDRESS address); - -@@ -770,6 +770,13 @@ static inline bool d3d12_resource_is_texture(const struct d3d12_resource *resour - return resource->desc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER; - } - -+struct vkd3d_resource_allocation_info -+{ -+ uint64_t offset; -+ uint64_t alignment; -+ uint64_t size_in_bytes; -+}; -+ - bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource); - HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device); - void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, -@@ -797,7 +804,7 @@ HRESULT vkd3d_create_buffer(struct d3d12_device *device, - const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, - const D3D12_RESOURCE_DESC *desc, VkBuffer *vk_buffer); - HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, -- const D3D12_RESOURCE_DESC *desc, D3D12_RESOURCE_ALLOCATION_INFO *allocation_info); -+ const D3D12_RESOURCE_DESC *desc, struct vkd3d_resource_allocation_info *allocation_info); - - enum vkd3d_view_type - { -@@ -1172,7 +1179,7 @@ struct d3d12_descriptor_set_layout - struct d3d12_root_signature - { - ID3D12RootSignature ID3D12RootSignature_iface; -- LONG refcount; -+ unsigned int refcount; - - VkPipelineLayout vk_pipeline_layout; - struct d3d12_descriptor_set_layout descriptor_set_layouts[VKD3D_MAX_DESCRIPTOR_SETS]; -@@ -1281,7 +1288,7 @@ struct d3d12_pipeline_uav_counter_state - struct d3d12_pipeline_state - { - ID3D12PipelineState ID3D12PipelineState_iface; -- LONG refcount; -+ unsigned int refcount; - - union - { -@@ -1748,7 +1755,7 @@ struct vkd3d_desc_object_cache - /* ID3D12Device */ - struct d3d12_device - { -- ID3D12Device5 ID3D12Device5_iface; -+ ID3D12Device7 ID3D12Device7_iface; - unsigned int refcount; - - VkDevice vk_device; -@@ -1823,29 +1830,29 @@ struct vkd3d_queue *d3d12_device_get_vkd3d_queue(struct d3d12_device *device, D3 - bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent); - void d3d12_device_mark_as_removed(struct d3d12_device *device, HRESULT reason, - const char *message, ...) VKD3D_PRINTF_FUNC(3, 4); --struct d3d12_device *unsafe_impl_from_ID3D12Device5(ID3D12Device5 *iface); -+struct d3d12_device *unsafe_impl_from_ID3D12Device7(ID3D12Device7 *iface); - HRESULT d3d12_device_add_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap); - void d3d12_device_remove_descriptor_heap(struct d3d12_device *device, struct d3d12_descriptor_heap *heap); - - static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object) - { -- return ID3D12Device5_QueryInterface(&device->ID3D12Device5_iface, iid, object); -+ return ID3D12Device7_QueryInterface(&device->ID3D12Device7_iface, iid, object); - } - - static inline ULONG d3d12_device_add_ref(struct d3d12_device *device) - { -- return ID3D12Device5_AddRef(&device->ID3D12Device5_iface); -+ return ID3D12Device7_AddRef(&device->ID3D12Device7_iface); - } - - static inline ULONG d3d12_device_release(struct d3d12_device *device) - { -- return ID3D12Device5_Release(&device->ID3D12Device5_iface); -+ return ID3D12Device7_Release(&device->ID3D12Device7_iface); - } - - static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type) - { -- return ID3D12Device5_GetDescriptorHandleIncrementSize(&device->ID3D12Device5_iface, descriptor_type); -+ return ID3D12Device7_GetDescriptorHandleIncrementSize(&device->ID3D12Device7_iface, descriptor_type); - } - - /* utils */ -@@ -1953,6 +1960,7 @@ bool is_write_resource_state(D3D12_RESOURCE_STATES state); - - HRESULT return_interface(void *iface, REFIID iface_iid, REFIID requested_iid, void **object); - -+const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle); - const char *debug_d3d12_box(const D3D12_BOX *box); - const char *debug_d3d12_shader_component_mapping(unsigned int mapping); - const char *debug_vk_extent_3d(VkExtent3D extent); --- -2.43.0 - diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch deleted file mode 100644 index 0e5167d0..00000000 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-5c917552c927835c6f446dbecf1aa6ff2cc.patch +++ /dev/null @@ -1,1667 +0,0 @@ -From a7881d22b7765f148af5eb1c9ebbf4eaace98f86 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 8 Feb 2024 12:06:22 +1100 -Subject: [PATCH 4/5] Updated vkd3d to - 5c917552c927835c6f446dbecf1aa6ff2cc30cbe. - ---- - libs/vkd3d/include/private/vkd3d_common.h | 12 - - libs/vkd3d/include/private/vkd3d_test.h | 40 +- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 6 + - libs/vkd3d/libs/vkd3d-shader/dxil.c | 232 ++++++++--- - libs/vkd3d/libs/vkd3d-shader/ir.c | 384 +++++++++++++++++- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 185 +++++---- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 6 + - libs/vkd3d/libs/vkd3d/command.c | 28 +- - libs/vkd3d/libs/vkd3d/device.c | 96 ++++- - libs/vkd3d/libs/vkd3d/resource.c | 10 +- - libs/vkd3d/libs/vkd3d/utils.c | 5 + - libs/vkd3d/libs/vkd3d/vkd3d_main.c | 8 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 29 +- - 13 files changed, 831 insertions(+), 210 deletions(-) - -diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h -index 666bb80faf9..b5a8240d28e 100644 ---- a/libs/vkd3d/include/private/vkd3d_common.h -+++ b/libs/vkd3d/include/private/vkd3d_common.h -@@ -304,18 +304,6 @@ static inline uint32_t vkd3d_atomic_increment_u32(uint32_t volatile *x) - return vkd3d_atomic_add_fetch_u32(x, 1); - } - --#ifndef _WIN32 --static inline LONG InterlockedIncrement(LONG volatile *x) --{ -- return vkd3d_atomic_increment_u32((uint32_t *)x); --} -- --static inline LONG InterlockedDecrement(LONG volatile *x) --{ -- return vkd3d_atomic_decrement_u32((uint32_t *)x); --} --#endif /* _WIN32 */ -- - static inline void vkd3d_parse_version(const char *version, int *major, int *minor) - { - *major = atoi(version); -diff --git a/libs/vkd3d/include/private/vkd3d_test.h b/libs/vkd3d/include/private/vkd3d_test.h -index 081443c4fa6..a337ac07269 100644 ---- a/libs/vkd3d/include/private/vkd3d_test.h -+++ b/libs/vkd3d/include/private/vkd3d_test.h -@@ -101,12 +101,12 @@ static void vkd3d_test_end_todo(void); - - struct vkd3d_test_state - { -- LONG success_count; -- LONG failure_count; -- LONG skip_count; -- LONG todo_count; -- LONG todo_success_count; -- LONG bug_count; -+ unsigned int success_count; -+ unsigned int failure_count; -+ unsigned int skip_count; -+ unsigned int todo_count; -+ unsigned int todo_success_count; -+ unsigned int bug_count; - - unsigned int debug_level; - -@@ -150,13 +150,13 @@ vkd3d_test_check_assert_that(unsigned int line, bool result, const char *fmt, va - { - if (result) - { -- InterlockedIncrement(&vkd3d_test_state.success_count); -+ vkd3d_atomic_increment_u32(&vkd3d_test_state.success_count); - if (vkd3d_test_state.debug_level > 1) - vkd3d_test_printf(line, "Test succeeded.\n"); - } - else - { -- InterlockedIncrement(&vkd3d_test_state.failure_count); -+ vkd3d_atomic_increment_u32(&vkd3d_test_state.failure_count); - vkd3d_test_printf(line, "Test failed: "); - vprintf(fmt, args); - } -@@ -180,7 +180,7 @@ vkd3d_test_check_ok(unsigned int line, bool result, const char *fmt, va_list arg - - if (is_bug && vkd3d_test_state.bug_enabled) - { -- InterlockedIncrement(&vkd3d_test_state.bug_count); -+ vkd3d_atomic_increment_u32(&vkd3d_test_state.bug_count); - if (is_todo) - result = !result; - if (result) -@@ -193,12 +193,12 @@ vkd3d_test_check_ok(unsigned int line, bool result, const char *fmt, va_list arg - { - if (result) - { -- InterlockedIncrement(&vkd3d_test_state.todo_success_count); -+ vkd3d_atomic_increment_u32(&vkd3d_test_state.todo_success_count); - vkd3d_test_printf(line, "Todo succeeded: "); - } - else - { -- InterlockedIncrement(&vkd3d_test_state.todo_count); -+ vkd3d_atomic_increment_u32(&vkd3d_test_state.todo_count); - vkd3d_test_printf(line, "Todo: "); - } - vprintf(fmt, args); -@@ -227,7 +227,7 @@ vkd3d_test_skip(unsigned int line, const char *fmt, ...) - vkd3d_test_printf(line, "Test skipped: "); - vprintf(fmt, args); - va_end(args); -- InterlockedIncrement(&vkd3d_test_state.skip_count); -+ vkd3d_atomic_increment_u32(&vkd3d_test_state.skip_count); - } - - static void VKD3D_PRINTF_FUNC(2, 3) VKD3D_UNUSED -@@ -293,16 +293,14 @@ int main(int argc, char **argv) - - vkd3d_test_main(argc, argv); - -- printf("%s: %lu tests executed (%lu failures, %lu skipped, %lu todo, %lu bugs).\n", -+ printf("%s: %u tests executed (%u failures, %u skipped, %u todo, %u bugs).\n", - vkd3d_test_name, -- (unsigned long)(vkd3d_test_state.success_count -- + vkd3d_test_state.failure_count + vkd3d_test_state.todo_count -- + vkd3d_test_state.todo_success_count), -- (unsigned long)(vkd3d_test_state.failure_count -- + vkd3d_test_state.todo_success_count), -- (unsigned long)vkd3d_test_state.skip_count, -- (unsigned long)vkd3d_test_state.todo_count, -- (unsigned long)vkd3d_test_state.bug_count); -+ vkd3d_test_state.success_count + vkd3d_test_state.failure_count -+ + vkd3d_test_state.todo_count + vkd3d_test_state.todo_success_count, -+ vkd3d_test_state.failure_count + vkd3d_test_state.todo_success_count, -+ vkd3d_test_state.skip_count, -+ vkd3d_test_state.todo_count, -+ vkd3d_test_state.bug_count); - - if (test_platform) - free(test_platform); -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index dd96b7fa50b..3f86bd45960 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -30,8 +30,11 @@ - static const char * const shader_opcode_names[] = - { - [VKD3DSIH_ABS ] = "abs", -+ [VKD3DSIH_ACOS ] = "acos", - [VKD3DSIH_ADD ] = "add", - [VKD3DSIH_AND ] = "and", -+ [VKD3DSIH_ASIN ] = "asin", -+ [VKD3DSIH_ATAN ] = "atan", - [VKD3DSIH_ATOMIC_AND ] = "atomic_and", - [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", - [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", -@@ -168,10 +171,13 @@ static const char * const shader_opcode_names[] = - [VKD3DSIH_GATHER4_S ] = "gather4_s", - [VKD3DSIH_GEO ] = "ge", - [VKD3DSIH_GEU ] = "ge_unord", -+ [VKD3DSIH_HCOS ] = "hcos", - [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", - [VKD3DSIH_HS_DECLS ] = "hs_decls", - [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", - [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", -+ [VKD3DSIH_HSIN ] = "hsin", -+ [VKD3DSIH_HTAN ] = "htan", - [VKD3DSIH_IADD ] = "iadd", - [VKD3DSIH_IBFE ] = "ibfe", - [VKD3DSIH_IDIV ] = "idiv", -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index ba951a6e51b..a001f6f0642 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -339,6 +339,12 @@ enum dx_intrinsic_opcode - DX_COS = 12, - DX_SIN = 13, - DX_TAN = 14, -+ DX_ACOS = 15, -+ DX_ASIN = 16, -+ DX_ATAN = 17, -+ DX_HCOS = 18, -+ DX_HSIN = 19, -+ DX_HTAN = 20, - DX_EXP = 21, - DX_FRC = 22, - DX_LOG = 23, -@@ -364,6 +370,7 @@ enum dx_intrinsic_opcode - DX_CREATE_HANDLE = 57, - DX_CBUFFER_LOAD_LEGACY = 59, - DX_TEXTURE_LOAD = 66, -+ DX_TEXTURE_STORE = 67, - DX_BUFFER_LOAD = 68, - DX_DERIV_COARSEX = 83, - DX_DERIV_COARSEY = 84, -@@ -2176,21 +2183,29 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type - } - - static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type, -- unsigned int component_count, struct sm6_parser *sm6) -+ unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6) - { - enum vkd3d_data_type data_type; - unsigned int id; - -- id = sm6_parser_alloc_ssa_id(sm6); -+ if (value && register_is_ssa(&value->u.reg) && value->u.reg.idx[0].offset) -+ { -+ id = value->u.reg.idx[0].offset; -+ TRACE("Using forward-allocated id %u.\n", id); -+ } -+ else -+ { -+ id = sm6_parser_alloc_ssa_id(sm6); -+ } - data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0)); - register_init_with_id(reg, VKD3DSPR_SSA, data_type, id); - reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; - } - - static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, -- struct sm6_parser *sm6) -+ struct sm6_value *value, struct sm6_parser *sm6) - { -- register_init_ssa_vector(reg, type, 1, sm6); -+ register_init_ssa_vector(reg, sm6_type_get_scalar_type(type, 0), 1, value, sm6); - } - - static void dst_param_init(struct vkd3d_shader_dst_param *param) -@@ -2200,6 +2215,13 @@ static void dst_param_init(struct vkd3d_shader_dst_param *param) - param->shift = 0; - } - -+static void dst_param_init_with_mask(struct vkd3d_shader_dst_param *param, unsigned int mask) -+{ -+ param->write_mask = mask; -+ param->modifiers = 0; -+ param->shift = 0; -+} -+ - static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx) - { - param->write_mask = 1u << component_idx; -@@ -2215,10 +2237,10 @@ static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned - } - - static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, -- struct sm6_parser *sm6) -+ struct sm6_value *value, struct sm6_parser *sm6) - { - dst_param_init(param); -- register_init_ssa_scalar(¶m->reg, type, sm6); -+ register_init_ssa_scalar(¶m->reg, type, value, sm6); - } - - static inline void src_param_init(struct vkd3d_shader_src_param *param) -@@ -2275,7 +2297,7 @@ static void instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio - struct vkd3d_shader_dst_param *param = instruction_dst_params_alloc(ins, 1, sm6); - struct sm6_value *dst = sm6_parser_get_current_value(sm6); - -- dst_param_init_ssa_scalar(param, dst->type, sm6); -+ dst_param_init_ssa_scalar(param, dst->type, dst, sm6); - param->write_mask = VKD3DSP_WRITEMASK_0; - dst->u.reg = param->reg; - } -@@ -2287,7 +2309,7 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio - struct sm6_value *dst = sm6_parser_get_current_value(sm6); - - dst_param_init_vector(param, component_count); -- register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, sm6); -+ register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, dst, sm6); - dst->u.reg = param->reg; - } - -@@ -2450,6 +2472,7 @@ static const struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, - 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) - { -+ struct sm6_value *value; - unsigned int idx; - uint64_t val_ref; - size_t operand; -@@ -2463,23 +2486,39 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru - if (operand == SIZE_MAX) - return SIZE_MAX; - -- if (operand >= sm6->value_count) -+ if (operand >= sm6->value_count && !fwd_type) - { -- if (!fwd_type) -+ /* Forward references are followed by a type id unless an earlier operand set the type, -+ * or it is contained in a function declaration. */ -+ if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) -+ return SIZE_MAX; -+ if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++]))) -+ return SIZE_MAX; -+ } -+ *rec_idx = idx; -+ -+ if (fwd_type) -+ { -+ value = &sm6->values[operand]; -+ if (value->type) - { -- /* Forward references are followed by a type id unless an earlier operand set the type, -- * or it is contained in a function declaration. */ -- if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) -- return SIZE_MAX; -- if (!(fwd_type = sm6_parser_get_type(sm6, record->operands[idx++]))) -- return SIZE_MAX; -+ if (value->type != fwd_type) -+ { -+ WARN("Value already has a mismatching type.\n"); -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, -+ "The type of a source value does not match the predefined type."); -+ } -+ } -+ else -+ { -+ value->type = fwd_type; -+ value->value_type = VALUE_TYPE_REG; -+ register_init_with_id(&value->u.reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type( -+ sm6_type_get_scalar_type(fwd_type, 0)), sm6_parser_alloc_ssa_id(sm6)); -+ value->u.reg.dimension = sm6_type_is_scalar(fwd_type) ? VSIR_DIMENSION_SCALAR -+ : VSIR_DIMENSION_VEC4; - } -- FIXME("Forward value references are not supported yet.\n"); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -- "Unsupported value forward reference."); -- return SIZE_MAX; - } -- *rec_idx = idx; - - return operand; - } -@@ -3476,7 +3515,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco - - dst_param_init(&dst_params[0]); - dst_param_init(&dst_params[1]); -- register_init_ssa_scalar(&dst_params[index].reg, a->type, sm6); -+ register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6); - vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); - dst->u.reg = dst_params[index].reg; - } -@@ -3547,47 +3586,36 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record - ins->handler_idx = VKD3DSIH_NOP; - } - --static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, -- const struct sm6_value *z_operand, struct function_emission_state *state, -- struct vkd3d_shader_register *reg) -+static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, -+ unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) - { -- const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; - struct vkd3d_shader_instruction *ins = state->ins; - struct vkd3d_shader_src_param *src_params; - struct vkd3d_shader_dst_param *dst_param; -- const unsigned int max_operands = 3; -- unsigned int i, component_count; - bool all_constant = true; -- -- for (component_count = 0; component_count < max_operands; ++component_count) -- { -- if (!z_operand && operands[component_count]->is_undefined) -- break; -- operand_regs[component_count] = &operands[component_count]->u.reg; -- all_constant &= register_is_constant_or_undef(operand_regs[component_count]); -- } -- if (z_operand) -- { -- all_constant &= register_is_constant(&z_operand->u.reg); -- operand_regs[component_count++] = &z_operand->u.reg; -- } -+ unsigned int i; - - if (component_count == 1) - { -- *reg = operands[0]->u.reg; -+ *reg = *operand_regs[0]; - return true; - } - -+ for (i = 0; i < component_count; ++i) -+ all_constant &= register_is_constant(operand_regs[i]); -+ - if (all_constant) - { - vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0]->data_type, 0); - reg->dimension = VSIR_DIMENSION_VEC4; - for (i = 0; i < component_count; ++i) - reg->u.immconst_u32[i] = operand_regs[i]->u.immconst_u32[0]; -+ for (; i < VKD3D_VEC4_SIZE; ++i) -+ reg->u.immconst_u32[i] = 0; - return true; - } - -- register_init_with_id(reg, VKD3DSPR_TEMP, operands[0]->u.reg.data_type, state->temp_idx++); -+ register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0]->data_type, state->temp_idx++); - reg->dimension = VSIR_DIMENSION_VEC4; - - for (i = 0; i < component_count; ++i, ++ins) -@@ -3613,6 +3641,40 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s - return true; - } - -+static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const struct sm6_value **operands, -+ unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) -+{ -+ const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; -+ unsigned int i; -+ -+ for (i = 0; i < component_count; ++i) -+ operand_regs[i] = &operands[i]->u.reg; -+ -+ return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); -+} -+ -+static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const struct sm6_value **operands, -+ const struct sm6_value *z_operand, struct function_emission_state *state, -+ struct vkd3d_shader_register *reg) -+{ -+ const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; -+ const unsigned int max_operands = 3; -+ unsigned int component_count; -+ -+ for (component_count = 0; component_count < max_operands; ++component_count) -+ { -+ if (!z_operand && operands[component_count]->is_undefined) -+ break; -+ operand_regs[component_count] = &operands[component_count]->u.reg; -+ } -+ if (z_operand) -+ { -+ operand_regs[component_count++] = &z_operand->u.reg; -+ } -+ -+ return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); -+} -+ - static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) - { - switch (op) -@@ -3625,6 +3687,18 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) - return VKD3DSIH_ISFINITE; - case DX_TAN: - return VKD3DSIH_TAN; -+ case DX_ACOS: -+ return VKD3DSIH_ACOS; -+ case DX_ASIN: -+ return VKD3DSIH_ASIN; -+ case DX_ATAN: -+ return VKD3DSIH_ATAN; -+ case DX_HCOS: -+ return VKD3DSIH_HCOS; -+ case DX_HSIN: -+ return VKD3DSIH_HSIN; -+ case DX_HTAN: -+ return VKD3DSIH_HTAN; - case DX_EXP: - return VKD3DSIH_EXP; - case DX_FRC: -@@ -3983,7 +4057,7 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ - dst_params = instruction_dst_params_alloc(ins, 2, sm6); - dst_param_init(&dst_params[0]); - dst_param_init(&dst_params[1]); -- register_init_ssa_scalar(&dst_params[index].reg, dst->type, sm6); -+ register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6); - vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); - dst->u.reg = dst_params[index].reg; - } -@@ -4099,6 +4173,56 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr - instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); - } - -+static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, -+ const struct sm6_value **operands, struct function_emission_state *state) -+{ -+ struct vkd3d_shader_register coord, texel; -+ struct vkd3d_shader_src_param *src_params; -+ struct vkd3d_shader_dst_param *dst_param; -+ unsigned int write_mask, component_count; -+ struct vkd3d_shader_instruction *ins; -+ const struct sm6_value *resource; -+ -+ resource = operands[0]; -+ if (!sm6_value_validate_is_texture_handle(resource, op, sm6)) -+ return; -+ -+ if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], NULL, state, &coord)) -+ return; -+ -+ write_mask = sm6_value_get_constant_uint(operands[8]); -+ if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) -+ { -+ WARN("Invalid write mask %#x.\n", write_mask); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Write mask %#x for a texture store operation is invalid.", write_mask); -+ return; -+ } -+ else if (write_mask & (write_mask + 1)) -+ { -+ /* In this case, it is unclear which source operands will be defined unless we encounter it in a shader. */ -+ FIXME("Unhandled write mask %#x.\n", write_mask); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Write mask %#x for a texture store operation is unhandled.", write_mask); -+ } -+ component_count = vsir_write_mask_component_count(write_mask); -+ -+ if (!sm6_parser_emit_composite_construct(sm6, &operands[4], component_count, state, &texel)) -+ return; -+ -+ ins = state->ins; -+ vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED); -+ -+ if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) -+ return; -+ src_param_init_vector_from_reg(&src_params[0], &coord); -+ src_param_init_vector_from_reg(&src_params[1], &texel); -+ -+ dst_param = instruction_dst_params_alloc(ins, 1, sm6); -+ dst_param->reg = resource->u.handle.reg; -+ dst_param_init_with_mask(dst_param, write_mask); -+} -+ - struct sm6_dx_opcode_info - { - const char *ret_type; -@@ -4127,6 +4251,9 @@ struct sm6_dx_opcode_info - */ - static const struct sm6_dx_opcode_info sm6_dx_op_table[] = - { -+ [DX_ACOS ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_ASIN ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_ATAN ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_BFREV ] = {"m", "R", sm6_parser_emit_dx_unary}, - [DX_BUFFER_LOAD ] = {"o", "Hii", sm6_parser_emit_dx_buffer_load}, - [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, -@@ -4145,6 +4272,9 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = - [DX_FMIN ] = {"g", "RR", sm6_parser_emit_dx_binary}, - [DX_FRC ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_IBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, -+ [DX_HCOS ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_HSIN ] = {"g", "R", sm6_parser_emit_dx_unary}, -+ [DX_HTAN ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_IMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, - [DX_IMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, - [DX_ISFINITE ] = {"1", "g", sm6_parser_emit_dx_unary}, -@@ -4166,6 +4296,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = - [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, - [DX_TAN ] = {"g", "R", sm6_parser_emit_dx_unary}, - [DX_TEXTURE_LOAD ] = {"o", "HiiiiCCC", sm6_parser_emit_dx_texture_load}, -+ [DX_TEXTURE_STORE ] = {"v", "Hiiiooooc", sm6_parser_emit_dx_texture_store}, - [DX_UBFE ] = {"m", "iiR", sm6_parser_emit_dx_tertiary}, - [DX_UMAX ] = {"m", "RR", sm6_parser_emit_dx_binary}, - [DX_UMIN ] = {"m", "RR", sm6_parser_emit_dx_binary}, -@@ -4725,8 +4856,8 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); - - src_param = instruction_src_params_alloc(ins, 1, sm6); -- src_param_init_scalar(src_param, elem_idx); - src_param->reg = src->u.reg; -+ src_param_init_scalar(src_param, elem_idx); - - instruction_dst_param_init_ssa_scalar(ins, sm6); - } -@@ -4919,7 +5050,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record - } - - dst->type = type; -- register_init_ssa_scalar(&dst->u.reg, type, sm6); -+ register_init_ssa_scalar(&dst->u.reg, type, dst, sm6); - - if (!(phi = sm6_block_phi_require_space(code_block, sm6))) - return; -@@ -5492,6 +5623,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - struct vkd3d_shader_instruction *ins; - size_t i, block_idx, block_count; - const struct dxil_record *record; -+ const struct sm6_type *fwd_type; - bool ret_found, is_terminator; - struct sm6_block *code_block; - struct sm6_value *dst; -@@ -5568,6 +5700,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - ins->handler_idx = VKD3DSIH_INVALID; - - dst = sm6_parser_get_current_value(sm6); -+ fwd_type = dst->type; - dst->type = NULL; - dst->value_type = VALUE_TYPE_REG; - is_terminator = false; -@@ -5647,6 +5780,13 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - else - assert(ins->handler_idx == VKD3DSIH_NOP); - -+ if (dst->type && fwd_type && dst->type != fwd_type) -+ { -+ WARN("Type mismatch.\n"); -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, -+ "The type of a result value does not match the type defined by a forward reference."); -+ } -+ - sm6->value_count += !!dst->type; - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index a0d6212cbf5..88634487482 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -470,6 +470,25 @@ static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned - dst->reg.idx[0].offset = idx; - } - -+static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx) -+{ -+ vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ dst->reg.idx[0].offset = idx; -+ dst->write_mask = VKD3DSP_WRITEMASK_0; -+} -+ -+static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx) -+{ -+ vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); -+ src->reg.idx[0].offset = idx; -+} -+ -+static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value) -+{ -+ vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); -+ src->reg.u.immconst_u32[0] = value; -+} -+ - void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, - enum vkd3d_shader_opcode handler_idx) - { -@@ -2637,6 +2656,359 @@ fail: - return VKD3D_ERROR_OUT_OF_MEMORY; - } - -+static void materialize_ssas_to_temps_process_src_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_src_param *src); -+ -+/* This is idempotent: it can be safely applied more than once on the -+ * same register. */ -+static void materialize_ssas_to_temps_process_reg(struct vkd3d_shader_parser *parser, struct vkd3d_shader_register *reg) -+{ -+ unsigned int i; -+ -+ if (reg->type == VKD3DSPR_SSA) -+ { -+ reg->type = VKD3DSPR_TEMP; -+ reg->idx[0].offset += parser->program.temp_count; -+ } -+ -+ for (i = 0; i < reg->idx_count; ++i) -+ if (reg->idx[i].rel_addr) -+ materialize_ssas_to_temps_process_src_param(parser, reg->idx[i].rel_addr); -+} -+ -+static void materialize_ssas_to_temps_process_dst_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_dst_param *dst) -+{ -+ materialize_ssas_to_temps_process_reg(parser, &dst->reg); -+} -+ -+static void materialize_ssas_to_temps_process_src_param(struct vkd3d_shader_parser *parser, struct vkd3d_shader_src_param *src) -+{ -+ materialize_ssas_to_temps_process_reg(parser, &src->reg); -+} -+ -+static const struct vkd3d_shader_src_param *materialize_ssas_to_temps_compute_source(struct vkd3d_shader_instruction *ins, -+ unsigned int label) -+{ -+ unsigned int i; -+ -+ assert(ins->handler_idx == VKD3DSIH_PHI); -+ -+ for (i = 0; i < ins->src_count; i += 2) -+ { -+ if (label_from_src_param(&ins->src[i + 1]) == label) -+ return &ins->src[i]; -+ } -+ -+ vkd3d_unreachable(); -+} -+ -+static bool materialize_ssas_to_temps_synthesize_mov(struct vkd3d_shader_parser *parser, -+ struct vkd3d_shader_instruction *instruction, const struct vkd3d_shader_location *loc, -+ const struct vkd3d_shader_dst_param *dest, const struct vkd3d_shader_src_param *cond, -+ const struct vkd3d_shader_src_param *source, bool invert) -+{ -+ struct vkd3d_shader_src_param *src; -+ struct vkd3d_shader_dst_param *dst; -+ -+ if (!vsir_instruction_init_with_params(&parser->program, instruction, loc, -+ cond ? VKD3DSIH_MOVC : VKD3DSIH_MOV, 1, cond ? 3 : 1)) -+ return false; -+ -+ dst = instruction->dst; -+ src = instruction->src; -+ -+ dst[0] = *dest; -+ materialize_ssas_to_temps_process_dst_param(parser, &dst[0]); -+ -+ assert(dst[0].write_mask == VKD3DSP_WRITEMASK_0); -+ assert(dst[0].modifiers == 0); -+ assert(dst[0].shift == 0); -+ -+ if (cond) -+ { -+ src[0] = *cond; -+ src[1 + invert] = *source; -+ memset(&src[2 - invert], 0, sizeof(src[2 - invert])); -+ src[2 - invert].reg = dst[0].reg; -+ materialize_ssas_to_temps_process_src_param(parser, &src[1]); -+ materialize_ssas_to_temps_process_src_param(parser, &src[2]); -+ } -+ else -+ { -+ src[0] = *source; -+ materialize_ssas_to_temps_process_src_param(parser, &src[0]); -+ } -+ -+ return true; -+} -+ -+static enum vkd3d_result materialize_ssas_to_temps(struct vkd3d_shader_parser *parser) -+{ -+ struct vkd3d_shader_instruction *instructions = NULL; -+ struct materialize_ssas_to_temps_block_data -+ { -+ size_t phi_begin; -+ size_t phi_count; -+ } *block_index = NULL; -+ size_t ins_capacity = 0, ins_count = 0, i; -+ unsigned int current_label = 0; -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, parser->program.instructions.count)) -+ goto fail; -+ -+ if (!(block_index = vkd3d_calloc(parser->program.block_count, sizeof(*block_index)))) -+ { -+ ERR("Failed to allocate block index.\n"); -+ goto fail; -+ } -+ -+ for (i = 0; i < parser->program.instructions.count; ++i) -+ { -+ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; -+ -+ switch (ins->handler_idx) -+ { -+ case VKD3DSIH_LABEL: -+ current_label = label_from_src_param(&ins->src[0]); -+ break; -+ -+ case VKD3DSIH_PHI: -+ assert(current_label != 0); -+ assert(i != 0); -+ if (block_index[current_label - 1].phi_begin == 0) -+ block_index[current_label - 1].phi_begin = i; -+ block_index[current_label - 1].phi_count += 1; -+ break; -+ -+ default: -+ current_label = 0; -+ break; -+ } -+ } -+ -+ for (i = 0; i < parser->program.instructions.count; ++i) -+ { -+ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; -+ size_t j; -+ -+ for (j = 0; j < ins->dst_count; ++j) -+ materialize_ssas_to_temps_process_dst_param(parser, &ins->dst[j]); -+ -+ for (j = 0; j < ins->src_count; ++j) -+ materialize_ssas_to_temps_process_src_param(parser, &ins->src[j]); -+ -+ switch (ins->handler_idx) -+ { -+ case VKD3DSIH_LABEL: -+ current_label = label_from_src_param(&ins->src[0]); -+ break; -+ -+ case VKD3DSIH_BRANCH: -+ { -+ if (vsir_register_is_label(&ins->src[0].reg)) -+ { -+ const struct materialize_ssas_to_temps_block_data *data = &block_index[label_from_src_param(&ins->src[0]) - 1]; -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + data->phi_count)) -+ goto fail; -+ -+ for (j = data->phi_begin; j < data->phi_begin + data->phi_count; ++j) -+ { -+ const struct vkd3d_shader_src_param *source; -+ -+ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); -+ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, -+ &parser->program.instructions.elements[j].dst[0], NULL, source, false)) -+ goto fail; -+ -+ ++ins_count; -+ } -+ } -+ else -+ { -+ struct materialize_ssas_to_temps_block_data *data_true = &block_index[label_from_src_param(&ins->src[1]) - 1], -+ *data_false = &block_index[label_from_src_param(&ins->src[2]) - 1]; -+ const struct vkd3d_shader_src_param *cond = &ins->src[0]; -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, -+ ins_count + data_true->phi_count + data_false->phi_count)) -+ goto fail; -+ -+ for (j = data_true->phi_begin; j < data_true->phi_begin + data_true->phi_count; ++j) -+ { -+ const struct vkd3d_shader_src_param *source; -+ -+ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); -+ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, -+ &parser->program.instructions.elements[j].dst[0], cond, source, false)) -+ goto fail; -+ -+ ++ins_count; -+ } -+ -+ for (j = data_false->phi_begin; j < data_false->phi_begin + data_false->phi_count; ++j) -+ { -+ const struct vkd3d_shader_src_param *source; -+ -+ source = materialize_ssas_to_temps_compute_source(&parser->program.instructions.elements[j], current_label); -+ if (!materialize_ssas_to_temps_synthesize_mov(parser, &instructions[ins_count], &ins->location, -+ &parser->program.instructions.elements[j].dst[0], cond, source, true)) -+ goto fail; -+ -+ ++ins_count; -+ } -+ } -+ break; -+ } -+ -+ case VKD3DSIH_PHI: -+ continue; -+ -+ default: -+ break; -+ } -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) -+ goto fail; -+ -+ instructions[ins_count++] = *ins; -+ } -+ -+ vkd3d_free(parser->program.instructions.elements); -+ vkd3d_free(block_index); -+ parser->program.instructions.elements = instructions; -+ parser->program.instructions.capacity = ins_capacity; -+ parser->program.instructions.count = ins_count; -+ parser->program.temp_count += parser->program.ssa_count; -+ parser->program.ssa_count = 0; -+ -+ return VKD3D_OK; -+ -+fail: -+ vkd3d_free(instructions); -+ vkd3d_free(block_index); -+ -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+} -+ -+static enum vkd3d_result simple_structurizer_run(struct vkd3d_shader_parser *parser) -+{ -+ const unsigned int block_temp_idx = parser->program.temp_count; -+ struct vkd3d_shader_instruction *instructions = NULL; -+ const struct vkd3d_shader_location no_loc = {0}; -+ size_t ins_capacity = 0, ins_count = 0, i; -+ bool first_label_found = false; -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, parser->program.instructions.count)) -+ goto fail; -+ -+ for (i = 0; i < parser->program.instructions.count; ++i) -+ { -+ struct vkd3d_shader_instruction *ins = &parser->program.instructions.elements[i]; -+ -+ switch (ins->handler_idx) -+ { -+ case VKD3DSIH_PHI: -+ case VKD3DSIH_SWITCH_MONOLITHIC: -+ vkd3d_unreachable(); -+ -+ case VKD3DSIH_LABEL: -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 4)) -+ goto fail; -+ -+ if (!first_label_found) -+ { -+ first_label_found = true; -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1)) -+ goto fail; -+ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); -+ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); -+ ins_count++; -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_LOOP, 0, 0)) -+ goto fail; -+ ins_count++; -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_SWITCH, 0, 1)) -+ goto fail; -+ src_param_init_temp_uint(&instructions[ins_count].src[0], block_temp_idx); -+ ins_count++; -+ } -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_CASE, 0, 1)) -+ goto fail; -+ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); -+ ins_count++; -+ break; -+ -+ case VKD3DSIH_BRANCH: -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 2)) -+ goto fail; -+ -+ if (vsir_register_is_label(&ins->src[0].reg)) -+ { -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOV, 1, 1)) -+ goto fail; -+ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); -+ src_param_init_const_uint(&instructions[ins_count].src[0], label_from_src_param(&ins->src[0])); -+ ins_count++; -+ } -+ else -+ { -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_MOVC, 1, 3)) -+ goto fail; -+ dst_param_init_temp_uint(&instructions[ins_count].dst[0], block_temp_idx); -+ instructions[ins_count].src[0] = ins->src[0]; -+ src_param_init_const_uint(&instructions[ins_count].src[1], label_from_src_param(&ins->src[1])); -+ src_param_init_const_uint(&instructions[ins_count].src[2], label_from_src_param(&ins->src[2])); -+ ins_count++; -+ } -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_BREAK, 0, 0)) -+ goto fail; -+ ins_count++; -+ break; -+ -+ case VKD3DSIH_RET: -+ default: -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) -+ goto fail; -+ -+ instructions[ins_count++] = *ins; -+ break; -+ } -+ } -+ -+ assert(first_label_found); -+ -+ if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 3)) -+ goto fail; -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDSWITCH, 0, 0)) -+ goto fail; -+ ins_count++; -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_ENDLOOP, 0, 0)) -+ goto fail; -+ ins_count++; -+ -+ if (!vsir_instruction_init_with_params(&parser->program, &instructions[ins_count], &no_loc, VKD3DSIH_RET, 0, 0)) -+ goto fail; -+ ins_count++; -+ -+ vkd3d_free(parser->program.instructions.elements); -+ parser->program.instructions.elements = instructions; -+ parser->program.instructions.capacity = ins_capacity; -+ parser->program.instructions.count = ins_count; -+ parser->program.temp_count += 1; -+ -+ return VKD3D_OK; -+ -+fail: -+ vkd3d_free(instructions); -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+} -+ - enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, - const struct vkd3d_shader_compile_info *compile_info) - { -@@ -2652,6 +3024,12 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, - { - if ((result = lower_switch_to_if_ladder(&parser->program)) < 0) - return result; -+ -+ if ((result = materialize_ssas_to_temps(parser)) < 0) -+ return result; -+ -+ if ((result = simple_structurizer_run(parser)) < 0) -+ return result; - } - else - { -@@ -2679,13 +3057,13 @@ enum vkd3d_result vkd3d_shader_normalise(struct vkd3d_shader_parser *parser, - - remove_dead_code(&parser->program); - -- if ((result = flatten_control_flow_constructs(parser)) < 0) -- return result; -- - if ((result = normalise_combined_samplers(parser)) < 0) - return result; - } - -+ if ((result = flatten_control_flow_constructs(parser)) < 0) -+ return result; -+ - if (TRACE_ON()) - vkd3d_shader_trace(&parser->program); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 9b6ce742976..6c92b03b216 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -3669,6 +3669,73 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil - type_id, vector1_id, vector2_id, components, component_count); - } - -+static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, -+ enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, -+ unsigned int component_count, uint32_t val_id) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ uint32_t type_id; -+ SpvOp op; -+ -+ assert(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); -+ -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; -+ return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, -+ data_type == VKD3D_DATA_UINT64 -+ ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) -+ : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); -+} -+ -+static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, -+ unsigned int component_count, uint32_t val_id, bool signedness) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ uint32_t type_id, true_id, false_id; -+ -+ true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); -+ false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); -+ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); -+} -+ -+static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler, -+ unsigned int component_count, uint32_t val_id, bool signedness) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ uint32_t type_id, true_id, false_id; -+ -+ true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, -+ component_count); -+ false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); -+ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); -+} -+ -+static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, -+ unsigned int component_count, uint32_t val_id, bool signedness) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ uint32_t type_id, true_id, false_id; -+ -+ true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); -+ false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); -+} -+ -+static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compiler, -+ unsigned int component_count, uint32_t val_id, bool signedness) -+{ -+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -+ uint32_t type_id, true_id, false_id; -+ -+ true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); -+ false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); -+ return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); -+} -+ - static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) - { -@@ -3777,8 +3844,21 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, - - if (component_type != reg_info->component_type) - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -+ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) -+ { -+ if (reg_info->component_type != VKD3D_SHADER_COMPONENT_UINT) -+ { -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -+ } -+ val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, -+ VKD3D_DATA_UINT, 1, val_id); -+ } -+ else -+ { -+ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -+ } - } - - return val_id; -@@ -3965,8 +4045,21 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - - if (component_type != reg_info.component_type) - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -- val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -+ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) -+ { -+ if (reg_info.component_type != VKD3D_SHADER_COMPONENT_UINT) -+ { -+ type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); -+ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -+ } -+ val_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, -+ VKD3D_DATA_UINT, component_count, val_id); -+ } -+ else -+ { -+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -+ } - } - - return val_id; -@@ -4160,6 +4253,9 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, - { - if (data_type_is_64_bit(reg->data_type)) - src_write_mask = vsir_write_mask_32_from_64(write_mask); -+ if (component_type == VKD3D_SHADER_COMPONENT_BOOL) -+ val_id = spirv_compiler_emit_bool_to_int(compiler, -+ vsir_write_mask_component_count(src_write_mask), val_id, false); - type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, - vsir_write_mask_component_count(src_write_mask)); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); -@@ -4383,73 +4479,6 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler - } - } - --static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, -- enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, -- unsigned int component_count, uint32_t val_id) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id; -- SpvOp op; -- -- assert(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); -- -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -- op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; -- return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, -- data_type == VKD3D_DATA_UINT64 -- ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) -- : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); --} -- --static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, -- unsigned int component_count, uint32_t val_id, bool signedness) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id, true_id, false_id; -- -- true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); -- false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); -- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); --} -- --static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compiler, -- unsigned int component_count, uint32_t val_id, bool signedness) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id, true_id, false_id; -- -- true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, -- component_count); -- false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); -- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); --} -- --static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compiler, -- unsigned int component_count, uint32_t val_id, bool signedness) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id, true_id, false_id; -- -- true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); -- false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); --} -- --static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compiler, -- unsigned int component_count, uint32_t val_id, bool signedness) --{ -- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- uint32_t type_id, true_id, false_id; -- -- true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); -- false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); -- return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); --} -- - typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct spirv_compiler *compiler, - uint32_t val_id); - -@@ -6968,6 +6997,9 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( - } - glsl_insts[] = - { -+ {VKD3DSIH_ACOS, GLSLstd450Acos}, -+ {VKD3DSIH_ASIN, GLSLstd450Asin}, -+ {VKD3DSIH_ATAN, GLSLstd450Atan}, - {VKD3DSIH_DFMA, GLSLstd450Fma}, - {VKD3DSIH_DMAX, GLSLstd450NMax}, - {VKD3DSIH_DMIN, GLSLstd450NMin}, -@@ -6976,6 +7008,9 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( - {VKD3DSIH_FIRSTBIT_LO, GLSLstd450FindILsb}, - {VKD3DSIH_FIRSTBIT_SHI, GLSLstd450FindSMsb}, - {VKD3DSIH_FRC, GLSLstd450Fract}, -+ {VKD3DSIH_HCOS, GLSLstd450Cosh}, -+ {VKD3DSIH_HSIN, GLSLstd450Sinh}, -+ {VKD3DSIH_HTAN, GLSLstd450Tanh}, - {VKD3DSIH_IMAX, GLSLstd450SMax}, - {VKD3DSIH_IMIN, GLSLstd450SMin}, - {VKD3DSIH_LOG, GLSLstd450Log2}, -@@ -7082,7 +7117,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, - } - - write_mask32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_write_mask_32_from_64(dst->write_mask) : dst->write_mask; -- swizzle32 = data_type_is_64_bit(dst->reg.data_type) ? vsir_swizzle_32_from_64(src->swizzle) : src->swizzle; -+ swizzle32 = data_type_is_64_bit(src->reg.data_type) ? vsir_swizzle_32_from_64(src->swizzle) : src->swizzle; - component_count = vsir_write_mask_component_count(write_mask32); - if (component_count != 1 && component_count != VKD3D_VEC4_SIZE - && dst_reg_info.write_mask == VKD3DSP_WRITEMASK_ALL) -@@ -9552,6 +9587,12 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - case VKD3DSIH_ISFINITE: - spirv_compiler_emit_isfinite(compiler, instruction); - break; -+ case VKD3DSIH_ACOS: -+ case VKD3DSIH_ASIN: -+ case VKD3DSIH_ATAN: -+ case VKD3DSIH_HCOS: -+ case VKD3DSIH_HSIN: -+ case VKD3DSIH_HTAN: - case VKD3DSIH_DFMA: - case VKD3DSIH_DMAX: - case VKD3DSIH_DMIN: -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index a709121f1a1..acfd39b7643 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -225,8 +225,11 @@ enum vkd3d_shader_error - enum vkd3d_shader_opcode - { - VKD3DSIH_ABS, -+ VKD3DSIH_ACOS, - VKD3DSIH_ADD, - VKD3DSIH_AND, -+ VKD3DSIH_ASIN, -+ VKD3DSIH_ATAN, - VKD3DSIH_ATOMIC_AND, - VKD3DSIH_ATOMIC_CMP_STORE, - VKD3DSIH_ATOMIC_IADD, -@@ -363,10 +366,13 @@ enum vkd3d_shader_opcode - VKD3DSIH_GATHER4_S, - VKD3DSIH_GEO, - VKD3DSIH_GEU, -+ VKD3DSIH_HCOS, - VKD3DSIH_HS_CONTROL_POINT_PHASE, - VKD3DSIH_HS_DECLS, - VKD3DSIH_HS_FORK_PHASE, - VKD3DSIH_HS_JOIN_PHASE, -+ VKD3DSIH_HSIN, -+ VKD3DSIH_HTAN, - VKD3DSIH_IADD, - VKD3DSIH_IBFE, - VKD3DSIH_IDIV, -diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index f9940b3d383..8a47dc494f7 100644 ---- a/libs/vkd3d/libs/vkd3d/command.c -+++ b/libs/vkd3d/libs/vkd3d/command.c -@@ -1921,12 +1921,12 @@ HRESULT d3d12_command_allocator_create(struct d3d12_device *device, - - static void d3d12_command_signature_incref(struct d3d12_command_signature *signature) - { -- vkd3d_atomic_increment(&signature->internal_refcount); -+ vkd3d_atomic_increment_u32(&signature->internal_refcount); - } - - static void d3d12_command_signature_decref(struct d3d12_command_signature *signature) - { -- unsigned int refcount = vkd3d_atomic_decrement(&signature->internal_refcount); -+ unsigned int refcount = vkd3d_atomic_decrement_u32(&signature->internal_refcount); - - if (!refcount) - { -@@ -4499,8 +4499,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I - { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); - -- TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", -- iface, root_parameter_index, base_descriptor.ptr); -+ TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n", -+ iface, root_parameter_index, debug_gpu_handle(base_descriptor)); - - d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_COMPUTE, - root_parameter_index, base_descriptor); -@@ -4511,8 +4511,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootDescriptorTable( - { - struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList5(iface); - -- TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", -- iface, root_parameter_index, base_descriptor.ptr); -+ TRACE("iface %p, root_parameter_index %u, base_descriptor %s.\n", -+ iface, root_parameter_index, debug_gpu_handle(base_descriptor)); - - d3d12_command_list_set_descriptor_table(list, VKD3D_PIPELINE_BIND_POINT_GRAPHICS, - root_parameter_index, base_descriptor); -@@ -5432,8 +5432,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID - struct d3d12_resource *resource_impl; - VkClearColorValue colour; - -- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", -- iface, gpu_handle.ptr, debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); -+ TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", -+ iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); - - resource_impl = unsafe_impl_from_ID3D12Resource(resource); - if (!(descriptor = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) -@@ -5496,8 +5496,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I - VkClearColorValue colour; - struct vkd3d_view *view; - -- TRACE("iface %p, gpu_handle %#"PRIx64", cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", -- iface, gpu_handle.ptr, debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); -+ TRACE("iface %p, gpu_handle %s, cpu_handle %s, resource %p, values %p, rect_count %u, rects %p.\n", -+ iface, debug_gpu_handle(gpu_handle), debug_cpu_handle(cpu_handle), resource, values, rect_count, rects); - - resource_impl = unsafe_impl_from_ID3D12Resource(resource); - if (!(view = d3d12_desc_from_cpu_handle(cpu_handle)->s.u.view)) -@@ -5963,15 +5963,15 @@ static void STDMETHODCALLTYPE d3d12_command_list_EndRenderPass(ID3D12GraphicsCom - static void STDMETHODCALLTYPE d3d12_command_list_InitializeMetaCommand(ID3D12GraphicsCommandList5 *iface, - ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) - { -- FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, -- meta_command, parameters_data, data_size_in_bytes); -+ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface, -+ meta_command, parameters_data, (uintptr_t)data_size_in_bytes); - } - - static void STDMETHODCALLTYPE d3d12_command_list_ExecuteMetaCommand(ID3D12GraphicsCommandList5 *iface, - ID3D12MetaCommand *meta_command, const void *parameters_data, SIZE_T data_size_in_bytes) - { -- FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %lu stub!\n", iface, -- meta_command, parameters_data, data_size_in_bytes); -+ FIXME("iface %p, meta_command %p, parameters_data %p, data_size_in_bytes %"PRIuPTR" stub!\n", iface, -+ meta_command, parameters_data, (uintptr_t)data_size_in_bytes); - } - - static void STDMETHODCALLTYPE d3d12_command_list_BuildRaytracingAccelerationStructure(ID3D12GraphicsCommandList5 *iface, -diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index cf8b506fdf5..90272818b3d 100644 ---- a/libs/vkd3d/libs/vkd3d/device.c -+++ b/libs/vkd3d/libs/vkd3d/device.c -@@ -3348,6 +3348,91 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device7 - return S_OK; - } - -+ case D3D12_FEATURE_D3D12_OPTIONS6: -+ { -+ D3D12_FEATURE_DATA_D3D12_OPTIONS6 *data = feature_data; -+ -+ if (feature_data_size != sizeof(*data)) -+ { -+ WARN("Invalid size %u.\n", feature_data_size); -+ return E_INVALIDARG; -+ } -+ -+ data->AdditionalShadingRatesSupported = FALSE; -+ data->PerPrimitiveShadingRateSupportedWithViewportIndexing = FALSE; -+ data->VariableShadingRateTier = D3D12_VARIABLE_SHADING_RATE_TIER_NOT_SUPPORTED; -+ data->ShadingRateImageTileSize = 0; -+ data->BackgroundProcessingSupported = FALSE; -+ -+ TRACE("Additional shading rates support %#x.\n", data->AdditionalShadingRatesSupported); -+ TRACE("Per-primitive shading rates with viewport indexing %#x.\n", -+ data->PerPrimitiveShadingRateSupportedWithViewportIndexing); -+ TRACE("Variable shading rate tier %#x.\n", data->VariableShadingRateTier); -+ TRACE("Shading rate image tile size %#x.\n", data->ShadingRateImageTileSize); -+ TRACE("Background processing support %#x.\n", data->BackgroundProcessingSupported); -+ return S_OK; -+ } -+ -+ case D3D12_FEATURE_D3D12_OPTIONS7: -+ { -+ D3D12_FEATURE_DATA_D3D12_OPTIONS7 *data = feature_data; -+ -+ if (feature_data_size != sizeof(*data)) -+ { -+ WARN("Invalid size %u.\n", feature_data_size); -+ return E_INVALIDARG; -+ } -+ -+ data->MeshShaderTier = D3D12_MESH_SHADER_TIER_NOT_SUPPORTED; -+ data->SamplerFeedbackTier = D3D12_SAMPLER_FEEDBACK_TIER_NOT_SUPPORTED; -+ -+ TRACE("Mesh shading tier %#x.\n", data->MeshShaderTier); -+ TRACE("Sampler feedback tier %#x.\n", data->SamplerFeedbackTier); -+ return S_OK; -+ } -+ -+ case D3D12_FEATURE_D3D12_OPTIONS8: -+ { -+ D3D12_FEATURE_DATA_D3D12_OPTIONS8 *data = feature_data; -+ -+ if (feature_data_size != sizeof(*data)) -+ { -+ WARN("Invalid size %u.\n", feature_data_size); -+ return E_INVALIDARG; -+ } -+ -+ data->UnalignedBlockTexturesSupported = FALSE; -+ -+ TRACE("Unaligned block texture support %#x.\n", data->UnalignedBlockTexturesSupported); -+ return S_OK; -+ } -+ -+ case D3D12_FEATURE_D3D12_OPTIONS9: -+ { -+ D3D12_FEATURE_DATA_D3D12_OPTIONS9 *data = feature_data; -+ -+ if (feature_data_size != sizeof(*data)) -+ { -+ WARN("Invalid size %u.\n", feature_data_size); -+ return E_INVALIDARG; -+ } -+ -+ data->MeshShaderPipelineStatsSupported = FALSE; -+ data->MeshShaderSupportsFullRangeRenderTargetArrayIndex = FALSE; -+ data->AtomicInt64OnTypedResourceSupported = FALSE; -+ data->AtomicInt64OnGroupSharedSupported = FALSE; -+ data->DerivativesInMeshAndAmplificationShadersSupported = FALSE; -+ data->WaveMMATier = D3D12_WAVE_MMA_TIER_NOT_SUPPORTED; -+ -+ TRACE("Mesh shader pipeline stats support %#x.\n", data->MeshShaderPipelineStatsSupported); -+ TRACE("Mesh shader RT array index full range %#x.\n", data->MeshShaderSupportsFullRangeRenderTargetArrayIndex); -+ TRACE("Atomic int64 on typed resource %#x.\n", data->AtomicInt64OnTypedResourceSupported); -+ TRACE("Atomic int64 on group shared mem %#x.\n", data->AtomicInt64OnGroupSharedSupported); -+ TRACE("Derivatives in mesh and amp shaders %#x.\n", data->DerivativesInMeshAndAmplificationShadersSupported); -+ TRACE("Wave MMA tier %#x.\n", data->WaveMMATier); -+ return S_OK; -+ } -+ - default: - FIXME("Unhandled feature %#x.\n", feature); - return E_NOTIMPL; -@@ -3402,8 +3487,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device7 - struct d3d12_root_signature *object; - HRESULT hr; - -- TRACE("iface %p, node_mask 0x%08x, bytecode %p, bytecode_length %lu, riid %s, root_signature %p.\n", -- iface, node_mask, bytecode, bytecode_length, debugstr_guid(riid), root_signature); -+ TRACE("iface %p, node_mask 0x%08x, bytecode %p, bytecode_length %"PRIuPTR", riid %s, root_signature %p.\n", -+ iface, node_mask, bytecode, (uintptr_t)bytecode_length, debugstr_guid(riid), root_signature); - - debug_ignored_node_mask(node_mask); - -@@ -4040,7 +4125,8 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device7 *iface - static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device7 *iface, - const void *blob, SIZE_T blob_size, REFIID iid, void **lib) - { -- FIXME("iface %p, blob %p, blob_size %lu, iid %s, lib %p stub!\n", iface, blob, blob_size, debugstr_guid(iid), lib); -+ FIXME("iface %p, blob %p, blob_size %"PRIuPTR", iid %s, lib %p stub!\n", -+ iface, blob, (uintptr_t)blob_size, debugstr_guid(iid), lib); - - return DXGI_ERROR_UNSUPPORTED; - } -@@ -4237,9 +4323,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateMetaCommand(ID3D12Device7 *i - SIZE_T data_size_in_bytes, REFIID iid, void **meta_command) - { - FIXME("iface %p, command_id %s, node_mask %#x, parameters_data %p, " -- "data_size_in_bytes %lu, iid %s, meta_command %p stub!\n", iface, -+ "data_size_in_bytes %"PRIuPTR", iid %s, meta_command %p stub!\n", iface, - debugstr_guid(command_id), node_mask, parameters_data, -- data_size_in_bytes, debugstr_guid(iid), meta_command); -+ (uintptr_t)data_size_in_bytes, debugstr_guid(iid), meta_command); - - return E_NOTIMPL; - } -diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index c04f48702a0..8f4d18358d2 100644 ---- a/libs/vkd3d/libs/vkd3d/resource.c -+++ b/libs/vkd3d/libs/vkd3d/resource.c -@@ -2314,14 +2314,14 @@ static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache) - - STATIC_ASSERT(!(ARRAY_SIZE(cache->heads) & HEAD_INDEX_MASK)); - -- i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; -+ i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK; - for (;;) - { - if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) - { - if ((u.object = cache->heads[i].head)) - { -- vkd3d_atomic_decrement(&cache->free_count); -+ vkd3d_atomic_decrement_u32(&cache->free_count); - cache->heads[i].head = u.header->next; - vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); - return u.object; -@@ -2345,7 +2345,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, - - /* Using the same index as above may result in a somewhat uneven distribution, - * but the main objective is to avoid costly spinlock contention. */ -- i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; -+ i = vkd3d_atomic_increment_u32(&cache->next_index) & HEAD_INDEX_MASK; - for (;;) - { - if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) -@@ -2357,7 +2357,7 @@ static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, - u.header->next = head; - cache->heads[i].head = u.object; - vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); -- vkd3d_atomic_increment(&cache->free_count); -+ vkd3d_atomic_increment_u32(&cache->free_count); - } - - #undef HEAD_INDEX_MASK -@@ -2429,7 +2429,7 @@ void vkd3d_view_decref(void *view, struct d3d12_device *device) - { - union d3d12_desc_object u = {view}; - -- if (vkd3d_atomic_decrement(&u.header->refcount)) -+ if (vkd3d_atomic_decrement_u32(&u.header->refcount)) - return; - - if (u.header->magic != VKD3D_DESCRIPTOR_MAGIC_CBV) -diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c -index 28913a83e8c..ac79ae5ddff 100644 ---- a/libs/vkd3d/libs/vkd3d/utils.c -+++ b/libs/vkd3d/libs/vkd3d/utils.c -@@ -678,6 +678,11 @@ const char *debug_d3d12_shader_component_mapping(unsigned int mapping) - debug_d3d12_shader_component(D3D12_DECODE_SHADER_4_COMPONENT_MAPPING(3, mapping))); - } - -+const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle) -+{ -+ return vkd3d_dbg_sprintf("{%#"PRIx64"}", handle.ptr); -+} -+ - const char *debug_vk_extent_3d(VkExtent3D extent) - { - return vkd3d_dbg_sprintf("(%u, %u, %u)", -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c -index f71b370137f..7919b7d8760 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c -@@ -222,8 +222,8 @@ HRESULT vkd3d_create_root_signature_deserializer(const void *data, SIZE_T data_s - struct d3d12_root_signature_deserializer *object; - HRESULT hr; - -- TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", -- data, data_size, debugstr_guid(iid), deserializer); -+ TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", -+ data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); - - if (!(object = vkd3d_malloc(sizeof(*object)))) - return E_OUTOFMEMORY; -@@ -406,8 +406,8 @@ HRESULT vkd3d_create_versioned_root_signature_deserializer(const void *data, SIZ - struct vkd3d_shader_code dxbc = {data, data_size}; - HRESULT hr; - -- TRACE("data %p, data_size %lu, iid %s, deserializer %p.\n", -- data, data_size, debugstr_guid(iid), deserializer); -+ TRACE("data %p, data_size %"PRIuPTR", iid %s, deserializer %p.\n", -+ data, (uintptr_t)data_size, debugstr_guid(iid), deserializer); - - if (!(object = vkd3d_malloc(sizeof(*object)))) - return E_OUTOFMEMORY; -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index 8ecf6764ab6..78f4f3514e2 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -@@ -257,16 +257,6 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) - { - } - --static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) --{ -- return InterlockedIncrement((LONG volatile *)x); --} -- --static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) --{ -- return InterlockedDecrement((LONG volatile *)x); --} -- - static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg) - { - return InterlockedCompareExchange((LONG volatile *)x, xchg, cmp) == cmp; -@@ -389,24 +379,6 @@ static inline void vkd3d_cond_destroy(struct vkd3d_cond *cond) - ERR("Could not destroy the condition variable, error %d.\n", ret); - } - --# if HAVE_SYNC_SUB_AND_FETCH --static inline unsigned int vkd3d_atomic_decrement(unsigned int volatile *x) --{ -- return __sync_sub_and_fetch(x, 1); --} --# else --# error "vkd3d_atomic_decrement() not implemented for this platform" --# endif /* HAVE_SYNC_SUB_AND_FETCH */ -- --# if HAVE_SYNC_ADD_AND_FETCH --static inline unsigned int vkd3d_atomic_increment(unsigned int volatile *x) --{ -- return __sync_add_and_fetch(x, 1); --} --# else --# error "vkd3d_atomic_increment() not implemented for this platform" --# endif /* HAVE_SYNC_ADD_AND_FETCH */ -- - # if HAVE_SYNC_BOOL_COMPARE_AND_SWAP - static inline bool vkd3d_atomic_compare_exchange(unsigned int volatile *x, unsigned int cmp, unsigned int xchg) - { -@@ -1963,6 +1935,7 @@ HRESULT return_interface(void *iface, REFIID iface_iid, REFIID requested_iid, vo - const char *debug_cpu_handle(D3D12_CPU_DESCRIPTOR_HANDLE handle); - const char *debug_d3d12_box(const D3D12_BOX *box); - const char *debug_d3d12_shader_component_mapping(unsigned int mapping); -+const char *debug_gpu_handle(D3D12_GPU_DESCRIPTOR_HANDLE handle); - const char *debug_vk_extent_3d(VkExtent3D extent); - const char *debug_vk_memory_heap_flags(VkMemoryHeapFlags flags); - const char *debug_vk_memory_property_flags(VkMemoryPropertyFlags flags); --- -2.43.0 - diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-5eba031fa1c7f606ffacf3cb7310615728d.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-5eba031fa1c7f606ffacf3cb7310615728d.patch deleted file mode 100644 index fa9314b1..00000000 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-5eba031fa1c7f606ffacf3cb7310615728d.patch +++ /dev/null @@ -1,113 +0,0 @@ -From ed09b9ae4c28d9a6b6d3a47cfe2de6bf6791db8f Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Sat, 10 Feb 2024 18:23:30 +1100 -Subject: [PATCH 5/5] Updated vkd3d to - 5eba031fa1c7f606ffacf3cb7310615728d150f0. - ---- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 18 ++++++++++++++++-- - libs/vkd3d/libs/vkd3d/device.c | 4 ++-- - 2 files changed, 18 insertions(+), 4 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 8dc353e11c0..5f6334a4d19 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -5572,11 +5572,11 @@ attribute: - $$->name = $2; - hlsl_block_init(&$$->instrs); - hlsl_block_add_block(&$$->instrs, $4.instrs); -- vkd3d_free($4.instrs); - $$->loc = @$; - $$->args_count = $4.args_count; - for (i = 0; i < $4.args_count; ++i) - hlsl_src_from_node(&$$->args[i], $4.args[i]); -+ free_parse_initializer(&$4); - } - - attribute_list: -@@ -5807,7 +5807,11 @@ func_prototype: - } - else - { -- free($1.attrs); -+ unsigned int i; -+ -+ for (i = 0; i < $1.count; ++i) -+ hlsl_free_attribute((void *)$1.attrs[i]); -+ vkd3d_free($1.attrs); - } - $$ = $2; - } -@@ -6992,8 +6996,10 @@ primary_expr: - if (!(var = hlsl_get_var(ctx->cur_scope, $1))) - { - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Variable \"%s\" is not defined.", $1); -+ vkd3d_free($1); - YYABORT; - } -+ vkd3d_free($1); - if (!(load = hlsl_new_var_load(ctx, var, &@1))) - YYABORT; - if (!($$ = make_block(ctx, &load->node))) -@@ -7067,12 +7073,17 @@ postfix_expr: - if (!(field = get_struct_field(type->e.record.fields, type->e.record.field_count, $3))) - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field \"%s\" is not defined.", $3); -+ vkd3d_free($3); - YYABORT; - } - - field_idx = field - type->e.record.fields; - if (!add_record_access(ctx, $1, node, field_idx, &@2)) -+ { -+ vkd3d_free($3); - YYABORT; -+ } -+ vkd3d_free($3); - $$ = $1; - } - else if (hlsl_is_numeric_type(node->data_type)) -@@ -7082,14 +7093,17 @@ postfix_expr: - if (!(swizzle = get_swizzle(ctx, node, $3, &@3))) - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle \"%s\".", $3); -+ vkd3d_free($3); - YYABORT; - } - hlsl_block_add_instr($1, swizzle); -+ vkd3d_free($3); - $$ = $1; - } - else - { - hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript \"%s\".", $3); -+ vkd3d_free($3); - YYABORT; - } - } -diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index 90272818b3d..1e094690f42 100644 ---- a/libs/vkd3d/libs/vkd3d/device.c -+++ b/libs/vkd3d/libs/vkd3d/device.c -@@ -3888,7 +3888,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device7 * - struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - FIXME("iface %p, object %p, attributes %p, access %#x, name %s, handle %p stub!\n", -- iface, object, attributes, access, debugstr_w(name, device->wchar_size), handle); -+ iface, object, attributes, (uint32_t)access, debugstr_w(name, device->wchar_size), handle); - - return E_NOTIMPL; - } -@@ -3908,7 +3908,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic - struct d3d12_device *device = impl_from_ID3D12Device7(iface); - - FIXME("iface %p, name %s, access %#x, handle %p stub!\n", -- iface, debugstr_w(name, device->wchar_size), access, handle); -+ iface, debugstr_w(name, device->wchar_size), (uint32_t)access, handle); - - return E_NOTIMPL; - } --- -2.43.0 -