From c4da0a89937007b4bb2691491fb3d74ca866e0bc Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 20 Sep 2023 08:16:07 +1000 Subject: [PATCH] Rebase against 6558611fa2d24447297cb62d168b924c33839c43. --- ...lement-IDirectMusicSegment8-Download.patch | 47 +- ...nd-in-IDirectMusicPerformance8-PlayS.patch | 22 +- ...771e442af16228a977eebba82224f06f6d02.patch | 4 +- ...46c7f65be8337a108a04a616ccd0c8a7732.patch} | 4802 +++++++++++++---- ...-622311da8e87c60110329044e29b88dd524.patch | 1097 ---- ...-269747dbf3ee32bf23e6d1ab388d2a058ca.patch | 947 ---- ...-a597dc8755af5d2ef4826f1b570927379af.patch | 1608 ------ ...-ee28861837c825818ace2e1e50825ade87a.patch | 432 -- staging/upstream-commit | 2 +- 9 files changed, 3930 insertions(+), 5031 deletions(-) rename patches/vkd3d-latest/{0002-Updated-vkd3d-to-4f2e07a45d0cdb82b1cbba0cfe95c87a697.patch => 0002-Updated-vkd3d-to-46c7f65be8337a108a04a616ccd0c8a7732.patch} (79%) delete mode 100644 patches/vkd3d-latest/0003-Updated-vkd3d-to-622311da8e87c60110329044e29b88dd524.patch delete mode 100644 patches/vkd3d-latest/0004-Updated-vkd3d-to-269747dbf3ee32bf23e6d1ab388d2a058ca.patch delete mode 100644 patches/vkd3d-latest/0005-Updated-vkd3d-to-a597dc8755af5d2ef4826f1b570927379af.patch delete mode 100644 patches/vkd3d-latest/0006-Updated-vkd3d-to-ee28861837c825818ace2e1e50825ade87a.patch diff --git a/patches/dmime-load-wave/0002-dmime-Implement-IDirectMusicSegment8-Download.patch b/patches/dmime-load-wave/0002-dmime-Implement-IDirectMusicSegment8-Download.patch index 1fd58926..cdb7f2a3 100644 --- a/patches/dmime-load-wave/0002-dmime-Implement-IDirectMusicSegment8-Download.patch +++ b/patches/dmime-load-wave/0002-dmime-Implement-IDirectMusicSegment8-Download.patch @@ -1,19 +1,19 @@ -From 87bf08071997f446498bdea2d18d1bb539a1990e Mon Sep 17 00:00:00 2001 +From cdbd2714d5454e6518b699e3cdbedd3e0a1243c5 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Fri, 2 Dec 2022 14:41:30 +1100 Subject: [PATCH] dmime: Implement IDirectMusicSegment8 Download --- dlls/dmime/dmime_private.h | 2 + - dlls/dmime/performance.c | 7 +++ - dlls/dmime/segment.c | 87 ++++++++++++++++++++++++++++++++++++-- - 3 files changed, 93 insertions(+), 3 deletions(-) + dlls/dmime/performance.c | 7 ++++ + dlls/dmime/segment.c | 80 +++++++++++++++++++++++++++++++++++++- + 3 files changed, 88 insertions(+), 1 deletion(-) diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h -index 6102fd5ec2f..da40b58ad9b 100644 +index eacde4b46be..cd34378b66e 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h -@@ -71,6 +71,8 @@ extern void set_audiopath_perf_pointer(IDirectMusicAudioPath*,IDirectMusicPerfor +@@ -70,6 +70,8 @@ extern void set_audiopath_perf_pointer(IDirectMusicAudioPath*,IDirectMusicPerfor extern void set_audiopath_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffer*); extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffer*); @@ -23,10 +23,10 @@ index 6102fd5ec2f..da40b58ad9b 100644 * Auxiliary definitions */ diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c -index 1f8de0837d5..622939f3553 100644 +index d8624427423..a707de39d50 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c -@@ -253,6 +253,13 @@ static inline struct performance *impl_from_IDirectMusicPerformance8(IDirectMusi +@@ -251,6 +251,13 @@ static inline struct performance *impl_from_IDirectMusicPerformance8(IDirectMusi return CONTAINING_RECORD(iface, struct performance, IDirectMusicPerformance8_iface); } @@ -41,34 +41,31 @@ index 1f8de0837d5..622939f3553 100644 static HRESULT WINAPI performance_QueryInterface(IDirectMusicPerformance8 *iface, REFIID riid, void **ret_iface) { diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c -index 39a5333fbbb..ce49ddc9940 100644 +index a72ec786623..ebee90eee92 100644 --- a/dlls/dmime/segment.c +++ b/dlls/dmime/segment.c -@@ -37,6 +37,7 @@ typedef struct IDirectMusicSegment8Impl { +@@ -54,6 +54,7 @@ struct segment PCMWAVEFORMAT wave_format; void *wave_data; int data_size; + IDirectSoundBuffer *buffer; - } IDirectMusicSegment8Impl; + }; - IDirectMusicSegment8Impl *create_segment(void); -@@ -90,6 +91,8 @@ static ULONG WINAPI IDirectMusicSegment8Impl_Release(IDirectMusicSegment8 *iface - TRACE("(%p) ref=%ld\n", This, ref); + static struct segment *segment_create(void); +@@ -114,6 +115,8 @@ static ULONG WINAPI segment_Release(IDirectMusicSegment8 *iface) + track_entry_destroy(entry); + } - if (!ref) { + if (This->buffer) + IDirectSoundBuffer_Release(This->buffer); if (This->wave_data) free(This->wave_data); -@@ -559,9 +562,87 @@ static HRESULT WINAPI IDirectMusicSegment8Impl_Compose(IDirectMusicSegment8 *ifa - static HRESULT WINAPI IDirectMusicSegment8Impl_Download(IDirectMusicSegment8 *iface, - IUnknown *pAudioPath) +@@ -517,7 +520,82 @@ static HRESULT WINAPI segment_Compose(IDirectMusicSegment8 *iface, MUSIC_TIME mt + static HRESULT WINAPI segment_Download(IDirectMusicSegment8 *iface, IUnknown *pAudioPath) { -- IDirectMusicSegment8Impl *This = impl_from_IDirectMusicSegment8(iface); -- FIXME("(%p, %p): stub\n", This, pAudioPath); -- return S_OK; -+ IDirectMusicSegment8Impl *This = impl_from_IDirectMusicSegment8(iface); + struct segment *This = impl_from_IDirectMusicSegment8(iface); +- FIXME("(%p, %p): stub\n", This, pAudioPath); + IDirectMusicPerformance8 *perf; + IDirectMusicAudioPath *audio; + IDirectSound *dsound; @@ -145,13 +142,9 @@ index 39a5333fbbb..ce49ddc9940 100644 + hr = IDirectSoundBuffer_Unlock(This->buffer, data, This->data_size, NULL, 0); + TRACE("IDirectSoundBuffer_Unlock hr 0x%08lx\n", hr); + -+ /*hr = IDirectSoundBuffer_Play(This->buffer, 0, 0, 0); -+ TRACE("IDirectSoundBuffer_Play hr 0x%08lx\n", hr);*/ -+ -+ return S_OK; + return S_OK; } - static HRESULT WINAPI IDirectMusicSegment8Impl_Unload(IDirectMusicSegment8 *iface, -- 2.40.1 diff --git a/patches/dmime-load-wave/0003-dmime-Play-a-sound-in-IDirectMusicPerformance8-PlayS.patch b/patches/dmime-load-wave/0003-dmime-Play-a-sound-in-IDirectMusicPerformance8-PlayS.patch index 4a6a9cd4..64441c37 100644 --- a/patches/dmime-load-wave/0003-dmime-Play-a-sound-in-IDirectMusicPerformance8-PlayS.patch +++ b/patches/dmime-load-wave/0003-dmime-Play-a-sound-in-IDirectMusicPerformance8-PlayS.patch @@ -1,4 +1,4 @@ -From 43007318a6303312b6226c9ede009e4299826af3 Mon Sep 17 00:00:00 2001 +From ea9bd0ec85254305b5783e1890ded6b21d200f41 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 12 Dec 2022 15:20:10 +1100 Subject: [PATCH] dmime: Play a sound in IDirectMusicPerformance8 PlaySegmentEx @@ -10,10 +10,10 @@ Subject: [PATCH] dmime: Play a sound in IDirectMusicPerformance8 PlaySegmentEx 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/dlls/dmime/dmime_private.h b/dlls/dmime/dmime_private.h -index da40b58ad9b..4532528f535 100644 +index cd34378b66e..c83f6675333 100644 --- a/dlls/dmime/dmime_private.h +++ b/dlls/dmime/dmime_private.h -@@ -72,6 +72,7 @@ extern void set_audiopath_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffe +@@ -71,6 +71,7 @@ extern void set_audiopath_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffe extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSoundBuffer*); extern IDirectSound *get_dsound_interface(IDirectMusicPerformance8*); @@ -22,10 +22,10 @@ index da40b58ad9b..4532528f535 100644 /***************************************************************************** * Auxiliary definitions diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c -index 622939f3553..c7b149f0686 100644 +index a707de39d50..2b09814cd6b 100644 --- a/dlls/dmime/performance.c +++ b/dlls/dmime/performance.c -@@ -1028,13 +1028,26 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, +@@ -1053,13 +1053,26 @@ static HRESULT WINAPI performance_PlaySegmentEx(IDirectMusicPerformance8 *iface, WCHAR *pwzSegmentName, IUnknown *pTransition, DWORD dwFlags, __int64 i64StartTime, IDirectMusicSegmentState **ppSegmentState, IUnknown *pFrom, IUnknown *pAudioPath) { @@ -59,22 +59,22 @@ index 622939f3553..c7b149f0686 100644 static HRESULT WINAPI performance_StopEx(IDirectMusicPerformance8 *iface, IUnknown *pObjectToStop, diff --git a/dlls/dmime/segment.c b/dlls/dmime/segment.c -index ce49ddc9940..ad121736acd 100644 +index ebee90eee92..8482cb21d34 100644 --- a/dlls/dmime/segment.c +++ b/dlls/dmime/segment.c -@@ -47,6 +47,12 @@ static inline IDirectMusicSegment8Impl *impl_from_IDirectMusicSegment8(IDirectMu - return CONTAINING_RECORD(iface, IDirectMusicSegment8Impl, IDirectMusicSegment8_iface); +@@ -64,6 +64,12 @@ static inline struct segment *impl_from_IDirectMusicSegment8(IDirectMusicSegment + return CONTAINING_RECORD(iface, struct segment, IDirectMusicSegment8_iface); } +IDirectSoundBuffer *get_segment_buffer(IDirectMusicSegment8 *iface) +{ -+ IDirectMusicSegment8Impl *This = impl_from_IDirectMusicSegment8(iface); ++ struct segment *This = impl_from_IDirectMusicSegment8(iface); + return This->buffer; +} + - static HRESULT WINAPI IDirectMusicSegment8Impl_QueryInterface(IDirectMusicSegment8 *iface, - REFIID riid, void **ret_iface) + static HRESULT WINAPI segment_QueryInterface(IDirectMusicSegment8 *iface, REFIID riid, void **ret_iface) { + struct segment *This = impl_from_IDirectMusicSegment8(iface); -- 2.40.1 diff --git a/patches/vkd3d-latest/0001-Update-vkd3d-to-771e442af16228a977eebba82224f06f6d02.patch b/patches/vkd3d-latest/0001-Update-vkd3d-to-771e442af16228a977eebba82224f06f6d02.patch index 2bac8b4a..b819f62e 100644 --- a/patches/vkd3d-latest/0001-Update-vkd3d-to-771e442af16228a977eebba82224f06f6d02.patch +++ b/patches/vkd3d-latest/0001-Update-vkd3d-to-771e442af16228a977eebba82224f06f6d02.patch @@ -1,4 +1,4 @@ -From ffc72a34adff66a7e763f682288f95498b8b5f28 Mon Sep 17 00:00:00 2001 +From c02f983dde361302e69fb6da9526801b59e41b07 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Wed, 17 May 2023 08:35:40 +1000 Subject: [PATCH] Update vkd3d to 771e442af16228a977eebba82224f06f6d0202fe @@ -27970,7 +27970,7 @@ index 79be999adf9..406d53a3391 100644 + #endif /* __VKD3D_SHADER_PRIVATE_H */ diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index 6eddcfa2d14..32439eec7eb 100644 +index 4e2d4295935..c5bd687bd69 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -1437,7 +1437,7 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-4f2e07a45d0cdb82b1cbba0cfe95c87a697.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-46c7f65be8337a108a04a616ccd0c8a7732.patch similarity index 79% rename from patches/vkd3d-latest/0002-Updated-vkd3d-to-4f2e07a45d0cdb82b1cbba0cfe95c87a697.patch rename to patches/vkd3d-latest/0002-Updated-vkd3d-to-46c7f65be8337a108a04a616ccd0c8a7732.patch index 70d68b98..bfb087bd 100644 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-4f2e07a45d0cdb82b1cbba0cfe95c87a697.patch +++ b/patches/vkd3d-latest/0002-Updated-vkd3d-to-46c7f65be8337a108a04a616ccd0c8a7732.patch @@ -1,157 +1,41 @@ -From f0dc4e3e02203e62ced4488f216509a27a81a8e0 Mon Sep 17 00:00:00 2001 +From 8dab6cb1d8d984bee47df2da8288e01289fd1379 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes -Date: Wed, 28 Jun 2023 16:27:03 +1000 -Subject: [PATCH] Updated vkd3d to 4f2e07a45d0cdb82b1cbba0cfe95c87a69799865. +Date: Wed, 20 Sep 2023 06:49:52 +1000 +Subject: [PATCH] Updated vkd3d to 46c7f65be8337a108a04a616ccd0c8a773216f3f. -Wine-staging 8.14 --- - include/d3d12.idl | 70 +- libs/vkd3d/Makefile.in | 1 + libs/vkd3d/include/private/vkd3d_common.h | 22 + - .../include/private/vkd3d_shader_utils.h | 63 + + .../include/private/vkd3d_shader_utils.h | 67 + libs/vkd3d/include/vkd3d.h | 35 + - libs/vkd3d/include/vkd3d_shader.h | 282 +- + libs/vkd3d/include/vkd3d_shader.h | 291 +- + libs/vkd3d/include/vkd3d_windows.h | 5 + libs/vkd3d/libs/vkd3d-common/debug.c | 17 +- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 48 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 415 ++- + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 50 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 430 ++- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 17 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 2370 +++++++++++++++++ - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 211 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 45 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 1600 ++++++----- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 638 +++-- - .../libs/vkd3d-shader/hlsl_constant_ops.c | 525 +++- - libs/vkd3d/libs/vkd3d-shader/ir.c | 230 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 2968 +++++++++++++++++ + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 289 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 68 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 1969 ++++++----- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 768 +++-- + .../libs/vkd3d-shader/hlsl_constant_ops.c | 525 ++- + libs/vkd3d/libs/vkd3d-shader/ir.c | 232 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 140 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 222 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 1216 +++++---- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 388 ++- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 78 +- - libs/vkd3d/libs/vkd3d/command.c | 673 +++-- - libs/vkd3d/libs/vkd3d/device.c | 22 +- - libs/vkd3d/libs/vkd3d/resource.c | 283 +- - libs/vkd3d/libs/vkd3d/state.c | 10 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 102 +- - 27 files changed, 7768 insertions(+), 1955 deletions(-) + libs/vkd3d/libs/vkd3d-shader/spirv.c | 457 ++- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 1385 +++++--- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 440 ++- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 128 +- + libs/vkd3d/libs/vkd3d/command.c | 674 ++-- + libs/vkd3d/libs/vkd3d/device.c | 245 +- + libs/vkd3d/libs/vkd3d/resource.c | 342 +- + libs/vkd3d/libs/vkd3d/state.c | 14 +- + libs/vkd3d/libs/vkd3d/vkd3d_main.c | 4 +- + libs/vkd3d/libs/vkd3d/vkd3d_private.h | 124 +- + 28 files changed, 9257 insertions(+), 2450 deletions(-) create mode 100644 libs/vkd3d/include/private/vkd3d_shader_utils.h create mode 100644 libs/vkd3d/libs/vkd3d-shader/dxil.c -diff --git a/include/d3d12.idl b/include/d3d12.idl -index 4fec32d2656..5811608b94f 100644 ---- a/include/d3d12.idl -+++ b/include/d3d12.idl -@@ -44,6 +44,7 @@ const UINT D3D12_DEFAULT_STENCIL_WRITE_MASK = 0xff; - const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff; - cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)") - const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32; -+const UINT D3D12_PACKED_TILE = 0xffffffff; - const UINT D3D12_UAV_SLOT_COUNT = 64; - const UINT D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; - const UINT D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; -@@ -72,6 +73,7 @@ const UINT D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT = 4096; - const UINT D3D12_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4; - const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256; - const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512; -+const UINT D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES = 65536; - const UINT D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT = 4096; - const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32; - const UINT D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16; -@@ -1853,6 +1855,24 @@ typedef struct D3D12_WRITEBUFFERIMMEDIATE_PARAMETER - UINT32 Value; - } D3D12_WRITEBUFFERIMMEDIATE_PARAMETER; - -+typedef enum D3D12_PROTECTED_RESOURCE_SESSION_FLAGS -+{ -+ D3D12_PROTECTED_RESOURCE_SESSION_FLAG_NONE = 0, -+} D3D12_PROTECTED_RESOURCE_SESSION_FLAGS; -+cpp_quote("DEFINE_ENUM_FLAG_OPERATORS(D3D12_PROTECTED_RESOURCE_SESSION_FLAGS);") -+ -+typedef enum D3D12_PROTECTED_SESSION_STATUS -+{ -+ D3D12_PROTECTED_SESSION_STATUS_OK = 0, -+ D3D12_PROTECTED_SESSION_STATUS_INVALID = 1, -+} D3D12_PROTECTED_SESSION_STATUS; -+ -+typedef struct D3D12_PROTECTED_RESOURCE_SESSION_DESC -+{ -+ UINT NodeMask; -+ D3D12_PROTECTED_RESOURCE_SESSION_FLAGS Flags; -+} D3D12_PROTECTED_RESOURCE_SESSION_DESC; -+ - [ - uuid(c4fec28f-7966-4e95-9f94-f431cb56c3b8), - object, -@@ -2214,6 +2234,41 @@ interface ID3D12GraphicsCommandList2 : ID3D12GraphicsCommandList1 - const D3D12_WRITEBUFFERIMMEDIATE_MODE *modes); - } - -+[ -+ uuid(a1533d18-0ac1-4084-85b9-89a96116806b), -+ object, -+ local, -+ pointer_default(unique) -+] -+interface ID3D12ProtectedSession : ID3D12DeviceChild -+{ -+ HRESULT GetStatusFence(REFIID riid, void **fence); -+ -+ D3D12_PROTECTED_SESSION_STATUS GetSessionStatus(); -+} -+ -+[ -+ uuid(6cd696f4-f289-40cc-8091-5a6c0a099c3d), -+ object, -+ local, -+ pointer_default(unique) -+] -+interface ID3D12ProtectedResourceSession : ID3D12ProtectedSession -+{ -+ D3D12_PROTECTED_RESOURCE_SESSION_DESC GetDesc(); -+} -+ -+[ -+ uuid(6fda83a7-b84c-4e38-9ac8-c7bd22016b3d), -+ object, -+ local, -+ pointer_default(unique) -+] -+interface ID3D12GraphicsCommandList3 : ID3D12GraphicsCommandList2 -+{ -+ void SetProtectedResourceSession(ID3D12ProtectedResourceSession *protected_resource_session); -+} -+ - typedef enum D3D12_TILE_RANGE_FLAGS - { - D3D12_TILE_RANGE_FLAG_NONE = 0x0, -@@ -2243,8 +2298,8 @@ interface ID3D12CommandQueue : ID3D12Pageable - ID3D12Heap *heap, - UINT range_count, - const D3D12_TILE_RANGE_FLAGS *range_flags, -- UINT *heap_range_offsets, -- UINT *range_tile_counts, -+ const UINT *heap_range_offsets, -+ const UINT *range_tile_counts, - D3D12_TILE_MAPPING_FLAGS flags); - - void CopyTileMappings(ID3D12Resource *dst_resource, -@@ -2378,6 +2433,17 @@ interface ID3D12Fence : ID3D12Pageable - HRESULT Signal(UINT64 value); - } - -+[ -+ uuid(433685fe-e22b-4ca0-a8db-b5b4f4dd0e4a), -+ object, -+ local, -+ pointer_default(unique) -+] -+interface ID3D12Fence1 : ID3D12Fence -+{ -+ D3D12_FENCE_FLAGS GetCreationFlags(); -+} -+ - [ - uuid(6102dee4-af59-4b09-b999-b44d73f09b24), - object, diff --git a/libs/vkd3d/Makefile.in b/libs/vkd3d/Makefile.in index 1ba0e9f71e1..f647af11d07 100644 --- a/libs/vkd3d/Makefile.in @@ -220,10 +104,10 @@ index 1ac23b4a085..f7d98f327f1 100644 return 'A' <= c && c <= 'Z'; diff --git a/libs/vkd3d/include/private/vkd3d_shader_utils.h b/libs/vkd3d/include/private/vkd3d_shader_utils.h new file mode 100644 -index 00000000000..00052a89988 +index 00000000000..c9f8001e590 --- /dev/null +++ b/libs/vkd3d/include/private/vkd3d_shader_utils.h -@@ -0,0 +1,63 @@ +@@ -0,0 +1,67 @@ +/* + * Copyright 2023 Conor McCarthy for CodeWeavers + * @@ -269,12 +153,16 @@ index 00000000000..00052a89988 + if (tag == TAG_SHDR || tag == TAG_SHEX) + { + *type = VKD3D_SHADER_SOURCE_DXBC_TPF; ++#ifndef VKD3D_SHADER_UNSUPPORTED_DXIL ++ break; ++#else + } + else if (tag == TAG_DXIL) + { + *type = VKD3D_SHADER_SOURCE_DXBC_DXIL; + /* Default to DXIL if both are present. */ + break; ++#endif + } + } + @@ -335,7 +223,7 @@ index 72ed3ced671..2ccda47248a 100644 VKD3D_API HRESULT vkd3d_create_image_resource(ID3D12Device *device, diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index 274241546ea..e98aad4fe95 100644 +index 274241546ea..fc2c1257d16 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -85,6 +85,16 @@ enum vkd3d_shader_structure_type @@ -355,10 +243,11 @@ index 274241546ea..e98aad4fe95 100644 VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; -@@ -134,6 +144,14 @@ enum vkd3d_shader_compile_option_formatting_flags +@@ -134,6 +144,15 @@ enum vkd3d_shader_compile_option_formatting_flags VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FORMATTING_FLAGS), }; ++/** Determines how matrices are stored. \since 1.9 */ +enum vkd3d_shader_compile_option_pack_matrix_order +{ + VKD3D_SHADER_COMPILE_OPTION_PACK_MATRIX_ROW_MAJOR = 0x00000001, @@ -370,12 +259,12 @@ index 274241546ea..e98aad4fe95 100644 enum vkd3d_shader_compile_option_name { /** -@@ -164,6 +182,15 @@ enum vkd3d_shader_compile_option_name +@@ -164,6 +183,15 @@ enum vkd3d_shader_compile_option_name * \since 1.7 */ VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE = 0x00000006, + /** -+ * This option specifies default matrix packing order. It's only supported for HLSL source type. ++ * This option specifies default matrix packing order for HLSL sources. + * Explicit variable modifiers or pragmas will take precedence. + * + * \a value is a member of enum vkd3d_shader_compile_option_pack_matrix_order. @@ -386,7 +275,7 @@ index 274241546ea..e98aad4fe95 100644 VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_NAME), }; -@@ -327,6 +354,25 @@ struct vkd3d_shader_parameter +@@ -327,6 +355,25 @@ struct vkd3d_shader_parameter } u; }; @@ -412,7 +301,7 @@ index 274241546ea..e98aad4fe95 100644 /** * Describes the mapping of a single resource or resource array to its binding * point in the target environment. -@@ -351,7 +397,14 @@ struct vkd3d_shader_resource_binding +@@ -351,7 +398,14 @@ struct vkd3d_shader_resource_binding * support multiple register spaces, this parameter must be set to 0. */ unsigned int register_space; @@ -428,7 +317,7 @@ index 274241546ea..e98aad4fe95 100644 unsigned int register_index; /** Shader stage(s) to which the resource is visible. */ enum vkd3d_shader_visibility shader_visibility; -@@ -611,6 +664,11 @@ enum vkd3d_shader_source_type +@@ -611,6 +665,11 @@ enum vkd3d_shader_source_type * model 1, 2, and 3 shaders. \since 1.3 */ VKD3D_SHADER_SOURCE_D3D_BYTECODE, @@ -440,7 +329,7 @@ index 274241546ea..e98aad4fe95 100644 VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE), }; -@@ -620,7 +678,7 @@ enum vkd3d_shader_target_type +@@ -620,7 +679,7 @@ enum vkd3d_shader_target_type { /** * The shader has no type or is to be ignored. This is not a valid value @@ -449,7 +338,16 @@ index 274241546ea..e98aad4fe95 100644 */ VKD3D_SHADER_TARGET_NONE, /** -@@ -1320,6 +1378,20 @@ struct vkd3d_shader_descriptor_info +@@ -1281,6 +1340,8 @@ enum vkd3d_shader_descriptor_info_flag + /** The descriptor is a UAV resource, on which the shader performs + * atomic ops. \since 1.6 */ + VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS = 0x00000008, ++ /** The descriptor is a raw (byte-addressed) buffer. \since 1.9 */ ++ VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER = 0x00000010, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_INFO_FLAG), + }; +@@ -1320,6 +1381,20 @@ struct vkd3d_shader_descriptor_info * A chained structure enumerating the descriptors declared by a shader. * * This structure extends vkd3d_shader_compile_info. @@ -470,7 +368,16 @@ index 274241546ea..e98aad4fe95 100644 */ struct vkd3d_shader_scan_descriptor_info { -@@ -1551,6 +1623,134 @@ static inline uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_com +@@ -1389,6 +1464,8 @@ enum vkd3d_shader_sysval_semantic + VKD3D_SHADER_SV_TESS_FACTOR_TRIINT = 0x0e, + VKD3D_SHADER_SV_TESS_FACTOR_LINEDET = 0x0f, + VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN = 0x10, ++ /** Render target; SV_Target in Direct3D shader model 6 shaders. \since 1.9 */ ++ VKD3D_SHADER_SV_TARGET = 0x40, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SYSVAL_SEMANTIC), + }; +@@ -1551,6 +1628,134 @@ static inline uint32_t vkd3d_shader_create_swizzle(enum vkd3d_shader_swizzle_com | ((w & VKD3D_SHADER_SWIZZLE_MASK) << VKD3D_SHADER_SWIZZLE_SHIFT(3)); } @@ -605,7 +512,7 @@ index 274241546ea..e98aad4fe95 100644 #ifdef LIBVKD3D_SHADER_SOURCE # define VKD3D_SHADER_API VKD3D_EXPORT #else -@@ -1623,12 +1823,14 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported +@@ -1623,12 +1828,14 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported * * Depending on the source and target types, this function may support the * following chained structures: @@ -621,7 +528,7 @@ index 274241546ea..e98aad4fe95 100644 * * \param compile_info A chained structure containing compilation parameters. * -@@ -1784,6 +1986,26 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver +@@ -1784,6 +1991,26 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver * Parse shader source code or byte code, returning various types of requested * information. * @@ -648,7 +555,7 @@ index 274241546ea..e98aad4fe95 100644 * Currently this function supports the following code types: * - VKD3D_SHADER_SOURCE_DXBC_TPF * -@@ -1791,6 +2013,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver +@@ -1791,6 +2018,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver * \n * The DXBC_TPF scanner supports the following chained structures: * - vkd3d_shader_scan_descriptor_info @@ -656,7 +563,7 @@ index 274241546ea..e98aad4fe95 100644 * \n * Although the \a compile_info parameter is read-only, chained structures * passed to this function need not be, and may serve as output parameters, -@@ -1827,12 +2050,18 @@ VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info( +@@ -1827,12 +2055,18 @@ VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info( struct vkd3d_shader_scan_descriptor_info *scan_descriptor_info); /** @@ -676,7 +583,7 @@ index 274241546ea..e98aad4fe95 100644 * \param dxbc Compiled byte code, in DXBC format. * * \param signature Output location in which the parsed root signature will be -@@ -2022,6 +2251,48 @@ VKD3D_SHADER_API int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxb +@@ -2022,6 +2256,48 @@ VKD3D_SHADER_API int vkd3d_shader_parse_dxbc(const struct vkd3d_shader_code *dxb VKD3D_SHADER_API int vkd3d_shader_serialize_dxbc(size_t section_count, const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages); @@ -725,16 +632,53 @@ index 274241546ea..e98aad4fe95 100644 #endif /* VKD3D_SHADER_NO_PROTOTYPES */ /** Type of vkd3d_shader_get_version(). */ -@@ -2087,6 +2358,9 @@ typedef int (*PFN_vkd3d_shader_parse_dxbc)(const struct vkd3d_shader_code *dxbc, +@@ -2087,6 +2363,13 @@ typedef int (*PFN_vkd3d_shader_parse_dxbc)(const struct vkd3d_shader_code *dxbc, typedef int (*PFN_vkd3d_shader_serialize_dxbc)(size_t section_count, const struct vkd3d_shader_dxbc_section_desc *sections, struct vkd3d_shader_code *dxbc, char **messages); ++/** Type of vkd3d_shader_build_varying_map(). \since 1.9 */ ++typedef void (*PFN_vkd3d_shader_build_varying_map)(const struct vkd3d_shader_signature *output_signature, ++ const struct vkd3d_shader_signature *input_signature, ++ unsigned int *count, struct vkd3d_shader_varying_map *varyings); +/** Type of vkd3d_shader_free_scan_signature_info(). \since 1.9 */ +typedef void (*PFN_vkd3d_shader_free_scan_signature_info)(struct vkd3d_shader_scan_signature_info *info); + #ifdef __cplusplus } #endif /* __cplusplus */ +diff --git a/libs/vkd3d/include/vkd3d_windows.h b/libs/vkd3d/include/vkd3d_windows.h +index 002ff667cbc..7b0e972d828 100644 +--- a/libs/vkd3d/include/vkd3d_windows.h ++++ b/libs/vkd3d/include/vkd3d_windows.h +@@ -64,6 +64,7 @@ typedef int HRESULT; + + # define DXGI_ERROR_NOT_FOUND _HRESULT_TYPEDEF_(0x887a0002) + # define DXGI_ERROR_MORE_DATA _HRESULT_TYPEDEF_(0x887a0003) ++# define DXGI_ERROR_UNSUPPORTED _HRESULT_TYPEDEF_(0x887a0004) + + # define D3DERR_INVALIDCALL _HRESULT_TYPEDEF_(0x8876086c) + +@@ -124,6 +125,8 @@ typedef struct _GUID + # endif + + typedef GUID IID; ++typedef GUID CLSID; ++typedef GUID UUID; + + # ifdef INITGUID + # ifndef __cplusplus +@@ -222,9 +225,11 @@ typedef struct SECURITY_ATTRIBUTES SECURITY_ATTRIBUTES; + # if defined(__cplusplus) && !defined(CINTERFACE) + # define REFIID const IID & + # define REFGUID const GUID & ++# define REFCLSID const CLSID & + # else + # define REFIID const IID * const + # define REFGUID const GUID * const ++# define REFCLSID const CLSID * const + # endif + + #if defined(__cplusplus) && !defined(CINTERFACE) diff --git a/libs/vkd3d/libs/vkd3d-common/debug.c b/libs/vkd3d/libs/vkd3d-common/debug.c index b363efbd360..aa7df5bd764 100644 --- a/libs/vkd3d/libs/vkd3d-common/debug.c @@ -779,7 +723,7 @@ index b363efbd360..aa7df5bd764 100644 vkd3d_dbg_voutput(fmt, args); va_end(args); diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 0a821b5c878..d72402eb250 100644 +index 0a821b5c878..f0c386f1b3a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -578,17 +578,17 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e @@ -844,8 +788,17 @@ index 0a821b5c878..d72402eb250 100644 }; const char *name; int i; +@@ -714,7 +714,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, + break; + + case VKD3D_DECL_USAGE_TEXCOORD: +- shader_addline(buffer, "texture%u", semantic->usage_idx); ++ shader_addline(buffer, "texcoord%u", semantic->usage_idx); + break; + + case VKD3D_DECL_USAGE_TANGENT: diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 712613ac13b..99a5bd7a438 100644 +index 712613ac13b..d5104ae9b79 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -214,6 +214,9 @@ struct vkd3d_shader_sm1_parser @@ -1297,7 +1250,28 @@ index 712613ac13b..99a5bd7a438 100644 return sm1->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK; } -@@ -1340,7 +1686,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe +@@ -1292,17 +1638,12 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe + + if (var->is_param && var->is_uniform) + { +- struct vkd3d_string_buffer *name; ++ char *new_name; + +- if (!(name = hlsl_get_string_buffer(ctx))) +- { +- buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; ++ if (!(new_name = hlsl_sprintf_alloc(ctx, "$%s", var->name))) + return; +- } +- vkd3d_string_buffer_printf(name, "$%s", var->name); + vkd3d_free((char *)var->name); +- var->name = hlsl_strdup(ctx, name->buffer); +- hlsl_release_string_buffer(ctx, name); ++ var->name = new_name; + } + } + } +@@ -1340,7 +1681,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe else { put_u32(buffer, vkd3d_make_u32(D3DXRS_SAMPLER, var->regs[r].id)); @@ -1306,7 +1280,7 @@ index 712613ac13b..99a5bd7a438 100644 } put_u32(buffer, 0); /* type */ put_u32(buffer, 0); /* FIXME: default value */ -@@ -1553,12 +1899,13 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ +@@ -1553,12 +1894,13 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ for (i = 0; i < ctx->constant_defs.count; ++i) { @@ -1321,7 +1295,7 @@ index 712613ac13b..99a5bd7a438 100644 }; if (ctx->profile->major_version > 1) -@@ -1567,7 +1914,7 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ +@@ -1567,7 +1909,7 @@ static void write_sm1_constant_defs(struct hlsl_ctx *ctx, struct vkd3d_bytecode_ write_sm1_dst_register(buffer, ®); for (x = 0; x < 4; ++x) @@ -1330,7 +1304,18 @@ index 712613ac13b..99a5bd7a438 100644 } } -@@ -1686,14 +2033,19 @@ static void write_sm1_sampler_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -1640,10 +1982,6 @@ static void write_sm1_sampler_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu + + switch (sampler_dim) + { +- case HLSL_SAMPLER_DIM_1D: +- res_type = VKD3D_SM1_RESOURCE_TEXTURE_1D; +- break; +- + case HLSL_SAMPLER_DIM_2D: + res_type = VKD3D_SM1_RESOURCE_TEXTURE_2D; + break; +@@ -1686,14 +2024,19 @@ static void write_sm1_sampler_dcls(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b if (!var->regs[HLSL_REGSET_SAMPLERS].allocated) continue; @@ -1352,7 +1337,7 @@ index 712613ac13b..99a5bd7a438 100644 reg_id = var->regs[HLSL_REGSET_SAMPLERS].id + i; write_sm1_sampler_dcl(ctx, buffer, reg_id, sampler_dim); -@@ -1844,6 +2196,35 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b +@@ -1844,6 +2187,35 @@ static void write_sm1_expr(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b } } @@ -1388,7 +1373,7 @@ index 712613ac13b..99a5bd7a438 100644 static void write_sm1_load(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, const struct hlsl_ir_node *instr) { const struct hlsl_ir_load *load = hlsl_ir_load(instr); -@@ -2038,6 +2419,10 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -2038,6 +2410,10 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b write_sm1_expr(ctx, buffer, instr); break; @@ -1399,7 +1384,7 @@ index 712613ac13b..99a5bd7a438 100644 case HLSL_IR_LOAD: write_sm1_load(ctx, buffer, instr); break; -@@ -2063,7 +2448,6 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -2063,7 +2439,6 @@ static void write_sm1_instructions(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) { struct vkd3d_bytecode_buffer buffer = {0}; @@ -1407,7 +1392,7 @@ index 712613ac13b..99a5bd7a438 100644 put_u32(&buffer, sm1_version(ctx->profile->type, ctx->profile->major_version, ctx->profile->minor_version)); -@@ -2076,10 +2460,17 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun +@@ -2076,10 +2451,17 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun put_u32(&buffer, D3DSIO_END); @@ -1480,10 +1465,10 @@ index 3e3f06faeb5..cedc3da4a83 100644 ret = VKD3D_ERROR_INVALID_ARGUMENT; diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c new file mode 100644 -index 00000000000..f9efe47f95d +index 00000000000..b78c78d34a7 --- /dev/null +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -0,0 +1,2370 @@ +@@ -0,0 +1,2968 @@ +/* + * Copyright 2023 Conor McCarthy for CodeWeavers + * @@ -1508,6 +1493,7 @@ index 00000000000..f9efe47f95d +#define VKD3D_SM6_VERSION_MINOR(version) (((version) >> 0) & 0xf) + +#define BITCODE_MAGIC VKD3D_MAKE_TAG('B', 'C', 0xc0, 0xde) ++#define DXIL_OP_MAX_OPERANDS 17 + +enum bitcode_block_id +{ @@ -1624,6 +1610,11 @@ index 00000000000..f9efe47f95d + VST_CODE_BBENTRY = 2, +}; + ++enum dx_intrinsic_opcode ++{ ++ DX_STORE_OUTPUT = 5, ++}; ++ +struct sm6_pointer_info +{ + const struct sm6_type *type; @@ -1728,6 +1719,8 @@ index 00000000000..f9efe47f95d + + struct sm6_block *blocks[1]; + size_t block_count; ++ ++ size_t value_count; +}; + +struct dxil_block @@ -1773,12 +1766,15 @@ index 00000000000..f9efe47f95d + struct sm6_symbol *global_symbols; + size_t global_symbol_count; + ++ struct vkd3d_shader_dst_param *output_params; ++ + struct sm6_function *functions; + size_t function_count; + + struct sm6_value *values; + size_t value_count; + size_t value_capacity; ++ size_t cur_max_value; + + struct vkd3d_shader_parser p; +}; @@ -1802,6 +1798,8 @@ index 00000000000..f9efe47f95d + struct dxil_abbrev abbrev; +}; + ++static const uint64_t CALL_CONV_FLAG_EXPLICIT_TYPE = 1ull << 15; ++ +static size_t size_add_with_overflow_check(size_t a, size_t b) +{ + size_t i = a + b; @@ -2747,6 +2745,16 @@ index 00000000000..f9efe47f95d + return type->class == TYPE_CLASS_INTEGER; +} + ++static inline bool sm6_type_is_i8(const struct sm6_type *type) ++{ ++ return type->class == TYPE_CLASS_INTEGER && type->u.width == 8; ++} ++ ++static inline bool sm6_type_is_i32(const struct sm6_type *type) ++{ ++ return type->class == TYPE_CLASS_INTEGER && type->u.width == 32; ++} ++ +static inline bool sm6_type_is_floating_point(const struct sm6_type *type) +{ + return type->class == TYPE_CLASS_FLOAT; @@ -2827,6 +2835,30 @@ index 00000000000..f9efe47f95d + return NULL; +} + ++/* Never returns null for elem_idx 0. */ ++static const struct sm6_type *sm6_type_get_scalar_type(const struct sm6_type *type, unsigned int elem_idx) ++{ ++ switch (type->class) ++ { ++ case TYPE_CLASS_ARRAY: ++ case TYPE_CLASS_VECTOR: ++ if (elem_idx >= type->u.array.count) ++ return NULL; ++ return sm6_type_get_scalar_type(type->u.array.elem_type, 0); ++ ++ case TYPE_CLASS_POINTER: ++ return sm6_type_get_scalar_type(type->u.pointer.type, 0); ++ ++ case TYPE_CLASS_STRUCT: ++ if (elem_idx >= type->u.struc->elem_count) ++ return NULL; ++ return sm6_type_get_scalar_type(type->u.struc->elem_types[elem_idx], 0); ++ ++ default: ++ return type; ++ } ++} ++ +static const struct sm6_type *sm6_parser_get_type(struct sm6_parser *sm6, uint64_t type_id) +{ + if (type_id >= sm6->type_count) @@ -2929,9 +2961,32 @@ index 00000000000..f9efe47f95d + return NULL; +} + ++static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg) ++{ ++ if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) ++ return UINT_MAX; ++ ++ if (reg->immconst_type == VKD3D_IMMCONST_VEC4) ++ WARN("Returning vec4.x.\n"); ++ ++ if (reg->type == VKD3DSPR_IMMCONST64) ++ { ++ if (reg->u.immconst_uint64[0] > UINT_MAX) ++ FIXME("Truncating 64-bit value.\n"); ++ return reg->u.immconst_uint64[0]; ++ } ++ ++ return reg->u.immconst_uint[0]; ++} ++ ++static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) ++{ ++ return value->value_type == VALUE_TYPE_FUNCTION; ++} ++ +static inline bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn) +{ -+ assert(fn->value_type == VALUE_TYPE_FUNCTION); ++ assert(sm6_value_is_function_dcl(fn)); + return fn->u.function.is_prototype && !strncmp(fn->u.function.name, "dx.op.", 6); +} + @@ -2941,6 +2996,60 @@ index 00000000000..f9efe47f95d + return &sm6->values[sm6->value_count]; +} + ++static inline bool sm6_value_is_register(const struct sm6_value *value) ++{ ++ return value->value_type == VALUE_TYPE_REG; ++} ++ ++static inline bool sm6_value_is_constant(const struct sm6_value *value) ++{ ++ return sm6_value_is_register(value) && register_is_constant(&value->u.reg); ++} ++ ++static inline bool sm6_value_is_undef(const struct sm6_value *value) ++{ ++ return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF; ++} ++ ++static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) ++{ ++ if (!sm6_value_is_constant(value)) ++ return UINT_MAX; ++ return register_get_uint_value(&value->u.reg); ++} ++ ++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) ++ { ++ ERR("Failed to allocate src params.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Out of memory allocating instruction src paramaters."); ++ return NULL; ++ } ++ ins->src = params; ++ ins->src_count = count; ++ return params; ++} ++ ++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) ++ { ++ ERR("Failed to allocate dst params.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Out of memory allocating instruction dst paramaters."); ++ return NULL; ++ } ++ ins->dst = params; ++ ins->dst_count = count; ++ return params; ++} ++ +static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type) +{ + if (type->class == TYPE_CLASS_INTEGER) @@ -2974,6 +3083,47 @@ index 00000000000..f9efe47f95d + return VKD3D_DATA_UINT; +} + ++static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx) ++{ ++ param->write_mask = 1u << component_idx; ++ param->modifiers = 0; ++ param->shift = 0; ++} ++ ++static inline void src_param_init(struct vkd3d_shader_src_param *param) ++{ ++ param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ param->modifiers = VKD3DSPSM_NONE; ++} ++ ++static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) ++{ ++ src_param_init(param); ++ param->reg = src->u.reg; ++} ++ ++static void register_address_init(struct vkd3d_shader_register *reg, const struct sm6_value *address, ++ unsigned int idx, struct sm6_parser *sm6) ++{ ++ assert(idx < ARRAY_SIZE(reg->idx)); ++ if (sm6_value_is_constant(address)) ++ { ++ reg->idx[idx].offset = sm6_value_get_constant_uint(address); ++ } ++ else if (sm6_value_is_undef(address)) ++ { ++ reg->idx[idx].offset = 0; ++ } ++ else ++ { ++ struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&sm6->p, 1); ++ if (rel_addr) ++ src_param_init_from_value(rel_addr, address); ++ reg->idx[idx].offset = 0; ++ reg->idx[idx].rel_addr = rel_addr; ++ } ++} ++ +/* Recurse through the block tree while maintaining a current value count. The current + * count is the sum of the global count plus all declarations within the current function. + * Store into value_capacity the highest count seen. */ @@ -2999,6 +3149,7 @@ index 00000000000..f9efe47f95d + * overestimate the value count somewhat, but this should be no problem. */ + value_count = size_add_with_overflow_check(value_count, max(block->record_count, 1u) - 1); + sm6->value_capacity = max(sm6->value_capacity, value_count); ++ sm6->functions[sm6->function_count].value_count = value_count; + /* The value count returns to its previous value after handling a function. */ + if (value_count < SIZE_MAX) + value_count = old_value_count; @@ -3010,6 +3161,77 @@ index 00000000000..f9efe47f95d + return value_count; +} + ++static size_t sm6_parser_get_value_index(struct sm6_parser *sm6, uint64_t idx) ++{ ++ size_t i; ++ ++ /* The value relative index is 32 bits. */ ++ if (idx > UINT32_MAX) ++ WARN("Ignoring upper 32 bits of relative index.\n"); ++ i = (uint32_t)sm6->value_count - (uint32_t)idx; ++ ++ /* This may underflow to produce a forward reference, but it must not exceeed the final value count. */ ++ if (i >= sm6->cur_max_value) ++ { ++ WARN("Invalid value index %"PRIx64" at %zu.\n", idx, sm6->value_count); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Invalid value relative index %u.", (unsigned int)idx); ++ return SIZE_MAX; ++ } ++ if (i == sm6->value_count) ++ { ++ WARN("Invalid value self-reference at %zu.\n", sm6->value_count); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Invalid value self-reference."); ++ return SIZE_MAX; ++ } ++ ++ return i; ++} ++ ++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) ++{ ++ unsigned int idx; ++ uint64_t val_ref; ++ size_t operand; ++ ++ idx = *rec_idx; ++ if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) ++ return SIZE_MAX; ++ val_ref = record->operands[idx++]; ++ ++ operand = sm6_parser_get_value_index(sm6, val_ref); ++ if (operand == SIZE_MAX) ++ return SIZE_MAX; ++ ++ if (operand >= sm6->value_count) ++ { ++ 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; ++ } ++ 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; ++} ++ ++static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm6, ++ const struct dxil_record *record, const struct sm6_type *type, unsigned int *rec_idx) ++{ ++ size_t operand = sm6_parser_get_value_idx_by_ref(sm6, record, type, rec_idx); ++ return operand == SIZE_MAX ? NULL : &sm6->values[operand]; ++} ++ +static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxil_record *record) +{ + const unsigned int max_count = 15; @@ -3302,6 +3524,81 @@ index 00000000000..f9efe47f95d + return VKD3D_OK; +} + ++static void dst_param_io_init(struct vkd3d_shader_dst_param *param, ++ const struct signature_element *e, enum vkd3d_shader_register_type reg_type) ++{ ++ enum vkd3d_shader_component_type component_type; ++ ++ param->write_mask = e->mask; ++ param->modifiers = 0; ++ param->shift = 0; ++ /* DXIL types do not have signedness. Load signed elements as unsigned. */ ++ component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type; ++ shader_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0); ++} ++ ++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) ++{ ++ struct vkd3d_shader_dst_param *param; ++ const struct signature_element *e; ++ unsigned int i; ++ ++ for (i = 0; i < s->element_count; ++i) ++ { ++ e = &s->elements[i]; ++ ++ param = ¶ms[i]; ++ dst_param_io_init(param, e, reg_type); ++ param->reg.idx[0].offset = i; ++ param->reg.idx_count = 1; ++ } ++} ++ ++static void sm6_parser_emit_signature(struct sm6_parser *sm6, const struct shader_signature *s, ++ enum vkd3d_shader_opcode handler_idx, enum vkd3d_shader_opcode siv_handler_idx, ++ struct vkd3d_shader_dst_param *params) ++{ ++ struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_dst_param *param; ++ const struct signature_element *e; ++ unsigned int i; ++ ++ for (i = 0; i < s->element_count; ++i) ++ { ++ e = &s->elements[i]; ++ ++ /* Do not check e->used_mask because in some cases it is zero for used elements. ++ * TODO: scan ahead for used I/O elements. */ ++ ++ if (e->sysval_semantic != VKD3D_SHADER_SV_NONE && e->sysval_semantic != VKD3D_SHADER_SV_TARGET) ++ { ++ ins = sm6_parser_add_instruction(sm6, siv_handler_idx); ++ param = &ins->declaration.register_semantic.reg; ++ ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic); ++ } ++ else ++ { ++ ins = sm6_parser_add_instruction(sm6, handler_idx); ++ param = &ins->declaration.dst; ++ } ++ ++ *param = params[i]; ++ } ++} ++ ++static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) ++{ ++ sm6_parser_init_signature(sm6, output_signature, ++ (sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSPR_COLOROUT : VKD3DSPR_OUTPUT, ++ sm6->output_params); ++} ++ ++static void sm6_parser_emit_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) ++{ ++ sm6_parser_emit_signature(sm6, output_signature, VKD3DSIH_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT_SIV, sm6->output_params); ++} ++ +static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6) +{ + size_t i, count = sm6->function_count; @@ -3324,6 +3621,258 @@ index 00000000000..f9efe47f95d + return block; +} + ++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) ++{ ++ 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]); ++ ++ 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); ++ 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); ++ return; ++ } ++ ++ value = operands[3]; ++ if (!sm6_value_is_register(value)) ++ { ++ WARN("Source value is not a register.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Expected store operation source to be a register."); ++ return; ++ } ++ ++ shader_instruction_init(ins, VKD3DSIH_MOV); ++ ++ if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) ++ return; ++ dst_param_init_scalar(dst_param, column_index); ++ dst_param->reg = sm6->output_params[row_index].reg; ++ if (e->register_count > 1) ++ register_address_init(&dst_param->reg, operands[1], 0, sm6); ++ ++ if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) ++ src_param_init_from_value(src_param, value); ++} ++ ++struct sm6_dx_opcode_info ++{ ++ const char ret_type; ++ const char *operand_info; ++ void (*handler)(struct sm6_parser *, struct sm6_block *, enum dx_intrinsic_opcode, ++ const struct sm6_value **, struct vkd3d_shader_instruction *); ++}; ++ ++/* ++ 8 -> int8 ++ i -> int32 ++ v -> void ++ o -> overloaded ++ */ ++static const struct sm6_dx_opcode_info sm6_dx_op_table[] = ++{ ++ [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output}, ++}; ++ ++static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_type *type, char info_type) ++{ ++ switch (info_type) ++ { ++ case 0: ++ FIXME("Invalid operand count.\n"); ++ return false; ++ case '8': ++ return sm6_type_is_i8(type); ++ case 'i': ++ return sm6_type_is_i32(type); ++ case 'v': ++ return !type; ++ case 'o': ++ /* TODO: some type checking may be possible */ ++ return true; ++ default: ++ FIXME("Unhandled operand code '%c'.\n", info_type); ++ return false; ++ } ++} ++ ++static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name, ++ const struct sm6_value **operands, unsigned int operand_count, struct sm6_value *dst) ++{ ++ const struct sm6_dx_opcode_info *info; ++ unsigned int i; ++ ++ info = &sm6_dx_op_table[op]; ++ ++ if (!sm6_parser_validate_operand_type(sm6, dst->type, info->ret_type)) ++ { ++ 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 ++ * a data type for the SSA result. */ ++ } ++ ++ for (i = 0; i < operand_count; ++i) ++ { ++ const struct sm6_value *value = operands[i]; ++ if (!sm6_value_is_register(value) || !sm6_parser_validate_operand_type(sm6, value->type, info->operand_info[i])) ++ { ++ 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, ++ "Operand %u for call to dx intrinsic function '%s' is invalid.", i + 1, name); ++ return false; ++ } ++ } ++ if (info->operand_info[operand_count]) ++ { ++ WARN("Missing operands for dx intrinsic id %u, '%s'.\n", op, name); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, ++ "Call to dx intrinsic function '%s' has missing operands.", name); ++ return false; ++ } ++ ++ return true; ++} ++ ++static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, ++ struct sm6_value *dst) ++{ ++ const struct sm6_type *type; ++ ++ ins->handler_idx = VKD3DSIH_NOP; ++ ++ if (!dst->type) ++ return; ++ ++ type = sm6_type_get_scalar_type(dst->type, 0); ++ shader_register_init(&dst->u.reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0); ++ /* dst->is_undefined is not set here because it flags only explicitly undefined values. */ ++} ++ ++static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op, ++ const char *name, const struct sm6_value **operands, unsigned int operand_count, ++ struct vkd3d_shader_instruction *ins, struct sm6_value *dst) ++{ ++ if (op >= ARRAY_SIZE(sm6_dx_op_table) || !sm6_dx_op_table[op].operand_info) ++ { ++ FIXME("Unhandled dx intrinsic function id %u, '%s'.\n", op, name); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC, ++ "Call to intrinsic function %s is unhandled.", name); ++ sm6_parser_emit_unhandled(sm6, ins, dst); ++ return; ++ } ++ ++ if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst)) ++ sm6_dx_op_table[op].handler(sm6, code_block, op, operands, ins); ++ else ++ sm6_parser_emit_unhandled(sm6, ins, dst); ++} ++ ++static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record, ++ struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) ++{ ++ const struct sm6_value *operands[DXIL_OP_MAX_OPERANDS]; ++ const struct sm6_value *fn_value, *op_value; ++ unsigned int i = 1, j, operand_count; ++ const struct sm6_type *type = NULL; ++ uint64_t call_conv; ++ ++ if (!dxil_record_validate_operand_min_count(record, 2, sm6)) ++ return; ++ ++ /* TODO: load the 1-based attributes index from record->operands[0] and validate against attribute count. */ ++ ++ if ((call_conv = record->operands[i++]) & CALL_CONV_FLAG_EXPLICIT_TYPE) ++ type = sm6_parser_get_type(sm6, record->operands[i++]); ++ if (call_conv &= ~CALL_CONV_FLAG_EXPLICIT_TYPE) ++ WARN("Ignoring calling convention %#"PRIx64".\n", call_conv); ++ ++ if (!(fn_value = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))) ++ return; ++ if (!sm6_value_is_function_dcl(fn_value)) ++ { ++ WARN("Function target value is not a function declaration.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Function call target value is not a function declaration."); ++ return; ++ } ++ ++ if (type && type != fn_value->type->u.pointer.type) ++ WARN("Explicit call type does not match function type.\n"); ++ type = fn_value->type->u.pointer.type; ++ ++ if (!sm6_type_is_void(type->u.function->ret_type)) ++ dst->type = type->u.function->ret_type; ++ ++ operand_count = type->u.function->param_count; ++ if (operand_count > ARRAY_SIZE(operands)) ++ { ++ WARN("Ignoring %zu operands.\n", operand_count - ARRAY_SIZE(operands)); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, ++ "Ignoring %zu operands for function call.", operand_count - ARRAY_SIZE(operands)); ++ operand_count = ARRAY_SIZE(operands); ++ } ++ ++ for (j = 0; j < operand_count; ++j) ++ { ++ if (!(operands[j] = sm6_parser_get_value_by_ref(sm6, record, type->u.function->param_types[j], &i))) ++ return; ++ } ++ if ((j = record->operand_count - i)) ++ { ++ WARN("Ignoring %u operands beyond the function parameter list.\n", j); ++ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, ++ "Ignoring %u function call operands beyond the parameter list.", j); ++ } ++ ++ if (!fn_value->u.function.is_prototype) ++ { ++ FIXME("Unhandled call to local function.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Call to a local function is unsupported."); ++ return; ++ } ++ if (!sm6_value_is_dx_intrinsic_dcl(fn_value)) ++ WARN("External function is not a dx intrinsic.\n"); ++ ++ if (!operand_count) ++ { ++ WARN("Missing dx intrinsic function id.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, ++ "The id for a dx intrinsic function is missing."); ++ return; ++ } ++ ++ op_value = operands[0]; ++ if (!sm6_value_is_constant(op_value) || !sm6_type_is_integer(op_value->type)) ++ { ++ WARN("dx intrinsic function id is not a constant int.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Expected a constant integer dx intrinsic function id."); ++ return; ++ } ++ sm6_parser_decode_dx_op(sm6, code_block, register_get_uint_value(&op_value->u.reg), ++ fn_value->u.function.name, &operands[1], operand_count - 1, ins, dst); ++} ++ +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) +{ @@ -3341,15 +3890,10 @@ index 00000000000..f9efe47f95d +{ + struct vkd3d_shader_instruction *ins; + const struct dxil_record *record; ++ bool ret_found, is_terminator; + struct sm6_block *code_block; + struct sm6_value *dst; + size_t i, block_idx; -+ bool ret_found; -+ enum -+ { -+ RESULT_VALUE, -+ RESULT_TERMINATE, -+ } result_type; + + if (sm6->function_count) + { @@ -3393,10 +3937,20 @@ index 00000000000..f9efe47f95d + } + code_block = function->blocks[0]; + ++ sm6->cur_max_value = function->value_count; ++ + for (i = 1, block_idx = 0, ret_found = false; i < block->record_count; ++i) + { + sm6->p.location.column = i; + ++ if (!code_block) ++ { ++ WARN("Invalid block count %zu.\n", function->block_count); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, ++ "Invalid block count %zu.", function->block_count); ++ return VKD3D_ERROR_INVALID_SHADER; ++ } ++ + /* block->record_count - 1 is the instruction count, but some instructions + * can emit >1 IR instruction, so extra may be used. */ + if (!vkd3d_array_reserve((void **)&code_block->instructions, &code_block->instruction_capacity, @@ -3412,14 +3966,17 @@ index 00000000000..f9efe47f95d + dst = sm6_parser_get_current_value(sm6); + dst->type = NULL; + dst->value_type = VALUE_TYPE_REG; -+ result_type = RESULT_VALUE; ++ is_terminator = false; + + record = block->records[i]; + switch (record->code) + { ++ case FUNC_CODE_INST_CALL: ++ sm6_parser_emit_call(sm6, record, code_block, ins, dst); ++ break; + case FUNC_CODE_INST_RET: + sm6_parser_emit_ret(sm6, record, code_block, ins); -+ result_type = RESULT_TERMINATE; ++ is_terminator = true; + ret_found = true; + break; + default: @@ -3427,7 +3984,11 @@ index 00000000000..f9efe47f95d + return VKD3D_ERROR_INVALID_SHADER; + } + -+ if (result_type == RESULT_TERMINATE) ++ if (sm6->p.failed) ++ 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; @@ -3436,6 +3997,7 @@ index 00000000000..f9efe47f95d + code_block->instruction_count += ins->handler_idx != VKD3DSIH_NOP; + else + assert(ins->handler_idx == VKD3DSIH_NOP); ++ + sm6->value_count += !!dst->type; + } + @@ -3482,6 +4044,8 @@ index 00000000000..f9efe47f95d + switch (block->id) + { + case CONSTANTS_BLOCK: ++ function = &sm6->functions[sm6->function_count]; ++ sm6->cur_max_value = function->value_count; + return sm6_parser_constants_init(sm6, block); + + case FUNCTION_BLOCK: @@ -3589,6 +4153,7 @@ index 00000000000..f9efe47f95d +static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t *byte_code, size_t byte_code_size, + const char *source_name, struct vkd3d_shader_message_context *message_context) +{ ++ const struct shader_signature *output_signature = &sm6->p.shader_desc.output_signature; + const struct vkd3d_shader_location location = {.source_name = source_name}; + uint32_t version_token, dxil_version, token_count, magic; + unsigned int chunk_offset, chunk_size; @@ -3744,6 +4309,14 @@ index 00000000000..f9efe47f95d + return ret; + } + ++ if (!(sm6->output_params = shader_parser_get_dst_params(&sm6->p, output_signature->element_count))) ++ { ++ ERR("Failed to allocate output parameters.\n"); ++ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Out of memory allocating output parameters."); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ + function_count = dxil_block_compute_function_count(&sm6->root_block); + if (!(sm6->functions = vkd3d_calloc(function_count, sizeof(*sm6->functions)))) + { @@ -3774,6 +4347,8 @@ index 00000000000..f9efe47f95d + return ret; + } + ++ sm6_parser_init_output_signature(sm6, output_signature); ++ + if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0) + { + if (ret == VKD3D_ERROR_OUT_OF_MEMORY) @@ -3782,11 +4357,17 @@ index 00000000000..f9efe47f95d + else if (ret == VKD3D_ERROR_INVALID_SHADER) + vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, + "DXIL module is invalid."); -+ else -+ vkd3d_unreachable(); + return ret; + } + ++ if (!sm6_parser_require_space(sm6, output_signature->element_count)) ++ { ++ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Out of memory emitting shader signature declarations."); ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ } ++ sm6_parser_emit_output_signature(sm6, output_signature); ++ + for (i = 0; i < sm6->function_count; ++i) + { + if (!sm6_block_emit_instructions(sm6->functions[i].blocks[0], sm6)) @@ -3810,6 +4391,8 @@ index 00000000000..f9efe47f95d + struct sm6_parser *sm6; + int ret; + ++ ERR("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n"); ++ + if (!(sm6 = vkd3d_calloc(1, sizeof(*sm6)))) + { + ERR("Failed to allocate parser.\n"); @@ -3855,10 +4438,38 @@ index 00000000000..f9efe47f95d + return ret; +} diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index ba5bcfbfaf0..8b706e1e667 100644 +index ba5bcfbfaf0..5fe9047bf25 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -430,6 +430,51 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl +@@ -72,6 +72,27 @@ void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, c + ctx->result = VKD3D_ERROR_NOT_IMPLEMENTED; + } + ++char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) ++{ ++ struct vkd3d_string_buffer *string; ++ va_list args; ++ char *ret; ++ ++ if (!(string = hlsl_get_string_buffer(ctx))) ++ return NULL; ++ va_start(args, fmt); ++ if (vkd3d_string_buffer_vprintf(string, fmt, args) < 0) ++ { ++ va_end(args); ++ hlsl_release_string_buffer(ctx, string); ++ return NULL; ++ } ++ va_end(args); ++ ret = hlsl_strdup(ctx, string->buffer); ++ hlsl_release_string_buffer(ctx, string); ++ return ret; ++} ++ + bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var) + { + struct hlsl_scope *scope = ctx->cur_scope; +@@ -430,6 +451,51 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl return type; } @@ -3910,7 +4521,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len) { -@@ -524,7 +569,9 @@ struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_de +@@ -524,7 +590,9 @@ struct hlsl_type *hlsl_deref_get_type(struct hlsl_ctx *ctx, const struct hlsl_de unsigned int i; assert(deref); @@ -3921,7 +4532,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 type = deref->var->data_type; for (i = 0; i < deref->path_len; ++i) -@@ -626,6 +673,7 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba +@@ -626,6 +694,7 @@ struct hlsl_type *hlsl_new_array_type(struct hlsl_ctx *ctx, struct hlsl_type *ba type->e.array.type = basic_type; type->dimx = basic_type->dimx; type->dimy = basic_type->dimy; @@ -3929,21 +4540,23 @@ index ba5bcfbfaf0..8b706e1e667 100644 hlsl_type_calculate_reg_size(ctx, type); list_add_tail(&ctx->types, &type->entry); -@@ -992,20 +1040,31 @@ struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *tem +@@ -991,21 +1060,31 @@ struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *tem + { struct vkd3d_string_buffer *string; struct hlsl_ir_var *var; - static LONG counter; +- static LONG counter; - const char *name; if (!(string = hlsl_get_string_buffer(ctx))) return NULL; - vkd3d_string_buffer_printf(string, "<%s-%u>", template, InterlockedIncrement(&counter)); +- vkd3d_string_buffer_printf(string, "<%s-%u>", template, InterlockedIncrement(&counter)); - if (!(name = hlsl_strdup(ctx, string->buffer))) - { - hlsl_release_string_buffer(ctx, string); - return NULL; - } - var = hlsl_new_var(ctx, name, type, loc, NULL, 0, NULL); ++ vkd3d_string_buffer_printf(string, "<%s-%u>", template, ctx->internal_name_counter++); + var = hlsl_new_synthetic_var_named(ctx, string->buffer, type, loc, true); hlsl_release_string_buffer(ctx, string); + return var; @@ -3969,7 +4582,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 return var; } -@@ -1432,7 +1491,7 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v +@@ -1432,7 +1511,7 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v } struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, @@ -3978,7 +4591,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 { struct hlsl_ir_jump *jump; -@@ -1440,6 +1499,7 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type +@@ -1440,6 +1519,7 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type return NULL; init_node(&jump->node, HLSL_IR_JUMP, NULL, loc); jump->type = type; @@ -3986,7 +4599,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 return &jump->node; } -@@ -1484,7 +1544,7 @@ static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, +@@ -1484,7 +1564,7 @@ static bool clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, hlsl_block_cleanup(dst_block); return false; } @@ -3995,7 +4608,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 if (!list_empty(&src->uses)) { -@@ -1585,9 +1645,9 @@ static struct hlsl_ir_node *clone_if(struct hlsl_ctx *ctx, struct clone_instr_ma +@@ -1585,9 +1665,9 @@ static struct hlsl_ir_node *clone_if(struct hlsl_ctx *ctx, struct clone_instr_ma return dst; } @@ -4007,7 +4620,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 } static struct hlsl_ir_node *clone_load(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_load *src) -@@ -1728,7 +1788,7 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, +@@ -1728,7 +1808,7 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, return clone_index(ctx, map, hlsl_ir_index(instr)); case HLSL_IR_JUMP: @@ -4016,7 +4629,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 case HLSL_IR_LOAD: return clone_load(ctx, map, hlsl_ir_load(instr)); -@@ -2065,6 +2125,31 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru +@@ -2065,6 +2145,31 @@ struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const stru } } @@ -4048,7 +4661,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type) { struct vkd3d_string_buffer *string; -@@ -2123,18 +2208,18 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) +@@ -2123,18 +2228,18 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) { static const char * const names[] = { @@ -4079,7 +4692,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 }; if (type >= ARRAY_SIZE(names)) -@@ -2146,10 +2231,11 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) +@@ -2146,10 +2251,11 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) { static const char * const names[] = { @@ -4095,7 +4708,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 }; assert(type < ARRAY_SIZE(names)); -@@ -2158,11 +2244,11 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) +@@ -2158,11 +2264,11 @@ const char *hlsl_jump_type_to_string(enum hlsl_ir_jump_type type) static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_node *instr); @@ -4109,7 +4722,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 { dump_instr(ctx, buffer, instr); vkd3d_string_buffer_printf(buffer, "\n"); -@@ -2337,7 +2423,11 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) +@@ -2337,7 +2443,11 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_COS] = "cos", [HLSL_OP1_COS_REDUCED] = "cos_reduced", [HLSL_OP1_DSX] = "dsx", @@ -4121,7 +4734,17 @@ index ba5bcfbfaf0..8b706e1e667 100644 [HLSL_OP1_EXP2] = "exp2", [HLSL_OP1_FRACT] = "fract", [HLSL_OP1_LOG2] = "log2", -@@ -2400,9 +2490,9 @@ static void dump_ir_if(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, +@@ -2376,7 +2486,8 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) + [HLSL_OP2_RSHIFT] = ">>", + + [HLSL_OP3_DP2ADD] = "dp2add", +- [HLSL_OP3_LERP] = "lerp", ++ [HLSL_OP3_MOVC] = "movc", ++ [HLSL_OP3_TERNARY] = "ternary", + }; + + return op_names[op]; +@@ -2400,9 +2511,9 @@ static void dump_ir_if(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, vkd3d_string_buffer_printf(buffer, "if ("); dump_src(buffer, &if_node->condition); vkd3d_string_buffer_printf(buffer, ") {\n"); @@ -4133,7 +4756,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 vkd3d_string_buffer_printf(buffer, " %10s }", ""); } -@@ -2418,8 +2508,12 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i +@@ -2418,8 +2529,12 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i vkd3d_string_buffer_printf(buffer, "continue"); break; @@ -4148,7 +4771,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 break; case HLSL_IR_JUMP_RETURN: -@@ -2431,7 +2525,7 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i +@@ -2431,7 +2546,7 @@ static void dump_ir_jump(struct vkd3d_string_buffer *buffer, const struct hlsl_i static void dump_ir_loop(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_loop *loop) { vkd3d_string_buffer_printf(buffer, "for (;;) {\n"); @@ -4157,7 +4780,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 vkd3d_string_buffer_printf(buffer, " %10s }", ""); } -@@ -2450,6 +2544,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru +@@ -2450,6 +2565,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru [HLSL_RESOURCE_GATHER_GREEN] = "gather_green", [HLSL_RESOURCE_GATHER_BLUE] = "gather_blue", [HLSL_RESOURCE_GATHER_ALPHA] = "gather_alpha", @@ -4166,7 +4789,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 }; assert(load->load_type < ARRAY_SIZE(type_names)); -@@ -2457,8 +2553,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru +@@ -2457,8 +2574,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru dump_deref(buffer, &load->resource); vkd3d_string_buffer_printf(buffer, ", sampler = "); dump_deref(buffer, &load->sampler); @@ -4180,7 +4803,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 if (load->sample_index.node) { vkd3d_string_buffer_printf(buffer, ", sample index = "); -@@ -2614,7 +2713,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl +@@ -2614,7 +2734,7 @@ void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl vkd3d_string_buffer_printf(&buffer, "\n"); } if (func->has_body) @@ -4189,7 +4812,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 vkd3d_string_buffer_trace(&buffer); vkd3d_string_buffer_cleanup(&buffer); -@@ -2703,6 +2802,7 @@ static void free_ir_if(struct hlsl_ir_if *if_node) +@@ -2703,6 +2823,7 @@ static void free_ir_if(struct hlsl_ir_if *if_node) static void free_ir_jump(struct hlsl_ir_jump *jump) { @@ -4197,7 +4820,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 vkd3d_free(jump); } -@@ -2822,7 +2922,7 @@ void hlsl_free_attribute(struct hlsl_attribute *attr) +@@ -2822,7 +2943,7 @@ void hlsl_free_attribute(struct hlsl_attribute *attr) for (i = 0; i < attr->args_count; ++i) hlsl_src_remove(&attr->args[i]); @@ -4206,7 +4829,24 @@ index ba5bcfbfaf0..8b706e1e667 100644 vkd3d_free((void *)attr->name); vkd3d_free(attr); } -@@ -3127,8 +3227,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) +@@ -2868,6 +2989,16 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function + struct hlsl_ir_function *func; + struct rb_entry *func_entry; + ++ if (ctx->internal_func_name) ++ { ++ char *internal_name; ++ ++ if (!(internal_name = hlsl_strdup(ctx, ctx->internal_func_name))) ++ return; ++ vkd3d_free(name); ++ name = internal_name; ++ } ++ + func_entry = rb_get(&ctx->functions, name); + if (func_entry) + { +@@ -3127,8 +3258,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) { @@ -4216,7 +4856,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 switch (bt) { -@@ -3148,6 +3248,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) +@@ -3148,6 +3279,8 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) break; default: @@ -4225,7 +4865,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 break; } -@@ -3199,9 +3301,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) +@@ -3199,9 +3332,11 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) } } @@ -4238,7 +4878,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 memset(ctx, 0, sizeof(*ctx)); ctx->profile = profile; -@@ -3210,7 +3314,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, +@@ -3210,7 +3345,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files)))) return false; @@ -4247,7 +4887,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 { vkd3d_free(ctx->source_files); return false; -@@ -3249,6 +3353,19 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, +@@ -3249,6 +3384,19 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const char *source_name, return false; ctx->cur_buffer = ctx->globals_buffer; @@ -4267,7 +4907,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 return true; } -@@ -3260,6 +3377,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) +@@ -3260,6 +3408,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) struct hlsl_type *type, *next_type; unsigned int i; @@ -4276,7 +4916,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 for (i = 0; i < ctx->source_files_count; ++i) vkd3d_free((void *)ctx->source_files[i]); vkd3d_free(ctx->source_files); -@@ -3283,6 +3402,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) +@@ -3283,6 +3433,8 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) vkd3d_free((void *)buffer->name); vkd3d_free(buffer); } @@ -4285,7 +4925,7 @@ index ba5bcfbfaf0..8b706e1e667 100644 } int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, -@@ -3324,7 +3445,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d +@@ -3324,7 +3476,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -4294,8 +4934,53 @@ index ba5bcfbfaf0..8b706e1e667 100644 return VKD3D_ERROR_OUT_OF_MEMORY; if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2) +@@ -3378,3 +3530,44 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d + hlsl_ctx_cleanup(&ctx); + return ret; + } ++ ++struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl) ++{ ++ const struct hlsl_ir_function_decl *saved_cur_function = ctx->cur_function; ++ struct vkd3d_shader_code code = {.code = hlsl, .size = strlen(hlsl)}; ++ const char *saved_internal_func_name = ctx->internal_func_name; ++ struct vkd3d_string_buffer *internal_name; ++ struct hlsl_ir_function_decl *func; ++ void *saved_scanner = ctx->scanner; ++ int ret; ++ ++ TRACE("name %s, hlsl %s.\n", debugstr_a(name), debugstr_a(hlsl)); ++ ++ /* The actual name of the function is mangled with a unique prefix, both to ++ * allow defining multiple variants of a function with the same name, and to ++ * avoid polluting the user name space. */ ++ ++ if (!(internal_name = hlsl_get_string_buffer(ctx))) ++ return NULL; ++ vkd3d_string_buffer_printf(internal_name, "<%s-%u>", name, ctx->internal_name_counter++); ++ ++ /* Save and restore everything that matters. ++ * Note that saving the scope stack is hard, and shouldn't be necessary. */ ++ ++ ctx->scanner = NULL; ++ ctx->internal_func_name = internal_name->buffer; ++ ctx->cur_function = NULL; ++ ret = hlsl_lexer_compile(ctx, &code); ++ ctx->scanner = saved_scanner; ++ ctx->internal_func_name = saved_internal_func_name; ++ ctx->cur_function = saved_cur_function; ++ if (ret) ++ { ++ ERR("Failed to compile intrinsic, error %u.\n", ret); ++ hlsl_release_string_buffer(ctx, internal_name); ++ return NULL; ++ } ++ func = hlsl_get_func_decl(ctx, internal_name->buffer); ++ hlsl_release_string_buffer(ctx, internal_name); ++ return func; ++} diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index bce48e94b24..0a8d3a692a3 100644 +index bce48e94b24..2cde5d58eba 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -257,7 +257,7 @@ struct hlsl_reg @@ -4316,7 +5001,15 @@ index bce48e94b24..0a8d3a692a3 100644 struct vkd3d_shader_location loc; unsigned int args_count; struct hlsl_src args[]; -@@ -417,11 +417,15 @@ struct hlsl_ir_var +@@ -356,6 +356,7 @@ struct hlsl_attribute + #define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400 + #define HLSL_STORAGE_IN 0x00000800 + #define HLSL_STORAGE_OUT 0x00001000 ++#define HLSL_MODIFIER_INLINE 0x00002000 + + #define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ + HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ +@@ -417,11 +418,15 @@ struct hlsl_ir_var enum hlsl_sampler_dim sampler_dim; struct vkd3d_shader_location first_sampler_dim_loc; } *objects_usage[HLSL_REGSET_LAST_OBJECT + 1]; @@ -4332,7 +5025,7 @@ index bce48e94b24..0a8d3a692a3 100644 }; /* Sized array of variables representing a function's parameters. */ -@@ -502,7 +506,11 @@ enum hlsl_ir_expr_op +@@ -502,7 +507,11 @@ enum hlsl_ir_expr_op HLSL_OP1_COS, HLSL_OP1_COS_REDUCED, /* Reduced range [-pi, pi] */ HLSL_OP1_DSX, @@ -4344,7 +5037,24 @@ index bce48e94b24..0a8d3a692a3 100644 HLSL_OP1_EXP2, HLSL_OP1_FLOOR, HLSL_OP1_FRACT, -@@ -558,7 +566,8 @@ enum hlsl_ir_jump_type +@@ -541,8 +550,15 @@ enum hlsl_ir_expr_op + HLSL_OP2_NEQUAL, + HLSL_OP2_RSHIFT, + ++ /* DP2ADD(a, b, c) computes the scalar product of a.xy and b.xy, ++ * then adds c. */ + HLSL_OP3_DP2ADD, +- HLSL_OP3_LERP, ++ /* MOVC(a, b, c) returns c if a is bitwise zero and b otherwise. ++ * TERNARY(a, b, c) returns c if a == 0 and b otherwise. ++ * They differ for floating point numbers, because ++ * -0.0 == 0.0, but it is not bitwise zero. */ ++ HLSL_OP3_MOVC, ++ HLSL_OP3_TERNARY, + }; + + #define HLSL_MAX_OPERANDS 3 +@@ -558,7 +574,8 @@ enum hlsl_ir_jump_type { HLSL_IR_JUMP_BREAK, HLSL_IR_JUMP_CONTINUE, @@ -4354,7 +5064,7 @@ index bce48e94b24..0a8d3a692a3 100644 HLSL_IR_JUMP_RETURN, }; -@@ -566,6 +575,8 @@ struct hlsl_ir_jump +@@ -566,6 +583,8 @@ struct hlsl_ir_jump { struct hlsl_ir_node node; enum hlsl_ir_jump_type type; @@ -4363,7 +5073,7 @@ index bce48e94b24..0a8d3a692a3 100644 }; struct hlsl_ir_swizzle -@@ -600,9 +611,11 @@ struct hlsl_deref +@@ -600,9 +619,11 @@ struct hlsl_deref * components, within the pertaining regset), from the start of the variable, of the part * referenced. * The path is lowered to this single offset -- whose value may vary between SM1 and SM4 -- @@ -4377,7 +5087,7 @@ index bce48e94b24..0a8d3a692a3 100644 }; struct hlsl_ir_load -@@ -624,6 +637,8 @@ enum hlsl_resource_load_type +@@ -624,6 +645,8 @@ enum hlsl_resource_load_type HLSL_RESOURCE_GATHER_GREEN, HLSL_RESOURCE_GATHER_BLUE, HLSL_RESOURCE_GATHER_ALPHA, @@ -4386,7 +5096,17 @@ index bce48e94b24..0a8d3a692a3 100644 }; struct hlsl_ir_resource_load -@@ -803,7 +818,11 @@ struct hlsl_ctx +@@ -782,6 +805,9 @@ struct hlsl_ctx + /* Pointer to the current function; changes as the parser reads the code. */ + const struct hlsl_ir_function_decl *cur_function; + ++ /* Counter for generating unique internal variable names. */ ++ unsigned int internal_name_counter; ++ + /* Default matrix majority for matrix types. Can be set by a pragma within the HLSL source. */ + unsigned int matrix_majority; + +@@ -803,7 +829,11 @@ struct hlsl_ctx * Only used for SM1 profiles. */ struct hlsl_constant_defs { @@ -4399,7 +5119,28 @@ index bce48e94b24..0a8d3a692a3 100644 size_t count, size; } constant_defs; /* Number of temp. registers required for the shader to run, i.e. the largest temp register -@@ -1055,10 +1074,12 @@ const char *debug_hlsl_writemask(unsigned int writemask); +@@ -814,6 +844,12 @@ struct hlsl_ctx + * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ + uint32_t thread_count[3]; + ++ /* In some cases we generate opcodes by parsing an HLSL function and then ++ * invoking it. If not NULL, this field is the name of the function that we ++ * are currently parsing, "mangled" with an internal prefix to avoid ++ * polluting the user namespace. */ ++ const char *internal_func_name; ++ + /* Whether the parser is inside a state block (effects' metadata) inside a variable declaration. */ + uint32_t in_state_block : 1; + /* Whether the numthreads() attribute has been provided in the entry-point function. */ +@@ -1049,16 +1085,20 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) + } + } + ++char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) VKD3D_PRINTF_FUNC(2, 3); ++ + const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); + const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type); + const char *debug_hlsl_writemask(unsigned int writemask); const char *debug_hlsl_swizzle(unsigned int swizzle, unsigned int count); struct vkd3d_string_buffer *hlsl_type_to_string(struct hlsl_ctx *ctx, const struct hlsl_type *type); @@ -4413,7 +5154,7 @@ index bce48e94b24..0a8d3a692a3 100644 struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false); void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl); bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var); -@@ -1120,7 +1141,7 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond +@@ -1120,7 +1160,7 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, @@ -4422,7 +5163,7 @@ index bce48e94b24..0a8d3a692a3 100644 void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); -@@ -1132,6 +1153,8 @@ struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hls +@@ -1132,6 +1172,8 @@ struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hls const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); @@ -4431,7 +5172,7 @@ index bce48e94b24..0a8d3a692a3 100644 struct hlsl_ir_node *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs, -@@ -1156,6 +1179,8 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned in +@@ -1156,6 +1198,8 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned in struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *template, struct hlsl_type *type, const struct vkd3d_shader_location *loc); @@ -4440,7 +5181,7 @@ index bce48e94b24..0a8d3a692a3 100644 struct hlsl_type *hlsl_new_texture_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format, unsigned int sample_count); struct hlsl_type *hlsl_new_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, struct hlsl_type *format); -@@ -1187,6 +1212,8 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type); +@@ -1187,6 +1231,8 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type); unsigned int hlsl_type_get_array_element_reg_size(const struct hlsl_type *type, enum hlsl_regset regset); struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int index); @@ -4449,7 +5190,7 @@ index bce48e94b24..0a8d3a692a3 100644 bool hlsl_type_is_row_major(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type); -@@ -1227,7 +1254,7 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun +@@ -1227,9 +1273,11 @@ int hlsl_sm1_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_fun bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, bool output, D3D_NAME *usage); bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, @@ -4457,9 +5198,13 @@ index bce48e94b24..0a8d3a692a3 100644 + bool output, enum vkd3d_shader_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx); int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out); ++struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl); ++ int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl); + + #endif diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 0e07fe578e1..29e0ff0c5be 100644 +index 0e07fe578e1..fb6d485ea69 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -53,7 +53,7 @@ struct parse_initializer @@ -4499,13 +5244,13 @@ index 0e07fe578e1..29e0ff0c5be 100644 -static struct hlsl_ir_node *node_from_list(struct list *list) +static struct hlsl_ir_node *node_from_block(struct hlsl_block *block) -+{ + { +- return LIST_ENTRY(list_tail(list), struct hlsl_ir_node, entry); + return LIST_ENTRY(list_tail(&block->instrs), struct hlsl_ir_node, entry); +} + +static struct hlsl_block *make_empty_block(struct hlsl_ctx *ctx) - { -- return LIST_ENTRY(list_tail(list), struct hlsl_ir_node, entry); ++{ + struct hlsl_block *block; + + if ((block = hlsl_alloc(ctx, sizeof(*block)))) @@ -4650,7 +5395,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 struct hlsl_ir_node *loop; unsigned int i; -@@ -476,7 +486,7 @@ static struct list *create_loop(struct hlsl_ctx *ctx, enum loop_type type, const +@@ -476,53 +486,49 @@ static struct list *create_loop(struct hlsl_ctx *ctx, enum loop_type type, const } else { @@ -4659,7 +5404,16 @@ index 0e07fe578e1..29e0ff0c5be 100644 } } else if (!strcmp(attr->name, "loop") -@@ -491,38 +501,34 @@ static struct list *create_loop(struct hlsl_ctx *ctx, enum loop_type type, const + || !strcmp(attr->name, "fastopt") + || !strcmp(attr->name, "allow_uav_condition")) + { +- hlsl_fixme(ctx, loc, "Unhandled attribute %s.", attr->name); ++ hlsl_fixme(ctx, loc, "Unhandled attribute '%s'.", attr->name); + } + else + { +- hlsl_warning(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "Unrecognized attribute %s.", attr->name); ++ hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Unrecognized attribute '%s'.", attr->name); } } @@ -5081,9 +5835,8 @@ index 0e07fe578e1..29e0ff0c5be 100644 return NULL; - return add_expr(ctx, instrs, op, args, common_type, loc); -+ return add_expr(ctx, block, op, args, common_type, loc); - } - +-} +- -static struct list *add_binary_arithmetic_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -{ @@ -5093,8 +5846,9 @@ index 0e07fe578e1..29e0ff0c5be 100644 - vkd3d_free(list2); - add_binary_arithmetic_expr(ctx, list1, op, arg1, arg2, loc); - return list1; --} -- ++ return add_expr(ctx, block, op, args, common_type, loc); + } + -static struct hlsl_ir_node *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_bitwise_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, @@ -5104,8 +5858,9 @@ index 0e07fe578e1..29e0ff0c5be 100644 check_integer_type(ctx, arg2); - return add_binary_arithmetic_expr(ctx, instrs, op, arg1, arg2, loc); --} -- ++ return add_binary_arithmetic_expr(ctx, block, op, arg1, arg2, loc); + } + -static struct list *add_binary_bitwise_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -{ @@ -5116,9 +5871,8 @@ index 0e07fe578e1..29e0ff0c5be 100644 - add_binary_bitwise_expr(ctx, list1, op, arg1, arg2, loc); - - return list1; -+ return add_binary_arithmetic_expr(ctx, block, op, arg1, arg2, loc); - } - +-} +- -static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, @@ -5202,8 +5956,9 @@ index 0e07fe578e1..29e0ff0c5be 100644 return NULL; - return add_expr(ctx, instrs, op, args, return_type, loc); --} -- ++ return add_expr(ctx, block, op, args, return_type, loc); + } + -static struct list *add_binary_shift_expr_merge(struct hlsl_ctx *ctx, struct list *list1, struct list *list2, - enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) -{ @@ -5214,9 +5969,8 @@ index 0e07fe578e1..29e0ff0c5be 100644 - add_binary_shift_expr(ctx, list1, op, arg1, arg2, loc); - - return list1; -+ return add_expr(ctx, block, op, args, return_type, loc); - } - +-} +- -static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct list *instrs, +static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, const struct vkd3d_shader_location *loc) @@ -5499,11 +6253,11 @@ index 0e07fe578e1..29e0ff0c5be 100644 - vkd3d_free(var_list); - return NULL; - } -- -- if (!var_list) -- return statements_list; + type = basic_type; +- if (!var_list) +- return statements_list; +- - invalid_modifiers = modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT); - if (invalid_modifiers) + if (shader_is_sm_5_1(ctx) && type->class == HLSL_CLASS_OBJECT) @@ -5637,11 +6391,11 @@ index 0e07fe578e1..29e0ff0c5be 100644 } - vkd3d_free(v->arrays.sizes); + } - -- if (!(var = hlsl_new_var(ctx, v->name, type, &v->loc, &v->semantic, modifiers, &v->reg_reservation))) ++ + if (!(var_name = vkd3d_strdup(v->name))) + return; -+ + +- if (!(var = hlsl_new_var(ctx, v->name, type, &v->loc, &v->semantic, modifiers, &v->reg_reservation))) + new_semantic = v->semantic; + if (v->semantic.name) + { @@ -5781,7 +6535,8 @@ index 0e07fe578e1..29e0ff0c5be 100644 + "Const variable \"%s\" is missing an initializer.", var->name); } + } -+ + +- if (!hlsl_add_var(ctx, var, local)) + if ((var->storage_modifiers & HLSL_STORAGE_STATIC) && type_has_numeric_components(var->data_type) + && type_has_object_components(var->data_type, false)) + { @@ -5792,8 +6547,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 + if (!hlsl_add_var(ctx, var, local)) + { + struct hlsl_ir_var *old = hlsl_get_var(ctx->cur_scope, var->name); - -- if (!hlsl_add_var(ctx, var, local)) ++ + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_REDEFINED, + "Variable \"%s\" was already declared in this scope.", var->name); + hlsl_note(ctx, &old->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously declared here.", old->name); @@ -5912,7 +6666,100 @@ index 0e07fe578e1..29e0ff0c5be 100644 } struct find_function_call_args -@@ -2394,18 +2447,18 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, +@@ -2277,6 +2330,92 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, + return args.decl; + } + ++static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; ++ ++ return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc); ++} ++ ++static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, ++ const struct parse_initializer *args, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *call; ++ unsigned int i; ++ ++ assert(args->args_count == func->parameters.count); ++ ++ for (i = 0; i < func->parameters.count; ++i) ++ { ++ struct hlsl_ir_var *param = func->parameters.vars[i]; ++ struct hlsl_ir_node *arg = args->args[i]; ++ ++ if (!hlsl_types_are_equal(arg->data_type, param->data_type)) ++ { ++ struct hlsl_ir_node *cast; ++ ++ if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) ++ return false; ++ args->args[i] = cast; ++ arg = cast; ++ } ++ ++ if (param->storage_modifiers & HLSL_STORAGE_IN) ++ { ++ struct hlsl_ir_node *store; ++ ++ if (!(store = hlsl_new_simple_store(ctx, param, arg))) ++ return false; ++ hlsl_block_add_instr(args->instrs, store); ++ } ++ } ++ ++ if (!(call = hlsl_new_call(ctx, func, loc))) ++ return false; ++ hlsl_block_add_instr(args->instrs, call); ++ ++ for (i = 0; i < func->parameters.count; ++i) ++ { ++ struct hlsl_ir_var *param = func->parameters.vars[i]; ++ struct hlsl_ir_node *arg = args->args[i]; ++ ++ if (param->storage_modifiers & HLSL_STORAGE_OUT) ++ { ++ struct hlsl_ir_load *load; ++ ++ if (arg->data_type->modifiers & HLSL_MODIFIER_CONST) ++ hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, ++ "Output argument to \"%s\" is const.", func->func->name); ++ ++ if (!(load = hlsl_new_var_load(ctx, param, &arg->loc))) ++ return false; ++ hlsl_block_add_instr(args->instrs, &load->node); ++ ++ if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) ++ return false; ++ } ++ } ++ ++ if (func->return_var) ++ { ++ struct hlsl_ir_load *load; ++ ++ if (!(load = hlsl_new_var_load(ctx, func->return_var, loc))) ++ return false; ++ hlsl_block_add_instr(args->instrs, &load->node); ++ } ++ else ++ { ++ struct hlsl_ir_node *expr; ++ ++ if (!(expr = hlsl_new_void_expr(ctx, loc))) ++ return false; ++ hlsl_block_add_instr(args->instrs, expr); ++ } ++ ++ return true; ++} ++ + static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, + const struct parse_initializer *params, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) + { +@@ -2394,18 +2533,18 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, if (!(one = hlsl_new_float_constant(ctx, 1.0f, loc))) return false; @@ -5934,7 +6781,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 return false; if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, load, mul, loc))) -@@ -2431,7 +2484,7 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, +@@ -2431,7 +2570,7 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, { if (!(zero = hlsl_new_float_constant(ctx, 0.0f, loc))) return false; @@ -5943,7 +6790,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) return false; -@@ -2442,14 +2495,14 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, +@@ -2442,14 +2581,14 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, { if (!(bfalse = hlsl_new_bool_constant(ctx, false, loc))) return false; @@ -5960,7 +6807,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 return false; if (!(or = add_binary_bitwise_expr(ctx, params->instrs, HLSL_OP2_BIT_OR, or, load, loc))) -@@ -2544,6 +2597,34 @@ static bool intrinsic_clamp(struct hlsl_ctx *ctx, +@@ -2544,6 +2683,34 @@ static bool intrinsic_clamp(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MIN, max, params->args[2], loc); } @@ -5995,7 +6842,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 static bool intrinsic_cos(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -2579,26 +2660,26 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, +@@ -2579,26 +2746,26 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) return false; @@ -6027,7 +6874,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl2, arg2_swzl2, loc))) return false; -@@ -2617,6 +2698,28 @@ static bool intrinsic_ddx(struct hlsl_ctx *ctx, +@@ -2617,6 +2784,28 @@ static bool intrinsic_ddx(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX, arg, loc); } @@ -6056,7 +6903,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 static bool intrinsic_ddy(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -2628,6 +2731,28 @@ static bool intrinsic_ddy(struct hlsl_ctx *ctx, +@@ -2628,6 +2817,28 @@ static bool intrinsic_ddy(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY, arg, loc); } @@ -6085,7 +6932,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 static bool intrinsic_distance(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { -@@ -2668,7 +2793,7 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx, +@@ -2668,7 +2879,7 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx, /* 1/ln(2) */ if (!(coeff = hlsl_new_float_constant(ctx, 1.442695f, loc))) return false; @@ -6094,7 +6941,15 @@ index 0e07fe578e1..29e0ff0c5be 100644 if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, coeff, params->args[0], loc))) return false; -@@ -2715,7 +2840,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer +@@ -2702,6 +2913,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer + const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_node *x, *y, *div, *abs, *frac, *neg_frac, *ge, *select, *zero; ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; + static const struct hlsl_constant_value zero_value; + + if (!(x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) +@@ -2715,7 +2927,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer if (!(zero = hlsl_new_constant(ctx, div->data_type, &zero_value, loc))) return false; @@ -6103,7 +6958,19 @@ index 0e07fe578e1..29e0ff0c5be 100644 if (!(abs = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, div, loc))) return false; -@@ -2806,7 +2931,7 @@ static bool intrinsic_lerp(struct hlsl_ctx *ctx, +@@ -2729,7 +2941,10 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer + if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc))) + return false; + +- if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac))) ++ operands[0] = ge; ++ operands[1] = frac; ++ operands[2] = neg_frac; ++ if (!(select = add_expr(ctx, params->instrs, HLSL_OP3_TERNARY, operands, x->data_type, loc))) + return false; + + return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, select, y, loc); +@@ -2806,7 +3021,7 @@ static bool intrinsic_lerp(struct hlsl_ctx *ctx, } static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, @@ -6112,49 +6979,106 @@ index 0e07fe578e1..29e0ff0c5be 100644 const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *log, *mul; -@@ -2861,15 +2986,15 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, - init_value.u[3].f = 1.0f; - if (!(init = hlsl_new_constant(ctx, ret_type, &init_value, loc))) +@@ -2823,14 +3038,17 @@ static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, + static bool intrinsic_lit(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +- struct hlsl_ir_node *n_l_neg, *n_h_neg, *specular_or, *specular_pow, *load; +- struct hlsl_ir_node *n_l, *n_h, *m, *diffuse, *zero, *store, *init; +- struct hlsl_constant_value init_value; +- struct hlsl_ir_load *var_load; +- struct hlsl_deref var_deref; +- struct hlsl_type *ret_type; +- struct hlsl_ir_var *var; +- struct hlsl_block block; ++ struct hlsl_ir_function_decl *func; ++ ++ static const char body[] = ++ "float4 lit(float n_l, float n_h, float m)\n" ++ "{\n" ++ " float4 ret;\n" ++ " ret.xw = 1.0;\n" ++ " ret.y = max(n_l, 0);\n" ++ " ret.z = (n_l < 0 || n_h < 0) ? 0 : pow(n_h, m);\n" ++ " return ret;\n" ++ "}"; + + if (params->args[0]->data_type->class != HLSL_CLASS_SCALAR + || params->args[1]->data_type->class != HLSL_CLASS_SCALAR +@@ -2840,70 +3058,10 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, return false; + } + +- if (!(n_l = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) +- return false; +- +- if (!(n_h = intrinsic_float_convert_arg(ctx, params, params->args[1], loc))) +- return false; +- +- if (!(m = intrinsic_float_convert_arg(ctx, params, params->args[2], loc))) +- return false; +- +- ret_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); +- +- if (!(var = hlsl_new_synthetic_var(ctx, "lit", ret_type, loc))) +- return false; +- hlsl_init_simple_deref_from_var(&var_deref, var); +- +- init_value.u[0].f = 1.0f; +- init_value.u[1].f = 0.0f; +- init_value.u[2].f = 0.0f; +- init_value.u[3].f = 1.0f; +- if (!(init = hlsl_new_constant(ctx, ret_type, &init_value, loc))) +- return false; - list_add_tail(params->instrs, &init->entry); -+ hlsl_block_add_instr(params->instrs, init); - - if (!(store = hlsl_new_simple_store(ctx, var, init))) - return false; +- +- if (!(store = hlsl_new_simple_store(ctx, var, init))) +- return false; - list_add_tail(params->instrs, &store->entry); -+ hlsl_block_add_instr(params->instrs, store); - - if (!(zero = hlsl_new_float_constant(ctx, 0.0f, loc))) - return false; +- +- if (!(zero = hlsl_new_float_constant(ctx, 0.0f, loc))) +- return false; - list_add_tail(params->instrs, &zero->entry); -+ hlsl_block_add_instr(params->instrs, zero); - - /* Diffuse component. */ - if (!(diffuse = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, n_l, zero, loc))) -@@ -2877,7 +3002,7 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, - - if (!hlsl_new_store_component(ctx, &block, &var_deref, 1, diffuse)) - return false; +- +- /* Diffuse component. */ +- if (!(diffuse = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, n_l, zero, loc))) +- return false; +- +- if (!hlsl_new_store_component(ctx, &block, &var_deref, 1, diffuse)) +- return false; - list_move_tail(params->instrs, &block.instrs); -+ hlsl_block_add_block(params->instrs, &block); - - /* Specular component. */ - if (!(n_h_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_h, zero, loc))) -@@ -2897,11 +3022,11 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, - - if (!hlsl_new_store_component(ctx, &block, &var_deref, 2, load)) - return false; +- +- /* Specular component. */ +- if (!(n_h_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_h, zero, loc))) +- return false; +- +- if (!(n_l_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_l, zero, loc))) +- return false; +- +- if (!(specular_or = add_binary_logical_expr(ctx, params->instrs, HLSL_OP2_LOGIC_OR, n_l_neg, n_h_neg, loc))) +- return false; +- +- if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc))) +- return false; +- +- if (!(load = hlsl_add_conditional(ctx, params->instrs, specular_or, zero, specular_pow))) +- return false; +- +- if (!hlsl_new_store_component(ctx, &block, &var_deref, 2, load)) +- return false; - list_move_tail(params->instrs, &block.instrs); -+ hlsl_block_add_block(params->instrs, &block); - - if (!(var_load = hlsl_new_var_load(ctx, var, loc))) +- +- if (!(var_load = hlsl_new_var_load(ctx, var, loc))) ++ if (!(func = hlsl_compile_internal_function(ctx, "lit", body))) return false; - list_add_tail(params->instrs, &var_load->node.entry); -+ hlsl_block_add_instr(params->instrs, &var_load->node); - return true; +- return true; ++ return add_user_call(ctx, func, params, loc); } -@@ -3034,10 +3159,12 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, + + static bool intrinsic_log(struct hlsl_ctx *ctx, +@@ -3034,10 +3192,12 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, { struct hlsl_ir_node *value1, *value2, *mul; @@ -6169,7 +7093,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 return false; if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, value1, value2, loc))) -@@ -3056,13 +3183,13 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, +@@ -3056,13 +3216,13 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, if (!hlsl_new_store_component(ctx, &block, &var_deref, j * matrix_type->dimx + i, instr)) return false; @@ -6185,7 +7109,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); } -@@ -3169,7 +3296,7 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, +@@ -3169,7 +3329,7 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, if (!(zero = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, arg->data_type->base_type), &zero_value, loc))) return false; @@ -6194,30 +7118,90 @@ index 0e07fe578e1..29e0ff0c5be 100644 /* Check if 0 < arg, cast bool to int */ -@@ -3229,7 +3356,7 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, +@@ -3205,62 +3365,33 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc); + } - if (!(one = hlsl_new_float_constant(ctx, 1.0, loc))) - return false; +-/* smoothstep(a, b, x) = p^2 (3 - 2p), where p = saturate((x - a)/(b - a)) */ +-static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, +- const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +-{ +- struct hlsl_ir_node *min_arg, *max_arg, *x_arg, *p, *p_num, *p_denom, *res, *one, *minus_two, *three; +- +- if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) +- return false; +- +- min_arg = params->args[0]; +- max_arg = params->args[1]; +- x_arg = params->args[2]; +- +- if (!(min_arg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, min_arg, loc))) +- return false; +- +- if (!(p_num = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, x_arg, min_arg, loc))) +- return false; +- +- if (!(p_denom = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, max_arg, min_arg, loc))) +- return false; +- +- if (!(one = hlsl_new_float_constant(ctx, 1.0, loc))) +- return false; - list_add_tail(params->instrs, &one->entry); -+ hlsl_block_add_instr(params->instrs, one); - - if (!(p_denom = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, one, p_denom, loc))) - return false; -@@ -3242,11 +3369,11 @@ static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, - - if (!(minus_two = hlsl_new_float_constant(ctx, -2.0, loc))) - return false; +- +- if (!(p_denom = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, one, p_denom, loc))) +- return false; +- +- if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p_num, p_denom, loc))) +- return false; +- +- if (!(p = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, p, loc))) +- return false; +- +- if (!(minus_two = hlsl_new_float_constant(ctx, -2.0, loc))) +- return false; - list_add_tail(params->instrs, &minus_two->entry); -+ hlsl_block_add_instr(params->instrs, minus_two); - - if (!(three = hlsl_new_float_constant(ctx, 3.0, loc))) - return false; +- +- if (!(three = hlsl_new_float_constant(ctx, 3.0, loc))) +- return false; - list_add_tail(params->instrs, &three->entry); -+ hlsl_block_add_instr(params->instrs, three); ++/* smoothstep(a, b, x) = p^2 (3 - 2p), where p = saturate((x - a)/(b - a)) */ ++static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_function_decl *func; ++ struct hlsl_type *type; ++ char *body; - if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, minus_two, p, loc))) +- if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, minus_two, p, loc))) +- return false; ++ static const char template[] = ++ "%s smoothstep(%s low, %s high, %s x)\n" ++ "{\n" ++ " %s p = saturate((x - low) / (high - low));\n" ++ " return (p * p) * (3 - 2 * p);\n" ++ "}"; + +- if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, three, res, loc))) ++ if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc))) return false; -@@ -3308,7 +3435,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * ++ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); + +- if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p, p, loc))) ++ if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name, type->name, type->name))) + return false; +- +- if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p, res, loc))) ++ func = hlsl_compile_internal_function(ctx, "smoothstep", body); ++ vkd3d_free(body); ++ if (!func) + return false; + +- return true; ++ return add_user_call(ctx, func, params, loc); + } + + static bool intrinsic_sqrt(struct hlsl_ctx *ctx, +@@ -3308,7 +3439,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * if (params->args_count == 4) { @@ -6226,7 +7210,51 @@ index 0e07fe578e1..29e0ff0c5be 100644 } sampler_type = params->args[0]->data_type; -@@ -3335,7 +3462,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * +@@ -3326,7 +3457,42 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * + + if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc))) +- coords = params->args[1]; ++ { ++ return false; ++ } ++ ++ /* tex1D() functions never produce 1D resource declarations. For newer profiles half offset ++ is used for the second coordinate, while older ones appear to replicate first coordinate.*/ ++ if (dim == HLSL_SAMPLER_DIM_1D) ++ { ++ struct hlsl_ir_load *load; ++ struct hlsl_ir_node *half; ++ struct hlsl_ir_var *var; ++ unsigned int idx = 0; ++ ++ if (!(var = hlsl_new_synthetic_var(ctx, "coords", hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), loc))) ++ return false; ++ ++ initialize_var_components(ctx, params->instrs, var, &idx, coords); ++ if (shader_profile_version_ge(ctx, 4, 0)) ++ { ++ if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc))) ++ return false; ++ hlsl_block_add_instr(params->instrs, half); ++ ++ initialize_var_components(ctx, params->instrs, var, &idx, half); ++ } ++ else ++ initialize_var_components(ctx, params->instrs, var, &idx, coords); ++ ++ if (!(load = hlsl_new_var_load(ctx, var, loc))) ++ return false; ++ hlsl_block_add_instr(params->instrs, &load->node); ++ ++ coords = &load->node; ++ ++ dim = HLSL_SAMPLER_DIM_2D; ++ } + + load_params.coords = coords; + load_params.resource = params->args[0]; +@@ -3335,10 +3501,16 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; @@ -6235,7 +7263,29 @@ index 0e07fe578e1..29e0ff0c5be 100644 return true; } -@@ -3369,7 +3496,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, ++static bool intrinsic_tex1D(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ return intrinsic_tex(ctx, params, loc, "tex1D", HLSL_SAMPLER_DIM_1D); ++} ++ + static bool intrinsic_tex2D(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -3351,6 +3523,12 @@ static bool intrinsic_tex3D(struct hlsl_ctx *ctx, + return intrinsic_tex(ctx, params, loc, "tex3D", HLSL_SAMPLER_DIM_3D); + } + ++static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE); ++} ++ + static bool intrinsic_transpose(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -3369,7 +3547,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, if ((string = hlsl_type_to_string(ctx, arg_type))) hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, @@ -6244,7 +7294,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 string->buffer); hlsl_release_string_buffer(ctx, string); return false; -@@ -3377,7 +3504,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, +@@ -3377,7 +3555,7 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, if (arg_type->class == HLSL_CLASS_SCALAR) { @@ -6253,7 +7303,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 return true; } -@@ -3393,18 +3520,18 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, +@@ -3393,18 +3571,18 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { struct hlsl_block block; @@ -6275,7 +7325,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 return true; } -@@ -3444,13 +3571,13 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, +@@ -3444,13 +3622,13 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, if (!(c = hlsl_new_float_constant(ctx, 255.0f + (0.5f / 256.0f), loc))) return false; @@ -6291,7 +7341,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 arg = swizzle; } -@@ -3458,7 +3585,7 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, +@@ -3458,7 +3636,7 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, if (!(ret = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, c, loc))) return false; @@ -6300,7 +7350,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_TRUNC, ret, loc); return true; -@@ -3482,10 +3609,15 @@ intrinsic_functions[] = +@@ -3482,10 +3660,15 @@ intrinsic_functions[] = {"asfloat", 1, true, intrinsic_asfloat}, {"asuint", -1, true, intrinsic_asuint}, {"clamp", 3, true, intrinsic_clamp}, @@ -6316,68 +7366,108 @@ index 0e07fe578e1..29e0ff0c5be 100644 {"distance", 2, true, intrinsic_distance}, {"dot", 2, true, intrinsic_dot}, {"exp", 1, true, intrinsic_exp}, -@@ -3527,7 +3659,14 @@ static int intrinsic_function_name_compare(const void *a, const void *b) +@@ -3514,8 +3697,10 @@ intrinsic_functions[] = + {"smoothstep", 3, true, intrinsic_smoothstep}, + {"sqrt", 1, true, intrinsic_sqrt}, + {"step", 2, true, intrinsic_step}, ++ {"tex1D", -1, false, intrinsic_tex1D}, + {"tex2D", -1, false, intrinsic_tex2D}, + {"tex3D", -1, false, intrinsic_tex3D}, ++ {"texCUBE", -1, false, intrinsic_texCUBE}, + {"transpose", 1, true, intrinsic_transpose}, + {"trunc", 1, true, intrinsic_trunc}, + }; +@@ -3527,7 +3712,7 @@ static int intrinsic_function_name_compare(const void *a, const void *b) return strcmp(a, func->name); } -static struct list *add_call(struct hlsl_ctx *ctx, const char *name, -+static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; -+ -+ return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc); -+} -+ +static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name, struct parse_initializer *args, const struct vkd3d_shader_location *loc) { struct intrinsic_function *intrinsic; -@@ -3561,13 +3700,13 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, +@@ -3535,79 +3720,8 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, - if (!(store = hlsl_new_simple_store(ctx, param, arg))) - goto fail; + if ((decl = find_function_call(ctx, name, args, loc))) + { +- struct hlsl_ir_node *call; +- unsigned int i; +- +- assert(args->args_count == decl->parameters.count); +- +- for (i = 0; i < decl->parameters.count; ++i) +- { +- struct hlsl_ir_var *param = decl->parameters.vars[i]; +- struct hlsl_ir_node *arg = args->args[i]; +- +- if (!hlsl_types_are_equal(arg->data_type, param->data_type)) +- { +- struct hlsl_ir_node *cast; +- +- if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) +- goto fail; +- args->args[i] = cast; +- arg = cast; +- } +- +- if (param->storage_modifiers & HLSL_STORAGE_IN) +- { +- struct hlsl_ir_node *store; +- +- if (!(store = hlsl_new_simple_store(ctx, param, arg))) +- goto fail; - list_add_tail(args->instrs, &store->entry); -+ hlsl_block_add_instr(args->instrs, store); - } - } - - if (!(call = hlsl_new_call(ctx, decl, loc))) +- } +- } +- +- if (!(call = hlsl_new_call(ctx, decl, loc))) ++ if (!add_user_call(ctx, decl, args, loc)) goto fail; - list_add_tail(args->instrs, &call->entry); -+ hlsl_block_add_instr(args->instrs, call); - - for (i = 0; i < decl->parameters.count; ++i) - { -@@ -3584,7 +3723,7 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, - - if (!(load = hlsl_new_var_load(ctx, param, &arg->loc))) - goto fail; +- +- for (i = 0; i < decl->parameters.count; ++i) +- { +- struct hlsl_ir_var *param = decl->parameters.vars[i]; +- struct hlsl_ir_node *arg = args->args[i]; +- +- if (param->storage_modifiers & HLSL_STORAGE_OUT) +- { +- struct hlsl_ir_load *load; +- +- if (arg->data_type->modifiers & HLSL_MODIFIER_CONST) +- hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, +- "Output argument to \"%s\" is const.", decl->func->name); +- +- if (!(load = hlsl_new_var_load(ctx, param, &arg->loc))) +- goto fail; - list_add_tail(args->instrs, &load->node.entry); -+ hlsl_block_add_instr(args->instrs, &load->node); - - if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) - goto fail; -@@ -3597,16 +3736,15 @@ static struct list *add_call(struct hlsl_ctx *ctx, const char *name, - - if (!(load = hlsl_new_var_load(ctx, decl->return_var, loc))) - goto fail; +- +- if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) +- goto fail; +- } +- } +- +- if (decl->return_var) +- { +- struct hlsl_ir_load *load; +- +- if (!(load = hlsl_new_var_load(ctx, decl->return_var, loc))) +- goto fail; - list_add_tail(args->instrs, &load->node.entry); -+ hlsl_block_add_instr(args->instrs, &load->node); - } - else - { +- } +- else +- { - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_ir_node *expr; - +- struct hlsl_ir_node *expr; +- - if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc))) -+ if (!(expr = hlsl_new_void_expr(ctx, loc))) - goto fail; +- goto fail; - list_add_tail(args->instrs, &expr->entry); -+ hlsl_block_add_instr(args->instrs, expr); - } +- } } else if ((intrinsic = bsearch(name, intrinsic_functions, ARRAY_SIZE(intrinsic_functions), -@@ -3662,7 +3800,7 @@ fail: + sizeof(*intrinsic_functions), intrinsic_function_name_compare))) +@@ -3662,7 +3776,7 @@ fail: return NULL; } @@ -6386,7 +7476,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_load *load; -@@ -3692,7 +3830,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type +@@ -3692,7 +3806,7 @@ static struct list *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type if (!(load = hlsl_new_var_load(ctx, var, loc))) return NULL; @@ -6395,7 +7485,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 vkd3d_free(params->args); return params->instrs; -@@ -3733,7 +3871,7 @@ static bool raise_invalid_method_object_type(struct hlsl_ctx *ctx, const struct +@@ -3733,7 +3847,7 @@ static bool raise_invalid_method_object_type(struct hlsl_ctx *ctx, const struct return false; } @@ -6404,7 +7494,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; -@@ -3761,7 +3899,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru +@@ -3761,7 +3875,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru } if (multisampled) { @@ -6413,7 +7503,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc))) return false; } -@@ -3769,7 +3907,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru +@@ -3769,7 +3883,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru assert(offset_dim); if (params->args_count > 1 + multisampled) { @@ -6422,7 +7512,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } -@@ -3779,7 +3917,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru +@@ -3779,7 +3893,7 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru } /* +1 for the mipmap level for non-multisampled textures */ @@ -6431,7 +7521,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc))) return false; -@@ -3788,11 +3926,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru +@@ -3788,11 +3902,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct list *instrs, stru if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; @@ -6445,7 +7535,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; -@@ -3829,13 +3967,13 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st +@@ -3829,13 +3943,13 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return false; } @@ -6461,7 +7551,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } -@@ -3851,12 +3989,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st +@@ -3851,12 +3965,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct list *instrs, st if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; @@ -6476,7 +7566,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; -@@ -3899,17 +4037,17 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs +@@ -3899,17 +4013,17 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs return false; } @@ -6497,7 +7587,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } -@@ -3925,12 +4063,12 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs +@@ -3925,12 +4039,12 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct list *instrs if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; @@ -6512,7 +7602,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; -@@ -3997,7 +4135,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st +@@ -3997,7 +4111,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st } else if (offset_dim && params->args_count > 2) { @@ -6521,7 +7611,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } -@@ -4022,7 +4160,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st +@@ -4022,7 +4136,7 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st return false; } @@ -6530,7 +7620,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) return false; -@@ -4032,11 +4170,187 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st +@@ -4032,11 +4146,187 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct list *instrs, st if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; @@ -6720,7 +7810,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; -@@ -4078,17 +4392,17 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs +@@ -4078,17 +4368,17 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs return false; } @@ -6741,7 +7831,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } -@@ -4102,11 +4416,11 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs +@@ -4102,11 +4392,11 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct list *instrs if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; @@ -6755,7 +7845,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; -@@ -4145,21 +4459,21 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr +@@ -4145,21 +4435,21 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr return false; } @@ -6781,7 +7871,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) return false; } -@@ -4173,14 +4487,14 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr +@@ -4173,14 +4463,14 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct list *instr if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) return false; @@ -6798,7 +7888,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc); } object_methods[] = -@@ -4191,6 +4505,8 @@ object_methods[] = +@@ -4191,6 +4481,8 @@ object_methods[] = { "GatherGreen", add_gather_method_call }, { "GatherRed", add_gather_method_call }, @@ -6807,7 +7897,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 { "Load", add_load_method_call }, { "Sample", add_sample_method_call }, -@@ -4208,7 +4524,7 @@ static int object_method_function_name_compare(const void *a, const void *b) +@@ -4208,7 +4500,7 @@ static int object_method_function_name_compare(const void *a, const void *b) return strcmp(a, func->name); } @@ -6816,7 +7906,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; -@@ -4229,7 +4545,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl +@@ -4229,7 +4521,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct list *instrs, struct hl if ((method = bsearch(name, object_methods, ARRAY_SIZE(object_methods), sizeof(*method), object_method_function_name_compare))) { @@ -6825,7 +7915,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 } else { -@@ -4272,6 +4588,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -4272,6 +4564,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type char *name; DWORD modifiers; struct hlsl_ir_node *instr; @@ -6833,7 +7923,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 struct list *list; struct parse_fields fields; struct parse_function function; -@@ -4399,38 +4716,9 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -4399,38 +4692,9 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %token C_INTEGER %token PRE_LINE @@ -6873,7 +7963,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 %token VAR_IDENTIFIER %token NEW_IDENTIFIER -@@ -4446,6 +4734,35 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -4446,6 +4710,35 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %type attribute_list %type attribute_list_optional @@ -6909,7 +7999,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 %type boolean %type buffer_type -@@ -4493,6 +4810,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type +@@ -4493,6 +4786,7 @@ static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type %type type_spec %type variable_decl %type variable_def @@ -6917,7 +8007,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 %% -@@ -4502,9 +4820,9 @@ hlsl_prog: +@@ -4502,9 +4796,9 @@ hlsl_prog: | hlsl_prog buffer_declaration buffer_body | hlsl_prog declaration_statement { @@ -6929,7 +8019,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 } | hlsl_prog preproc_directive | hlsl_prog ';' -@@ -4561,25 +4879,19 @@ preproc_directive: +@@ -4561,25 +4855,19 @@ preproc_directive: } } @@ -6964,7 +8054,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 } struct_spec: -@@ -4686,7 +4998,7 @@ attribute: +@@ -4686,7 +4974,7 @@ attribute: YYABORT; } $$->name = $2; @@ -6973,7 +8063,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 $$->loc = @$; $$->args_count = 0; } -@@ -4701,8 +5013,8 @@ attribute: +@@ -4701,8 +4989,8 @@ attribute: YYABORT; } $$->name = $2; @@ -6984,7 +8074,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 vkd3d_free($4.instrs); $$->loc = @$; $$->args_count = $4.args_count; -@@ -4758,15 +5070,15 @@ func_declaration: +@@ -4758,15 +5046,15 @@ func_declaration: "Function \"%s\" is already defined.", decl->func->name); hlsl_note(ctx, &decl->loc, VKD3D_SHADER_LOG_ERROR, "\"%s\" was previously defined here.", decl->func->name); @@ -7003,7 +8093,17 @@ index 0e07fe578e1..29e0ff0c5be 100644 /* Semantics are taken from whichever definition has a body. * We can't just replace the hlsl_ir_var pointers, though: if -@@ -4943,7 +5255,7 @@ func_prototype: +@@ -4817,6 +5105,9 @@ func_prototype_no_attrs: + struct hlsl_ir_var *var; + struct hlsl_type *type; + ++ /* Functions are unconditionally inlined. */ ++ modifiers &= ~HLSL_MODIFIER_INLINE; ++ + if (modifiers & ~HLSL_MODIFIERS_MAJORITY_MASK) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Only majority modifiers are allowed on functions."); +@@ -4943,7 +5234,7 @@ func_prototype: compound_statement: '{' '}' { @@ -7012,7 +8112,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } | '{' scope_start statement_list '}' -@@ -5261,7 +5573,12 @@ type_no_void: +@@ -5261,7 +5552,12 @@ type_no_void: { validate_texture_format_type(ctx, $3, &@3); @@ -7026,7 +8126,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 $$ = hlsl_new_texture_type(ctx, $1, $3, 0); } | texture_ms_type '<' type ',' shift_expr '>' -@@ -5270,7 +5587,7 @@ type_no_void: +@@ -5270,7 +5566,7 @@ type_no_void: struct hlsl_block block; hlsl_block_init(&block); @@ -7035,7 +8135,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 sample_count = evaluate_static_expression_as_uint(ctx, &block, &@5); -@@ -5325,7 +5642,7 @@ type_no_void: +@@ -5325,7 +5621,7 @@ type_no_void: $$ = hlsl_get_type(ctx->cur_scope, $1, true, true); if ($$->is_minimum_precision) { @@ -7044,7 +8144,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 { hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Target profile doesn't support minimum-precision types."); -@@ -5354,10 +5671,10 @@ type: +@@ -5354,10 +5650,10 @@ type: declaration_statement: declaration @@ -7057,7 +8157,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } -@@ -5416,23 +5733,12 @@ type_spec: +@@ -5416,22 +5712,11 @@ type_spec: } declaration: @@ -7071,19 +8171,18 @@ index 0e07fe578e1..29e0ff0c5be 100644 + if (!($$ = initialize_vars(ctx, $1))) YYABORT; - $$ = declare_vars(ctx, type, modifiers, &@1, $3); - } - +- } +- -variables_def_optional: - %empty - { - $$ = NULL; -- } + } - | variables_def -- + variables_def: variable_def - { -@@ -5446,6 +5752,33 @@ variables_def: +@@ -5446,6 +5731,33 @@ variables_def: list_add_tail($$, &$3->entry); } @@ -7117,7 +8216,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 variable_decl: any_identifier arrays colon_attribute { -@@ -5461,7 +5794,7 @@ state: +@@ -5461,7 +5773,7 @@ state: any_identifier '=' expr ';' { vkd3d_free($1); @@ -7126,7 +8225,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 } state_block_start: -@@ -5487,6 +5820,38 @@ variable_def: +@@ -5487,6 +5799,38 @@ variable_def: ctx->in_state_block = 0; } @@ -7165,7 +8264,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 arrays: %empty { -@@ -5495,17 +5860,12 @@ arrays: +@@ -5495,17 +5839,12 @@ arrays: } | '[' expr ']' arrays { @@ -7185,7 +8284,18 @@ index 0e07fe578e1..29e0ff0c5be 100644 $$ = $4; -@@ -5618,10 +5978,10 @@ complex_initializer: +@@ -5610,6 +5949,10 @@ var_modifiers: + { + $$ = add_modifiers(ctx, $2, HLSL_STORAGE_IN | HLSL_STORAGE_OUT, &@1); + } ++ | KW_INLINE var_modifiers ++ { ++ $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_INLINE, &@1); ++ } + + + complex_initializer: +@@ -5618,10 +5961,10 @@ complex_initializer: $$.args_count = 1; if (!($$.args = hlsl_alloc(ctx, sizeof(*$$.args)))) { @@ -7198,7 +8308,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 $$.instrs = $1; $$.braces = false; } -@@ -5653,7 +6013,7 @@ complex_initializer_list: +@@ -5653,7 +5996,7 @@ complex_initializer_list: $$.args = new_args; for (i = 0; i < $3.args_count; ++i) $$.args[$$.args_count++] = $3.args[i]; @@ -7207,7 +8317,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 free_parse_initializer(&$3); } -@@ -5666,10 +6026,10 @@ initializer_expr_list: +@@ -5666,10 +6009,10 @@ initializer_expr_list: $$.args_count = 1; if (!($$.args = hlsl_alloc(ctx, sizeof(*$$.args)))) { @@ -7220,7 +8330,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 $$.instrs = $1; $$.braces = false; } -@@ -5681,13 +6041,13 @@ initializer_expr_list: +@@ -5681,13 +6024,13 @@ initializer_expr_list: if (!(new_args = hlsl_realloc(ctx, $$.args, ($$.args_count + 1) * sizeof(*$$.args)))) { free_parse_initializer(&$$); @@ -7238,7 +8348,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 } boolean: -@@ -5705,15 +6065,14 @@ statement_list: +@@ -5705,15 +6048,14 @@ statement_list: | statement_list statement { $$ = $1; @@ -7256,7 +8366,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 | jump_statement | selection_statement | loop_statement -@@ -5721,47 +6080,47 @@ statement: +@@ -5721,47 +6063,67 @@ statement: jump_statement: KW_RETURN expr ';' { @@ -7288,22 +8398,32 @@ index 0e07fe578e1..29e0ff0c5be 100644 - if (!(discard = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD, &@1))) + + if (!(c = hlsl_new_uint_constant(ctx, ~0u, &@1))) - return false; -- list_add_tail($$, &discard->entry); ++ return false; + hlsl_block_add_instr($$, c); + + if (!(discard = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD_NZ, c, &@1))) -+ return false; + return false; +- list_add_tail($$, &discard->entry); + hlsl_block_add_instr($$, discard); } selection_statement: - KW_IF '(' expr ')' if_body +- KW_IF '(' expr ')' if_body ++ attribute_list_optional KW_IF '(' expr ')' if_body { - struct hlsl_ir_node *condition = node_from_list($3); - struct hlsl_block then_block, else_block; -+ struct hlsl_ir_node *condition = node_from_block($3); ++ struct hlsl_ir_node *condition = node_from_block($4); ++ const struct parse_attribute_list *attributes = &$1; struct hlsl_ir_node *instr; ++ unsigned int i; ++ ++ if (attribute_list_has_duplicates(attributes)) ++ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Found duplicate attribute."); ++ ++ for (i = 0; i < attributes->count; ++i) ++ { ++ const struct hlsl_attribute *attr = attributes->attrs[i]; - hlsl_block_init(&then_block); - list_move_tail(&then_block.instrs, $5.then_block); @@ -7312,29 +8432,41 @@ index 0e07fe578e1..29e0ff0c5be 100644 - list_move_tail(&else_block.instrs, $5.else_block); - vkd3d_free($5.then_block); - vkd3d_free($5.else_block); -- ++ if (!strcmp(attr->name, "branch") ++ || !strcmp(attr->name, "flatten")) ++ { ++ hlsl_warning(ctx, &@1, VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE, "Unhandled attribute '%s'.", attr->name); ++ } ++ else ++ { ++ hlsl_warning(ctx, &@1, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Unrecognized attribute '%s'.", attr->name); ++ } ++ } + - if (!(instr = hlsl_new_if(ctx, condition, &then_block, &else_block, &@1))) -+ if (!(instr = hlsl_new_if(ctx, condition, $5.then_block, $5.else_block, &@1))) ++ if (!(instr = hlsl_new_if(ctx, condition, $6.then_block, $6.else_block, &@2))) + { -+ destroy_block($5.then_block); -+ destroy_block($5.else_block); ++ destroy_block($6.then_block); ++ destroy_block($6.else_block); YYABORT; + } -+ destroy_block($5.then_block); -+ destroy_block($5.else_block); ++ destroy_block($6.then_block); ++ destroy_block($6.else_block); if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1) { struct vkd3d_string_buffer *string; -@@ -5772,7 +6131,7 @@ selection_statement: +@@ -5771,8 +6133,8 @@ selection_statement: + "if condition type %s is not scalar.", string->buffer); hlsl_release_string_buffer(ctx, string); } - $$ = $3; +- $$ = $3; - list_add_tail($$, &instr->entry); ++ $$ = $4; + hlsl_block_add_instr($$, instr); } if_body: -@@ -5810,7 +6169,7 @@ loop_statement: +@@ -5810,7 +6172,7 @@ loop_statement: expr_optional: %empty { @@ -7343,7 +8475,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } | expr -@@ -5826,7 +6185,7 @@ func_arguments: +@@ -5826,7 +6188,7 @@ func_arguments: { $$.args = NULL; $$.args_count = 0; @@ -7352,7 +8484,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; $$.braces = false; } -@@ -5839,7 +6198,7 @@ primary_expr: +@@ -5839,7 +6201,7 @@ primary_expr: if (!(c = hlsl_new_float_constant(ctx, $1, &@1))) YYABORT; @@ -7361,7 +8493,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } | C_INTEGER -@@ -5848,7 +6207,7 @@ primary_expr: +@@ -5848,7 +6210,7 @@ primary_expr: if (!(c = hlsl_new_int_constant(ctx, $1, &@1))) YYABORT; @@ -7370,7 +8502,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } | boolean -@@ -5857,7 +6216,7 @@ primary_expr: +@@ -5857,7 +6219,7 @@ primary_expr: if (!(c = hlsl_new_bool_constant(ctx, $1, &@1))) YYABORT; @@ -7379,7 +8511,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 { hlsl_free_instr(c); YYABORT; -@@ -5875,7 +6234,7 @@ primary_expr: +@@ -5875,7 +6237,7 @@ primary_expr: } if (!(load = hlsl_new_var_load(ctx, var, &@1))) YYABORT; @@ -7388,7 +8520,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } | '(' expr ')' -@@ -5903,7 +6262,7 @@ primary_expr: +@@ -5903,7 +6265,7 @@ primary_expr: YYABORT; if (!(load = hlsl_new_var_load(ctx, var, &@1))) YYABORT; @@ -7397,7 +8529,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } else -@@ -5919,7 +6278,7 @@ postfix_expr: +@@ -5919,7 +6281,7 @@ postfix_expr: { if (!add_increment(ctx, $1, false, true, &@2)) { @@ -7406,7 +8538,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } $$ = $1; -@@ -5928,14 +6287,14 @@ postfix_expr: +@@ -5928,14 +6290,14 @@ postfix_expr: { if (!add_increment(ctx, $1, true, true, &@2)) { @@ -7423,7 +8555,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 if (node->data_type->class == HLSL_CLASS_STRUCT) { -@@ -5963,7 +6322,7 @@ postfix_expr: +@@ -5963,7 +6325,7 @@ postfix_expr: hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid swizzle \"%s\".", $3); YYABORT; } @@ -7432,7 +8564,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 $$ = $1; } else -@@ -5974,17 +6333,17 @@ postfix_expr: +@@ -5974,17 +6336,17 @@ postfix_expr: } | postfix_expr '[' expr ']' { @@ -7456,7 +8588,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 } /* var_modifiers is necessary to avoid shift/reduce conflicts. */ -@@ -6025,14 +6384,14 @@ postfix_expr: +@@ -6025,14 +6387,14 @@ postfix_expr: } | postfix_expr '.' any_identifier '(' func_arguments ')' { @@ -7474,7 +8606,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 vkd3d_free($5.args); YYABORT; } -@@ -6046,7 +6405,7 @@ unary_expr: +@@ -6046,7 +6408,7 @@ unary_expr: { if (!add_increment(ctx, $2, false, false, &@1)) { @@ -7483,7 +8615,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } $$ = $2; -@@ -6055,7 +6414,7 @@ unary_expr: +@@ -6055,7 +6417,7 @@ unary_expr: { if (!add_increment(ctx, $2, true, false, &@1)) { @@ -7492,7 +8624,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } $$ = $2; -@@ -6066,23 +6425,23 @@ unary_expr: +@@ -6066,23 +6428,23 @@ unary_expr: } | '-' unary_expr { @@ -7520,7 +8652,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 struct hlsl_type *dst_type; unsigned int i; -@@ -6118,9 +6477,9 @@ unary_expr: +@@ -6118,9 +6480,9 @@ unary_expr: YYABORT; } @@ -7532,7 +8664,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 YYABORT; } $$ = $6; -@@ -6130,120 +6489,121 @@ mul_expr: +@@ -6130,120 +6492,122 @@ mul_expr: unary_expr | mul_expr '*' unary_expr { @@ -7666,6 +8798,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 + struct hlsl_ir_node *cond = node_from_block($1); + struct hlsl_ir_node *first = node_from_block($3); + struct hlsl_ir_node *second = node_from_block($5); ++ struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = { 0 }; struct hlsl_type *common_type; - list_move_tail($1, $3); @@ -7679,7 +8812,19 @@ index 0e07fe578e1..29e0ff0c5be 100644 if (!(common_type = get_common_numeric_type(ctx, first, second, &@3))) YYABORT; -@@ -6264,15 +6624,15 @@ assignment_expr: +@@ -6254,7 +6618,10 @@ conditional_expr: + if (!(second = add_implicit_conversion(ctx, $1, second, common_type, &@5))) + YYABORT; + +- if (!hlsl_add_conditional(ctx, $1, cond, first, second)) ++ args[0] = cond; ++ args[1] = first; ++ args[2] = second; ++ if (!add_expr(ctx, $1, HLSL_OP3_TERNARY, args, common_type, &@1)) + YYABORT; + $$ = $1; + } +@@ -6264,15 +6631,15 @@ assignment_expr: conditional_expr | unary_expr assign_op assignment_expr { @@ -7698,7 +8843,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 if (!add_assignment(ctx, $3, lhs, $2, rhs)) YYABORT; $$ = $3; -@@ -6329,6 +6689,6 @@ expr: +@@ -6329,6 +6696,6 @@ expr: | expr ',' assignment_expr { $$ = $1; @@ -7708,7 +8853,7 @@ index 0e07fe578e1..29e0ff0c5be 100644 + destroy_block($3); } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 765b1907426..bfa605f4ba7 100644 +index 765b1907426..be024842164 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -97,6 +97,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str @@ -7746,16 +8891,32 @@ index 765b1907426..bfa605f4ba7 100644 if (!(offset = new_offset_instr_from_deref(ctx, &block, deref, &instr->loc))) return false; -@@ -160,7 +161,7 @@ static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der +@@ -160,12 +161,12 @@ static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der /* Split uniforms into two variables representing the constant and temp * registers, and copy the former to the latter, so that writes to uniforms * work. */ -static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, struct hlsl_ir_var *temp) +static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_var *temp) { - struct vkd3d_string_buffer *name; +- struct vkd3d_string_buffer *name; struct hlsl_ir_var *uniform; -@@ -187,7 +188,7 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru + struct hlsl_ir_node *store; + struct hlsl_ir_load *load; ++ char *new_name; + + /* Use the synthetic name for the temp, rather than the uniform, so that we + * can write the uniform name into the shader reflection data. */ +@@ -179,15 +180,13 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct list *instrs, stru + uniform->is_param = temp->is_param; + uniform->buffer = temp->buffer; + +- if (!(name = hlsl_get_string_buffer(ctx))) ++ if (!(new_name = hlsl_sprintf_alloc(ctx, "", temp->name))) + return; +- vkd3d_string_buffer_printf(name, "", temp->name); +- temp->name = hlsl_strdup(ctx, name->buffer); +- hlsl_release_string_buffer(ctx, name); ++ temp->name = new_name; if (!(load = hlsl_new_var_load(ctx, uniform, &temp->loc))) return; @@ -7764,7 +8925,57 @@ index 765b1907426..bfa605f4ba7 100644 if (!(store = hlsl_new_simple_store(ctx, temp, &load->node))) return; -@@ -300,7 +301,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir +@@ -234,16 +233,15 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + uint32_t index, bool output, const struct vkd3d_shader_location *loc) + { + struct hlsl_semantic new_semantic; +- struct vkd3d_string_buffer *name; + struct hlsl_ir_var *ext_var; ++ char *new_name; + +- if (!(name = hlsl_get_string_buffer(ctx))) ++ if (!(new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", output ? "output" : "input", semantic->name, index))) + return NULL; +- vkd3d_string_buffer_printf(name, "<%s-%s%u>", output ? "output" : "input", semantic->name, index); + + LIST_FOR_EACH_ENTRY(ext_var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { +- if (!ascii_strcasecmp(ext_var->name, name->buffer)) ++ if (!ascii_strcasecmp(ext_var->name, new_name)) + { + if (output) + { +@@ -270,25 +268,23 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir + } + } + +- hlsl_release_string_buffer(ctx, name); ++ vkd3d_free(new_name); + return ext_var; + } + } + + if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) + { +- hlsl_release_string_buffer(ctx, name); ++ vkd3d_free(new_name); + return NULL; + } + new_semantic.index = index; +- if (!(ext_var = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), type, loc, &new_semantic, +- modifiers, NULL))) ++ if (!(ext_var = hlsl_new_var(ctx, new_name, type, loc, &new_semantic, modifiers, NULL))) + { +- hlsl_release_string_buffer(ctx, name); ++ vkd3d_free(new_name); + hlsl_cleanup_semantic(&new_semantic); + return NULL; + } +- hlsl_release_string_buffer(ctx, name); + if (output) + ext_var->is_output_semantic = 1; + else +@@ -300,7 +296,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir return ext_var; } @@ -7773,7 +8984,20 @@ index 765b1907426..bfa605f4ba7 100644 unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index) { struct hlsl_type *type = lhs->node.data_type, *vector_type_src, *vector_type_dst; -@@ -363,7 +364,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct +@@ -320,9 +316,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct + if (!semantic->name) + return; + +- vector_type_src = hlsl_get_vector_type(ctx, type->base_type, +- (ctx->profile->major_version < 4) ? 4 : hlsl_type_minor_size(type)); + vector_type_dst = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); ++ vector_type_src = vector_type_dst; ++ if (ctx->profile->major_version < 4 && ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX) ++ vector_type_src = hlsl_get_vector_type(ctx, type->base_type, 4); + + for (i = 0; i < hlsl_type_major_size(type); ++i) + { +@@ -363,7 +360,7 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *instrs, struct } } @@ -7782,7 +9006,7 @@ index 765b1907426..bfa605f4ba7 100644 unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index) { struct vkd3d_shader_location *loc = &lhs->node.loc; -@@ -405,30 +406,30 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct list *instrs +@@ -405,30 +402,30 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct list *instrs return; list_add_after(&c->entry, &element_load->node.entry); @@ -7819,7 +9043,7 @@ index 765b1907426..bfa605f4ba7 100644 unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index) { struct hlsl_type *type = rhs->node.data_type, *vector_type; -@@ -463,11 +464,11 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct +@@ -463,11 +460,11 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct { if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) return; @@ -7833,7 +9057,7 @@ index 765b1907426..bfa605f4ba7 100644 } else { -@@ -475,16 +476,16 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct +@@ -475,16 +472,16 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct list *instrs, struct if (!(load = hlsl_new_load_index(ctx, &rhs->src, NULL, &var->loc))) return; @@ -7853,7 +9077,7 @@ index 765b1907426..bfa605f4ba7 100644 unsigned int modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index) { struct vkd3d_shader_location *loc = &rhs->node.loc; -@@ -519,34 +520,34 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct list *instrs +@@ -519,34 +516,34 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct list *instrs if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) return; @@ -7895,7 +9119,7 @@ index 765b1907426..bfa605f4ba7 100644 } bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), -@@ -573,6 +574,37 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, +@@ -573,6 +570,37 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, return progress; } @@ -7933,7 +9157,7 @@ index 765b1907426..bfa605f4ba7 100644 static bool transform_instr_derefs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { bool res; -@@ -666,7 +698,7 @@ static void insert_early_return_break(struct hlsl_ctx *ctx, +@@ -666,7 +694,7 @@ static void insert_early_return_break(struct hlsl_ctx *ctx, return; list_add_after(&cf_instr->entry, &load->node.entry); @@ -7942,7 +9166,63 @@ index 765b1907426..bfa605f4ba7 100644 return; hlsl_block_add_instr(&then_block, jump); -@@ -1689,7 +1721,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ +@@ -906,6 +934,55 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h + return &coords_load->node; + } + ++/* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that ++ * represents matrix swizzles (e.g. mat._m01_m23) before we know if they will be used in the lhs of ++ * an assignment or as a value made from different components of the matrix. The former cases should ++ * have already been split into several separate assignments, but the latter are lowered by this ++ * pass. */ ++static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) ++{ ++ struct hlsl_ir_swizzle *swizzle; ++ struct hlsl_ir_load *var_load; ++ struct hlsl_deref var_deref; ++ struct hlsl_type *matrix_type; ++ struct hlsl_ir_var *var; ++ unsigned int x, y, k, i; ++ ++ if (instr->type != HLSL_IR_SWIZZLE) ++ return false; ++ swizzle = hlsl_ir_swizzle(instr); ++ matrix_type = swizzle->val.node->data_type; ++ if (matrix_type->class != HLSL_CLASS_MATRIX) ++ return false; ++ ++ if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc))) ++ return false; ++ hlsl_init_simple_deref_from_var(&var_deref, var); ++ ++ for (i = 0; i < instr->data_type->dimx; ++i) ++ { ++ struct hlsl_block store_block; ++ struct hlsl_ir_node *load; ++ ++ y = (swizzle->swizzle >> (8 * i + 4)) & 0xf; ++ x = (swizzle->swizzle >> 8 * i) & 0xf; ++ k = y * matrix_type->dimx + x; ++ ++ if (!(load = hlsl_add_load_component(ctx, block, swizzle->val.node, k, &instr->loc))) ++ return false; ++ ++ if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, load)) ++ return false; ++ hlsl_block_add_block(block, &store_block); ++ } ++ ++ if (!(var_load = hlsl_new_var_load(ctx, var, &instr->loc))) ++ return false; ++ hlsl_block_add_instr(block, &var_load->node); ++ ++ return true; ++} ++ + /* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct + * record access before knowing if they will be used in the lhs of an assignment --in which case + * they are lowered into a deref-- or as the load of an element within a larger value. +@@ -1689,7 +1766,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ { struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr); @@ -7951,7 +9231,7 @@ index 765b1907426..bfa605f4ba7 100644 { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, "Loaded resource must have a single uniform source."); -@@ -1704,7 +1736,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ +@@ -1704,7 +1781,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ if (load->sampler.var) { @@ -7960,7 +9240,7 @@ index 765b1907426..bfa605f4ba7 100644 { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, "Resource load sampler must have a single uniform source."); -@@ -1722,7 +1754,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ +@@ -1722,7 +1799,7 @@ static bool validate_static_object_references(struct hlsl_ctx *ctx, struct hlsl_ { struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr); @@ -7969,7 +9249,7 @@ index 765b1907426..bfa605f4ba7 100644 { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, "Accessed resource must have a single uniform source."); -@@ -1889,7 +1921,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -1889,7 +1966,7 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr if (rhs->type != HLSL_IR_LOAD) { @@ -7978,7 +9258,7 @@ index 765b1907426..bfa605f4ba7 100644 return false; } -@@ -2066,6 +2098,137 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir +@@ -2066,6 +2143,137 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir return false; } @@ -8116,7 +9396,62 @@ index 765b1907426..bfa605f4ba7 100644 /* Lower DIV to RCP + MUL. */ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { -@@ -2264,7 +2427,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -2232,6 +2440,54 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * + return true; + } + ++/* Use 'movc' for the ternary operator. */ ++static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], *replacement; ++ struct hlsl_ir_node *zero, *cond, *first, *second; ++ struct hlsl_constant_value zero_value = { 0 }; ++ struct hlsl_ir_expr *expr; ++ struct hlsl_type *type; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return false; ++ ++ expr = hlsl_ir_expr(instr); ++ if (expr->op != HLSL_OP3_TERNARY) ++ return false; ++ ++ cond = expr->operands[0].node; ++ first = expr->operands[1].node; ++ second = expr->operands[2].node; ++ ++ if (cond->data_type->base_type == HLSL_TYPE_FLOAT) ++ { ++ if (!(zero = hlsl_new_constant(ctx, cond->data_type, &zero_value, &instr->loc))) ++ return false; ++ list_add_tail(&instr->entry, &zero->entry); ++ ++ memset(operands, 0, sizeof(operands)); ++ operands[0] = zero; ++ operands[1] = cond; ++ type = cond->data_type; ++ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy); ++ if (!(cond = hlsl_new_expr(ctx, HLSL_OP2_NEQUAL, operands, type, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &cond->entry); ++ } ++ ++ memset(operands, 0, sizeof(operands)); ++ operands[0] = cond; ++ operands[1] = first; ++ operands[2] = second; ++ if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_MOVC, operands, first->data_type, &instr->loc))) ++ return false; ++ list_add_before(&instr->entry, &replacement->entry); ++ ++ hlsl_replace_node(instr, replacement); ++ return true; ++} ++ + static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + struct hlsl_type *type = instr->data_type, *arg_type; +@@ -2264,7 +2520,7 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; } @@ -8125,7 +9460,7 @@ index 765b1907426..bfa605f4ba7 100644 struct hlsl_ir_node *condition, struct hlsl_ir_node *if_true, struct hlsl_ir_node *if_false) { struct hlsl_block then_block, else_block; -@@ -2290,18 +2453,18 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *ins +@@ -2290,18 +2546,18 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct list *ins if (!(iff = hlsl_new_if(ctx, condition, &then_block, &else_block, &condition->loc))) return NULL; @@ -8148,7 +9483,7 @@ index 765b1907426..bfa605f4ba7 100644 struct hlsl_type *type = instr->data_type, *utype; struct hlsl_constant_value high_bit_value; struct hlsl_ir_expr *expr; -@@ -2322,56 +2485,52 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +@@ -2322,56 +2578,52 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2))) return false; @@ -8200,12 +9535,12 @@ index 765b1907426..bfa605f4ba7 100644 if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc))) return false; - list_add_before(&instr->entry, &neg->entry); -+ hlsl_block_add_instr(block, neg); - +- - if (!(cond = hlsl_add_conditional(ctx, &instr->entry, and, neg, cast3))) - return false; - hlsl_replace_node(instr, cond); -- ++ hlsl_block_add_instr(block, neg); + - return true; + return hlsl_add_conditional(ctx, block, and, neg, cast3); } @@ -8218,7 +9553,7 @@ index 765b1907426..bfa605f4ba7 100644 struct hlsl_type *type = instr->data_type, *utype; struct hlsl_constant_value high_bit_value; struct hlsl_ir_expr *expr; -@@ -2394,45 +2553,41 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, +@@ -2394,45 +2646,41 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, high_bit_value.u[i].u = 0x80000000; if (!(high_bit = hlsl_new_constant(ctx, type, &high_bit_value, &instr->loc))) return false; @@ -8274,7 +9609,7 @@ index 765b1907426..bfa605f4ba7 100644 } static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -@@ -2516,9 +2671,9 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void +@@ -2516,9 +2764,9 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void return false; } @@ -8286,7 +9621,7 @@ index 765b1907426..bfa605f4ba7 100644 struct hlsl_type *type = instr->data_type, *btype; struct hlsl_constant_value one_value; struct hlsl_ir_expr *expr; -@@ -2539,47 +2694,100 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr +@@ -2539,47 +2787,100 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, arg2, arg1))) return false; @@ -8401,7 +9736,7 @@ index 765b1907426..bfa605f4ba7 100644 return true; } -@@ -2698,7 +2906,7 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) +@@ -2698,7 +2999,7 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) continue; regset = hlsl_type_get_regset(var->data_type); @@ -8410,7 +9745,7 @@ index 765b1907426..bfa605f4ba7 100644 { if (var->reg_reservation.reg_type != get_regset_name(regset)) { -@@ -2716,7 +2924,7 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) +@@ -2716,7 +3017,7 @@ static void allocate_register_reservations(struct hlsl_ctx *ctx) var->regs[regset].id = var->reg_reservation.reg_index; TRACE("Allocated reserved %s to %c%u-%c%u.\n", var->name, var->reg_reservation.reg_type, var->reg_reservation.reg_index, var->reg_reservation.reg_type, @@ -8419,7 +9754,7 @@ index 765b1907426..bfa605f4ba7 100644 } } } -@@ -2806,7 +3014,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2806,7 +3107,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop load->sampler.offset.node->last_read = last_read; } @@ -8429,7 +9764,7 @@ index 765b1907426..bfa605f4ba7 100644 if (load->texel_offset.node) load->texel_offset.node->last_read = last_read; if (load->lod.node) -@@ -2848,8 +3057,15 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop +@@ -2848,8 +3150,15 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop index->idx.node->last_read = last_read; break; } @@ -8446,7 +9781,7 @@ index 765b1907426..bfa605f4ba7 100644 break; } } -@@ -2966,7 +3182,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a +@@ -2966,7 +3275,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a record_allocation(ctx, allocator, reg_idx, writemask, first_write, last_read); ret.id = reg_idx; @@ -8455,7 +9790,7 @@ index 765b1907426..bfa605f4ba7 100644 ret.writemask = hlsl_combine_writemasks(writemask, (1u << component_count) - 1); ret.allocated = true; return ret; -@@ -3002,7 +3218,7 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo +@@ -3002,7 +3311,7 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, first_write, last_read); ret.id = reg_idx; @@ -8464,7 +9799,7 @@ index 765b1907426..bfa605f4ba7 100644 ret.allocated = true; return ret; } -@@ -3034,7 +3250,7 @@ static const char *debug_register(char class, struct hlsl_reg reg, const struct +@@ -3034,7 +3343,7 @@ static const char *debug_register(char class, struct hlsl_reg reg, const struct return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); } @@ -8473,7 +9808,7 @@ index 765b1907426..bfa605f4ba7 100644 { struct hlsl_ir_resource_load *load; struct hlsl_ir_var *var; -@@ -3046,15 +3262,16 @@ static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_n +@@ -3046,15 +3355,16 @@ static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_n load = hlsl_ir_resource_load(instr); var = load->resource.var; @@ -8492,7 +9827,7 @@ index 765b1907426..bfa605f4ba7 100644 dim = var->objects_usage[regset][index].sampler_dim; if (dim != load->sampling_dim) -@@ -3072,25 +3289,39 @@ static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_n +@@ -3072,25 +3382,39 @@ static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_n return false; } } @@ -8504,17 +9839,12 @@ index 765b1907426..bfa605f4ba7 100644 - if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) - return false; + var->objects_usage[regset][index].sampler_dim = load->sampling_dim; - -- var->objects_usage[regset][index].used = true; -- var->objects_usage[regset][index].sampler_dim = load->sampling_dim; ++ + return false; +} -- if (load->sampler.var) -- { -- var = load->sampler.var; -- if (!hlsl_regset_index_from_deref(ctx, &load->sampler, HLSL_REGSET_SAMPLERS, &index)) -- return false; +- var->objects_usage[regset][index].used = true; +- var->objects_usage[regset][index].sampler_dim = load->sampling_dim; +static bool track_object_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_resource_load *load; @@ -8522,11 +9852,16 @@ index 765b1907426..bfa605f4ba7 100644 + enum hlsl_regset regset; + unsigned int index; -- var->objects_usage[HLSL_REGSET_SAMPLERS][index].used = true; -- } +- if (load->sampler.var) +- { +- var = load->sampler.var; +- if (!hlsl_regset_index_from_deref(ctx, &load->sampler, HLSL_REGSET_SAMPLERS, &index)) +- return false; + if (instr->type != HLSL_IR_RESOURCE_LOAD) + return false; -+ + +- var->objects_usage[HLSL_REGSET_SAMPLERS][index].used = true; +- } + load = hlsl_ir_resource_load(instr); + var = load->resource.var; + @@ -8547,7 +9882,7 @@ index 765b1907426..bfa605f4ba7 100644 } return false; -@@ -3100,7 +3331,7 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) +@@ -3100,7 +3424,7 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) { struct hlsl_ir_var *var; struct hlsl_type *type; @@ -8556,7 +9891,7 @@ index 765b1907426..bfa605f4ba7 100644 LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { -@@ -3108,12 +3339,10 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) +@@ -3108,12 +3432,10 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) for (k = 0; k <= HLSL_REGSET_LAST_OBJECT; ++k) { @@ -8573,7 +9908,7 @@ index 765b1907426..bfa605f4ba7 100644 } } } -@@ -3192,10 +3421,33 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, +@@ -3192,10 +3514,33 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, } } @@ -8608,7 +9943,7 @@ index 765b1907426..bfa605f4ba7 100644 struct hlsl_ir_node *instr; LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) -@@ -3206,66 +3458,52 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, +@@ -3206,66 +3551,52 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, { struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); const struct hlsl_type *type = instr->data_type; @@ -8712,7 +10047,7 @@ index 765b1907426..bfa605f4ba7 100644 } break; -@@ -3297,8 +3535,6 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -3297,8 +3628,6 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi struct register_allocator allocator = {0}; struct hlsl_ir_var *var; @@ -8721,7 +10056,7 @@ index 765b1907426..bfa605f4ba7 100644 LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { if (var->is_uniform && var->last_read) -@@ -3315,6 +3551,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi +@@ -3315,6 +3644,8 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi } } @@ -8730,7 +10065,7 @@ index 765b1907426..bfa605f4ba7 100644 vkd3d_free(allocator.allocations); } -@@ -3410,7 +3648,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var +@@ -3410,7 +3741,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var { var->regs[HLSL_REGSET_NUMERIC].allocated = true; var->regs[HLSL_REGSET_NUMERIC].id = (*counter)++; @@ -8739,7 +10074,7 @@ index 765b1907426..bfa605f4ba7 100644 var->regs[HLSL_REGSET_NUMERIC].writemask = (1 << var->data_type->dimx) - 1; TRACE("Allocated %s to %s.\n", var->name, debug_register(output ? 'o' : 'v', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); -@@ -3497,7 +3735,7 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx) +@@ -3497,7 +3828,7 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx) LIST_FOR_EACH_ENTRY(var1, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -8748,7 +10083,7 @@ index 765b1907426..bfa605f4ba7 100644 continue; buffer = var1->buffer; -@@ -3508,7 +3746,7 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx) +@@ -3508,7 +3839,7 @@ static void validate_buffer_offsets(struct hlsl_ctx *ctx) { unsigned int var1_reg_size, var2_reg_size; @@ -8757,7 +10092,7 @@ index 765b1907426..bfa605f4ba7 100644 continue; if (var1 == var2 || var1->buffer != var2->buffer) -@@ -3558,7 +3796,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -3558,7 +3889,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -8766,7 +10101,7 @@ index 765b1907426..bfa605f4ba7 100644 { if (var->is_param) var->buffer = ctx->params_buffer; -@@ -3589,7 +3827,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -3589,7 +3920,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } buffer->reg.id = buffer->reservation.reg_index; @@ -8775,7 +10110,7 @@ index 765b1907426..bfa605f4ba7 100644 buffer->reg.allocated = true; TRACE("Allocated reserved %s to cb%u.\n", buffer->name, index); } -@@ -3599,7 +3837,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -3599,7 +3930,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) ++index; buffer->reg.id = index; @@ -8784,7 +10119,7 @@ index 765b1907426..bfa605f4ba7 100644 buffer->reg.allocated = true; TRACE("Allocated %s to cb%u.\n", buffer->name, index); ++index; -@@ -3618,7 +3856,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) +@@ -3618,7 +3949,7 @@ static void allocate_buffers(struct hlsl_ctx *ctx) } static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum hlsl_regset regset, @@ -8793,7 +10128,7 @@ index 765b1907426..bfa605f4ba7 100644 { const struct hlsl_ir_var *var; unsigned int start, count; -@@ -3632,11 +3870,14 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum +@@ -3632,11 +3963,14 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum * bound there even if the reserved vars aren't used. */ start = var->reg_reservation.reg_index; count = var->data_type->reg_size[regset]; @@ -8809,7 +10144,7 @@ index 765b1907426..bfa605f4ba7 100644 } else { -@@ -3667,11 +3908,12 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -3667,11 +4001,12 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -8823,7 +10158,7 @@ index 765b1907426..bfa605f4ba7 100644 if (var->regs[regset].allocated) { const struct hlsl_ir_var *reserved_object, *last_reported = NULL; -@@ -3690,7 +3932,10 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -3690,7 +4025,10 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) { index = var->regs[regset].id + i; @@ -8835,7 +10170,7 @@ index 765b1907426..bfa605f4ba7 100644 if (reserved_object && reserved_object != var && reserved_object != last_reported) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_OVERLAPPING_RESERVATIONS, -@@ -3709,7 +3954,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) +@@ -3709,7 +4047,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, enum hlsl_regset regset) while (available < count) { @@ -8844,7 +10179,7 @@ index 765b1907426..bfa605f4ba7 100644 available = 0; else ++available; -@@ -3853,6 +4098,7 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref +@@ -3853,6 +4191,7 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *offset) { struct hlsl_ir_node *offset_node = deref->offset.node; @@ -8852,7 +10187,7 @@ index 765b1907426..bfa605f4ba7 100644 unsigned int size; if (!offset_node) -@@ -3869,8 +4115,9 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref +@@ -3869,8 +4208,9 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref return false; *offset = hlsl_ir_constant(offset_node)->value.u[0].u; @@ -8863,7 +10198,7 @@ index 765b1907426..bfa605f4ba7 100644 if (*offset >= size) { hlsl_error(ctx, &deref->offset.node->loc, VKD3D_SHADER_ERROR_HLSL_OFFSET_OUT_OF_BOUNDS, -@@ -3900,7 +4147,8 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere +@@ -3900,7 +4240,8 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere struct hlsl_reg ret = var->regs[HLSL_REGSET_NUMERIC]; unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); @@ -8873,7 +10208,13 @@ index 765b1907426..bfa605f4ba7 100644 ret.id += offset / 4; -@@ -4008,7 +4256,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4003,12 +4344,13 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry + + while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); + ++ lower_ir(ctx, lower_matrix_swizzles, body); + hlsl_transform_ir(ctx, lower_index_loads, body, NULL); + LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) @@ -8882,7 +10223,7 @@ index 765b1907426..bfa605f4ba7 100644 } for (i = 0; i < entry_func->parameters.count; ++i) -@@ -4017,7 +4265,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4017,7 +4359,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (hlsl_type_is_resource(var->data_type) || (var->storage_modifiers & HLSL_STORAGE_UNIFORM)) { @@ -8891,7 +10232,7 @@ index 765b1907426..bfa605f4ba7 100644 } else { -@@ -4033,9 +4281,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4033,9 +4375,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry } if (var->storage_modifiers & HLSL_STORAGE_IN) @@ -8903,7 +10244,7 @@ index 765b1907426..bfa605f4ba7 100644 } } if (entry_func->return_var) -@@ -4044,7 +4292,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4044,7 +4386,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Entry point \"%s\" is missing a return value semantic.", entry_func->func->name); @@ -8912,7 +10253,7 @@ index 765b1907426..bfa605f4ba7 100644 } for (i = 0; i < entry_func->attr_count; ++i) -@@ -4062,6 +4310,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4062,6 +4404,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, "Entry point \"%s\" is missing a [numthreads] attribute.", entry_func->func->name); @@ -8923,7 +10264,7 @@ index 765b1907426..bfa605f4ba7 100644 hlsl_transform_ir(ctx, lower_broadcasts, body, NULL); while (hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL)); do -@@ -4075,10 +4327,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4075,10 +4421,10 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_transform_ir(ctx, lower_narrowing_casts, body, NULL); hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); hlsl_transform_ir(ctx, lower_int_dot, body, NULL); @@ -8937,7 +10278,7 @@ index 765b1907426..bfa605f4ba7 100644 hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); do { -@@ -4094,6 +4346,13 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4094,6 +4440,15 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_transform_ir(ctx, lower_casts_to_bool, body, NULL); hlsl_transform_ir(ctx, lower_int_dot, body, NULL); @@ -8948,10 +10289,12 @@ index 765b1907426..bfa605f4ba7 100644 + hlsl_transform_ir(ctx, track_object_components_usage, body, NULL); + sort_synthetic_separated_samplers_first(ctx); + ++ if (profile->major_version >= 4) ++ hlsl_transform_ir(ctx, lower_ternary, body, NULL); if (profile->major_version < 4) { hlsl_transform_ir(ctx, lower_division, body, NULL); -@@ -4107,9 +4366,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry +@@ -4107,9 +4462,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_transform_ir(ctx, lower_abs, body, NULL); } @@ -9713,7 +11056,7 @@ index 301113c8477..41a72ab6c0d 100644 default: diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 9eefb82c226..705905f7888 100644 +index 9eefb82c226..6d7c89653e3 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -85,6 +85,72 @@ static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_i @@ -9789,6 +11132,15 @@ index 9eefb82c226..705905f7888 100644 struct hull_flattener { struct vkd3d_shader_instruction_array instructions; +@@ -230,7 +296,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali + return VKD3D_OK; + } + +-static void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, ++void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, + enum vkd3d_data_type data_type, unsigned int idx_count) + { + reg->type = reg_type; @@ -247,13 +313,13 @@ static void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_s reg->immconst_type = VKD3D_IMMCONST_SCALAR; } @@ -10196,10 +11548,10 @@ index 94079696280..6fb61eff6c3 100644 } } diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 3542b5fac51..fa605f185ae 100644 +index 3542b5fac51..95f6914acb7 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -199,6 +199,21 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d +@@ -199,6 +199,16 @@ enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d } } @@ -10208,11 +11560,6 @@ index 3542b5fac51..fa605f185ae 100644 + return reg->type == VKD3DSPR_UNDEF; +} + -+static inline bool register_is_constant(const struct vkd3d_shader_register *reg) -+{ -+ return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); -+} -+ +static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg) +{ + return register_is_constant(reg) || register_is_undef(reg); @@ -10221,7 +11568,7 @@ index 3542b5fac51..fa605f185ae 100644 #define VKD3D_SPIRV_VERSION 0x00010000 #define VKD3D_SPIRV_GENERATOR_ID 18 #define VKD3D_SPIRV_GENERATOR_VERSION 8 -@@ -1746,6 +1761,38 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, +@@ -1746,6 +1756,38 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, } } @@ -10260,7 +11607,7 @@ index 3542b5fac51..fa605f185ae 100644 static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point) { vkd3d_spirv_stream_init(&builder->debug_stream); -@@ -2263,7 +2310,7 @@ struct spirv_compiler +@@ -2263,7 +2305,7 @@ struct spirv_compiler uint32_t binding_idx; @@ -10269,7 +11616,7 @@ index 3542b5fac51..fa605f185ae 100644 unsigned int input_control_point_count; unsigned int output_control_point_count; bool use_vocp; -@@ -2333,7 +2380,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) +@@ -2333,7 +2375,7 @@ 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, @@ -10278,7 +11625,7 @@ index 3542b5fac51..fa605f185ae 100644 struct vkd3d_shader_message_context *message_context, const struct vkd3d_shader_location *location) { const struct shader_signature *patch_constant_signature = &shader_desc->patch_constant_signature; -@@ -2429,13 +2476,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve +@@ -2429,13 +2471,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vkd3d_shader_ve compiler->shader_type = shader_version->type; @@ -10292,7 +11639,7 @@ index 3542b5fac51..fa605f185ae 100644 if ((shader_interface = vkd3d_find_struct(compile_info->next, INTERFACE_INFO))) { compiler->xfb_info = vkd3d_find_struct(compile_info->next, TRANSFORM_FEEDBACK_INFO); -@@ -2536,13 +2576,13 @@ static bool spirv_compiler_check_shader_visibility(const struct spirv_compiler * +@@ -2536,13 +2571,13 @@ static bool spirv_compiler_check_shader_visibility(const struct spirv_compiler * } static struct vkd3d_push_constant_buffer_binding *spirv_compiler_find_push_constant_buffer( @@ -10310,7 +11657,86 @@ index 3542b5fac51..fa605f185ae 100644 return NULL; for (i = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) -@@ -3211,13 +3251,13 @@ static bool spirv_compiler_get_register_info(const struct spirv_compiler *compil +@@ -2559,8 +2594,8 @@ static struct vkd3d_push_constant_buffer_binding *spirv_compiler_find_push_const + return NULL; + } + +-static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *compiler, +- const struct vkd3d_shader_resource *resource, const struct vkd3d_shader_sampler *sampler) ++static bool spirv_compiler_has_combined_sampler_for_resource(const struct spirv_compiler *compiler, ++ const struct vkd3d_shader_register_range *range) + { + const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; + const struct vkd3d_shader_combined_resource_sampler *combined_sampler; +@@ -2569,10 +2604,35 @@ static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *com + if (!shader_interface->combined_sampler_count) + return false; + +- if (resource && (resource->reg.reg.type == VKD3DSPR_UAV || resource->range.last != resource->range.first)) ++ if (range->last != range->first) + return false; + +- if (sampler && sampler->range.first != sampler->range.last) ++ for (i = 0; i < shader_interface->combined_sampler_count; ++i) ++ { ++ combined_sampler = &shader_interface->combined_samplers[i]; ++ ++ if (!spirv_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility)) ++ continue; ++ ++ if ((combined_sampler->resource_space == range->space ++ && combined_sampler->resource_index == range->first)) ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool spirv_compiler_has_combined_sampler_for_sampler(const struct spirv_compiler *compiler, ++ const struct vkd3d_shader_register_range *range) ++{ ++ const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; ++ const struct vkd3d_shader_combined_resource_sampler *combined_sampler; ++ unsigned int i; ++ ++ if (!shader_interface->combined_sampler_count) ++ return false; ++ ++ if (range->last != range->first) + return false; + + for (i = 0; i < shader_interface->combined_sampler_count; ++i) +@@ -2582,10 +2642,8 @@ static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *com + if (!spirv_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility)) + continue; + +- if ((!resource || (combined_sampler->resource_space == resource->range.space +- && combined_sampler->resource_index == resource->range.first)) +- && (!sampler || (combined_sampler->sampler_space == sampler->range.space +- && combined_sampler->sampler_index == sampler->range.first))) ++ if (combined_sampler->sampler_space == range->space ++ && combined_sampler->sampler_index == range->first) + return true; + } + +@@ -2603,6 +2661,16 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_error(struct spirv_compiler * + compiler->failed = true; + } + ++static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_warning(struct spirv_compiler *compiler, ++ enum vkd3d_shader_error error, const char *format, ...) ++{ ++ va_list args; ++ ++ va_start(args, format); ++ vkd3d_shader_vwarning(compiler->message_context, &compiler->location, error, format, args); ++ va_end(args); ++} ++ + static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spirv_compiler *compiler, + const struct vkd3d_shader_register_range *range) + { +@@ -3211,13 +3279,13 @@ static bool spirv_compiler_get_register_info(const struct spirv_compiler *compil struct vkd3d_symbol reg_symbol, *symbol; struct rb_entry *entry; @@ -10326,7 +11752,7 @@ index 3542b5fac51..fa605f185ae 100644 register_info->descriptor_array = NULL; register_info->member_idx = 0; register_info->component_type = VKD3D_SHADER_COMPONENT_FLOAT; -@@ -3553,6 +3593,19 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi +@@ -3553,6 +3621,19 @@ static uint32_t spirv_compiler_emit_load_constant64(struct spirv_compiler *compi vkd3d_component_type_from_data_type(reg->data_type), component_count, values); } @@ -10346,7 +11772,7 @@ index 3542b5fac51..fa605f185ae 100644 static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask, const struct vkd3d_shader_register_info *reg_info) -@@ -3563,7 +3616,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, +@@ -3563,7 +3644,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, enum vkd3d_shader_component_type component_type; unsigned int skipped_component_mask; @@ -10355,7 +11781,7 @@ index 3542b5fac51..fa605f185ae 100644 assert(vkd3d_write_mask_component_count(write_mask) == 1); component_idx = vkd3d_write_mask_get_component_idx(write_mask); -@@ -3615,6 +3668,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, +@@ -3615,6 +3696,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, return spirv_compiler_emit_load_constant(compiler, reg, swizzle, write_mask); else if (reg->type == VKD3DSPR_IMMCONST64) return spirv_compiler_emit_load_constant64(compiler, reg, swizzle, write_mask); @@ -10364,7 +11790,7 @@ index 3542b5fac51..fa605f185ae 100644 component_count = vkd3d_write_mask_component_count(write_mask); component_type = vkd3d_component_type_from_data_type(reg->data_type); -@@ -3827,7 +3882,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, +@@ -3827,7 +3910,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, unsigned int src_write_mask = write_mask; uint32_t type_id; @@ -10373,7 +11799,7 @@ index 3542b5fac51..fa605f185ae 100644 if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) return; -@@ -3998,6 +4053,11 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler +@@ -3998,6 +4081,11 @@ static void spirv_compiler_emit_interpolation_decorations(struct spirv_compiler vkd3d_spirv_enable_capability(builder, SpvCapabilitySampleRateShading); vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationSample, NULL, 0); break; @@ -10385,7 +11811,7 @@ index 3542b5fac51..fa605f185ae 100644 default: FIXME("Unhandled interpolation mode %#x.\n", mode); break; -@@ -4542,7 +4602,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +@@ -4542,7 +4630,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, } else { @@ -10394,7 +11820,49 @@ index 3542b5fac51..fa605f185ae 100644 input_id = spirv_compiler_emit_array_variable(compiler, &builder->global_stream, storage_class, component_type, input_component_count, array_sizes, 2); -@@ -4918,9 +4978,15 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, +@@ -4704,13 +4792,16 @@ static bool is_dual_source_blending(const struct spirv_compiler *compiler) + + static void calculate_clip_or_cull_distance_mask(const struct signature_element *e, uint32_t *mask) + { ++ unsigned int write_mask; ++ + if (e->semantic_index >= sizeof(*mask) * CHAR_BIT / VKD3D_VEC4_SIZE) + { + FIXME("Invalid semantic index %u for clip/cull distance.\n", e->semantic_index); + return; + } + +- *mask |= (e->mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); ++ write_mask = e->mask >> vkd3d_write_mask_get_component_idx(e->mask); ++ *mask |= (write_mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); + } + + /* Emits arrayed SPIR-V built-in variables. */ +@@ -4874,7 +4965,6 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + component_type = builtin->component_type; + if (!builtin->spirv_array_size) + output_component_count = builtin->component_count; +- component_idx = 0; + } + else + { +@@ -4888,14 +4978,9 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, + || needs_private_io_variable(builtin)) + { + use_private_variable = true; +- reg_write_mask = write_mask; +- } +- else +- { +- component_idx = vkd3d_write_mask_get_component_idx(write_mask); +- reg_write_mask = write_mask >> component_idx; + } + ++ reg_write_mask = write_mask >> component_idx; + vkd3d_symbol_make_register(®_symbol, reg); + + if (rb_get(&compiler->symbol_table, ®_symbol)) +@@ -4918,9 +5003,15 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, spirv_compiler_emit_register_execution_mode(compiler, &dst->reg); } @@ -10411,7 +11879,7 @@ index 3542b5fac51..fa605f185ae 100644 if (is_patch_constant) location += shader_signature_next_location(&compiler->output_signature); -@@ -4929,10 +4995,10 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, +@@ -4929,10 +5020,10 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, storage_class, component_type, output_component_count, array_sizes, 2); vkd3d_spirv_add_iface_variable(builder, id); @@ -10424,7 +11892,7 @@ index 3542b5fac51..fa605f185ae 100644 } else { -@@ -5258,8 +5324,7 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler +@@ -5258,8 +5349,7 @@ static void spirv_compiler_emit_dcl_global_flags(struct spirv_compiler *compiler WARN("Unhandled global flags %#x.\n", flags); } @@ -10434,7 +11902,7 @@ index 3542b5fac51..fa605f185ae 100644 { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; size_t function_location; -@@ -5270,11 +5335,11 @@ static void spirv_compiler_emit_dcl_temps(struct spirv_compiler *compiler, +@@ -5270,11 +5360,11 @@ static void spirv_compiler_emit_dcl_temps(struct spirv_compiler *compiler, vkd3d_spirv_begin_function_stream_insertion(builder, function_location); assert(!compiler->temp_count); @@ -10449,14 +11917,14 @@ index 3542b5fac51..fa605f185ae 100644 if (!i) compiler->temp_id = id; assert(id == compiler->temp_id + i); -@@ -5473,28 +5538,24 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * +@@ -5473,50 +5563,55 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * return var_id; } -static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) -+static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, unsigned int size, -+ const struct vkd3d_shader_register_range *range, const struct vkd3d_shader_register *reg) ++static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, ++ const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size_in_bytes) { - const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -10466,9 +11934,18 @@ index 3542b5fac51..fa605f185ae 100644 struct vkd3d_push_constant_buffer_binding *push_cb; struct vkd3d_descriptor_variable_info var_info; struct vkd3d_symbol reg_symbol; ++ unsigned int size; ++ ++ struct vkd3d_shader_register reg = ++ { ++ .type = VKD3DSPR_CONSTBUFFER, ++ .idx[0].offset = register_id, ++ .idx_count = 1, ++ }; - assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC)); -- ++ size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t)); + - if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, cb))) + if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range))) { @@ -10476,14 +11953,18 @@ index 3542b5fac51..fa605f185ae 100644 * spirv_compiler_emit_push_constant_buffers(). */ - unsigned int cb_size_in_bytes = cb->size * VKD3D_VEC4_SIZE * sizeof(uint32_t); -+ unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t); - push_cb->reg = *reg; +- push_cb->reg = *reg; - push_cb->size = cb->size; +- if (cb_size_in_bytes > push_cb->pc.size) ++ push_cb->reg = reg; + push_cb->size = size; - if (cb_size_in_bytes > push_cb->pc.size) ++ if (size_in_bytes > push_cb->pc.size) { WARN("Constant buffer size %u exceeds push constant size %u.\n", -@@ -5504,17 +5565,17 @@ static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compi +- cb_size_in_bytes, push_cb->pc.size); ++ size_in_bytes, push_cb->pc.size); + } + return; } vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); @@ -10500,28 +11981,59 @@ index 3542b5fac51..fa605f185ae 100644 var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id, - reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); -+ reg, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); ++ ®, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); - vkd3d_symbol_make_register(®_symbol, reg); +- vkd3d_symbol_make_register(®_symbol, reg); ++ vkd3d_symbol_make_register(®_symbol, ®); vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, -@@ -5524,6 +5585,16 @@ static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compi + VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); + reg_symbol.descriptor_array = var_info.array_symbol; +@@ -5557,29 +5652,34 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi spirv_compiler_put_symbol(compiler, ®_symbol); } -+static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler, -+ const struct vkd3d_shader_instruction *instruction) -+{ -+ const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; -+ -+ assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC)); -+ -+ spirv_compiler_emit_constant_buffer(compiler, cb->size, &cb->range, &cb->src.reg); -+} -+ - static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) +-static void spirv_compiler_emit_dcl_sampler(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) ++static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compiler, ++ const struct vkd3d_shader_register_range *range, unsigned int register_id) { -@@ -5624,13 +5695,13 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty +- const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler; + const SpvStorageClass storage_class = SpvStorageClassUniformConstant; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; +- const struct vkd3d_shader_register *reg = &sampler->src.reg; + struct vkd3d_descriptor_variable_info var_info; + struct vkd3d_symbol reg_symbol; + uint32_t type_id, var_id; + +- vkd3d_symbol_make_sampler(®_symbol, reg); +- reg_symbol.info.sampler.range = sampler->range; ++ const struct vkd3d_shader_register reg = ++ { ++ .type = VKD3DSPR_SAMPLER, ++ .idx[0].offset = register_id, ++ .idx_count = 1, ++ }; ++ ++ vkd3d_symbol_make_sampler(®_symbol, ®); ++ reg_symbol.info.sampler.range = *range; + spirv_compiler_put_symbol(compiler, ®_symbol); + +- if (spirv_compiler_has_combined_sampler(compiler, NULL, sampler)) ++ if (spirv_compiler_has_combined_sampler_for_sampler(compiler, range)) + return; + + type_id = vkd3d_spirv_get_op_type_sampler(builder); +- var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, +- &sampler->range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info); ++ var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, ++ range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info); + +- vkd3d_symbol_make_register(®_symbol, reg); ++ vkd3d_symbol_make_register(®_symbol, ®); + vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, + VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); + reg_symbol.descriptor_array = var_info.array_symbol; +@@ -5624,13 +5724,13 @@ static SpvImageFormat image_format_for_image_read(enum vkd3d_shader_component_ty } } @@ -10538,7 +12050,7 @@ index 3542b5fac51..fa605f185ae 100644 unsigned int i; for (i = 0; i < descriptor_info->descriptor_count; ++i) -@@ -5650,7 +5721,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler +@@ -5650,7 +5750,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler bool raw_structured, uint32_t depth) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -10547,7 +12059,7 @@ index 3542b5fac51..fa605f185ae 100644 bool uav_read, uav_atomics; uint32_t sampled_type_id; SpvImageFormat format; -@@ -5685,7 +5756,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi +@@ -5685,7 +5785,7 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi const struct vkd3d_shader_combined_resource_sampler *current; uint32_t image_type_id, type_id, ptr_type_id, var_id; enum vkd3d_shader_binding_flag resource_type_flag; @@ -10556,16 +12068,162 @@ index 3542b5fac51..fa605f185ae 100644 struct vkd3d_symbol symbol; unsigned int i; bool depth; -@@ -5818,7 +5889,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp +@@ -5761,20 +5861,30 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi + } + + static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *compiler, +- const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, +- enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw) ++ const struct vkd3d_shader_register_range *range, unsigned int register_id, ++ unsigned int sample_count, bool is_uav, enum vkd3d_shader_resource_type resource_type, ++ enum vkd3d_shader_resource_data_type resource_data_type, unsigned int structure_stride, bool raw) + { + struct vkd3d_descriptor_variable_info var_info, counter_var_info = {0}; + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + SpvStorageClass storage_class = SpvStorageClassUniformConstant; + uint32_t counter_type_id, type_id, var_id, counter_var_id = 0; +- const struct vkd3d_shader_register *reg = &resource->reg.reg; + const struct vkd3d_spirv_resource_type *resource_type_info; + enum vkd3d_shader_component_type sampled_type; + struct vkd3d_symbol resource_symbol; +- bool is_uav; + +- is_uav = reg->type == VKD3DSPR_UAV; ++ struct vkd3d_shader_register reg = ++ { ++ .type = is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, ++ .idx[0].offset = register_id, ++ .idx_count = 1, ++ }; ++ ++ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1) ++ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; ++ else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY && sample_count == 1) ++ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; ++ + if (!(resource_type_info = spirv_compiler_enable_resource_type(compiler, + resource_type, is_uav))) + { +@@ -5782,11 +5892,11 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + return; + } + +- sampled_type = vkd3d_component_type_from_data_type(resource_data_type); ++ sampled_type = vkd3d_component_type_from_resource_data_type(resource_data_type); + +- if (spirv_compiler_has_combined_sampler(compiler, resource, NULL)) ++ if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) + { +- spirv_compiler_emit_combined_sampler_declarations(compiler, reg, &resource->range, ++ spirv_compiler_emit_combined_sampler_declarations(compiler, ®, range, + resource_type, sampled_type, structure_stride, raw, resource_type_info); + return; + } +@@ -5809,19 +5919,18 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + } + else + { +- type_id = spirv_compiler_get_image_type_id(compiler, reg, &resource->range, ++ type_id = spirv_compiler_get_image_type_id(compiler, ®, range, + resource_type_info, sampled_type, structure_stride || raw, 0); + } + +- var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, +- &resource->range, resource_type, false, &var_info); ++ var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, ++ range, resource_type, false, &var_info); if (is_uav) { - const struct vkd3d_shader_descriptor_info *d; + const struct vkd3d_shader_descriptor_info1 *d; - d = spirv_compiler_get_descriptor_info(compiler, - VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, &resource->range); -@@ -6236,9 +6307,6 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) +- d = spirv_compiler_get_descriptor_info(compiler, +- VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, &resource->range); ++ d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range); + + if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) + vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); +@@ -5853,15 +5962,15 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + type_id = struct_id; + } + +- counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, +- &resource->range, resource_type, true, &counter_var_info); ++ counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, ++ type_id, ®, range, resource_type, true, &counter_var_info); + } + } + +- vkd3d_symbol_make_resource(&resource_symbol, reg); ++ vkd3d_symbol_make_resource(&resource_symbol, ®); + resource_symbol.id = var_id; + resource_symbol.descriptor_array = var_info.array_symbol; +- resource_symbol.info.resource.range = resource->range; ++ resource_symbol.info.resource.range = *range; + resource_symbol.info.resource.sampled_type = sampled_type; + resource_symbol.info.resource.type_id = type_id; + resource_symbol.info.resource.resource_type_info = resource_type_info; +@@ -5874,58 +5983,6 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + spirv_compiler_put_symbol(compiler, &resource_symbol); + } + +-static void spirv_compiler_emit_dcl_resource(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) +-{ +- const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic; +- enum vkd3d_shader_resource_type resource_type = semantic->resource_type; +- uint32_t flags = instruction->flags; +- +- /* We don't distinguish between APPEND and COUNTER UAVs. */ +- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER; +- if (flags) +- FIXME("Unhandled UAV flags %#x.\n", flags); +- +- if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && semantic->sample_count == 1) +- resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; +- else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY && semantic->sample_count == 1) +- resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; +- +- spirv_compiler_emit_resource_declaration(compiler, &semantic->resource, +- resource_type, semantic->resource_data_type[0], 0, false); +-} +- +-static void spirv_compiler_emit_dcl_resource_raw(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) +-{ +- const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource; +- uint32_t flags = instruction->flags; +- +- /* We don't distinguish between APPEND and COUNTER UAVs. */ +- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER; +- if (flags) +- FIXME("Unhandled UAV flags %#x.\n", flags); +- +- spirv_compiler_emit_resource_declaration(compiler, &resource->resource, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, true); +-} +- +-static void spirv_compiler_emit_dcl_resource_structured(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) +-{ +- const struct vkd3d_shader_structured_resource *resource = &instruction->declaration.structured_resource; +- unsigned int stride = resource->byte_stride; +- uint32_t flags = instruction->flags; +- +- /* We don't distinguish between APPEND and COUNTER UAVs. */ +- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER; +- if (flags) +- FIXME("Unhandled UAV flags %#x.\n", flags); +- +- spirv_compiler_emit_resource_declaration(compiler, &resource->resource, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, stride / 4, false); +-} +- + static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler, + const struct vkd3d_shader_register *reg, unsigned int size, unsigned int structure_stride) + { +@@ -6236,9 +6293,6 @@ static void spirv_compiler_leave_shader_phase(struct spirv_compiler *compiler) vkd3d_spirv_build_op_function_end(builder); @@ -10575,7 +12233,7 @@ index 3542b5fac51..fa605f185ae 100644 if (is_in_control_point_phase(compiler)) { if (compiler->epilogue_function_id) -@@ -6640,7 +6708,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, +@@ -6640,7 +6694,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, uint32_t components[VKD3D_VEC4_SIZE]; unsigned int i, component_count; @@ -10584,7 +12242,22 @@ index 3542b5fac51..fa605f185ae 100644 goto general_implementation; spirv_compiler_get_register_info(compiler, &dst->reg, &dst_reg_info); -@@ -9103,9 +9171,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -7398,7 +7452,13 @@ static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *c + assert(compiler->control_flow_depth); + assert(cf_info->current_block == VKD3D_BLOCK_SWITCH); + +- assert(src->swizzle == VKD3D_SHADER_NO_SWIZZLE && src->reg.type == VKD3DSPR_IMMCONST); ++ if (src->swizzle != VKD3D_SHADER_SWIZZLE(X, X, X, X)) ++ { ++ WARN("Unexpected src swizzle %#x.\n", src->swizzle); ++ spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE, ++ "The swizzle for a switch case value is not scalar."); ++ } ++ assert(src->reg.type == VKD3DSPR_IMMCONST); + value = *src->reg.u.immconst_uint; + + if (!vkd3d_array_reserve((void **)&cf_info->u.switch_.case_blocks, &cf_info->u.switch_.case_blocks_size, +@@ -9103,33 +9163,12 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VKD3DSIH_DCL_GLOBAL_FLAGS: spirv_compiler_emit_dcl_global_flags(compiler, instruction); break; @@ -10594,42 +12267,99 @@ index 3542b5fac51..fa605f185ae 100644 case VKD3DSIH_DCL_INDEXABLE_TEMP: spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); break; -@@ -9426,6 +9491,7 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +- case VKD3DSIH_DCL_CONSTANT_BUFFER: +- spirv_compiler_emit_dcl_constant_buffer(compiler, instruction); +- break; + case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: + spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); + break; +- case VKD3DSIH_DCL_SAMPLER: +- spirv_compiler_emit_dcl_sampler(compiler, instruction); +- break; +- case VKD3DSIH_DCL: +- case VKD3DSIH_DCL_UAV_TYPED: +- spirv_compiler_emit_dcl_resource(compiler, instruction); +- break; +- case VKD3DSIH_DCL_RESOURCE_RAW: +- case VKD3DSIH_DCL_UAV_RAW: +- spirv_compiler_emit_dcl_resource_raw(compiler, instruction); +- break; +- case VKD3DSIH_DCL_RESOURCE_STRUCTURED: +- case VKD3DSIH_DCL_UAV_STRUCTURED: +- spirv_compiler_emit_dcl_resource_structured(compiler, instruction); +- break; + case VKD3DSIH_DCL_TGSM_RAW: + spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction); + break; +@@ -9425,7 +9464,16 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VKD3DSIH_CUT_STREAM: spirv_compiler_emit_cut_stream(compiler, instruction); break; ++ case VKD3DSIH_DCL: ++ case VKD3DSIH_DCL_CONSTANT_BUFFER: case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: ++ case VKD3DSIH_DCL_RESOURCE_RAW: ++ case VKD3DSIH_DCL_RESOURCE_STRUCTURED: ++ case VKD3DSIH_DCL_SAMPLER: + case VKD3DSIH_DCL_TEMPS: ++ case VKD3DSIH_DCL_UAV_RAW: ++ case VKD3DSIH_DCL_UAV_STRUCTURED: ++ case VKD3DSIH_DCL_UAV_TYPED: case VKD3DSIH_HS_DECLS: case VKD3DSIH_NOP: /* nothing to do */ -@@ -9437,6 +9503,26 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, +@@ -9437,6 +9485,50 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, return ret; } -+static void spirv_compiler_emit_sm1_constant_buffer(struct spirv_compiler *compiler, -+ const struct vkd3d_shader_desc *desc, enum vkd3d_shader_d3dbc_constant_register set, -+ enum vkd3d_data_type data_type) ++static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler) +{ -+ struct vkd3d_shader_register_range range = {.space = 0, .first = set, .last = set}; -+ uint32_t count = desc->flat_constant_count[set].external; -+ struct vkd3d_shader_register reg = -+ { -+ .type = VKD3DSPR_CONSTBUFFER, -+ .idx[0].offset = set, /* register ID */ -+ .idx[1].offset = set, /* register index */ -+ .idx[2].offset = count, /* size */ -+ .idx_count = 3, -+ .data_type = data_type, -+ }; ++ unsigned int i; + -+ if (count) -+ spirv_compiler_emit_constant_buffer(compiler, count, &range, ®); ++ for (i = 0; i < compiler->scan_descriptor_info->descriptor_count; ++i) ++ { ++ const struct vkd3d_shader_descriptor_info1 *descriptor = &compiler->scan_descriptor_info->descriptors[i]; ++ struct vkd3d_shader_register_range range; ++ ++ range.first = descriptor->register_index; ++ if (descriptor->count == ~0u) ++ range.last = ~0u; ++ else ++ range.last = descriptor->register_index + descriptor->count - 1; ++ range.space = descriptor->register_space; ++ ++ switch (descriptor->type) ++ { ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: ++ spirv_compiler_emit_sampler_declaration(compiler, &range, descriptor->register_id); ++ break; ++ ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: ++ spirv_compiler_emit_cbv_declaration(compiler, &range, descriptor->register_id, descriptor->buffer_size); ++ break; ++ ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: ++ spirv_compiler_emit_resource_declaration(compiler, &range, descriptor->register_id, ++ descriptor->sample_count, false, descriptor->resource_type, descriptor->resource_data_type, ++ descriptor->structure_stride / 4, descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER); ++ break; ++ ++ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: ++ spirv_compiler_emit_resource_declaration(compiler, &range, descriptor->register_id, ++ descriptor->sample_count, true, descriptor->resource_type, descriptor->resource_data_type, ++ descriptor->structure_stride / 4, descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER); ++ break; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++ } +} + static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_parser *parser, struct vkd3d_shader_code *spirv) -@@ -9444,28 +9530,36 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -9444,28 +9536,31 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -10641,12 +12371,7 @@ index 3542b5fac51..fa605f185ae 100644 + if (parser->shader_desc.temp_count) + spirv_compiler_emit_temps(compiler, parser->shader_desc.temp_count); + -+ spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, -+ VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, VKD3D_DATA_FLOAT); -+ spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, -+ VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, VKD3D_DATA_INT); -+ spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, -+ VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, VKD3D_DATA_UINT); ++ spirv_compiler_emit_descriptor_declarations(compiler); + compiler->location.column = 0; compiler->location.line = 1; @@ -10678,7 +12403,7 @@ index 3542b5fac51..fa605f185ae 100644 if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) spirv_compiler_emit_shader_signature_outputs(compiler); -@@ -9541,7 +9635,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, +@@ -9541,7 +9636,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, } int spirv_compile(struct vkd3d_shader_parser *parser, @@ -10688,7 +12413,7 @@ index 3542b5fac51..fa605f185ae 100644 struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index d066b13ee4e..550f9b27cc7 100644 +index d066b13ee4e..045fb6c5f64 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -430,6 +430,8 @@ enum vkd3d_sm4_register_type @@ -10700,6 +12425,15 @@ index d066b13ee4e..550f9b27cc7 100644 }; enum vkd3d_sm4_extended_operand_type +@@ -505,7 +507,7 @@ enum vkd3d_sm4_input_primitive_type + + enum vkd3d_sm4_swizzle_type + { +- VKD3D_SM4_SWIZZLE_NONE = 0x0, ++ VKD3D_SM4_SWIZZLE_NONE = 0x0, /* swizzle bitfield contains a mask */ + VKD3D_SM4_SWIZZLE_VEC4 = 0x1, + VKD3D_SM4_SWIZZLE_SCALAR = 0x2, + }; @@ -571,6 +573,12 @@ struct sm4_index_range_array struct sm4_index_range ranges[MAX_REG_OUTPUT * 2]; }; @@ -10722,7 +12456,27 @@ index d066b13ee4e..550f9b27cc7 100644 struct vkd3d_shader_parser p; }; -@@ -989,6 +999,8 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i +@@ -697,6 +707,19 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, + VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z; + } + ++static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode, ++ uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) ++{ ++ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, ++ (struct vkd3d_shader_src_param *)&ins->src[0]); ++ if (ins->src[0].reg.type != VKD3DSPR_IMMCONST) ++ { ++ FIXME("Switch case value is not a 32-bit constant.\n"); ++ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_CASE_VALUE, ++ "Switch case value is not a 32-bit immediate constant register."); ++ } ++} ++ + static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, + const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { +@@ -989,6 +1012,8 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { ins->declaration.count = *tokens; @@ -10731,7 +12485,17 @@ index d066b13ee4e..550f9b27cc7 100644 } static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode, -@@ -1466,50 +1478,10 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = +@@ -1203,7 +1228,8 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = + {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, + {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", + shader_sm4_read_conditional_op}, +- {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u"}, ++ {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", ++ shader_sm4_read_case_condition}, + {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, + {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", + shader_sm4_read_conditional_op}, +@@ -1466,50 +1492,10 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, }; @@ -10786,7 +12550,7 @@ index d066b13ee4e..550f9b27cc7 100644 }; static const enum vkd3d_shader_register_precision register_precision_table[] = -@@ -1522,18 +1494,104 @@ static const enum vkd3d_shader_register_precision register_precision_table[] = +@@ -1522,18 +1508,104 @@ static const enum vkd3d_shader_register_precision register_precision_table[] = /* VKD3D_SM4_REGISTER_PRECISION_MIN_UINT_16 */ VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16, }; @@ -10892,7 +12656,7 @@ index d066b13ee4e..550f9b27cc7 100644 static void map_register(const struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_register *reg) { switch (sm4->p.shader_version.type) -@@ -1640,6 +1698,7 @@ static bool sm4_register_is_descriptor(enum vkd3d_sm4_register_type register_typ +@@ -1640,6 +1712,7 @@ static bool sm4_register_is_descriptor(enum vkd3d_sm4_register_type register_typ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) { @@ -10900,7 +12664,7 @@ index d066b13ee4e..550f9b27cc7 100644 enum vkd3d_sm4_register_precision precision; enum vkd3d_sm4_register_type register_type; enum vkd3d_sm4_extended_operand_type type; -@@ -1654,15 +1713,15 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui +@@ -1654,15 +1727,15 @@ static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const ui token = *(*ptr)++; register_type = (token & VKD3D_SM4_REGISTER_TYPE_MASK) >> VKD3D_SM4_REGISTER_TYPE_SHIFT; @@ -10919,7 +12683,168 @@ index d066b13ee4e..550f9b27cc7 100644 } param->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; param->non_uniform = false; -@@ -2362,6 +2421,8 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t +@@ -1953,6 +2026,7 @@ static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_pa + static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, + const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param) + { ++ unsigned int dimension, mask; + DWORD token; + + if (*ptr >= end) +@@ -1968,37 +2042,63 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons + return false; + } + +- if (src_param->reg.type == VKD3DSPR_IMMCONST || src_param->reg.type == VKD3DSPR_IMMCONST64) ++ switch ((dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT)) + { +- src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; +- } +- else +- { +- enum vkd3d_sm4_swizzle_type swizzle_type = +- (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT; ++ case VKD3D_SM4_DIMENSION_NONE: ++ case VKD3D_SM4_DIMENSION_SCALAR: ++ src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ break; + +- switch (swizzle_type) ++ case VKD3D_SM4_DIMENSION_VEC4: + { +- case VKD3D_SM4_SWIZZLE_NONE: +- if (shader_sm4_is_scalar_register(&src_param->reg)) +- src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); +- else ++ enum vkd3d_sm4_swizzle_type swizzle_type = ++ (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT; ++ ++ switch (swizzle_type) ++ { ++ case VKD3D_SM4_SWIZZLE_NONE: + src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; +- break; + +- case VKD3D_SM4_SWIZZLE_SCALAR: +- src_param->swizzle = (token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT; +- src_param->swizzle = (src_param->swizzle & 0x3) * 0x01010101; +- break; ++ mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT; ++ /* Mask seems only to be used for vec4 constants and is always zero. */ ++ if (!register_is_constant(&src_param->reg)) ++ { ++ FIXME("Source mask %#x is not for a constant.\n", mask); ++ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK, ++ "Unhandled mask %#x for a non-constant source register.", mask); ++ } ++ else if (mask) ++ { ++ FIXME("Unhandled mask %#x.\n", mask); ++ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK, ++ "Unhandled source register mask %#x.", mask); ++ } + +- case VKD3D_SM4_SWIZZLE_VEC4: +- src_param->swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT); +- break; ++ break; + +- default: +- FIXME("Unhandled swizzle type %#x.\n", swizzle_type); +- break; ++ case VKD3D_SM4_SWIZZLE_SCALAR: ++ src_param->swizzle = (token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT; ++ src_param->swizzle = (src_param->swizzle & 0x3) * 0x01010101; ++ break; ++ ++ case VKD3D_SM4_SWIZZLE_VEC4: ++ src_param->swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT); ++ break; ++ ++ default: ++ FIXME("Unhandled swizzle type %#x.\n", swizzle_type); ++ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE, ++ "Source register swizzle type %#x is invalid.", swizzle_type); ++ break; ++ } ++ break; + } ++ ++ default: ++ FIXME("Unhandled dimension %#x.\n", dimension); ++ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION, ++ "Source register dimension %#x is invalid.", dimension); ++ break; + } + + if (register_is_input_output(&src_param->reg) && !shader_sm4_validate_input_output_register(priv, +@@ -2011,7 +2111,9 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons + static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, + const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param) + { ++ enum vkd3d_sm4_swizzle_type swizzle_type; + enum vkd3d_shader_src_modifier modifier; ++ unsigned int dimension, swizzle; + DWORD token; + + if (*ptr >= end) +@@ -2033,10 +2135,53 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons + return false; + } + +- dst_param->write_mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT; ++ switch ((dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT)) ++ { ++ case VKD3D_SM4_DIMENSION_NONE: ++ dst_param->write_mask = 0; ++ break; ++ ++ case VKD3D_SM4_DIMENSION_SCALAR: ++ dst_param->write_mask = VKD3DSP_WRITEMASK_0; ++ break; ++ ++ case VKD3D_SM4_DIMENSION_VEC4: ++ swizzle_type = (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT; ++ switch (swizzle_type) ++ { ++ case VKD3D_SM4_SWIZZLE_NONE: ++ dst_param->write_mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT; ++ break; ++ ++ case VKD3D_SM4_SWIZZLE_VEC4: ++ swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT); ++ if (swizzle != VKD3D_SHADER_NO_SWIZZLE) ++ { ++ FIXME("Unhandled swizzle %#x.\n", swizzle); ++ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_SWIZZLE, ++ "Unhandled destination register swizzle %#x.", swizzle); ++ } ++ dst_param->write_mask = VKD3DSP_WRITEMASK_ALL; ++ break; ++ ++ default: ++ FIXME("Unhandled swizzle type %#x.\n", swizzle_type); ++ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE, ++ "Destination register swizzle type %#x is invalid.", swizzle_type); ++ break; ++ } ++ break; ++ ++ default: ++ FIXME("Unhandled dimension %#x.\n", dimension); ++ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION, ++ "Destination register dimension %#x is invalid.", dimension); ++ break; ++ } ++ + if (data_type == VKD3D_DATA_DOUBLE) + dst_param->write_mask = vkd3d_write_mask_64_from_32(dst_param->write_mask); +- /* Scalar registers are declared with no write mask in shader bytecode. */ ++ /* 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; + dst_param->modifiers = 0; +@@ -2362,6 +2507,8 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, const uint32_t sm4->output_map[e->register_index] = e->semantic_index; } @@ -10928,7 +12853,7 @@ index d066b13ee4e..550f9b27cc7 100644 return true; } -@@ -2442,6 +2503,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -2442,6 +2589,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi } shader_desc = &sm4->p.shader_desc; @@ -10936,7 +12861,7 @@ index d066b13ee4e..550f9b27cc7 100644 if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name, shader_desc)) < 0) { -@@ -2499,7 +2561,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -2499,7 +2647,7 @@ int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compi return sm4->p.failed ? VKD3D_ERROR_INVALID_SHADER : VKD3D_OK; } @@ -10945,7 +12870,7 @@ index d066b13ee4e..550f9b27cc7 100644 static bool type_is_integer(const struct hlsl_type *type) { -@@ -2516,7 +2578,7 @@ static bool type_is_integer(const struct hlsl_type *type) +@@ -2516,7 +2664,7 @@ static bool type_is_integer(const struct hlsl_type *type) } bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semantic *semantic, @@ -10954,7 +12879,7 @@ index d066b13ee4e..550f9b27cc7 100644 { unsigned int i; -@@ -2526,24 +2588,24 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem +@@ -2526,24 +2674,24 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem bool output; enum vkd3d_shader_type shader_type; enum vkd3d_sm4_swizzle_type swizzle_type; @@ -10988,7 +12913,7 @@ index d066b13ee4e..550f9b27cc7 100644 }; for (i = 0; i < ARRAY_SIZE(register_table); ++i) -@@ -2552,7 +2614,8 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem +@@ -2552,7 +2700,8 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem && output == register_table[i].output && ctx->profile->type == register_table[i].shader_type) { @@ -10998,7 +12923,7 @@ index d066b13ee4e..550f9b27cc7 100644 if (swizzle_type) *swizzle_type = register_table[i].swizzle_type; *has_idx = register_table[i].has_idx; -@@ -2624,7 +2687,8 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant +@@ -2624,7 +2773,8 @@ bool hlsl_sm4_usage_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_semant return true; } @@ -11008,7 +12933,7 @@ index d066b13ee4e..550f9b27cc7 100644 { /* Native D3DDisassemble() expects at least the sizes of the ISGN and OSGN * sections to be aligned. Without this, the sections themselves will be -@@ -2632,6 +2696,9 @@ static void add_section(struct dxbc_writer *dxbc, uint32_t tag, struct vkd3d_byt +@@ -2632,6 +2782,9 @@ static void add_section(struct dxbc_writer *dxbc, uint32_t tag, struct vkd3d_byt size_t size = bytecode_align(buffer); dxbc_writer_add_section(dxbc, tag, buffer->data, size); @@ -11018,7 +12943,7 @@ index d066b13ee4e..550f9b27cc7 100644 } static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, bool output) -@@ -2649,7 +2716,6 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, +@@ -2649,7 +2802,6 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { unsigned int width = (1u << var->data_type->dimx) - 1, use_mask; @@ -11026,7 +12951,7 @@ index d066b13ee4e..550f9b27cc7 100644 uint32_t usage_idx, reg_idx; D3D_NAME usage; bool has_idx; -@@ -2663,14 +2729,13 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, +@@ -2663,14 +2815,13 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, continue; usage_idx = var->semantic.index; @@ -11042,7 +12967,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg_idx = var->regs[HLSL_REGSET_NUMERIC].id; } -@@ -2739,7 +2804,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, +@@ -2739,7 +2890,7 @@ static void write_sm4_signature(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc, set_u32(&buffer, count_position, i); @@ -11051,7 +12976,7 @@ index d066b13ee4e..550f9b27cc7 100644 } static D3D_SHADER_VARIABLE_CLASS sm4_class(const struct hlsl_type *type) -@@ -2827,6 +2892,22 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) +@@ -2827,6 +2978,22 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) return D3D_SVT_VERTEXSHADER; case HLSL_TYPE_VOID: return D3D_SVT_VOID; @@ -11074,7 +12999,7 @@ index d066b13ee4e..550f9b27cc7 100644 default: vkd3d_unreachable(); } -@@ -2967,47 +3048,154 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ +@@ -2967,47 +3134,154 @@ static D3D_SRV_DIMENSION sm4_rdef_resource_dimension(const struct hlsl_type *typ } } @@ -11100,38 +13025,38 @@ index d066b13ee4e..550f9b27cc7 100644 + const struct extern_resource *aa = (const struct extern_resource *)a; + const struct extern_resource *bb = (const struct extern_resource *)b; + int r; -+ -+ if ((r = vkd3d_u32_compare(aa->regset, bb->regset))) -+ return r; - aa_regset = hlsl_type_get_regset(aa->data_type); - bb_regset = hlsl_type_get_regset(bb->data_type); -+ return vkd3d_u32_compare(aa->id, bb->id); -+} -+ -+static void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) -+{ -+ unsigned int i; ++ if ((r = vkd3d_u32_compare(aa->regset, bb->regset))) ++ return r; - if (aa_regset != bb_regset) - return aa_regset - bb_regset; -+ for (i = 0; i < count; ++i) -+ vkd3d_free(extern_resources[i].name); -+ vkd3d_free(extern_resources); ++ return vkd3d_u32_compare(aa->id, bb->id); +} - return aa->regs[aa_regset].id - bb->regs[bb_regset].id; -+static const char *string_skip_tag(const char *string) ++static void sm4_free_extern_resources(struct extern_resource *extern_resources, unsigned int count) +{ -+ if (!strncmp(string, "", strlen(""))) -+ return string + strlen(""); -+ return string; ++ unsigned int i; ++ ++ for (i = 0; i < count; ++i) ++ vkd3d_free(extern_resources[i].name); ++ vkd3d_free(extern_resources); } -static const struct hlsl_ir_var **sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) -+static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) ++static const char *string_skip_tag(const char *string) { - const struct hlsl_ir_var **extern_resources = NULL; ++ if (!strncmp(string, "", strlen(""))) ++ return string + strlen(""); ++ return string; ++} ++ ++static struct extern_resource *sm4_get_extern_resources(struct hlsl_ctx *ctx, unsigned int *count) ++{ + bool separate_components = ctx->profile->major_version == 5 && ctx->profile->minor_version == 0; + struct extern_resource *extern_resources = NULL; const struct hlsl_ir_var *var; @@ -11226,9 +13151,7 @@ index d066b13ee4e..550f9b27cc7 100644 + *count = 0; + return NULL; + } - -- extern_resources[*count] = var; -- ++*count; ++ + if (!(name = hlsl_strdup(ctx, string_skip_tag(var->name)))) + { + sm4_free_extern_resources(extern_resources, *count); @@ -11237,7 +13160,9 @@ index d066b13ee4e..550f9b27cc7 100644 + } + + extern_resources[*count].var = var; -+ + +- extern_resources[*count] = var; +- ++*count; + extern_resources[*count].name = name; + extern_resources[*count].data_type = var->data_type; + extern_resources[*count].is_user_packed = !!var->reg_reservation.reg_type; @@ -11251,7 +13176,7 @@ index d066b13ee4e..550f9b27cc7 100644 } qsort(extern_resources, *count, sizeof(*extern_resources), sm4_compare_extern_resources); -@@ -3020,8 +3208,8 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3020,8 +3294,8 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) size_t cbuffers_offset, resources_offset, creator_offset, string_offset; size_t cbuffer_position, resource_position, creator_position; const struct hlsl_profile_info *profile = ctx->profile; @@ -11261,7 +13186,7 @@ index d066b13ee4e..550f9b27cc7 100644 const struct hlsl_buffer *cbuffer; const struct hlsl_ir_var *var; -@@ -3075,18 +3263,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3075,18 +3349,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) for (i = 0; i < extern_resources_count; ++i) { @@ -11284,7 +13209,7 @@ index d066b13ee4e..550f9b27cc7 100644 { put_u32(&buffer, 0); put_u32(&buffer, 0); -@@ -3094,15 +3279,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3094,15 +3365,15 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) } else { @@ -11305,7 +13230,7 @@ index d066b13ee4e..550f9b27cc7 100644 put_u32(&buffer, flags); } -@@ -3128,9 +3313,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3128,9 +3399,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) for (i = 0; i < extern_resources_count; ++i) { @@ -11317,7 +13242,7 @@ index d066b13ee4e..550f9b27cc7 100644 set_u32(&buffer, resources_offset + i * 8 * sizeof(uint32_t), string_offset); } -@@ -3234,9 +3419,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) +@@ -3234,9 +3505,9 @@ static void write_sm4_rdef(struct hlsl_ctx *ctx, struct dxbc_writer *dxbc) creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL)); set_u32(&buffer, creator_position, creator_offset); @@ -11329,7 +13254,7 @@ index d066b13ee4e..550f9b27cc7 100644 } static enum vkd3d_sm4_resource_type sm4_resource_dimension(const struct hlsl_type *type) -@@ -3308,8 +3493,8 @@ static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_mod +@@ -3308,8 +3579,8 @@ static uint32_t sm4_encode_instruction_modifier(const struct sm4_instruction_mod struct sm4_register { @@ -11340,7 +13265,7 @@ index d066b13ee4e..550f9b27cc7 100644 unsigned int idx_count; enum vkd3d_sm4_dimension dim; uint32_t immconst_uint[4]; -@@ -3346,8 +3531,9 @@ struct sm4_instruction +@@ -3346,8 +3617,9 @@ struct sm4_instruction static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *reg, unsigned int *writemask, enum vkd3d_sm4_swizzle_type *swizzle_type, @@ -11351,7 +13276,7 @@ index d066b13ee4e..550f9b27cc7 100644 const struct hlsl_ir_var *var = deref->var; if (var->is_uniform) -@@ -3356,37 +3542,37 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r +@@ -3356,37 +3628,37 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r if (regset == HLSL_REGSET_TEXTURES) { @@ -11401,7 +13326,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg->idx_count = 1; *writemask = VKD3DSP_WRITEMASK_ALL; } -@@ -3395,12 +3581,12 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r +@@ -3395,12 +3667,12 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref) + var->buffer_offset; assert(data_type->class <= HLSL_CLASS_VECTOR); @@ -11417,7 +13342,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg->idx_count = 2; *writemask = ((1u << data_type->dimx) - 1) << (offset & 3); } -@@ -3415,7 +3601,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r +@@ -3415,7 +3687,7 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r if (has_idx) { @@ -11426,7 +13351,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg->idx_count = 1; } -@@ -3427,11 +3613,11 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r +@@ -3427,11 +3699,11 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); assert(hlsl_reg.allocated); @@ -11440,7 +13365,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg->idx_count = 1; *writemask = hlsl_reg.writemask; } -@@ -3446,11 +3632,11 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r +@@ -3446,11 +3718,11 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r if (has_idx) { @@ -11454,7 +13379,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg->dim = VKD3D_SM4_DIMENSION_SCALAR; else reg->dim = VKD3D_SM4_DIMENSION_VEC4; -@@ -3461,9 +3647,9 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r +@@ -3461,9 +3733,9 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); assert(hlsl_reg.allocated); @@ -11466,7 +13391,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg->idx_count = 1; *writemask = hlsl_reg.writemask; } -@@ -3473,22 +3659,22 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r +@@ -3473,22 +3745,22 @@ static void sm4_register_from_deref(struct hlsl_ctx *ctx, struct sm4_register *r struct hlsl_reg hlsl_reg = hlsl_reg_from_deref(ctx, deref); assert(hlsl_reg.allocated); @@ -11493,7 +13418,7 @@ index d066b13ee4e..550f9b27cc7 100644 if (src->swizzle_type == VKD3D_SM4_SWIZZLE_VEC4) src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); } -@@ -3497,10 +3683,10 @@ static void sm4_register_from_node(struct sm4_register *reg, unsigned int *write +@@ -3497,10 +3769,10 @@ static void sm4_register_from_node(struct sm4_register *reg, unsigned int *write enum vkd3d_sm4_swizzle_type *swizzle_type, const struct hlsl_ir_node *instr) { assert(instr->reg.allocated); @@ -11506,7 +13431,7 @@ index d066b13ee4e..550f9b27cc7 100644 reg->idx_count = 1; *writemask = instr->reg.writemask; } -@@ -3516,7 +3702,7 @@ static void sm4_src_from_constant_value(struct sm4_src_register *src, +@@ -3516,7 +3788,7 @@ static void sm4_src_from_constant_value(struct sm4_src_register *src, const struct hlsl_constant_value *value, unsigned int width, unsigned int map_writemask) { src->swizzle_type = VKD3D_SM4_SWIZZLE_NONE; @@ -11515,7 +13440,19 @@ index d066b13ee4e..550f9b27cc7 100644 if (width == 1) { src->reg.dim = VKD3D_SM4_DIMENSION_SCALAR; -@@ -3553,17 +3739,100 @@ static void sm4_src_from_node(struct sm4_src_register *src, +@@ -3529,8 +3801,10 @@ static void sm4_src_from_constant_value(struct sm4_src_register *src, + src->reg.dim = VKD3D_SM4_DIMENSION_VEC4; + for (i = 0; i < 4; ++i) + { +- if (map_writemask & (1u << i)) ++ if ((map_writemask & (1u << i)) && (j < width)) + src->reg.immconst_uint[i] = value->u[j++].u; ++ else ++ src->reg.immconst_uint[i] = 0; + } + } + } +@@ -3553,17 +3827,100 @@ static void sm4_src_from_node(struct sm4_src_register *src, src->swizzle = hlsl_map_swizzle(hlsl_swizzle_from_writemask(writemask), map_writemask); } @@ -11621,7 +13558,7 @@ index d066b13ee4e..550f9b27cc7 100644 order += reg->dim == VKD3D_SM4_DIMENSION_VEC4 ? 4 : 1; order += reg->idx_count; if (reg->mod) -@@ -3571,8 +3840,9 @@ static uint32_t sm4_register_order(const struct sm4_register *reg) +@@ -3571,8 +3928,9 @@ static uint32_t sm4_register_order(const struct sm4_register *reg) return order; } @@ -11632,7 +13569,7 @@ index d066b13ee4e..550f9b27cc7 100644 uint32_t token = instr->opcode; unsigned int size = 1, i, j; -@@ -3600,43 +3870,10 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st +@@ -3600,43 +3958,10 @@ static void write_sm4_instruction(struct vkd3d_bytecode_buffer *buffer, const st } for (i = 0; i < instr->dst_count; ++i) @@ -11678,7 +13615,7 @@ index d066b13ee4e..550f9b27cc7 100644 if (instr->byte_stride) put_u32(buffer, instr->byte_stride); -@@ -3672,67 +3909,75 @@ static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, +@@ -3672,67 +3997,75 @@ static bool encode_texel_offset_as_aoffimmi(struct sm4_instruction *instr, return true; } @@ -11774,7 +13711,7 @@ index d066b13ee4e..550f9b27cc7 100644 .dsts[0].reg.idx_count = 1, .dst_count = 1, -@@ -3742,11 +3987,11 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -3742,11 +4075,11 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b if (uav) { @@ -11788,7 +13725,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; default: instr.opcode = VKD3D_SM5_OP_DCL_UAV_TYPED; -@@ -3765,13 +4010,13 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -3765,13 +4098,13 @@ static void write_sm4_dcl_textures(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b instr.opcode |= component_type->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; } @@ -11805,7 +13742,7 @@ index d066b13ee4e..550f9b27cc7 100644 const bool output = var->is_output_semantic; D3D_NAME usage; bool has_idx; -@@ -3782,11 +4027,11 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -3782,11 +4115,11 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b .dst_count = 1, }; @@ -11819,7 +13756,7 @@ index d066b13ee4e..550f9b27cc7 100644 instr.dsts[0].reg.idx_count = 1; } else -@@ -3797,16 +4042,16 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -3797,16 +4130,16 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b } else { @@ -11840,7 +13777,7 @@ index d066b13ee4e..550f9b27cc7 100644 if (usage == ~0u) usage = D3D_NAME_UNDEFINED; -@@ -3866,10 +4111,10 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b +@@ -3866,10 +4199,10 @@ static void write_sm4_dcl_semantic(struct hlsl_ctx *ctx, struct vkd3d_bytecode_b break; } @@ -11853,7 +13790,7 @@ index d066b13ee4e..550f9b27cc7 100644 { struct sm4_instruction instr = { -@@ -3879,33 +4124,35 @@ static void write_sm4_dcl_temps(struct vkd3d_bytecode_buffer *buffer, uint32_t t +@@ -3879,33 +4212,35 @@ static void write_sm4_dcl_temps(struct vkd3d_bytecode_buffer *buffer, uint32_t t .idx_count = 1, }; @@ -11896,7 +13833,7 @@ index d066b13ee4e..550f9b27cc7 100644 const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src, unsigned int src_mod) { struct sm4_instruction instr; -@@ -3920,12 +4167,11 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ +@@ -3920,12 +4255,11 @@ static void write_sm4_unary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d_ instr.srcs[0].reg.mod = src_mod; instr.src_count = 1; @@ -11912,7 +13849,7 @@ index d066b13ee4e..550f9b27cc7 100644 { struct sm4_instruction instr; -@@ -3935,7 +4181,7 @@ static void write_sm4_unary_op_with_two_destinations(struct vkd3d_bytecode_buffe +@@ -3935,7 +4269,7 @@ static void write_sm4_unary_op_with_two_destinations(struct vkd3d_bytecode_buffe assert(dst_idx < ARRAY_SIZE(instr.dsts)); sm4_dst_from_node(&instr.dsts[dst_idx], dst); assert(1 - dst_idx >= 0); @@ -11921,7 +13858,7 @@ index d066b13ee4e..550f9b27cc7 100644 instr.dsts[1 - dst_idx].reg.dim = VKD3D_SM4_DIMENSION_NONE; instr.dsts[1 - dst_idx].reg.idx_count = 0; instr.dst_count = 2; -@@ -3943,10 +4189,10 @@ static void write_sm4_unary_op_with_two_destinations(struct vkd3d_bytecode_buffe +@@ -3943,10 +4277,10 @@ static void write_sm4_unary_op_with_two_destinations(struct vkd3d_bytecode_buffe sm4_src_from_node(&instr.srcs[0], src, instr.dsts[dst_idx].writemask); instr.src_count = 1; @@ -11934,7 +13871,7 @@ index d066b13ee4e..550f9b27cc7 100644 const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) { struct sm4_instruction instr; -@@ -3961,11 +4207,11 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d +@@ -3961,11 +4295,11 @@ static void write_sm4_binary_op(struct vkd3d_bytecode_buffer *buffer, enum vkd3d sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); instr.src_count = 2; @@ -11948,7 +13885,7 @@ index d066b13ee4e..550f9b27cc7 100644 const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) { struct sm4_instruction instr; -@@ -3980,10 +4226,10 @@ static void write_sm4_binary_op_dot(struct vkd3d_bytecode_buffer *buffer, enum v +@@ -3980,10 +4314,10 @@ static void write_sm4_binary_op_dot(struct vkd3d_bytecode_buffer *buffer, enum v sm4_src_from_node(&instr.srcs[1], src2, VKD3DSP_WRITEMASK_ALL); instr.src_count = 2; @@ -11961,7 +13898,7 @@ index d066b13ee4e..550f9b27cc7 100644 enum vkd3d_sm4_opcode opcode, const struct hlsl_ir_node *dst, unsigned dst_idx, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2) { -@@ -3995,7 +4241,7 @@ static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buff +@@ -3995,7 +4329,7 @@ static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buff assert(dst_idx < ARRAY_SIZE(instr.dsts)); sm4_dst_from_node(&instr.dsts[dst_idx], dst); assert(1 - dst_idx >= 0); @@ -11970,11 +13907,31 @@ index d066b13ee4e..550f9b27cc7 100644 instr.dsts[1 - dst_idx].reg.dim = VKD3D_SM4_DIMENSION_NONE; instr.dsts[1 - dst_idx].reg.idx_count = 0; instr.dst_count = 2; -@@ -4004,15 +4250,15 @@ static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buff +@@ -4004,15 +4338,35 @@ static void write_sm4_binary_op_with_two_destinations(struct vkd3d_bytecode_buff sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[dst_idx].writemask); instr.src_count = 2; - write_sm4_instruction(buffer, &instr); ++ write_sm4_instruction(tpf, &instr); ++} ++ ++static void write_sm4_ternary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opcode opcode, ++ const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2, ++ const struct hlsl_ir_node *src3) ++{ ++ struct sm4_instruction instr; ++ ++ memset(&instr, 0, sizeof(instr)); ++ instr.opcode = opcode; ++ ++ sm4_dst_from_node(&instr.dsts[0], dst); ++ instr.dst_count = 1; ++ ++ sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask); ++ sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); ++ sm4_src_from_node(&instr.srcs[2], src3, instr.dsts[0].writemask); ++ instr.src_count = 3; ++ + write_sm4_instruction(tpf, &instr); } @@ -11989,7 +13946,7 @@ index d066b13ee4e..550f9b27cc7 100644 bool multisampled = resource_type->base_type == HLSL_TYPE_TEXTURE && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); bool uav = (hlsl_type_get_regset(resource_type) == HLSL_REGSET_UAVS); -@@ -4029,7 +4275,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf +@@ -4029,7 +4383,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf { if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) { @@ -11998,7 +13955,7 @@ index d066b13ee4e..550f9b27cc7 100644 "Offset must resolve to integer literal in the range -8 to 7."); return; } -@@ -4052,7 +4298,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf +@@ -4052,7 +4406,7 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf sm4_src_from_node(&instr.srcs[0], coords, coords_writemask); @@ -12007,7 +13964,7 @@ index d066b13ee4e..550f9b27cc7 100644 instr.src_count = 2; -@@ -4067,13 +4313,13 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf +@@ -4067,13 +4421,13 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf memset(&instr.srcs[2], 0, sizeof(instr.srcs[2])); instr.srcs[2].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; @@ -12024,7 +13981,7 @@ index d066b13ee4e..550f9b27cc7 100644 } else { -@@ -4083,13 +4329,11 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf +@@ -4083,13 +4437,11 @@ static void write_sm4_ld(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf ++instr.src_count; } @@ -12040,7 +13997,7 @@ index d066b13ee4e..550f9b27cc7 100644 const struct hlsl_ir_node *texel_offset = load->texel_offset.node; const struct hlsl_ir_node *coords = load->coords.node; const struct hlsl_deref *resource = &load->resource; -@@ -4132,7 +4376,7 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer +@@ -4132,7 +4484,7 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer { if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) { @@ -12049,7 +14006,7 @@ index d066b13ee4e..550f9b27cc7 100644 "Offset must resolve to integer literal in the range -8 to 7."); return; } -@@ -4142,8 +4386,8 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer +@@ -4142,8 +4494,8 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer instr.dst_count = 1; sm4_src_from_node(&instr.srcs[0], coords, VKD3DSP_WRITEMASK_ALL); @@ -12060,7 +14017,7 @@ index d066b13ee4e..550f9b27cc7 100644 instr.src_count = 3; if (load->load_type == HLSL_RESOURCE_SAMPLE_LOD -@@ -4165,7 +4409,52 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer +@@ -4165,7 +4517,52 @@ static void write_sm4_sample(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer ++instr.src_count; } @@ -12114,7 +14071,7 @@ index d066b13ee4e..550f9b27cc7 100644 } static bool type_is_float(const struct hlsl_type *type) -@@ -4173,8 +4462,7 @@ static bool type_is_float(const struct hlsl_type *type) +@@ -4173,8 +4570,7 @@ static bool type_is_float(const struct hlsl_type *type) return type->base_type == HLSL_TYPE_FLOAT || type->base_type == HLSL_TYPE_HALF; } @@ -12124,7 +14081,7 @@ index d066b13ee4e..550f9b27cc7 100644 const struct hlsl_ir_node *arg, uint32_t mask) { struct sm4_instruction instr; -@@ -4187,16 +4475,15 @@ static void write_sm4_cast_from_bool(struct hlsl_ctx *ctx, +@@ -4187,16 +4583,15 @@ static void write_sm4_cast_from_bool(struct hlsl_ctx *ctx, sm4_src_from_node(&instr.srcs[0], arg, instr.dsts[0].writemask); instr.srcs[1].swizzle_type = VKD3D_SM4_SWIZZLE_NONE; @@ -12144,7 +14101,7 @@ index d066b13ee4e..550f9b27cc7 100644 { static const union { -@@ -4218,23 +4505,23 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, +@@ -4218,23 +4613,23 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -12173,7 +14130,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; default: -@@ -4247,20 +4534,20 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, +@@ -4247,20 +4642,20 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -12198,7 +14155,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; default: -@@ -4273,20 +4560,20 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, +@@ -4273,20 +4668,20 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -12223,7 +14180,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; default: -@@ -4295,7 +4582,7 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, +@@ -4295,7 +4690,7 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, break; case HLSL_TYPE_DOUBLE: @@ -12232,7 +14189,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; case HLSL_TYPE_BOOL: -@@ -4305,26 +4592,25 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, +@@ -4305,35 +4700,35 @@ static void write_sm4_cast(struct hlsl_ctx *ctx, } } @@ -12264,7 +14221,9 @@ index d066b13ee4e..550f9b27cc7 100644 { const struct hlsl_ir_node *arg1 = expr->operands[0].node; const struct hlsl_ir_node *arg2 = expr->operands[1].node; -@@ -4333,7 +4619,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, ++ const struct hlsl_ir_node *arg3 = expr->operands[2].node; + const struct hlsl_type *dst_type = expr->node.data_type; + struct vkd3d_string_buffer *dst_type_string; assert(expr->node.reg.allocated); @@ -12273,7 +14232,7 @@ index d066b13ee4e..550f9b27cc7 100644 return; switch (expr->op) -@@ -4342,161 +4628,181 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4342,161 +4737,181 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (dst_type->base_type) { case HLSL_TYPE_FLOAT: @@ -12486,7 +14445,7 @@ index d066b13ee4e..550f9b27cc7 100644 } break; -@@ -4507,15 +4813,15 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4507,15 +4922,15 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (arg1->data_type->dimx) { case 4: @@ -12505,7 +14464,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; case 1: -@@ -4525,7 +4831,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4525,7 +4940,7 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, break; default: @@ -12514,7 +14473,7 @@ index d066b13ee4e..550f9b27cc7 100644 } break; -@@ -4538,18 +4844,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4538,18 +4953,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (src_type->base_type) { case HLSL_TYPE_FLOAT: @@ -12537,7 +14496,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; } break; -@@ -4564,21 +4870,21 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4564,21 +4979,21 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (src_type->base_type) { case HLSL_TYPE_FLOAT: @@ -12564,7 +14523,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; } break; -@@ -4593,21 +4899,21 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4593,21 +5008,21 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (src_type->base_type) { case HLSL_TYPE_FLOAT: @@ -12591,7 +14550,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; } break; -@@ -4615,37 +4921,37 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4615,37 +5030,37 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, case HLSL_OP2_LOGIC_AND: assert(dst_type->base_type == HLSL_TYPE_BOOL); @@ -12636,7 +14595,7 @@ index d066b13ee4e..550f9b27cc7 100644 } break; -@@ -4653,19 +4959,19 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4653,19 +5068,19 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (dst_type->base_type) { case HLSL_TYPE_FLOAT: @@ -12660,7 +14619,7 @@ index d066b13ee4e..550f9b27cc7 100644 } break; -@@ -4673,11 +4979,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4673,11 +5088,11 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (dst_type->base_type) { case HLSL_TYPE_UINT: @@ -12674,7 +14633,7 @@ index d066b13ee4e..550f9b27cc7 100644 } break; -@@ -4685,18 +4991,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4685,18 +5100,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (dst_type->base_type) { case HLSL_TYPE_FLOAT: @@ -12696,7 +14655,7 @@ index d066b13ee4e..550f9b27cc7 100644 } break; -@@ -4709,18 +5015,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4709,18 +5124,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, switch (src_type->base_type) { case HLSL_TYPE_FLOAT: @@ -12719,7 +14678,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; } break; -@@ -4729,18 +5035,18 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, +@@ -4729,18 +5144,22 @@ static void write_sm4_expr(struct hlsl_ctx *ctx, case HLSL_OP2_RSHIFT: assert(type_is_integer(dst_type)); assert(dst_type->base_type != HLSL_TYPE_BOOL); @@ -12728,6 +14687,10 @@ index d066b13ee4e..550f9b27cc7 100644 &expr->node, arg1, arg2); break; ++ case HLSL_OP3_MOVC: ++ write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MOVC, &expr->node, arg1, arg2, arg3); ++ break; ++ default: - hlsl_fixme(ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); + hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); @@ -12742,7 +14705,7 @@ index d066b13ee4e..550f9b27cc7 100644 { struct sm4_instruction instr = { -@@ -4751,26 +5057,25 @@ static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf +@@ -4751,26 +5170,25 @@ static void write_sm4_if(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buf assert(iff->condition.node->data_type->dimx == 1); sm4_src_from_node(&instr.srcs[0], iff->condition.node, VKD3DSP_WRITEMASK_ALL); @@ -12775,7 +14738,7 @@ index d066b13ee4e..550f9b27cc7 100644 { struct sm4_instruction instr = {0}; -@@ -4780,19 +5085,13 @@ static void write_sm4_jump(struct hlsl_ctx *ctx, +@@ -4780,19 +5198,13 @@ static void write_sm4_jump(struct hlsl_ctx *ctx, instr.opcode = VKD3D_SM4_OP_BREAK; break; @@ -12797,7 +14760,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; } -@@ -4800,11 +5099,11 @@ static void write_sm4_jump(struct hlsl_ctx *ctx, +@@ -4800,11 +5212,11 @@ static void write_sm4_jump(struct hlsl_ctx *ctx, vkd3d_unreachable(); default: @@ -12811,7 +14774,7 @@ index d066b13ee4e..550f9b27cc7 100644 } /* Does this variable's data come directly from the API user, rather than being -@@ -4818,8 +5117,7 @@ static bool var_is_user_input(struct hlsl_ctx *ctx, const struct hlsl_ir_var *va +@@ -4818,8 +5230,7 @@ static bool var_is_user_input(struct hlsl_ctx *ctx, const struct hlsl_ir_var *va return var->is_input_semantic && ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX; } @@ -12821,7 +14784,7 @@ index d066b13ee4e..550f9b27cc7 100644 { const struct hlsl_type *type = load->node.data_type; struct sm4_instruction instr; -@@ -4830,7 +5128,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, +@@ -4830,7 +5241,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, instr.dst_count = 1; assert(type->class <= HLSL_CLASS_LAST_NUMERIC); @@ -12830,7 +14793,7 @@ index d066b13ee4e..550f9b27cc7 100644 { struct hlsl_constant_value value; -@@ -4839,7 +5137,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, +@@ -4839,7 +5250,7 @@ static void write_sm4_load(struct hlsl_ctx *ctx, instr.opcode = VKD3D_SM4_OP_MOVC; @@ -12839,7 +14802,7 @@ index d066b13ee4e..550f9b27cc7 100644 memset(&value, 0xff, sizeof(value)); sm4_src_from_constant_value(&instr.srcs[1], &value, type->dimx, instr.dsts[0].writemask); -@@ -4851,33 +5149,31 @@ static void write_sm4_load(struct hlsl_ctx *ctx, +@@ -4851,33 +5262,31 @@ static void write_sm4_load(struct hlsl_ctx *ctx, { instr.opcode = VKD3D_SM4_OP_MOV; @@ -12882,7 +14845,7 @@ index d066b13ee4e..550f9b27cc7 100644 { struct sm4_src_register *src; struct sm4_instruction instr; -@@ -4895,9 +5191,9 @@ static void write_sm4_gather(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer +@@ -4895,9 +5304,9 @@ static void write_sm4_gather(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer { if (!encode_texel_offset_as_aoffimmi(&instr, texel_offset)) { @@ -12894,7 +14857,7 @@ index d066b13ee4e..550f9b27cc7 100644 "Offset must resolve to integer literal in the range -8 to 7 for profiles < 5."); return; } -@@ -4906,58 +5202,39 @@ static void write_sm4_gather(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer +@@ -4906,58 +5315,39 @@ static void write_sm4_gather(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer } } @@ -12961,7 +14924,7 @@ index d066b13ee4e..550f9b27cc7 100644 coords, sample_index, texel_offset, load->sampling_dim); break; -@@ -4967,64 +5244,61 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, +@@ -4967,64 +5357,61 @@ static void write_sm4_resource_load(struct hlsl_ctx *ctx, case HLSL_RESOURCE_SAMPLE_LOD: case HLSL_RESOURCE_SAMPLE_LOD_BIAS: case HLSL_RESOURCE_SAMPLE_GRAD: @@ -13051,7 +15014,7 @@ index d066b13ee4e..550f9b27cc7 100644 { const struct hlsl_ir_node *rhs = store->rhs.node; struct sm4_instruction instr; -@@ -5033,18 +5307,17 @@ static void write_sm4_store(struct hlsl_ctx *ctx, +@@ -5033,18 +5420,17 @@ static void write_sm4_store(struct hlsl_ctx *ctx, memset(&instr, 0, sizeof(instr)); instr.opcode = VKD3D_SM4_OP_MOV; @@ -13073,7 +15036,7 @@ index d066b13ee4e..550f9b27cc7 100644 { struct sm4_instruction instr; unsigned int writemask; -@@ -5060,11 +5333,10 @@ static void write_sm4_swizzle(struct hlsl_ctx *ctx, +@@ -5060,11 +5446,10 @@ static void write_sm4_swizzle(struct hlsl_ctx *ctx, swizzle->swizzle, swizzle->node.data_type->dimx), instr.dsts[0].writemask); instr.src_count = 1; @@ -13087,7 +15050,7 @@ index d066b13ee4e..550f9b27cc7 100644 { const struct hlsl_ir_node *instr; -@@ -5074,12 +5346,12 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * +@@ -5074,12 +5459,12 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * { if (instr->data_type->class == HLSL_CLASS_MATRIX) { @@ -13102,7 +15065,7 @@ index d066b13ee4e..550f9b27cc7 100644 break; } -@@ -5099,43 +5371,43 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * +@@ -5099,43 +5484,43 @@ static void write_sm4_block(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer * vkd3d_unreachable(); case HLSL_IR_EXPR: @@ -13156,7 +15119,7 @@ index d066b13ee4e..550f9b27cc7 100644 } } } -@@ -5144,12 +5416,13 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, +@@ -5144,12 +5529,13 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *entry_func, struct dxbc_writer *dxbc) { const struct hlsl_profile_info *profile = ctx->profile; @@ -13171,7 +15134,7 @@ index d066b13ee4e..550f9b27cc7 100644 static const uint16_t shader_types[VKD3D_SHADER_TYPE_COUNT] = { -@@ -5164,6 +5437,8 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, +@@ -5164,6 +5550,8 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, VKD3D_SM4_LIB, }; @@ -13180,7 +15143,7 @@ index d066b13ee4e..550f9b27cc7 100644 extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count); put_u32(&buffer, vkd3d_make_u32((profile->major_version << 4) | profile->minor_version, shader_types[profile->type])); -@@ -5172,45 +5447,42 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, +@@ -5172,45 +5560,42 @@ static void write_sm4_shdr(struct hlsl_ctx *ctx, LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) @@ -13191,11 +15154,11 @@ index d066b13ee4e..550f9b27cc7 100644 for (i = 0; i < extern_resources_count; ++i) { - enum hlsl_regset regset; -+ const struct extern_resource *resource = &extern_resources[i]; - +- - var = extern_resources[i]; - regset = hlsl_type_get_regset(var->data_type); -- ++ const struct extern_resource *resource = &extern_resources[i]; + - if (regset == HLSL_REGSET_SAMPLERS) - write_sm4_dcl_samplers(&buffer, var); - else if (regset == HLSL_REGSET_TEXTURES) @@ -13242,7 +15205,7 @@ index d066b13ee4e..550f9b27cc7 100644 int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out) diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 343fdb2252e..c777bad2206 100644 +index 343fdb2252e..0245d83a10b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -415,6 +415,8 @@ static const char *shader_get_source_type_suffix(enum vkd3d_shader_source_type t @@ -13351,7 +15314,7 @@ index 343fdb2252e..c777bad2206 100644 vkd3d_free(context->cf_info); } -@@ -652,18 +694,23 @@ static struct vkd3d_shader_cf_info *vkd3d_shader_scan_find_innermost_loop_cf_inf +@@ -652,18 +694,24 @@ static struct vkd3d_shader_cf_info *vkd3d_shader_scan_find_innermost_loop_cf_inf return NULL; } @@ -13371,7 +15334,8 @@ index 343fdb2252e..c777bad2206 100644 { - if (context->uav_ranges[i].id == range_id) - return &context->scan_descriptor_info->descriptors[context->uav_ranges[i].descriptor_idx]; -+ if (context->scan_descriptor_info->descriptors[i].register_id == range_id) ++ if (context->scan_descriptor_info->descriptors[i].type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV ++ && context->scan_descriptor_info->descriptors[i].register_id == range_id) + { + context->scan_descriptor_info->descriptors[i].flags |= flag; + break; @@ -13382,7 +15346,7 @@ index 343fdb2252e..c777bad2206 100644 } static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instruction *instruction) -@@ -679,13 +726,7 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr +@@ -679,13 +727,7 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_register *reg) { @@ -13397,7 +15361,7 @@ index 343fdb2252e..c777bad2206 100644 } static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_instruction *instruction) -@@ -698,13 +739,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in +@@ -698,13 +740,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_register *reg) { @@ -13412,7 +15376,7 @@ index 343fdb2252e..c777bad2206 100644 } static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_instruction *instruction) -@@ -717,22 +752,16 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_ +@@ -717,93 +753,76 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_register *reg) { @@ -13426,13 +15390,14 @@ index 343fdb2252e..c777bad2206 100644 + vkd3d_shader_scan_add_uav_flag(context, reg, VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS); } - static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, +-static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, - enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register_range *range, - enum vkd3d_shader_resource_type resource_type, enum vkd3d_shader_resource_data_type resource_data_type, - unsigned int flags) ++static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, + enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, + const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, -+ enum vkd3d_shader_resource_data_type resource_data_type, unsigned int flags) ++ enum vkd3d_shader_resource_data_type resource_data_type) { - struct vkd3d_shader_scan_descriptor_info *info = context->scan_descriptor_info; - struct vkd3d_shader_descriptor_info *d; @@ -13441,18 +15406,27 @@ index 343fdb2252e..c777bad2206 100644 if (!vkd3d_array_reserve((void **)&info->descriptors, &context->descriptors_size, info->descriptor_count + 1, sizeof(*info->descriptors))) -@@ -743,6 +772,7 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c + { + ERR("Failed to allocate descriptor info.\n"); +- return false; ++ return NULL; + } d = &info->descriptors[info->descriptor_count]; ++ memset(d, 0, sizeof(*d)); d->type = type; + d->register_id = reg->idx[0].offset; d->register_space = range->space; d->register_index = range->first; d->resource_type = resource_type; -@@ -754,23 +784,6 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c - return true; - } + d->resource_data_type = resource_data_type; +- d->flags = flags; + d->count = (range->last == ~0u) ? ~0u : range->last - range->first + 1; + ++info->descriptor_count; +- return true; +-} +- -static bool vkd3d_shader_scan_add_uav_range(struct vkd3d_shader_scan_context *context, - unsigned int id, unsigned int descriptor_idx) -{ @@ -13468,30 +15442,60 @@ index 343fdb2252e..c777bad2206 100644 - ++context->uav_range_count; - - return true; --} -- ++ return d; + } + static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_instruction *instruction) { -@@ -779,7 +792,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc + const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; ++ struct vkd3d_shader_descriptor_info1 *d; + if (!context->scan_descriptor_info) return; - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, &cb->range, -+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, &cb->src.reg, &cb->range, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); ++ if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ++ &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) ++ return; ++ d->buffer_size = cb->size * 16; } -@@ -796,7 +809,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte - flags = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; - else - flags = 0; + static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_instruction *instruction) + { + const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler; +- unsigned int flags; ++ struct vkd3d_shader_descriptor_info1 *d; + + if (!context->scan_descriptor_info) + return; + ++ if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, ++ &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT))) ++ return; ++ + if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) +- flags = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; +- else +- flags = 0; - vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &sampler->range, -+ vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &sampler->src.reg, &sampler->range, - VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT, flags); +- VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT, flags); ++ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; } -@@ -813,10 +826,8 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, +- enum vkd3d_shader_resource_data_type resource_data_type) ++ enum vkd3d_shader_resource_data_type resource_data_type, ++ unsigned int sample_count, unsigned int structure_stride, bool raw) + { ++ struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_descriptor_type type; + + if (!context->scan_descriptor_info) +@@ -813,10 +832,13 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; else type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; @@ -13499,12 +15503,42 @@ index 343fdb2252e..c777bad2206 100644 - if (type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) - vkd3d_shader_scan_add_uav_range(context, resource->reg.reg.idx[0].offset, - context->scan_descriptor_info->descriptor_count - 1); -+ vkd3d_shader_scan_add_descriptor(context, type, &resource->reg.reg, &resource->range, -+ resource_type, resource_data_type, 0); ++ if (!(d = vkd3d_shader_scan_add_descriptor(context, type, &resource->reg.reg, ++ &resource->range, resource_type, resource_data_type))) ++ return; ++ d->sample_count = sample_count; ++ d->structure_stride = structure_stride; ++ if (raw) ++ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; } static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context, -@@ -1066,22 +1077,64 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte +@@ -875,7 +897,7 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca + } + + vkd3d_shader_scan_resource_declaration(context, &semantic->resource, +- semantic->resource_type, resource_data_type); ++ semantic->resource_type, resource_data_type, semantic->sample_count, 0, false); + } + + static void vkd3d_shader_scan_error(struct vkd3d_shader_scan_context *context, +@@ -909,12 +931,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte + case VKD3DSIH_DCL_RESOURCE_RAW: + case VKD3DSIH_DCL_UAV_RAW: + vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT); ++ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true); + break; + case VKD3DSIH_DCL_RESOURCE_STRUCTURED: + case VKD3DSIH_DCL_UAV_STRUCTURED: + vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, +- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT); ++ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, ++ instruction->declaration.structured_resource.byte_stride, false); + break; + case VKD3DSIH_IF: + cf_info = vkd3d_shader_scan_push_cf_info(context); +@@ -1066,22 +1089,64 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_OK; } @@ -13558,16 +15592,16 @@ index 343fdb2252e..c777bad2206 100644 - if ((scan_descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO))) + descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); + if (descriptor_info1) -+ { -+ descriptor_info1->descriptors = NULL; -+ descriptor_info1->descriptor_count = 0; -+ } -+ else if (descriptor_info) { - scan_descriptor_info->descriptors = NULL; - scan_descriptor_info->descriptor_count = 0; -+ descriptor_info1 = &local_descriptor_info1; ++ descriptor_info1->descriptors = NULL; ++ descriptor_info1->descriptor_count = 0; } ++ else if (descriptor_info) ++ { ++ descriptor_info1 = &local_descriptor_info1; ++ } + signature_info = vkd3d_find_struct(compile_info->next, SCAN_SIGNATURE_INFO); - vkd3d_shader_scan_context_init(&context, compile_info, scan_descriptor_info, message_context); @@ -13575,7 +15609,7 @@ index 343fdb2252e..c777bad2206 100644 if (TRACE_ON()) { -@@ -1092,13 +1145,47 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info +@@ -1092,13 +1157,52 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info { instruction = &parser->instructions.elements[i]; if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0) @@ -13587,14 +15621,19 @@ index 343fdb2252e..c777bad2206 100644 + + for (i = 0; i < ARRAY_SIZE(parser->shader_desc.flat_constant_count); ++i) + { ++ unsigned int size = parser->shader_desc.flat_constant_count[i].external; + struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; + struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1}; ++ struct vkd3d_shader_descriptor_info1 *d; + + if (parser->shader_desc.flat_constant_count[i].external) -+ vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, -+ &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); -+ } -+ ++ { ++ if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, ++ &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) ++ d->buffer_size = size * 16; + } + } + + if (!ret && signature_info) + { + if (!vkd3d_shader_signature_from_shader_signature(&signature_info->input, &parser->shader_desc.input_signature) @@ -13604,9 +15643,9 @@ index 343fdb2252e..c777bad2206 100644 + &parser->shader_desc.patch_constant_signature)) + { + ret = VKD3D_ERROR_OUT_OF_MEMORY; - } - } - ++ } ++ } ++ + if (!ret && descriptor_info) + ret = convert_descriptor_info(descriptor_info, descriptor_info1); + @@ -13626,7 +15665,7 @@ index 343fdb2252e..c777bad2206 100644 vkd3d_shader_scan_context_cleanup(&context); return ret; } -@@ -1115,7 +1202,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info, +@@ -1115,7 +1219,7 @@ static int scan_dxbc(const struct vkd3d_shader_compile_info *compile_info, return ret; } @@ -13635,7 +15674,7 @@ index 343fdb2252e..c777bad2206 100644 vkd3d_shader_parser_destroy(parser); return ret; -@@ -1133,7 +1220,25 @@ static int scan_d3dbc(const struct vkd3d_shader_compile_info *compile_info, +@@ -1133,7 +1237,25 @@ static int scan_d3dbc(const struct vkd3d_shader_compile_info *compile_info, return ret; } @@ -13662,7 +15701,7 @@ index 343fdb2252e..c777bad2206 100644 vkd3d_shader_parser_destroy(parser); return ret; -@@ -1152,6 +1257,8 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char +@@ -1152,6 +1274,8 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char if ((ret = vkd3d_shader_validate_compile_info(compile_info, false)) < 0) return ret; @@ -13671,7 +15710,7 @@ index 343fdb2252e..c777bad2206 100644 vkd3d_shader_message_context_init(&message_context, compile_info->log_level); switch (compile_info->source_type) -@@ -1169,6 +1276,10 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char +@@ -1169,6 +1293,10 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char ret = scan_d3dbc(compile_info, &message_context); break; @@ -13682,7 +15721,7 @@ index 343fdb2252e..c777bad2206 100644 default: ERR("Unsupported source type %#x.\n", compile_info->source_type); ret = VKD3D_ERROR_INVALID_ARGUMENT; -@@ -1186,7 +1297,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, +@@ -1186,7 +1314,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { @@ -13691,7 +15730,7 @@ index 343fdb2252e..c777bad2206 100644 struct vkd3d_glsl_generator *glsl_generator; struct vkd3d_shader_compile_info scan_info; int ret; -@@ -1194,11 +1305,8 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, +@@ -1194,11 +1322,8 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, vkd3d_shader_dump_shader(compile_info->source_type, parser->shader_version.type, &compile_info->source); scan_info = *compile_info; @@ -13704,7 +15743,7 @@ index 343fdb2252e..c777bad2206 100644 return ret; switch (compile_info->target_type) -@@ -1212,7 +1320,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, +@@ -1212,7 +1337,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, message_context, &parser->location))) { ERR("Failed to create GLSL generator.\n"); @@ -13713,7 +15752,7 @@ index 343fdb2252e..c777bad2206 100644 return VKD3D_ERROR; } -@@ -1230,7 +1338,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, +@@ -1230,7 +1355,7 @@ static int vkd3d_shader_parser_compile(struct vkd3d_shader_parser *parser, assert(0); } @@ -13722,7 +15761,7 @@ index 343fdb2252e..c777bad2206 100644 return ret; } -@@ -1291,6 +1399,24 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_ +@@ -1291,6 +1416,24 @@ static int compile_d3d_bytecode(const struct vkd3d_shader_compile_info *compile_ return VKD3D_ERROR; } @@ -13747,7 +15786,7 @@ index 343fdb2252e..c777bad2206 100644 int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, char **messages) { -@@ -1305,6 +1431,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, +@@ -1305,6 +1448,8 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, if ((ret = vkd3d_shader_validate_compile_info(compile_info, true)) < 0) return ret; @@ -13756,7 +15795,7 @@ index 343fdb2252e..c777bad2206 100644 vkd3d_shader_message_context_init(&message_context, compile_info->log_level); switch (compile_info->source_type) -@@ -1321,6 +1449,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, +@@ -1321,6 +1466,10 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, ret = compile_d3d_bytecode(compile_info, out, &message_context); break; @@ -13767,7 +15806,7 @@ index 343fdb2252e..c777bad2206 100644 default: vkd3d_unreachable(); } -@@ -1339,6 +1471,15 @@ void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_ +@@ -1339,6 +1488,15 @@ void vkd3d_shader_free_scan_descriptor_info(struct vkd3d_shader_scan_descriptor_ vkd3d_free(scan_descriptor_info->descriptors); } @@ -13783,7 +15822,7 @@ index 343fdb2252e..c777bad2206 100644 void vkd3d_shader_free_shader_code(struct vkd3d_shader_code *shader_code) { TRACE("shader_code %p.\n", shader_code); -@@ -1401,43 +1542,6 @@ void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signatu +@@ -1401,43 +1559,6 @@ void vkd3d_shader_free_root_signature(struct vkd3d_shader_versioned_root_signatu desc->version = 0; } @@ -13827,23 +15866,37 @@ index 343fdb2252e..c777bad2206 100644 void shader_signature_cleanup(struct shader_signature *signature) { vkd3d_free(signature->elements); -@@ -1526,6 +1630,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns +@@ -1526,6 +1647,9 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns VKD3D_SHADER_SOURCE_DXBC_TPF, VKD3D_SHADER_SOURCE_HLSL, VKD3D_SHADER_SOURCE_D3D_BYTECODE, ++#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL + VKD3D_SHADER_SOURCE_DXBC_DXIL, ++#endif }; TRACE("count %p.\n", count); -@@ -1564,6 +1669,7 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( +@@ -1564,6 +1688,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( switch (source_type) { ++#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL + case VKD3D_SHADER_SOURCE_DXBC_DXIL: ++#endif case VKD3D_SHADER_SOURCE_DXBC_TPF: *count = ARRAY_SIZE(dxbc_tpf_types); return dxbc_tpf_types; -@@ -1792,3 +1898,41 @@ void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *ins +@@ -1649,9 +1776,6 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, + { + void *params; + +- if (!count) +- return NULL; +- + if (count > allocator->count - allocator->index) + { + struct vkd3d_shader_param_node *next = shader_param_allocator_node_create(allocator); +@@ -1792,3 +1916,41 @@ void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *ins vkd3d_free(instructions->icbs[i]); vkd3d_free(instructions->icbs); } @@ -13886,10 +15939,34 @@ index 343fdb2252e..c777bad2206 100644 + *ret_count = count; +} diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 406d53a3391..c719085e11f 100644 +index 406d53a3391..eab1c730ae9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -133,10 +133,13 @@ enum vkd3d_shader_error +@@ -78,9 +78,14 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_TPF_TOO_MANY_REGISTERS = 1004, + VKD3D_SHADER_ERROR_TPF_INVALID_IO_REGISTER = 1005, + VKD3D_SHADER_ERROR_TPF_INVALID_INDEX_RANGE_DCL = 1006, ++ VKD3D_SHADER_ERROR_TPF_INVALID_CASE_VALUE = 1007, ++ VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION = 1008, ++ VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE = 1009, + + VKD3D_SHADER_WARNING_TPF_MASK_NOT_CONTIGUOUS = 1300, + VKD3D_SHADER_WARNING_TPF_UNHANDLED_INDEX_RANGE_MASK = 1301, ++ VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK = 1302, ++ VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_SWIZZLE = 1303, + + VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND = 2000, + VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001, +@@ -88,6 +93,8 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003, + VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004, + ++ VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300, ++ + VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000, + VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001, + VKD3D_SHADER_ERROR_RS_INVALID_ROOT_PARAMETER_TYPE = 3002, +@@ -133,10 +140,14 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE = 5024, VKD3D_SHADER_ERROR_HLSL_RECURSIVE_CALL = 5025, VKD3D_SHADER_ERROR_HLSL_INCONSISTENT_SAMPLER = 5026, @@ -13900,10 +15977,11 @@ index 406d53a3391..c719085e11f 100644 VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE = 5302, + VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT = 5303, + VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304, ++ VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305, VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, -@@ -145,8 +148,31 @@ enum vkd3d_shader_error +@@ -145,8 +156,33 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE = 7002, VKD3D_SHADER_ERROR_D3DBC_INVALID_RESOURCE_TYPE = 7003, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY = 7004, @@ -13924,18 +16002,20 @@ index 406d53a3391..c719085e11f 100644 + VKD3D_SHADER_ERROR_DXIL_INVALID_FUNCTION_DCL = 8009, + VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID = 8010, + VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011, ++ VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND = 8012, + + VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, + VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, + VKD3D_SHADER_WARNING_DXIL_INVALID_BLOCK_LENGTH = 8302, + VKD3D_SHADER_WARNING_DXIL_INVALID_MODULE_LENGTH = 8303, + VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS = 8304, ++ VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC = 8305, + + VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, }; enum vkd3d_shader_opcode -@@ -486,6 +512,9 @@ enum vkd3d_shader_register_type +@@ -486,6 +522,9 @@ enum vkd3d_shader_register_type VKD3DSPR_DEPTHOUTLE, VKD3DSPR_RASTERIZER, VKD3DSPR_OUTSTENCILREF, @@ -13945,15 +16025,32 @@ index 406d53a3391..c719085e11f 100644 VKD3DSPR_INVALID = ~0u, }; -@@ -516,6 +545,7 @@ enum vkd3d_data_type +@@ -516,8 +555,14 @@ enum vkd3d_data_type VKD3D_DATA_DOUBLE, VKD3D_DATA_CONTINUED, VKD3D_DATA_UNUSED, + VKD3D_DATA_UINT8, }; ++static inline bool data_type_is_integer(enum vkd3d_data_type data_type) ++{ ++ return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT; ++} ++ enum vkd3d_immconst_type -@@ -784,6 +814,8 @@ enum vkd3d_shader_input_sysval_semantic + { + VKD3D_IMMCONST_SCALAR, +@@ -696,6 +741,9 @@ struct vkd3d_shader_register + } u; + }; + ++void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, ++ enum vkd3d_data_type data_type, unsigned int idx_count); ++ + struct vkd3d_shader_dst_param + { + struct vkd3d_shader_register reg; +@@ -784,6 +832,8 @@ enum vkd3d_shader_input_sysval_semantic VKD3D_SIV_LINE_DENSITY_TESS_FACTOR = 22, }; @@ -13962,7 +16059,7 @@ index 406d53a3391..c719085e11f 100644 struct signature_element { unsigned int sort_index; -@@ -792,16 +824,21 @@ struct signature_element +@@ -792,16 +842,21 @@ struct signature_element unsigned int stream_index; enum vkd3d_shader_sysval_semantic sysval_semantic; enum vkd3d_shader_component_type component_type; @@ -13984,7 +16081,7 @@ index 406d53a3391..c719085e11f 100644 unsigned int element_count; }; -@@ -811,9 +848,17 @@ struct vkd3d_shader_desc +@@ -811,9 +866,17 @@ struct vkd3d_shader_desc { const uint32_t *byte_code; size_t byte_code_size; @@ -14002,7 +16099,7 @@ index 406d53a3391..c719085e11f 100644 }; struct vkd3d_shader_register_semantic -@@ -945,6 +990,8 @@ struct vkd3d_shader_instruction +@@ -945,6 +1008,8 @@ struct vkd3d_shader_instruction } declaration; }; @@ -14011,7 +16108,19 @@ index 406d53a3391..c719085e11f 100644 static inline bool vkd3d_shader_instruction_has_texel_offset(const struct vkd3d_shader_instruction *ins) { return ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w; -@@ -1066,6 +1113,24 @@ static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parse +@@ -965,6 +1030,11 @@ static inline bool vkd3d_shader_register_is_patch_constant(const struct vkd3d_sh + return reg->type == VKD3DSPR_PATCHCONST; + } + ++static inline bool register_is_constant(const struct vkd3d_shader_register *reg) ++{ ++ return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); ++} ++ + struct vkd3d_shader_location + { + const char *source_name; +@@ -1066,6 +1136,27 @@ static inline void vkd3d_shader_parser_destroy(struct vkd3d_shader_parser *parse parser->ops->parser_destroy(parser); } @@ -14024,6 +16133,9 @@ index 406d53a3391..c719085e11f 100644 + enum vkd3d_shader_resource_type resource_type; + enum vkd3d_shader_resource_data_type resource_data_type; + unsigned int flags; ++ unsigned int sample_count; ++ unsigned int buffer_size; ++ unsigned int structure_stride; + unsigned int count; +}; + @@ -14036,7 +16148,7 @@ index 406d53a3391..c719085e11f 100644 void vkd3d_shader_trace(const struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_version *shader_version); -@@ -1167,6 +1232,8 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi +@@ -1167,6 +1258,8 @@ int vkd3d_shader_sm1_parser_create(const struct vkd3d_shader_compile_info *compi struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser); int vkd3d_shader_sm4_parser_create(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_parser **parser); @@ -14045,7 +16157,7 @@ index 406d53a3391..c719085e11f 100644 void free_shader_desc(struct vkd3d_shader_desc *desc); -@@ -1186,7 +1253,7 @@ void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator); +@@ -1186,7 +1279,7 @@ void vkd3d_glsl_generator_destroy(struct vkd3d_glsl_generator *generator); #define SPIRV_MAX_SRC_COUNT 6 int spirv_compile(struct vkd3d_shader_parser *parser, @@ -14054,7 +16166,38 @@ index 406d53a3391..c719085e11f 100644 const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); -@@ -1339,6 +1406,7 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain, +@@ -1240,6 +1333,30 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( + } + } + ++static inline enum vkd3d_shader_component_type vkd3d_component_type_from_resource_data_type( ++ enum vkd3d_shader_resource_data_type data_type) ++{ ++ switch (data_type) ++ { ++ case VKD3D_SHADER_RESOURCE_DATA_FLOAT: ++ case VKD3D_SHADER_RESOURCE_DATA_UNORM: ++ case VKD3D_SHADER_RESOURCE_DATA_SNORM: ++ return VKD3D_SHADER_COMPONENT_FLOAT; ++ case VKD3D_SHADER_RESOURCE_DATA_UINT: ++ return VKD3D_SHADER_COMPONENT_UINT; ++ case VKD3D_SHADER_RESOURCE_DATA_INT: ++ return VKD3D_SHADER_COMPONENT_INT; ++ case VKD3D_SHADER_RESOURCE_DATA_DOUBLE: ++ case VKD3D_SHADER_RESOURCE_DATA_CONTINUED: ++ return VKD3D_SHADER_COMPONENT_DOUBLE; ++ default: ++ FIXME("Unhandled data type %#x.\n", data_type); ++ /* fall-through */ ++ case VKD3D_SHADER_RESOURCE_DATA_MIXED: ++ return VKD3D_SHADER_COMPONENT_UINT; ++ } ++} ++ + enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, + unsigned int index); + +@@ -1339,6 +1456,7 @@ static inline void *vkd3d_find_struct_(const struct vkd3d_struct *chain, } #define VKD3D_DXBC_HEADER_SIZE (8 * sizeof(uint32_t)) @@ -14062,7 +16205,7 @@ index 406d53a3391..c719085e11f 100644 #define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') -@@ -1369,11 +1437,7 @@ void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void +@@ -1369,11 +1487,7 @@ void dxbc_writer_add_section(struct dxbc_writer *dxbc, uint32_t tag, const void void dxbc_writer_init(struct dxbc_writer *dxbc); int dxbc_writer_write(struct dxbc_writer *dxbc, struct vkd3d_shader_code *code); @@ -14077,7 +16220,7 @@ index 406d53a3391..c719085e11f 100644 #endif /* __VKD3D_SHADER_PRIVATE_H */ diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index 32439eec7eb..8b5f7899cf3 100644 +index c5bd687bd69..42a98763438 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -26,6 +26,7 @@ static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkF @@ -14566,7 +16709,7 @@ index 32439eec7eb..8b5f7899cf3 100644 ID3D12PipelineState *pipeline_state) { FIXME("iface %p, pipline_state %p stub!\n", iface, pipeline_state); -@@ -3185,6 +3217,20 @@ static void command_list_flush_vk_heap_updates(struct d3d12_command_list *list) +@@ -3185,6 +3217,23 @@ static void command_list_flush_vk_heap_updates(struct d3d12_command_list *list) } } @@ -14578,7 +16721,10 @@ index 32439eec7eb..8b5f7899cf3 100644 + { + /* Descriptors can be written after binding. */ + FIXME("Flushing descriptor updates while list %p is not closed.\n", list); -+ command_list_flush_vk_heap_updates(list); ++ vkd3d_mutex_lock(&heap->vk_sets_mutex); ++ d3d12_desc_flush_vk_heap_updates_locked(heap, list->device); ++ vkd3d_mutex_unlock(&heap->vk_sets_mutex); ++ return; + } + list->descriptor_heaps[list->descriptor_heap_count++] = heap; + } @@ -14587,7 +16733,7 @@ index 32439eec7eb..8b5f7899cf3 100644 static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *list, enum vkd3d_pipeline_bind_point bind_point, struct d3d12_descriptor_heap *heap) { -@@ -3209,18 +3255,6 @@ static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *l +@@ -3209,18 +3258,6 @@ static void d3d12_command_list_bind_descriptor_heap(struct d3d12_command_list *l bindings->sampler_heap_id = heap->serial_id; } @@ -14606,7 +16752,7 @@ index 32439eec7eb..8b5f7899cf3 100644 vkd3d_mutex_lock(&heap->vk_sets_mutex); for (set = 0; set < ARRAY_SIZE(heap->vk_descriptor_sets); ++set) -@@ -3353,11 +3387,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c +@@ -3353,11 +3390,11 @@ static void d3d12_command_list_check_index_buffer_strip_cut_value(struct d3d12_c } } @@ -14620,7 +16766,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, vertex_count_per_instance %u, instance_count %u, " -@@ -3377,11 +3411,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom +@@ -3377,11 +3414,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawInstanced(ID3D12GraphicsCom instance_count, start_vertex_location, start_instance_location)); } @@ -14634,7 +16780,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, index_count_per_instance %u, instance_count %u, start_vertex_location %u, " -@@ -3403,10 +3437,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap +@@ -3403,10 +3440,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_DrawIndexedInstanced(ID3D12Grap instance_count, start_vertex_location, base_vertex_location, start_instance_location)); } @@ -14647,7 +16793,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, x %u, y %u, z %u.\n", iface, x, y, z); -@@ -3422,10 +3456,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL +@@ -3422,10 +3459,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_Dispatch(ID3D12GraphicsCommandL VK_CALL(vkCmdDispatch(list->vk_command_buffer, x, y, z)); } @@ -14660,7 +16806,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_vk_device_procs *vk_procs; VkBufferCopy buffer_copy; -@@ -3624,7 +3658,7 @@ static HRESULT d3d12_command_list_allocate_transfer_buffer(struct d3d12_command_ +@@ -3624,7 +3661,7 @@ static HRESULT d3d12_command_list_allocate_transfer_buffer(struct d3d12_command_ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_command_list *list, struct d3d12_resource *dst_resource, unsigned int dst_sub_resource_idx, const struct vkd3d_format *dst_format, struct d3d12_resource *src_resource, @@ -14669,7 +16815,7 @@ index 32439eec7eb..8b5f7899cf3 100644 { const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; const D3D12_RESOURCE_DESC *dst_desc = &dst_resource->desc; -@@ -3651,6 +3685,7 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com +@@ -3651,6 +3688,7 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com buffer_image_copy.bufferImageHeight = 0; vk_image_subresource_layers_from_d3d12(&buffer_image_copy.imageSubresource, src_format, src_sub_resource_idx, src_desc->MipLevels); @@ -14677,7 +16823,7 @@ index 32439eec7eb..8b5f7899cf3 100644 src_miplevel_idx = buffer_image_copy.imageSubresource.mipLevel; buffer_image_copy.imageOffset.x = 0; buffer_image_copy.imageOffset.y = 0; -@@ -3658,7 +3693,7 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com +@@ -3658,7 +3696,7 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com vk_extent_3d_from_d3d12_miplevel(&buffer_image_copy.imageExtent, src_desc, src_miplevel_idx); buffer_size = src_format->byte_count * buffer_image_copy.imageExtent.width * @@ -14686,7 +16832,7 @@ index 32439eec7eb..8b5f7899cf3 100644 if (FAILED(hr = d3d12_command_list_allocate_transfer_buffer(list, buffer_size, &transfer_buffer))) { ERR("Failed to allocate transfer buffer, hr %#x.\n", hr); -@@ -3684,6 +3719,7 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com +@@ -3684,6 +3722,7 @@ static void d3d12_command_list_copy_incompatible_texture_region(struct d3d12_com vk_image_subresource_layers_from_d3d12(&buffer_image_copy.imageSubresource, dst_format, dst_sub_resource_idx, dst_desc->MipLevels); @@ -14694,7 +16840,7 @@ index 32439eec7eb..8b5f7899cf3 100644 dst_miplevel_idx = buffer_image_copy.imageSubresource.mipLevel; assert(d3d12_resource_desc_get_width(src_desc, src_miplevel_idx) == -@@ -3705,11 +3741,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box) +@@ -3705,11 +3744,11 @@ static bool validate_d3d12_box(const D3D12_BOX *box) && box->back > box->front; } @@ -14708,7 +16854,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_format *src_format, *dst_format; const struct vkd3d_vk_device_procs *vk_procs; -@@ -3813,7 +3849,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic +@@ -3813,7 +3852,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic { d3d12_command_list_copy_incompatible_texture_region(list, dst_resource, dst->u.SubresourceIndex, dst_format, @@ -14717,7 +16863,7 @@ index 32439eec7eb..8b5f7899cf3 100644 return; } -@@ -3830,11 +3866,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic +@@ -3830,11 +3869,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTextureRegion(ID3D12Graphic } } @@ -14732,7 +16878,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; VkBufferCopy vk_buffer_copy; VkImageCopy vk_image_copy; -@@ -3867,16 +3904,29 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm +@@ -3867,16 +3907,29 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm else { layer_count = d3d12_resource_desc_get_layer_count(&dst_resource->desc); @@ -14763,7 +16909,7 @@ index 32439eec7eb..8b5f7899cf3 100644 vk_image_copy.dstSubresource.layerCount = layer_count; vk_image_copy.srcSubresource.layerCount = layer_count; VK_CALL(vkCmdCopyImage(list->vk_command_buffer, src_resource->u.vk_image, -@@ -3886,7 +3936,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm +@@ -3886,7 +3939,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyResource(ID3D12GraphicsComm } } @@ -14772,7 +16918,7 @@ index 32439eec7eb..8b5f7899cf3 100644 ID3D12Resource *tiled_resource, const D3D12_TILED_RESOURCE_COORDINATE *tile_region_start_coordinate, const D3D12_TILE_REGION_SIZE *tile_region_size, ID3D12Resource *buffer, UINT64 buffer_offset, D3D12_TILE_COPY_FLAGS flags) -@@ -3897,11 +3947,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand +@@ -3897,11 +3950,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_CopyTiles(ID3D12GraphicsCommand buffer, buffer_offset, flags); } @@ -14786,7 +16932,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_format *src_format, *dst_format, *vk_format; struct d3d12_resource *dst_resource, *src_resource; const struct vkd3d_vk_device_procs *vk_procs; -@@ -3964,10 +4014,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi +@@ -3964,10 +4017,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresource(ID3D12Graphi VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vk_image_resolve)); } @@ -14799,7 +16945,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, topology %#x.\n", iface, topology); -@@ -3978,11 +4028,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr +@@ -3978,11 +4031,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetPrimitiveTopology(ID3D12Gr d3d12_command_list_invalidate_current_pipeline(list); } @@ -14813,7 +16959,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; -@@ -4016,10 +4066,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo +@@ -4016,10 +4069,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); } @@ -14826,7 +16972,7 @@ index 32439eec7eb..8b5f7899cf3 100644 VkRect2D vk_rects[D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; -@@ -4044,10 +4094,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic +@@ -4044,10 +4097,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); } @@ -14839,7 +16985,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, blend_factor %p.\n", iface, blend_factor); -@@ -4056,10 +4106,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics +@@ -4056,10 +4109,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12Graphics VK_CALL(vkCmdSetBlendConstants(list->vk_command_buffer, blend_factor)); } @@ -14852,7 +16998,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; TRACE("iface %p, stencil_ref %u.\n", iface, stencil_ref); -@@ -4068,11 +4118,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC +@@ -4068,11 +4121,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetStencilRef(ID3D12GraphicsC VK_CALL(vkCmdSetStencilReference(list->vk_command_buffer, VK_STENCIL_FRONT_AND_BACK, stencil_ref)); } @@ -14866,7 +17012,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state); -@@ -4123,10 +4173,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA +@@ -4123,10 +4176,10 @@ static unsigned int d3d12_find_ds_multiplanar_transition(const D3D12_RESOURCE_BA return 0; } @@ -14879,7 +17025,7 @@ index 32439eec7eb..8b5f7899cf3 100644 bool have_aliasing_barriers = false, have_split_barriers = false; const struct vkd3d_vk_device_procs *vk_procs; const struct vkd3d_vulkan_info *vk_info; -@@ -4349,13 +4399,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC +@@ -4349,13 +4402,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsC WARN("Issuing split barrier(s) on D3D12_RESOURCE_BARRIER_FLAG_END_ONLY.\n"); } @@ -14895,7 +17041,7 @@ index 32439eec7eb..8b5f7899cf3 100644 UINT heap_count, ID3D12DescriptorHeap *const *heaps) { TRACE("iface %p, heap_count %u, heaps %p.\n", iface, heap_count, heaps); -@@ -4381,10 +4431,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis +@@ -4381,10 +4434,10 @@ static void d3d12_command_list_set_root_signature(struct d3d12_command_list *lis d3d12_command_list_invalidate_root_parameters(list, bind_point); } @@ -14908,7 +17054,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_signature %p.\n", iface, root_signature); -@@ -4392,10 +4442,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G +@@ -4392,10 +4445,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootSignature(ID3D12G unsafe_impl_from_ID3D12RootSignature(root_signature)); } @@ -14921,7 +17067,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_signature %p.\n", iface, root_signature); -@@ -4408,6 +4458,7 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l +@@ -4408,6 +4461,7 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l { struct vkd3d_pipeline_bindings *bindings = &list->pipeline_bindings[bind_point]; const struct d3d12_root_signature *root_signature = bindings->root_signature; @@ -14929,7 +17075,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_desc *desc; assert(root_signature_get_descriptor_table(root_signature, index)); -@@ -4418,15 +4469,25 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l +@@ -4418,15 +4472,25 @@ static void d3d12_command_list_set_descriptor_table(struct d3d12_command_list *l if (bindings->descriptor_tables[index] == desc) return; @@ -14957,7 +17103,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", iface, root_parameter_index, base_descriptor.ptr); -@@ -4435,10 +4496,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I +@@ -4435,10 +4499,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootDescriptorTable(I root_parameter_index, base_descriptor); } @@ -14970,7 +17116,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, base_descriptor %#"PRIx64".\n", iface, root_parameter_index, base_descriptor.ptr); -@@ -4460,10 +4521,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis +@@ -4460,10 +4524,10 @@ static void d3d12_command_list_set_root_constants(struct d3d12_command_list *lis c->stage_flags, c->offset + offset * sizeof(uint32_t), count * sizeof(uint32_t), data)); } @@ -14983,7 +17129,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", iface, root_parameter_index, data, dst_offset); -@@ -4472,10 +4533,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3 +@@ -4472,10 +4536,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstant(ID3 root_parameter_index, dst_offset, 1, &data); } @@ -14996,7 +17142,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, data 0x%08x, dst_offset %u.\n", iface, root_parameter_index, data, dst_offset); -@@ -4484,10 +4545,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID +@@ -4484,10 +4548,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRoot32BitConstant(ID root_parameter_index, dst_offset, 1, &data); } @@ -15009,7 +17155,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", iface, root_parameter_index, constant_count, data, dst_offset); -@@ -4496,10 +4557,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID +@@ -4496,10 +4560,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRoot32BitConstants(ID root_parameter_index, dst_offset, constant_count, data); } @@ -15022,7 +17168,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, constant_count %u, data %p, dst_offset %u.\n", iface, root_parameter_index, constant_count, data, dst_offset); -@@ -4561,9 +4622,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, +@@ -4561,9 +4625,9 @@ static void d3d12_command_list_set_root_cbv(struct d3d12_command_list *list, } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferView( @@ -15034,7 +17180,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); -@@ -4572,9 +4633,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie +@@ -4572,9 +4636,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootConstantBufferVie } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootConstantBufferView( @@ -15046,7 +17192,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); -@@ -4633,9 +4694,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li +@@ -4633,9 +4697,9 @@ static void d3d12_command_list_set_root_descriptor(struct d3d12_command_list *li } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceView( @@ -15058,7 +17204,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); -@@ -4645,9 +4706,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie +@@ -4645,9 +4709,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootShaderResourceVie } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceView( @@ -15070,7 +17216,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); -@@ -4657,9 +4718,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi +@@ -4657,9 +4721,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootShaderResourceVi } static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessView( @@ -15082,7 +17228,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); -@@ -4669,9 +4730,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi +@@ -4669,9 +4733,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetComputeRootUnorderedAccessVi } static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessView( @@ -15094,7 +17240,7 @@ index 32439eec7eb..8b5f7899cf3 100644 TRACE("iface %p, root_parameter_index %u, address %#"PRIx64".\n", iface, root_parameter_index, address); -@@ -4680,10 +4741,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV +@@ -4680,10 +4744,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetGraphicsRootUnorderedAccessV root_parameter_index, address); } @@ -15107,7 +17253,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_vk_device_procs *vk_procs; struct d3d12_resource *resource; enum VkIndexType index_type; -@@ -4723,10 +4784,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics +@@ -4723,10 +4787,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetIndexBuffer(ID3D12Graphics view->BufferLocation - resource->gpu_address, index_type)); } @@ -15120,7 +17266,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct vkd3d_null_resources *null_resources; struct vkd3d_gpu_va_allocator *gpu_va_allocator; VkDeviceSize offsets[ARRAY_SIZE(list->strides)]; -@@ -4781,10 +4842,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi +@@ -4781,10 +4845,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_IASetVertexBuffers(ID3D12Graphi d3d12_command_list_invalidate_current_pipeline(list); } @@ -15133,7 +17279,7 @@ index 32439eec7eb..8b5f7899cf3 100644 VkDeviceSize offsets[ARRAY_SIZE(list->so_counter_buffers)]; VkDeviceSize sizes[ARRAY_SIZE(list->so_counter_buffers)]; VkBuffer buffers[ARRAY_SIZE(list->so_counter_buffers)]; -@@ -4846,11 +4907,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm +@@ -4846,11 +4910,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_SOSetTargets(ID3D12GraphicsComm VK_CALL(vkCmdBindTransformFeedbackBuffersEXT(list->vk_command_buffer, first, count, buffers, offsets, sizes)); } @@ -15147,7 +17293,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct d3d12_rtv_desc *rtv_desc; const struct d3d12_dsv_desc *dsv_desc; VkFormat prev_dsv_format; -@@ -5051,12 +5112,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, +@@ -5051,12 +5115,12 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, } } @@ -15162,7 +17308,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct d3d12_dsv_desc *dsv_desc = d3d12_dsv_desc_from_cpu_handle(dsv); struct VkAttachmentDescription attachment_desc; struct VkAttachmentReference ds_reference; -@@ -5100,10 +5161,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra +@@ -5100,10 +5164,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra &clear_value, rect_count, rects); } @@ -15175,7 +17321,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const struct d3d12_rtv_desc *rtv_desc = d3d12_rtv_desc_from_cpu_handle(rtv); struct VkAttachmentDescription attachment_desc; struct VkAttachmentReference color_reference; -@@ -5348,11 +5409,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12 +@@ -5348,11 +5412,11 @@ static const struct vkd3d_format *vkd3d_fixup_clear_uav_uint_colour(struct d3d12 } } @@ -15189,7 +17335,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct vkd3d_view *descriptor, *uint_view = NULL; struct d3d12_device *device = list->device; struct vkd3d_texture_view_desc view_desc; -@@ -5414,11 +5475,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID +@@ -5414,11 +5478,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID vkd3d_view_decref(uint_view, device); } @@ -15203,7 +17349,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_resource *resource_impl; VkClearColorValue colour; struct vkd3d_view *view; -@@ -5434,16 +5495,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I +@@ -5434,16 +5498,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewFloat(I d3d12_command_list_clear_uav(list, resource_impl, view, &colour, rect_count, rects); } @@ -15223,7 +17369,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); const struct vkd3d_vk_device_procs *vk_procs; VkQueryControlFlags flags = 0; -@@ -5470,10 +5531,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman +@@ -5470,10 +5534,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_BeginQuery(ID3D12GraphicsComman VK_CALL(vkCmdBeginQuery(list->vk_command_buffer, query_heap->vk_query_pool, index, flags)); } @@ -15236,7 +17382,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_query_heap *query_heap = unsafe_impl_from_ID3D12QueryHeap(heap); const struct vkd3d_vk_device_procs *vk_procs; -@@ -5515,12 +5576,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type) +@@ -5515,12 +5579,12 @@ static size_t get_query_stride(D3D12_QUERY_TYPE type) return sizeof(uint64_t); } @@ -15251,7 +17397,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_resource *buffer = unsafe_impl_from_ID3D12Resource(dst_buffer); const struct vkd3d_vk_device_procs *vk_procs; unsigned int i, first, count; -@@ -5596,10 +5657,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics +@@ -5596,10 +5660,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveQueryData(ID3D12Graphics } } @@ -15264,7 +17410,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_resource *resource = unsafe_impl_from_ID3D12Resource(buffer); const struct vkd3d_vulkan_info *vk_info = &list->device->vk_info; const struct vkd3d_vk_device_procs *vk_procs; -@@ -5668,19 +5729,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo +@@ -5668,19 +5732,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPredication(ID3D12GraphicsCo } } @@ -15287,7 +17433,7 @@ index 32439eec7eb..8b5f7899cf3 100644 { FIXME("iface %p stub!\n", iface); } -@@ -5689,14 +5750,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN +@@ -5689,14 +5753,14 @@ STATIC_ASSERT(sizeof(VkDispatchIndirectCommand) == sizeof(D3D12_DISPATCH_ARGUMEN STATIC_ASSERT(sizeof(VkDrawIndexedIndirectCommand) == sizeof(D3D12_DRAW_INDEXED_ARGUMENTS)); STATIC_ASSERT(sizeof(VkDrawIndirectCommand) == sizeof(D3D12_DRAW_ARGUMENTS)); @@ -15304,7 +17450,7 @@ index 32439eec7eb..8b5f7899cf3 100644 const D3D12_COMMAND_SIGNATURE_DESC *signature_desc; const struct vkd3d_vk_device_procs *vk_procs; unsigned int i; -@@ -5714,6 +5775,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC +@@ -5714,6 +5778,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC return; } @@ -15313,7 +17459,7 @@ index 32439eec7eb..8b5f7899cf3 100644 signature_desc = &sig_impl->desc; for (i = 0; i < signature_desc->NumArgumentDescs; ++i) { -@@ -5776,6 +5839,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC +@@ -5776,6 +5842,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC if (!d3d12_command_list_update_compute_state(list)) { WARN("Failed to update compute state, ignoring dispatch.\n"); @@ -15321,7 +17467,7 @@ index 32439eec7eb..8b5f7899cf3 100644 return; } -@@ -5788,9 +5852,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC +@@ -5788,9 +5855,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_ExecuteIndirect(ID3D12GraphicsC break; } } @@ -15334,7 +17480,7 @@ index 32439eec7eb..8b5f7899cf3 100644 ID3D12Resource *dst_buffer, UINT64 dst_offset, ID3D12Resource *src_buffer, UINT64 src_offset, UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, -@@ -5803,7 +5869,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap +@@ -5803,7 +5872,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT(ID3D12Grap dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); } @@ -15343,7 +17489,7 @@ index 32439eec7eb..8b5f7899cf3 100644 ID3D12Resource *dst_buffer, UINT64 dst_offset, ID3D12Resource *src_buffer, UINT64 src_offset, UINT dependent_resource_count, ID3D12Resource * const *dependent_resources, -@@ -5816,20 +5882,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr +@@ -5816,20 +5885,20 @@ static void STDMETHODCALLTYPE d3d12_command_list_AtomicCopyBufferUINT64(ID3D12Gr dependent_resource_count, dependent_resources, dependent_sub_resource_ranges); } @@ -15367,7 +17513,7 @@ index 32439eec7eb..8b5f7899cf3 100644 ID3D12Resource *dst_resource, UINT dst_sub_resource_idx, UINT dst_x, UINT dst_y, ID3D12Resource *src_resource, UINT src_sub_resource_idx, D3D12_RECT *src_rect, DXGI_FORMAT format, D3D12_RESOLVE_MODE mode) -@@ -5841,16 +5907,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12 +@@ -5841,16 +5910,16 @@ static void STDMETHODCALLTYPE d3d12_command_list_ResolveSubresourceRegion(ID3D12 src_resource, src_sub_resource_idx, src_rect, format, mode); } @@ -15387,7 +17533,7 @@ index 32439eec7eb..8b5f7899cf3 100644 struct d3d12_resource *resource; unsigned int i; -@@ -5863,7 +5929,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap +@@ -5863,7 +5932,13 @@ static void STDMETHODCALLTYPE d3d12_command_list_WriteBufferImmediate(ID3D12Grap } } @@ -15402,7 +17548,7 @@ index 32439eec7eb..8b5f7899cf3 100644 { /* IUnknown methods */ d3d12_command_list_QueryInterface, -@@ -5939,6 +6011,8 @@ static const struct ID3D12GraphicsCommandList2Vtbl d3d12_command_list_vtbl = +@@ -5939,6 +6014,8 @@ static const struct ID3D12GraphicsCommandList2Vtbl d3d12_command_list_vtbl = d3d12_command_list_SetViewInstanceMask, /* ID3D12GraphicsCommandList2 methods */ d3d12_command_list_WriteBufferImmediate, @@ -15411,7 +17557,7 @@ index 32439eec7eb..8b5f7899cf3 100644 }; static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12CommandList *iface) -@@ -5946,7 +6020,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma +@@ -5946,7 +6023,7 @@ static struct d3d12_command_list *unsafe_impl_from_ID3D12CommandList(ID3D12Comma if (!iface) return NULL; assert(iface->lpVtbl == (struct ID3D12CommandListVtbl *)&d3d12_command_list_vtbl); @@ -15420,7 +17566,7 @@ index 32439eec7eb..8b5f7899cf3 100644 } static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d3d12_device *device, -@@ -5955,7 +6029,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d +@@ -5955,7 +6032,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d { HRESULT hr; @@ -15429,7 +17575,7 @@ index 32439eec7eb..8b5f7899cf3 100644 list->refcount = 1; list->type = type; -@@ -6063,8 +6137,35 @@ static ULONG STDMETHODCALLTYPE d3d12_command_queue_AddRef(ID3D12CommandQueue *if +@@ -6063,8 +6140,35 @@ static ULONG STDMETHODCALLTYPE d3d12_command_queue_AddRef(ID3D12CommandQueue *if return refcount; } @@ -15465,7 +17611,7 @@ index 32439eec7eb..8b5f7899cf3 100644 vkd3d_free(array->ops); } -@@ -6162,17 +6263,131 @@ static struct vkd3d_cs_op_data *d3d12_command_queue_op_array_require_space(struc +@@ -6162,17 +6266,131 @@ static struct vkd3d_cs_op_data *d3d12_command_queue_op_array_require_space(struc return &array->ops[array->count++]; } @@ -15497,8 +17643,7 @@ index 32439eec7eb..8b5f7899cf3 100644 ID3D12Resource *resource, UINT region_count, const D3D12_TILED_RESOURCE_COORDINATE *region_start_coordinates, const D3D12_TILE_REGION_SIZE *region_sizes, ID3D12Heap *heap, UINT range_count, const D3D12_TILE_RANGE_FLAGS *range_flags, -- UINT *heap_range_offsets, UINT *range_tile_counts, D3D12_TILE_MAPPING_FLAGS flags) -+ const UINT *heap_range_offsets, const UINT *range_tile_counts, D3D12_TILE_MAPPING_FLAGS flags) + const UINT *heap_range_offsets, const UINT *range_tile_counts, D3D12_TILE_MAPPING_FLAGS flags) { - FIXME("iface %p, resource %p, region_count %u, region_start_coordinates %p, " + struct d3d12_resource *resource_impl = unsafe_impl_from_ID3D12Resource(resource); @@ -15600,7 +17745,7 @@ index 32439eec7eb..8b5f7899cf3 100644 } static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12CommandQueue *iface, -@@ -6183,10 +6398,34 @@ static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12Command +@@ -6183,10 +6401,34 @@ static void STDMETHODCALLTYPE d3d12_command_queue_CopyTileMappings(ID3D12Command const D3D12_TILE_REGION_SIZE *region_size, D3D12_TILE_MAPPING_FLAGS flags) { @@ -15637,7 +17782,7 @@ index 32439eec7eb..8b5f7899cf3 100644 } static void d3d12_command_queue_execute(struct d3d12_command_queue *command_queue, -@@ -6214,8 +6453,6 @@ static void d3d12_command_queue_execute(struct d3d12_command_queue *command_queu +@@ -6214,8 +6456,6 @@ static void d3d12_command_queue_execute(struct d3d12_command_queue *command_queu ERR("Failed to submit queue(s), vr %d.\n", vr); vkd3d_queue_release(vkd3d_queue); @@ -15646,7 +17791,7 @@ index 32439eec7eb..8b5f7899cf3 100644 } static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue) -@@ -6273,7 +6510,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm +@@ -6273,7 +6513,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue))) { ERR("Failed to add op.\n"); @@ -15655,7 +17800,7 @@ index 32439eec7eb..8b5f7899cf3 100644 } op->opcode = VKD3D_CS_OP_EXECUTE; op->u.execute.buffers = buffers; -@@ -6281,6 +6518,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm +@@ -6281,6 +6521,7 @@ static void STDMETHODCALLTYPE d3d12_command_queue_ExecuteCommandLists(ID3D12Comm d3d12_command_queue_submit_locked(command_queue); @@ -15663,7 +17808,7 @@ index 32439eec7eb..8b5f7899cf3 100644 vkd3d_mutex_unlock(&command_queue->op_mutex); return; } -@@ -6348,6 +6586,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue * +@@ -6348,6 +6589,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Signal(ID3D12CommandQueue * if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue))) { @@ -15671,7 +17816,7 @@ index 32439eec7eb..8b5f7899cf3 100644 hr = E_OUTOFMEMORY; goto done; } -@@ -6686,6 +6925,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if +@@ -6686,6 +6928,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_queue_Wait(ID3D12CommandQueue *if if (!(op = d3d12_command_queue_op_array_require_space(&command_queue->op_queue))) { @@ -15679,7 +17824,7 @@ index 32439eec7eb..8b5f7899cf3 100644 hr = E_OUTOFMEMORY; goto done; } -@@ -6922,22 +7162,31 @@ static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue * +@@ -6922,22 +7165,31 @@ static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue * return d3d12_command_queue_fixup_after_flush_locked(queue); } d3d12_command_queue_wait_locked(queue, fence, op->u.wait.value); @@ -15713,7 +17858,7 @@ index 32439eec7eb..8b5f7899cf3 100644 *flushed_any |= true; } -@@ -7000,6 +7249,8 @@ static HRESULT d3d12_command_queue_init(struct d3d12_command_queue *queue, +@@ -7000,6 +7252,8 @@ static HRESULT d3d12_command_queue_init(struct d3d12_command_queue *queue, if (FAILED(hr = vkd3d_fence_worker_start(&queue->fence_worker, queue->vkd3d_queue, device))) goto fail_destroy_op_mutex; @@ -15722,7 +17867,7 @@ index 32439eec7eb..8b5f7899cf3 100644 d3d12_device_add_ref(queue->device = device); return S_OK; -@@ -7105,16 +7356,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSign +@@ -7105,16 +7359,7 @@ static ULONG STDMETHODCALLTYPE d3d12_command_signature_Release(ID3D12CommandSign TRACE("%p decreasing refcount to %u.\n", signature, refcount); if (!refcount) @@ -15740,7 +17885,7 @@ index 32439eec7eb..8b5f7899cf3 100644 return refcount; } -@@ -7221,6 +7463,7 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_ +@@ -7221,6 +7466,7 @@ HRESULT d3d12_command_signature_create(struct d3d12_device *device, const D3D12_ object->ID3D12CommandSignature_iface.lpVtbl = &d3d12_command_signature_vtbl; object->refcount = 1; @@ -15749,7 +17894,7 @@ index 32439eec7eb..8b5f7899cf3 100644 object->desc = *desc; if (!(object->desc.pArgumentDescs = vkd3d_calloc(desc->NumArgumentDescs, sizeof(*desc->pArgumentDescs)))) diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index 4263dcf4184..a2e1f13dec3 100644 +index 4263dcf4184..c33061073a3 100644 --- a/libs/vkd3d/libs/vkd3d/device.c +++ b/libs/vkd3d/libs/vkd3d/device.c @@ -1464,6 +1464,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, @@ -15761,7 +17906,203 @@ index 4263dcf4184..a2e1f13dec3 100644 vulkan_info->rasterization_stream = physical_device_info->xfb_properties.transformFeedbackRasterizationStreamSelect; vulkan_info->transform_feedback_queries = physical_device_info->xfb_properties.transformFeedbackQueries; vulkan_info->uav_read_without_format = features->shaderStorageImageReadWithoutFormat; -@@ -2655,8 +2657,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device *if +@@ -2433,34 +2435,39 @@ static void device_init_descriptor_pool_sizes(struct d3d12_device *device) + + static void vkd3d_desc_object_cache_init(struct vkd3d_desc_object_cache *cache, size_t size) + { +- cache->head = NULL; ++ memset(cache, 0, sizeof(*cache)); + cache->size = size; + } + + static void vkd3d_desc_object_cache_cleanup(struct vkd3d_desc_object_cache *cache) + { + union d3d12_desc_object u; ++ unsigned int i; + void *next; + +- for (u.object = cache->head; u.object; u.object = next) ++ for (i = 0; i < ARRAY_SIZE(cache->heads); ++i) + { +- next = u.header->next; +- vkd3d_free(u.object); ++ for (u.object = cache->heads[i].head; u.object; u.object = next) ++ { ++ next = u.header->next; ++ vkd3d_free(u.object); ++ } + } + } + + /* ID3D12Device */ +-static inline struct d3d12_device *impl_from_ID3D12Device(ID3D12Device *iface) ++static inline struct d3d12_device *impl_from_ID3D12Device1(ID3D12Device1 *iface) + { +- return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device_iface); ++ return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device1_iface); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *iface, + REFIID riid, void **object) + { + TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); + +- if (IsEqualGUID(riid, &IID_ID3D12Device) ++ if (IsEqualGUID(riid, &IID_ID3D12Device1) ++ || IsEqualGUID(riid, &IID_ID3D12Device) + || IsEqualGUID(riid, &IID_ID3D12Object) + || IsEqualGUID(riid, &IID_IUnknown)) + { +@@ -2475,9 +2482,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device *iface + return E_NOINTERFACE; + } + +-static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device *iface) ++static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + ULONG refcount = InterlockedIncrement(&device->refcount); + + TRACE("%p increasing refcount to %u.\n", device, refcount); +@@ -2485,9 +2492,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device *iface) + return refcount; + } + +-static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface) ++static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + ULONG refcount = InterlockedDecrement(&device->refcount); + + TRACE("%p decreasing refcount to %u.\n", device, refcount); +@@ -2521,10 +2528,10 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface) + return refcount; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *iface, + REFGUID guid, UINT *data_size, void *data) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + TRACE("iface %p, guid %s, data_size %p, data %p.\n", + iface, debugstr_guid(guid), data_size, data); +@@ -2532,10 +2539,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device *iface + return vkd3d_get_private_data(&device->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *iface, + REFGUID guid, UINT data_size, const void *data) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + TRACE("iface %p, guid %s, data_size %u, data %p.\n", + iface, debugstr_guid(guid), data_size, data); +@@ -2543,19 +2550,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device *iface + return vkd3d_set_private_data(&device->private_store, guid, data_size, data); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device1 *iface, + REFGUID guid, const IUnknown *data) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(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(ID3D12Device *iface, const WCHAR *name) ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, const WCHAR *name) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size)); + +@@ -2563,17 +2570,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device *iface, const + VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name); + } + +-static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device *iface) ++static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device1 *iface) + { + TRACE("iface %p.\n", iface); + + return 1; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 *iface, + const D3D12_COMMAND_QUEUE_DESC *desc, REFIID riid, void **command_queue) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_command_queue *object; + HRESULT hr; + +@@ -2587,10 +2594,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device *i + riid, command_queue); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device1 *iface, + D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **command_allocator) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_command_allocator *object; + HRESULT hr; + +@@ -2604,10 +2611,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic + riid, command_allocator); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device1 *iface, + const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_pipeline_state *object; + HRESULT hr; + +@@ -2621,10 +2628,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12 + &IID_ID3D12PipelineState, riid, pipeline_state); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device1 *iface, + const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_pipeline_state *object; + HRESULT hr; + +@@ -2638,11 +2645,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12D + &IID_ID3D12PipelineState, riid, pipeline_state); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device1 *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_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_command_list *object; + HRESULT hr; + +@@ -2655,8 +2662,8 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device *if initial_pipeline_state, &object))) return hr; @@ -15772,15 +18113,156 @@ index 4263dcf4184..a2e1f13dec3 100644 } /* Direct3D feature levels restrict which formats can be optionally supported. */ -@@ -3412,6 +3414,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, - struct d3d12_device *device = impl_from_ID3D12Device(iface); +@@ -2765,10 +2772,10 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) + return true; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1 *iface, + D3D12_FEATURE feature, void *feature_data, UINT feature_data_size) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n", + iface, feature, feature_data, feature_data_size); +@@ -3267,10 +3274,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * + } + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1 *iface, + const D3D12_DESCRIPTOR_HEAP_DESC *desc, REFIID riid, void **descriptor_heap) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_descriptor_heap *object; + HRESULT hr; + +@@ -3284,7 +3291,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device + &IID_ID3D12DescriptorHeap, riid, descriptor_heap); + } + +-static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device *iface, ++static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device1 *iface, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) + { + TRACE("iface %p, descriptor_heap_type %#x.\n", iface, descriptor_heap_type); +@@ -3307,11 +3314,11 @@ static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D + } + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1 *iface, + UINT node_mask, const void *bytecode, SIZE_T bytecode_length, + REFIID riid, void **root_signature) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_root_signature *object; + HRESULT hr; + +@@ -3327,10 +3334,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device * + &IID_ID3D12RootSignature, riid, root_signature); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device1 *iface, + const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_desc tmp = {0}; + + TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); +@@ -3339,11 +3346,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device1 *iface, + ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_desc tmp = {0}; + + TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", +@@ -3353,11 +3360,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device1 *iface, + ID3D12Resource *resource, ID3D12Resource *counter_resource, + const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_desc tmp = {0}; + + TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n", +@@ -3368,7 +3375,7 @@ static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Devic + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1 *iface, + ID3D12Resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +@@ -3376,10 +3383,10 @@ static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device * + iface, resource, desc, descriptor.ptr); + + d3d12_rtv_desc_create_rtv(d3d12_rtv_desc_from_cpu_handle(descriptor), +- impl_from_ID3D12Device(iface), unsafe_impl_from_ID3D12Resource(resource), desc); ++ impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1 *iface, + ID3D12Resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc, + D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +@@ -3387,13 +3394,13 @@ static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device * + iface, resource, desc, descriptor.ptr); + + d3d12_dsv_desc_create_dsv(d3d12_dsv_desc_from_cpu_handle(descriptor), +- impl_from_ID3D12Device(iface), unsafe_impl_from_ID3D12Resource(resource), desc); ++ impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc); + } + +-static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface, + const D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_desc tmp = {0}; + + TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); +@@ -3402,16 +3409,17 @@ static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device *iface, + d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); + } + +-static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *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_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); unsigned int dst_range_idx, dst_idx, src_range_idx, src_idx; unsigned int dst_range_size, src_range_size; + struct d3d12_descriptor_heap *dst_heap; const struct d3d12_desc *src; struct d3d12_desc *dst; -@@ -3441,13 +3444,14 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, +@@ -3441,13 +3449,14 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, src_range_size = src_descriptor_range_sizes ? src_descriptor_range_sizes[src_range_idx] : 1; dst = d3d12_desc_from_cpu_handle(dst_descriptor_range_offsets[dst_range_idx]); @@ -15796,7 +18278,166 @@ index 4263dcf4184..a2e1f13dec3 100644 } if (dst_idx >= dst_range_size) -@@ -3745,7 +3749,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface, +@@ -3463,7 +3472,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, + } + } + +-static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 *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) +@@ -3478,10 +3487,10 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device *i + } + + static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo( +- ID3D12Device *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, ++ ID3D12Device1 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, + UINT count, const D3D12_RESOURCE_DESC *resource_descs) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + const D3D12_RESOURCE_DESC *desc; + uint64_t requested_alignment; + +@@ -3554,10 +3563,10 @@ invalid: + return info; + } + +-static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device *iface, ++static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device1 *iface, + D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + bool coherent; + + TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n", +@@ -3597,12 +3606,12 @@ static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapPrope + return heap_properties; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device1 *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_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_resource *object; + HRESULT hr; + +@@ -3621,10 +3630,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi + return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface, + const D3D12_HEAP_DESC *desc, REFIID iid, void **heap) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_heap *object; + HRESULT hr; + +@@ -3640,12 +3649,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device *iface, + return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1 *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_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_heap *heap_object; + struct d3d12_resource *object; + HRESULT hr; +@@ -3664,11 +3673,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device + return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device1 *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_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_resource *object; + HRESULT hr; + +@@ -3682,11 +3691,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Devic + return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 *iface, + ID3D12DeviceChild *object, const SECURITY_ATTRIBUTES *attributes, DWORD access, + const WCHAR *name, HANDLE *handle) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(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); +@@ -3694,7 +3703,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device *i + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *iface, + HANDLE handle, REFIID riid, void **object) + { + FIXME("iface %p, handle %p, riid %s, object %p stub!\n", +@@ -3703,10 +3712,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device *ifa + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device1 *iface, + const WCHAR *name, DWORD access, HANDLE *handle) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + FIXME("iface %p, name %s, access %#x, handle %p stub!\n", + iface, debugstr_w(name, device->wchar_size), access, handle); +@@ -3714,7 +3723,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface, + UINT object_count, ID3D12Pageable * const *objects) + { + FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", +@@ -3723,7 +3732,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device *iface, + return S_OK; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device1 *iface, + UINT object_count, ID3D12Pageable * const *objects) + { + FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", +@@ -3732,10 +3741,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device *iface, + return S_OK; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface, + UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_fence *object; + HRESULT hr; + +@@ -3745,24 +3754,24 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface, if (FAILED(hr = d3d12_fence_create(device, initial_value, flags, &object))) return hr; @@ -15804,14 +18445,77 @@ index 4263dcf4184..a2e1f13dec3 100644 + return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence); } - static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device *iface) -@@ -3889,12 +3893,18 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface +-static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device *iface) ++static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device1 *iface) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + TRACE("iface %p.\n", iface); + + return device->removed_reason; + } + +-static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 *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_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(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; +@@ -3842,10 +3851,10 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *i + *total_bytes = total; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *iface, + const D3D12_QUERY_HEAP_DESC *desc, REFIID iid, void **heap) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_query_heap *object; + HRESULT hr; + +@@ -3858,18 +3867,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device *ifac + return return_interface(&object->ID3D12QueryHeap_iface, &IID_ID3D12QueryHeap, iid, heap); + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device *iface, BOOL enable) ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device1 *iface, BOOL enable) + { + FIXME("iface %p, enable %#x stub!\n", iface, enable); + + return E_NOTIMPL; + } + +-static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device *iface, ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device1 *iface, + const D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *root_signature, + REFIID iid, void **command_signature) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + struct d3d12_command_signature *object; + HRESULT hr; + +@@ -3883,23 +3892,29 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic + &IID_ID3D12CommandSignature, iid, command_signature); + } + +-static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface, ++static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *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) { - FIXME("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " + const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource); -+ struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " "standard_title_shape %p, sub_resource_tiling_count %p, " @@ -15825,9 +18529,114 @@ index 4263dcf4184..a2e1f13dec3 100644 + sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); } - static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid) +-static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid) ++static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface, LUID *luid) + { +- struct d3d12_device *device = impl_from_ID3D12Device(iface); ++ struct d3d12_device *device = impl_from_ID3D12Device1(iface); + + TRACE("iface %p, luid %p.\n", iface, luid); + +@@ -3908,7 +3923,33 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, + return luid; + } + +-static const struct ID3D12DeviceVtbl d3d12_device_vtbl = ++static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device1 *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); ++ ++ return DXGI_ERROR_UNSUPPORTED; ++} ++ ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device1 *iface, ++ ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count, ++ D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event) ++{ ++ FIXME("iface %p, fences %p, values %p, fence_count %u, flags %#x, event %p stub!\n", ++ iface, fences, values, fence_count, flags, event); ++ ++ return E_NOTIMPL; ++} ++ ++static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1 *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); ++ ++ return S_OK; ++} ++ ++static const struct ID3D12Device1Vtbl d3d12_device_vtbl = + { + /* IUnknown methods */ + d3d12_device_QueryInterface, +@@ -3957,14 +3998,18 @@ static const struct ID3D12DeviceVtbl d3d12_device_vtbl = + d3d12_device_CreateCommandSignature, + d3d12_device_GetResourceTiling, + d3d12_device_GetAdapterLuid, ++ /* ID3D12Device1 methods */ ++ d3d12_device_CreatePipelineLibrary, ++ d3d12_device_SetEventOnMultipleFenceCompletion, ++ d3d12_device_SetResidencyPriority, + }; + +-struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) ++struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface) + { + if (!iface) + return NULL; + assert(iface->lpVtbl == &d3d12_device_vtbl); +- return impl_from_ID3D12Device(iface); ++ return impl_from_ID3D12Device1(iface); + } + + static HRESULT d3d12_device_init(struct d3d12_device *device, +@@ -3973,7 +4018,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, + const struct vkd3d_vk_device_procs *vk_procs; + HRESULT hr; + +- device->ID3D12Device_iface.lpVtbl = &d3d12_device_vtbl; ++ device->ID3D12Device1_iface.lpVtbl = &d3d12_device_vtbl; + device->refcount = 1; + + vkd3d_instance_incref(device->vkd3d_instance = instance); +@@ -4170,28 +4215,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_ID3D12Device(device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + + return d3d12_device->parent; + } + + VkDevice vkd3d_get_vk_device(ID3D12Device *device) + { +- struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + + return d3d12_device->vk_device; + } + + VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device) + { +- struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + + return d3d12_device->vk_physical_device; + } + + struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device) + { +- struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device); ++ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); + + return d3d12_device->vkd3d_instance; + } diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index ea7b6859cc1..cd3856c2937 100644 +index ea7b6859cc1..f3842958d96 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -779,6 +779,7 @@ static HRESULT vkd3d_create_image(struct d3d12_device *device, @@ -15919,8 +18728,8 @@ index ea7b6859cc1..cd3856c2937 100644 + size->width = (width + tile_extent->width - 1) / tile_extent->width; + size->height = (height + tile_extent->height - 1) / tile_extent->height; + size->depth = (depth + tile_extent->depth - 1) / tile_extent->depth; - } - ++} ++ +void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, + UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, + UINT *subresource_tiling_count, UINT first_subresource_tiling, @@ -15978,8 +18787,8 @@ index ea7b6859cc1..cd3856c2937 100644 + subresource_tilings[i].DepthInTiles = tile_info->extent.depth; + } + *subresource_tiling_count = i; -+} -+ + } + +static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device) +{ + unsigned int i, start_idx, subresource_count, tile_count, miplevel_idx; @@ -16157,7 +18966,98 @@ index ea7b6859cc1..cd3856c2937 100644 TRACE("Created reserved resource %p.\n", object); *resource = object; -@@ -2368,13 +2606,11 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr +@@ -1982,7 +2220,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_ID3D12Device(device); ++ struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device1((ID3D12Device1 *)device); + struct d3d12_resource *object; + HRESULT hr; + +@@ -2044,38 +2282,67 @@ ULONG vkd3d_resource_decref(ID3D12Resource *resource) + return d3d12_resource_decref(impl_from_ID3D12Resource(resource)); + } + +-/* Objects are cached so that vkd3d_view_incref() can safely check the refcount +- * of an object freed by another thread. */ ++#define HEAD_INDEX_MASK (ARRAY_SIZE(cache->heads) - 1) ++ ++/* Objects are cached so that vkd3d_view_incref() can safely check the refcount of an ++ * object freed by another thread. This could be implemented as a single atomic linked ++ * list, but it requires handling the ABA problem, which brings issues with cross-platform ++ * support, compiler support, and non-universal x86-64 support for 128-bit CAS. */ + static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache) + { + union d3d12_desc_object u; +- void *next; ++ unsigned int i; + +- do ++ STATIC_ASSERT(!(ARRAY_SIZE(cache->heads) & HEAD_INDEX_MASK)); ++ ++ i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; ++ for (;;) + { +- u.object = cache->head; +- if (!u.object) ++ if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) ++ { ++ if ((u.object = cache->heads[i].head)) ++ { ++ vkd3d_atomic_decrement(&cache->free_count); ++ cache->heads[i].head = u.header->next; ++ vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); ++ return u.object; ++ } ++ vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); ++ } ++ /* Keeping a free count avoids uncertainty over when this loop should terminate, ++ * which could result in excess allocations gradually increasing without limit. */ ++ if (cache->free_count < ARRAY_SIZE(cache->heads)) + return vkd3d_malloc(cache->size); +- next = u.header->next; +- } +- while (!vkd3d_atomic_compare_exchange_pointer(&cache->head, u.object, next)); + +- return u.object; ++ i = (i + 1) & HEAD_INDEX_MASK; ++ } + } + + static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, void *object) + { + union d3d12_desc_object u = {object}; ++ unsigned int i; + void *head; + +- do ++ /* 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; ++ for (;;) + { +- head = cache->head; +- u.header->next = head; ++ if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) ++ break; ++ i = (i + 1) & HEAD_INDEX_MASK; + } +- while (!vkd3d_atomic_compare_exchange_pointer(&cache->head, head, u.object)); ++ ++ head = cache->heads[i].head; ++ u.header->next = head; ++ cache->heads[i].head = u.object; ++ vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); ++ vkd3d_atomic_increment(&cache->free_count); + } + ++#undef HEAD_INDEX_MASK ++ + static struct vkd3d_cbuffer_desc *vkd3d_cbuffer_desc_create(struct d3d12_device *device) + { + struct vkd3d_cbuffer_desc *desc; +@@ -2368,13 +2635,11 @@ void d3d12_desc_flush_vk_heap_updates_locked(struct d3d12_descriptor_heap *descr descriptor_writes_free_object_refs(&writes, device); } @@ -16172,7 +19072,7 @@ index ea7b6859cc1..cd3856c2937 100644 head = descriptor_heap->dirty_list_head; /* Only one thread can swap the value away from zero. */ -@@ -2388,14 +2624,20 @@ static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst) +@@ -2388,14 +2653,20 @@ static void d3d12_desc_mark_as_modified(struct d3d12_desc *dst) } } @@ -16197,7 +19097,7 @@ index ea7b6859cc1..cd3856c2937 100644 } static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_device *device) -@@ -2403,7 +2645,9 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_devic +@@ -2403,7 +2674,9 @@ static void d3d12_desc_destroy(struct d3d12_desc *descriptor, struct d3d12_devic d3d12_desc_replace(descriptor, NULL, device); } @@ -16208,7 +19108,7 @@ index ea7b6859cc1..cd3856c2937 100644 struct d3d12_device *device) { struct d3d12_desc tmp; -@@ -2411,7 +2655,7 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, +@@ -2411,7 +2684,7 @@ void d3d12_desc_copy(struct d3d12_desc *dst, const struct d3d12_desc *src, assert(dst != src); tmp.s.u.object = d3d12_desc_get_object_ref(src, device); @@ -16217,7 +19117,7 @@ index ea7b6859cc1..cd3856c2937 100644 } static VkDeviceSize vkd3d_get_required_texel_buffer_alignment(const struct d3d12_device *device, -@@ -3810,7 +4054,15 @@ static D3D12_GPU_DESCRIPTOR_HANDLE * STDMETHODCALLTYPE d3d12_descriptor_heap_Get +@@ -3810,7 +4083,15 @@ static D3D12_GPU_DESCRIPTOR_HANDLE * STDMETHODCALLTYPE d3d12_descriptor_heap_Get TRACE("iface %p, descriptor %p.\n", iface, descriptor); @@ -16234,7 +19134,7 @@ index ea7b6859cc1..cd3856c2937 100644 return descriptor; } -@@ -3913,7 +4165,7 @@ static HRESULT d3d12_descriptor_heap_vk_descriptor_sets_init(struct d3d12_descri +@@ -3913,7 +4194,7 @@ static HRESULT d3d12_descriptor_heap_vk_descriptor_sets_init(struct d3d12_descri descriptor_heap->vk_descriptor_pool = VK_NULL_HANDLE; memset(descriptor_heap->vk_descriptor_sets, 0, sizeof(descriptor_heap->vk_descriptor_sets)); @@ -16243,7 +19143,7 @@ index ea7b6859cc1..cd3856c2937 100644 && desc->Type != D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER)) return S_OK; -@@ -3944,6 +4196,7 @@ static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descript +@@ -3944,6 +4225,7 @@ static HRESULT d3d12_descriptor_heap_init(struct d3d12_descriptor_heap *descript if (FAILED(hr = vkd3d_private_store_init(&descriptor_heap->private_store))) return hr; @@ -16252,7 +19152,7 @@ index ea7b6859cc1..cd3856c2937 100644 vkd3d_mutex_init(&descriptor_heap->vk_sets_mutex); diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 5e46b467252..2d8138245d8 100644 +index 5e46b467252..7ae46c862cc 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c @@ -20,6 +20,7 @@ @@ -16263,6 +19163,17 @@ index 5e46b467252..2d8138245d8 100644 /* ID3D12RootSignature */ static inline struct d3d12_root_signature *impl_from_ID3D12RootSignature(ID3D12RootSignature *iface) +@@ -374,8 +375,8 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig + + if (unbounded && range->OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) + { +- WARN("An unbounded range with offset D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND occurs after " +- "another unbounded range.\n"); ++ WARN("A range with offset D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND occurs after " ++ "an unbounded range.\n"); + return E_INVALIDARG; + } + @@ -1978,14 +1979,14 @@ static HRESULT create_shader_stage(struct d3d12_device *device, compile_info.next = shader_interface; compile_info.source.code = code->pShaderBytecode; @@ -16305,8 +19216,26 @@ index 5e46b467252..2d8138245d8 100644 return vkd3d_shader_scan(&compile_info, NULL); } +diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c +index 88301fbb313..159560afd8e 100644 +--- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c ++++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c +@@ -71,11 +71,11 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, + + if (!device) + { +- ID3D12Device_Release(&object->ID3D12Device_iface); ++ ID3D12Device_Release(&object->ID3D12Device1_iface); + return S_FALSE; + } + +- return return_interface(&object->ID3D12Device_iface, &IID_ID3D12Device, iid, device); ++ return return_interface(&object->ID3D12Device1_iface, &IID_ID3D12Device, iid, device); + } + + /* ID3D12RootSignatureDeserializer */ diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index b0150754434..4bd6812b16e 100644 +index b0150754434..a18287b4cd4 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -147,9 +147,12 @@ struct vkd3d_vulkan_info @@ -16531,6 +19460,67 @@ index b0150754434..4bd6812b16e 100644 D3D12_COMMAND_SIGNATURE_DESC desc; +@@ -1600,9 +1690,17 @@ struct vkd3d_uav_clear_state + HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d3d12_device *device); + void vkd3d_uav_clear_state_cleanup(struct vkd3d_uav_clear_state *state, struct d3d12_device *device); + ++struct desc_object_cache_head ++{ ++ void *head; ++ unsigned int spinlock; ++}; ++ + struct vkd3d_desc_object_cache + { +- void * volatile head; ++ struct desc_object_cache_head heads[16]; ++ unsigned int next_index; ++ unsigned int free_count; + size_t size; + }; + +@@ -1611,7 +1709,7 @@ struct vkd3d_desc_object_cache + /* ID3D12Device */ + struct d3d12_device + { +- ID3D12Device ID3D12Device_iface; ++ ID3D12Device1 ID3D12Device1_iface; + LONG refcount; + + VkDevice vk_device; +@@ -1677,27 +1775,27 @@ 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_ID3D12Device(ID3D12Device *iface); ++struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface); + + static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object) + { +- return ID3D12Device_QueryInterface(&device->ID3D12Device_iface, iid, object); ++ return ID3D12Device1_QueryInterface(&device->ID3D12Device1_iface, iid, object); + } + + static inline ULONG d3d12_device_add_ref(struct d3d12_device *device) + { +- return ID3D12Device_AddRef(&device->ID3D12Device_iface); ++ return ID3D12Device1_AddRef(&device->ID3D12Device1_iface); + } + + static inline ULONG d3d12_device_release(struct d3d12_device *device) + { +- return ID3D12Device_Release(&device->ID3D12Device_iface); ++ return ID3D12Device1_Release(&device->ID3D12Device1_iface); + } + + static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device, + D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type) + { +- return ID3D12Device_GetDescriptorHandleIncrementSize(&device->ID3D12Device_iface, descriptor_type); ++ return ID3D12Device1_GetDescriptorHandleIncrementSize(&device->ID3D12Device1_iface, descriptor_type); + } + + /* utils */ -- 2.40.1 diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-622311da8e87c60110329044e29b88dd524.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-622311da8e87c60110329044e29b88dd524.patch deleted file mode 100644 index f989e263..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-622311da8e87c60110329044e29b88dd524.patch +++ /dev/null @@ -1,1097 +0,0 @@ -From e6120e9ab920e7db19231334703f46b3479a23d9 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 24 Aug 2023 08:49:26 +1000 -Subject: [PATCH] Updated vkd3d to 622311da8e87c60110329044e29b88dd524e28e7. - ---- - libs/vkd3d/include/vkd3d_shader.h | 2 + - libs/vkd3d/include/vkd3d_windows.h | 1 + - .../libs/vkd3d-shader/vkd3d_shader_main.c | 58 +++-- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 3 + - libs/vkd3d/libs/vkd3d/device.c | 225 ++++++++++-------- - libs/vkd3d/libs/vkd3d/resource.c | 59 +++-- - libs/vkd3d/libs/vkd3d/state.c | 4 +- - libs/vkd3d/libs/vkd3d/vkd3d_main.c | 4 +- - libs/vkd3d/libs/vkd3d/vkd3d_private.h | 22 +- - 9 files changed, 236 insertions(+), 142 deletions(-) - -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index e98aad4fe95..cfe54dbff53 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -1339,6 +1339,8 @@ enum vkd3d_shader_descriptor_info_flag - /** The descriptor is a UAV resource, on which the shader performs - * atomic ops. \since 1.6 */ - VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS = 0x00000008, -+ /** The descriptor is a raw (byte-addressed) buffer. \since 1.9 */ -+ VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER = 0x00000010, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_DESCRIPTOR_INFO_FLAG), - }; -diff --git a/libs/vkd3d/include/vkd3d_windows.h b/libs/vkd3d/include/vkd3d_windows.h -index 002ff667cbc..2daa74e92eb 100644 ---- a/libs/vkd3d/include/vkd3d_windows.h -+++ b/libs/vkd3d/include/vkd3d_windows.h -@@ -64,6 +64,7 @@ typedef int HRESULT; - - # define DXGI_ERROR_NOT_FOUND _HRESULT_TYPEDEF_(0x887a0002) - # define DXGI_ERROR_MORE_DATA _HRESULT_TYPEDEF_(0x887a0003) -+# define DXGI_ERROR_UNSUPPORTED _HRESULT_TYPEDEF_(0x887a0004) - - # define D3DERR_INVALIDCALL _HRESULT_TYPEDEF_(0x8876086c) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index c777bad2206..2bc8613f2ef 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -755,10 +755,10 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont - vkd3d_shader_scan_add_uav_flag(context, reg, VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS); - } - --static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, -+static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, - enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, - const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, -- enum vkd3d_shader_resource_data_type resource_data_type, unsigned int flags) -+ enum vkd3d_shader_resource_data_type resource_data_type) - { - struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; - struct vkd3d_shader_descriptor_info1 *d; -@@ -767,56 +767,61 @@ static bool vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *c - info->descriptor_count + 1, sizeof(*info->descriptors))) - { - ERR("Failed to allocate descriptor info.\n"); -- return false; -+ return NULL; - } - - d = &info->descriptors[info->descriptor_count]; -+ memset(d, 0, sizeof(*d)); - d->type = type; - d->register_id = reg->idx[0].offset; - d->register_space = range->space; - d->register_index = range->first; - d->resource_type = resource_type; - d->resource_data_type = resource_data_type; -- d->flags = flags; - d->count = (range->last == ~0u) ? ~0u : range->last - range->first + 1; - ++info->descriptor_count; - -- return true; -+ return d; - } - - static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_scan_context *context, - const struct vkd3d_shader_instruction *instruction) - { - const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; -+ struct vkd3d_shader_descriptor_info1 *d; - - if (!context->scan_descriptor_info) - return; - -- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, &cb->src.reg, &cb->range, -- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); -+ if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, -+ &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) -+ return; -+ d->buffer_size = cb->size * 16; - } - - static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_context *context, - const struct vkd3d_shader_instruction *instruction) - { - const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler; -- unsigned int flags; -+ struct vkd3d_shader_descriptor_info1 *d; - - if (!context->scan_descriptor_info) - return; - -+ if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, -+ &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT))) -+ return; -+ - if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) -- flags = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; -- else -- flags = 0; -- vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &sampler->src.reg, &sampler->range, -- VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT, flags); -+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; - } - - static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, - const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, -- enum vkd3d_shader_resource_data_type resource_data_type) -+ enum vkd3d_shader_resource_data_type resource_data_type, -+ unsigned int sample_count, unsigned int structure_stride, bool raw) - { -+ struct vkd3d_shader_descriptor_info1 *d; - enum vkd3d_shader_descriptor_type type; - - if (!context->scan_descriptor_info) -@@ -826,8 +831,13 @@ static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_cont - type = VKD3D_SHADER_DESCRIPTOR_TYPE_UAV; - else - type = VKD3D_SHADER_DESCRIPTOR_TYPE_SRV; -- vkd3d_shader_scan_add_descriptor(context, type, &resource->reg.reg, &resource->range, -- resource_type, resource_data_type, 0); -+ if (!(d = vkd3d_shader_scan_add_descriptor(context, type, &resource->reg.reg, -+ &resource->range, resource_type, resource_data_type))) -+ return; -+ d->sample_count = sample_count; -+ d->structure_stride = structure_stride; -+ if (raw) -+ d->flags |= VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; - } - - static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_scan_context *context, -@@ -886,7 +896,7 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca - } - - vkd3d_shader_scan_resource_declaration(context, &semantic->resource, -- semantic->resource_type, resource_data_type); -+ semantic->resource_type, resource_data_type, semantic->sample_count, 0, false); - } - - static void vkd3d_shader_scan_error(struct vkd3d_shader_scan_context *context, -@@ -920,12 +930,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte - case VKD3DSIH_DCL_RESOURCE_RAW: - case VKD3DSIH_DCL_UAV_RAW: - vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, -- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT); -+ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true); - break; - case VKD3DSIH_DCL_RESOURCE_STRUCTURED: - case VKD3DSIH_DCL_UAV_STRUCTURED: - vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, -- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT); -+ VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, -+ instruction->declaration.structured_resource.byte_stride, false); - break; - case VKD3DSIH_IF: - cf_info = vkd3d_shader_scan_push_cf_info(context); -@@ -1150,12 +1161,17 @@ static int scan_with_parser(const struct vkd3d_shader_compile_info *compile_info - - for (i = 0; i < ARRAY_SIZE(parser->shader_desc.flat_constant_count); ++i) - { -+ unsigned int size = parser->shader_desc.flat_constant_count[i].external; - struct vkd3d_shader_register_range range = {.space = 0, .first = i, .last = i}; - struct vkd3d_shader_register reg = {.idx[0].offset = i, .idx_count = 1}; -+ struct vkd3d_shader_descriptor_info1 *d; - - if (parser->shader_desc.flat_constant_count[i].external) -- vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, -- &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0); -+ { -+ if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, -+ &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) -+ d->buffer_size = size * 16; -+ } - } - - if (!ret && signature_info) -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index c719085e11f..bf925a44690 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1122,6 +1122,9 @@ struct vkd3d_shader_descriptor_info1 - enum vkd3d_shader_resource_type resource_type; - enum vkd3d_shader_resource_data_type resource_data_type; - unsigned int flags; -+ unsigned int sample_count; -+ unsigned int buffer_size; -+ unsigned int structure_stride; - unsigned int count; - }; - -diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c -index a2e1f13dec3..c33061073a3 100644 ---- a/libs/vkd3d/libs/vkd3d/device.c -+++ b/libs/vkd3d/libs/vkd3d/device.c -@@ -2435,34 +2435,39 @@ static void device_init_descriptor_pool_sizes(struct d3d12_device *device) - - static void vkd3d_desc_object_cache_init(struct vkd3d_desc_object_cache *cache, size_t size) - { -- cache->head = NULL; -+ memset(cache, 0, sizeof(*cache)); - cache->size = size; - } - - static void vkd3d_desc_object_cache_cleanup(struct vkd3d_desc_object_cache *cache) - { - union d3d12_desc_object u; -+ unsigned int i; - void *next; - -- for (u.object = cache->head; u.object; u.object = next) -+ for (i = 0; i < ARRAY_SIZE(cache->heads); ++i) - { -- next = u.header->next; -- vkd3d_free(u.object); -+ for (u.object = cache->heads[i].head; u.object; u.object = next) -+ { -+ next = u.header->next; -+ vkd3d_free(u.object); -+ } - } - } - - /* ID3D12Device */ --static inline struct d3d12_device *impl_from_ID3D12Device(ID3D12Device *iface) -+static inline struct d3d12_device *impl_from_ID3D12Device1(ID3D12Device1 *iface) - { -- return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device_iface); -+ return CONTAINING_RECORD(iface, struct d3d12_device, ID3D12Device1_iface); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device1 *iface, - REFIID riid, void **object) - { - TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object); - -- if (IsEqualGUID(riid, &IID_ID3D12Device) -+ if (IsEqualGUID(riid, &IID_ID3D12Device1) -+ || IsEqualGUID(riid, &IID_ID3D12Device) - || IsEqualGUID(riid, &IID_ID3D12Object) - || IsEqualGUID(riid, &IID_IUnknown)) - { -@@ -2477,9 +2482,9 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_QueryInterface(ID3D12Device *iface - return E_NOINTERFACE; - } - --static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device *iface) -+static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device1 *iface) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - ULONG refcount = InterlockedIncrement(&device->refcount); - - TRACE("%p increasing refcount to %u.\n", device, refcount); -@@ -2487,9 +2492,9 @@ static ULONG STDMETHODCALLTYPE d3d12_device_AddRef(ID3D12Device *iface) - return refcount; - } - --static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface) -+static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device1 *iface) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - ULONG refcount = InterlockedDecrement(&device->refcount); - - TRACE("%p decreasing refcount to %u.\n", device, refcount); -@@ -2523,10 +2528,10 @@ static ULONG STDMETHODCALLTYPE d3d12_device_Release(ID3D12Device *iface) - return refcount; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device1 *iface, - REFGUID guid, UINT *data_size, void *data) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - TRACE("iface %p, guid %s, data_size %p, data %p.\n", - iface, debugstr_guid(guid), data_size, data); -@@ -2534,10 +2539,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_GetPrivateData(ID3D12Device *iface - return vkd3d_get_private_data(&device->private_store, guid, data_size, data); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device1 *iface, - REFGUID guid, UINT data_size, const void *data) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - TRACE("iface %p, guid %s, data_size %u, data %p.\n", - iface, debugstr_guid(guid), data_size, data); -@@ -2545,19 +2550,19 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateData(ID3D12Device *iface - return vkd3d_set_private_data(&device->private_store, guid, data_size, data); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetPrivateDataInterface(ID3D12Device1 *iface, - REFGUID guid, const IUnknown *data) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(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(ID3D12Device *iface, const WCHAR *name) -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device1 *iface, const WCHAR *name) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - TRACE("iface %p, name %s.\n", iface, debugstr_w(name, device->wchar_size)); - -@@ -2565,17 +2570,17 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_SetName(ID3D12Device *iface, const - VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT, name); - } - --static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device *iface) -+static UINT STDMETHODCALLTYPE d3d12_device_GetNodeCount(ID3D12Device1 *iface) - { - TRACE("iface %p.\n", iface); - - return 1; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device1 *iface, - const D3D12_COMMAND_QUEUE_DESC *desc, REFIID riid, void **command_queue) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_command_queue *object; - HRESULT hr; - -@@ -2589,10 +2594,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandQueue(ID3D12Device *i - riid, command_queue); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Device1 *iface, - D3D12_COMMAND_LIST_TYPE type, REFIID riid, void **command_allocator) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_command_allocator *object; - HRESULT hr; - -@@ -2606,10 +2611,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandAllocator(ID3D12Devic - riid, command_allocator); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12Device1 *iface, - const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_pipeline_state *object; - HRESULT hr; - -@@ -2623,10 +2628,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateGraphicsPipelineState(ID3D12 - &IID_ID3D12PipelineState, riid, pipeline_state); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12Device1 *iface, - const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, REFIID riid, void **pipeline_state) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_pipeline_state *object; - HRESULT hr; - -@@ -2640,11 +2645,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateComputePipelineState(ID3D12D - &IID_ID3D12PipelineState, riid, pipeline_state); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandList(ID3D12Device1 *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_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_command_list *object; - HRESULT hr; - -@@ -2767,10 +2772,10 @@ bool d3d12_device_is_uma(struct d3d12_device *device, bool *coherent) - return true; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device1 *iface, - D3D12_FEATURE feature, void *feature_data, UINT feature_data_size) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - TRACE("iface %p, feature %#x, feature_data %p, feature_data_size %u.\n", - iface, feature, feature_data, feature_data_size); -@@ -3269,10 +3274,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device * - } - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device1 *iface, - const D3D12_DESCRIPTOR_HEAP_DESC *desc, REFIID riid, void **descriptor_heap) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_descriptor_heap *object; - HRESULT hr; - -@@ -3286,7 +3291,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateDescriptorHeap(ID3D12Device - &IID_ID3D12DescriptorHeap, riid, descriptor_heap); - } - --static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device *iface, -+static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D12Device1 *iface, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_heap_type) - { - TRACE("iface %p, descriptor_heap_type %#x.\n", iface, descriptor_heap_type); -@@ -3309,11 +3314,11 @@ static UINT STDMETHODCALLTYPE d3d12_device_GetDescriptorHandleIncrementSize(ID3D - } - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device1 *iface, - UINT node_mask, const void *bytecode, SIZE_T bytecode_length, - REFIID riid, void **root_signature) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_root_signature *object; - HRESULT hr; - -@@ -3329,10 +3334,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateRootSignature(ID3D12Device * - &IID_ID3D12RootSignature, riid, root_signature); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device1 *iface, - const D3D12_CONSTANT_BUFFER_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_desc tmp = {0}; - - TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); -@@ -3341,11 +3346,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateConstantBufferView(ID3D12Device - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device1 *iface, - ID3D12Resource *resource, const D3D12_SHADER_RESOURCE_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_desc tmp = {0}; - - TRACE("iface %p, resource %p, desc %p, descriptor %#lx.\n", -@@ -3355,11 +3360,11 @@ static void STDMETHODCALLTYPE d3d12_device_CreateShaderResourceView(ID3D12Device - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Device1 *iface, - ID3D12Resource *resource, ID3D12Resource *counter_resource, - const D3D12_UNORDERED_ACCESS_VIEW_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_desc tmp = {0}; - - TRACE("iface %p, resource %p, counter_resource %p, desc %p, descriptor %#lx.\n", -@@ -3370,7 +3375,7 @@ static void STDMETHODCALLTYPE d3d12_device_CreateUnorderedAccessView(ID3D12Devic - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device1 *iface, - ID3D12Resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -@@ -3378,10 +3383,10 @@ static void STDMETHODCALLTYPE d3d12_device_CreateRenderTargetView(ID3D12Device * - iface, resource, desc, descriptor.ptr); - - d3d12_rtv_desc_create_rtv(d3d12_rtv_desc_from_cpu_handle(descriptor), -- impl_from_ID3D12Device(iface), unsafe_impl_from_ID3D12Resource(resource), desc); -+ impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device1 *iface, - ID3D12Resource *resource, const D3D12_DEPTH_STENCIL_VIEW_DESC *desc, - D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -@@ -3389,13 +3394,13 @@ static void STDMETHODCALLTYPE d3d12_device_CreateDepthStencilView(ID3D12Device * - iface, resource, desc, descriptor.ptr); - - d3d12_dsv_desc_create_dsv(d3d12_dsv_desc_from_cpu_handle(descriptor), -- impl_from_ID3D12Device(iface), unsafe_impl_from_ID3D12Resource(resource), desc); -+ impl_from_ID3D12Device1(iface), unsafe_impl_from_ID3D12Resource(resource), desc); - } - --static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device1 *iface, - const D3D12_SAMPLER_DESC *desc, D3D12_CPU_DESCRIPTOR_HANDLE descriptor) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_desc tmp = {0}; - - TRACE("iface %p, desc %p, descriptor %#lx.\n", iface, desc, descriptor.ptr); -@@ -3404,14 +3409,14 @@ static void STDMETHODCALLTYPE d3d12_device_CreateSampler(ID3D12Device *iface, - d3d12_desc_write_atomic(d3d12_desc_from_cpu_handle(descriptor), &tmp, device); - } - --static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device1 *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_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(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; -@@ -3467,7 +3472,7 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptors(ID3D12Device *iface, - } - } - --static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device1 *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) -@@ -3482,10 +3487,10 @@ static void STDMETHODCALLTYPE d3d12_device_CopyDescriptorsSimple(ID3D12Device *i - } - - static D3D12_RESOURCE_ALLOCATION_INFO * STDMETHODCALLTYPE d3d12_device_GetResourceAllocationInfo( -- ID3D12Device *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, -+ ID3D12Device1 *iface, D3D12_RESOURCE_ALLOCATION_INFO *info, UINT visible_mask, - UINT count, const D3D12_RESOURCE_DESC *resource_descs) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - const D3D12_RESOURCE_DESC *desc; - uint64_t requested_alignment; - -@@ -3558,10 +3563,10 @@ invalid: - return info; - } - --static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device *iface, -+static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapProperties(ID3D12Device1 *iface, - D3D12_HEAP_PROPERTIES *heap_properties, UINT node_mask, D3D12_HEAP_TYPE heap_type) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - bool coherent; - - TRACE("iface %p, heap_properties %p, node_mask 0x%08x, heap_type %#x.\n", -@@ -3601,12 +3606,12 @@ static D3D12_HEAP_PROPERTIES * STDMETHODCALLTYPE d3d12_device_GetCustomHeapPrope - return heap_properties; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Device1 *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_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_resource *object; - HRESULT hr; - -@@ -3625,10 +3630,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommittedResource(ID3D12Devi - return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device1 *iface, - const D3D12_HEAP_DESC *desc, REFIID iid, void **heap) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_heap *object; - HRESULT hr; - -@@ -3644,12 +3649,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateHeap(ID3D12Device *iface, - return return_interface(&object->ID3D12Heap_iface, &IID_ID3D12Heap, iid, heap); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device1 *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_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_heap *heap_object; - struct d3d12_resource *object; - HRESULT hr; -@@ -3668,11 +3673,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePlacedResource(ID3D12Device - return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Device1 *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_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_resource *object; - HRESULT hr; - -@@ -3686,11 +3691,11 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateReservedResource(ID3D12Devic - return return_interface(&object->ID3D12Resource_iface, &IID_ID3D12Resource, iid, resource); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device1 *iface, - ID3D12DeviceChild *object, const SECURITY_ATTRIBUTES *attributes, DWORD access, - const WCHAR *name, HANDLE *handle) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(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); -@@ -3698,7 +3703,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateSharedHandle(ID3D12Device *i - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device1 *iface, - HANDLE handle, REFIID riid, void **object) - { - FIXME("iface %p, handle %p, riid %s, object %p stub!\n", -@@ -3707,10 +3712,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandle(ID3D12Device *ifa - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Device1 *iface, - const WCHAR *name, DWORD access, HANDLE *handle) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - FIXME("iface %p, name %s, access %#x, handle %p stub!\n", - iface, debugstr_w(name, device->wchar_size), access, handle); -@@ -3718,7 +3723,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_OpenSharedHandleByName(ID3D12Devic - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device1 *iface, - UINT object_count, ID3D12Pageable * const *objects) - { - FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", -@@ -3727,7 +3732,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_MakeResident(ID3D12Device *iface, - return S_OK; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device1 *iface, - UINT object_count, ID3D12Pageable * const *objects) - { - FIXME_ONCE("iface %p, object_count %u, objects %p stub!\n", -@@ -3736,10 +3741,10 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_Evict(ID3D12Device *iface, - return S_OK; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device1 *iface, - UINT64 initial_value, D3D12_FENCE_FLAGS flags, REFIID riid, void **fence) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_fence *object; - HRESULT hr; - -@@ -3752,21 +3757,21 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateFence(ID3D12Device *iface, - return return_interface(&object->ID3D12Fence1_iface, &IID_ID3D12Fence1, riid, fence); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device *iface) -+static HRESULT STDMETHODCALLTYPE d3d12_device_GetDeviceRemovedReason(ID3D12Device1 *iface) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - TRACE("iface %p.\n", iface); - - return device->removed_reason; - } - --static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device1 *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_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(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; -@@ -3846,10 +3851,10 @@ static void STDMETHODCALLTYPE d3d12_device_GetCopyableFootprints(ID3D12Device *i - *total_bytes = total; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device1 *iface, - const D3D12_QUERY_HEAP_DESC *desc, REFIID iid, void **heap) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_query_heap *object; - HRESULT hr; - -@@ -3862,18 +3867,18 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateQueryHeap(ID3D12Device *ifac - return return_interface(&object->ID3D12QueryHeap_iface, &IID_ID3D12QueryHeap, iid, heap); - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device *iface, BOOL enable) -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetStablePowerState(ID3D12Device1 *iface, BOOL enable) - { - FIXME("iface %p, enable %#x stub!\n", iface, enable); - - return E_NOTIMPL; - } - --static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device *iface, -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Device1 *iface, - const D3D12_COMMAND_SIGNATURE_DESC *desc, ID3D12RootSignature *root_signature, - REFIID iid, void **command_signature) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - struct d3d12_command_signature *object; - HRESULT hr; - -@@ -3887,14 +3892,14 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreateCommandSignature(ID3D12Devic - &IID_ID3D12CommandSignature, iid, command_signature); - } - --static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface, -+static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device1 *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_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " - "standard_title_shape %p, sub_resource_tiling_count %p, " -@@ -3907,9 +3912,9 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface - sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); - } - --static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid) -+static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device1 *iface, LUID *luid) - { -- struct d3d12_device *device = impl_from_ID3D12Device(iface); -+ struct d3d12_device *device = impl_from_ID3D12Device1(iface); - - TRACE("iface %p, luid %p.\n", iface, luid); - -@@ -3918,7 +3923,33 @@ static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, - return luid; - } - --static const struct ID3D12DeviceVtbl d3d12_device_vtbl = -+static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device1 *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); -+ -+ return DXGI_ERROR_UNSUPPORTED; -+} -+ -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device1 *iface, -+ ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count, -+ D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event) -+{ -+ FIXME("iface %p, fences %p, values %p, fence_count %u, flags %#x, event %p stub!\n", -+ iface, fences, values, fence_count, flags, event); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device1 *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); -+ -+ return S_OK; -+} -+ -+static const struct ID3D12Device1Vtbl d3d12_device_vtbl = - { - /* IUnknown methods */ - d3d12_device_QueryInterface, -@@ -3967,14 +3998,18 @@ static const struct ID3D12DeviceVtbl d3d12_device_vtbl = - d3d12_device_CreateCommandSignature, - d3d12_device_GetResourceTiling, - d3d12_device_GetAdapterLuid, -+ /* ID3D12Device1 methods */ -+ d3d12_device_CreatePipelineLibrary, -+ d3d12_device_SetEventOnMultipleFenceCompletion, -+ d3d12_device_SetResidencyPriority, - }; - --struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface) -+struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface) - { - if (!iface) - return NULL; - assert(iface->lpVtbl == &d3d12_device_vtbl); -- return impl_from_ID3D12Device(iface); -+ return impl_from_ID3D12Device1(iface); - } - - static HRESULT d3d12_device_init(struct d3d12_device *device, -@@ -3983,7 +4018,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device, - const struct vkd3d_vk_device_procs *vk_procs; - HRESULT hr; - -- device->ID3D12Device_iface.lpVtbl = &d3d12_device_vtbl; -+ device->ID3D12Device1_iface.lpVtbl = &d3d12_device_vtbl; - device->refcount = 1; - - vkd3d_instance_incref(device->vkd3d_instance = instance); -@@ -4180,28 +4215,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_ID3D12Device(device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); - - return d3d12_device->parent; - } - - VkDevice vkd3d_get_vk_device(ID3D12Device *device) - { -- struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); - - return d3d12_device->vk_device; - } - - VkPhysicalDevice vkd3d_get_vk_physical_device(ID3D12Device *device) - { -- struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); - - return d3d12_device->vk_physical_device; - } - - struct vkd3d_instance *vkd3d_instance_from_device(ID3D12Device *device) - { -- struct d3d12_device *d3d12_device = impl_from_ID3D12Device(device); -+ struct d3d12_device *d3d12_device = impl_from_ID3D12Device1((ID3D12Device1 *)device); - - return d3d12_device->vkd3d_instance; - } -diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c -index cd3856c2937..f3842958d96 100644 ---- a/libs/vkd3d/libs/vkd3d/resource.c -+++ b/libs/vkd3d/libs/vkd3d/resource.c -@@ -2220,7 +2220,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_ID3D12Device(device); -+ struct d3d12_device *d3d12_device = unsafe_impl_from_ID3D12Device1((ID3D12Device1 *)device); - struct d3d12_resource *object; - HRESULT hr; - -@@ -2282,38 +2282,67 @@ ULONG vkd3d_resource_decref(ID3D12Resource *resource) - return d3d12_resource_decref(impl_from_ID3D12Resource(resource)); - } - --/* Objects are cached so that vkd3d_view_incref() can safely check the refcount -- * of an object freed by another thread. */ -+#define HEAD_INDEX_MASK (ARRAY_SIZE(cache->heads) - 1) -+ -+/* Objects are cached so that vkd3d_view_incref() can safely check the refcount of an -+ * object freed by another thread. This could be implemented as a single atomic linked -+ * list, but it requires handling the ABA problem, which brings issues with cross-platform -+ * support, compiler support, and non-universal x86-64 support for 128-bit CAS. */ - static void *vkd3d_desc_object_cache_get(struct vkd3d_desc_object_cache *cache) - { - union d3d12_desc_object u; -- void *next; -+ unsigned int i; - -- do -+ STATIC_ASSERT(!(ARRAY_SIZE(cache->heads) & HEAD_INDEX_MASK)); -+ -+ i = (vkd3d_atomic_increment(&cache->next_index)) & HEAD_INDEX_MASK; -+ for (;;) - { -- u.object = cache->head; -- if (!u.object) -+ if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) -+ { -+ if ((u.object = cache->heads[i].head)) -+ { -+ vkd3d_atomic_decrement(&cache->free_count); -+ cache->heads[i].head = u.header->next; -+ vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); -+ return u.object; -+ } -+ vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); -+ } -+ /* Keeping a free count avoids uncertainty over when this loop should terminate, -+ * which could result in excess allocations gradually increasing without limit. */ -+ if (cache->free_count < ARRAY_SIZE(cache->heads)) - return vkd3d_malloc(cache->size); -- next = u.header->next; -- } -- while (!vkd3d_atomic_compare_exchange_pointer(&cache->head, u.object, next)); - -- return u.object; -+ i = (i + 1) & HEAD_INDEX_MASK; -+ } - } - - static void vkd3d_desc_object_cache_push(struct vkd3d_desc_object_cache *cache, void *object) - { - union d3d12_desc_object u = {object}; -+ unsigned int i; - void *head; - -- do -+ /* 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; -+ for (;;) - { -- head = cache->head; -- u.header->next = head; -+ if (vkd3d_atomic_compare_exchange(&cache->heads[i].spinlock, 0, 1)) -+ break; -+ i = (i + 1) & HEAD_INDEX_MASK; - } -- while (!vkd3d_atomic_compare_exchange_pointer(&cache->head, head, u.object)); -+ -+ head = cache->heads[i].head; -+ u.header->next = head; -+ cache->heads[i].head = u.object; -+ vkd3d_atomic_exchange(&cache->heads[i].spinlock, 0); -+ vkd3d_atomic_increment(&cache->free_count); - } - -+#undef HEAD_INDEX_MASK -+ - static struct vkd3d_cbuffer_desc *vkd3d_cbuffer_desc_create(struct d3d12_device *device) - { - struct vkd3d_cbuffer_desc *desc; -diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 2d8138245d8..7ae46c862cc 100644 ---- a/libs/vkd3d/libs/vkd3d/state.c -+++ b/libs/vkd3d/libs/vkd3d/state.c -@@ -375,8 +375,8 @@ static HRESULT d3d12_root_signature_info_count_descriptors(struct d3d12_root_sig - - if (unbounded && range->OffsetInDescriptorsFromTableStart == D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) - { -- WARN("An unbounded range with offset D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND occurs after " -- "another unbounded range.\n"); -+ WARN("A range with offset D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND occurs after " -+ "an unbounded range.\n"); - return E_INVALIDARG; - } - -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_main.c b/libs/vkd3d/libs/vkd3d/vkd3d_main.c -index 88301fbb313..159560afd8e 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_main.c -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_main.c -@@ -71,11 +71,11 @@ HRESULT vkd3d_create_device(const struct vkd3d_device_create_info *create_info, - - if (!device) - { -- ID3D12Device_Release(&object->ID3D12Device_iface); -+ ID3D12Device_Release(&object->ID3D12Device1_iface); - return S_FALSE; - } - -- return return_interface(&object->ID3D12Device_iface, &IID_ID3D12Device, iid, device); -+ return return_interface(&object->ID3D12Device1_iface, &IID_ID3D12Device, iid, device); - } - - /* ID3D12RootSignatureDeserializer */ -diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -index 4bd6812b16e..a18287b4cd4 100644 ---- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h -+++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h -@@ -1690,9 +1690,17 @@ struct vkd3d_uav_clear_state - HRESULT vkd3d_uav_clear_state_init(struct vkd3d_uav_clear_state *state, struct d3d12_device *device); - void vkd3d_uav_clear_state_cleanup(struct vkd3d_uav_clear_state *state, struct d3d12_device *device); - -+struct desc_object_cache_head -+{ -+ void *head; -+ unsigned int spinlock; -+}; -+ - struct vkd3d_desc_object_cache - { -- void * volatile head; -+ struct desc_object_cache_head heads[16]; -+ unsigned int next_index; -+ unsigned int free_count; - size_t size; - }; - -@@ -1701,7 +1709,7 @@ struct vkd3d_desc_object_cache - /* ID3D12Device */ - struct d3d12_device - { -- ID3D12Device ID3D12Device_iface; -+ ID3D12Device1 ID3D12Device1_iface; - LONG refcount; - - VkDevice vk_device; -@@ -1767,27 +1775,27 @@ 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_ID3D12Device(ID3D12Device *iface); -+struct d3d12_device *unsafe_impl_from_ID3D12Device1(ID3D12Device1 *iface); - - static inline HRESULT d3d12_device_query_interface(struct d3d12_device *device, REFIID iid, void **object) - { -- return ID3D12Device_QueryInterface(&device->ID3D12Device_iface, iid, object); -+ return ID3D12Device1_QueryInterface(&device->ID3D12Device1_iface, iid, object); - } - - static inline ULONG d3d12_device_add_ref(struct d3d12_device *device) - { -- return ID3D12Device_AddRef(&device->ID3D12Device_iface); -+ return ID3D12Device1_AddRef(&device->ID3D12Device1_iface); - } - - static inline ULONG d3d12_device_release(struct d3d12_device *device) - { -- return ID3D12Device_Release(&device->ID3D12Device_iface); -+ return ID3D12Device1_Release(&device->ID3D12Device1_iface); - } - - static inline unsigned int d3d12_device_get_descriptor_handle_increment_size(struct d3d12_device *device, - D3D12_DESCRIPTOR_HEAP_TYPE descriptor_type) - { -- return ID3D12Device_GetDescriptorHandleIncrementSize(&device->ID3D12Device_iface, descriptor_type); -+ return ID3D12Device1_GetDescriptorHandleIncrementSize(&device->ID3D12Device1_iface, descriptor_type); - } - - /* utils */ --- -2.40.1 - diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-269747dbf3ee32bf23e6d1ab388d2a058ca.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-269747dbf3ee32bf23e6d1ab388d2a058ca.patch deleted file mode 100644 index b4b5e54d..00000000 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-269747dbf3ee32bf23e6d1ab388d2a058ca.patch +++ /dev/null @@ -1,947 +0,0 @@ -From 5d17ecf1f2fc977fe26e8a7acaf54e9d60b97204 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 29 Aug 2023 07:21:37 +1000 -Subject: [PATCH] Updated vkd3d to 269747dbf3ee32bf23e6d1ab388d2a058ca90f9f. - ---- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 1 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 47 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 5 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 296 +++++++++--------- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 144 +++++++-- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 37 +++ - libs/vkd3d/libs/vkd3d/command.c | 5 +- - 7 files changed, 347 insertions(+), 188 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 0a8d3a692a3..070fec74326 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -356,6 +356,7 @@ struct hlsl_attribute - #define HLSL_MODIFIER_COLUMN_MAJOR 0x00000400 - #define HLSL_STORAGE_IN 0x00000800 - #define HLSL_STORAGE_OUT 0x00001000 -+#define HLSL_MODIFIER_INLINE 0x00002000 - - #define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ - HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 29e0ff0c5be..43ea4b4d038 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -493,11 +493,11 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum loop_type type, - || !strcmp(attr->name, "fastopt") - || !strcmp(attr->name, "allow_uav_condition")) - { -- hlsl_fixme(ctx, loc, "Unhandled attribute %s.", attr->name); -+ hlsl_fixme(ctx, loc, "Unhandled attribute '%s'.", attr->name); - } - else - { -- hlsl_warning(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_IMPLEMENTED, "Unrecognized attribute %s.", attr->name); -+ hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Unrecognized attribute '%s'.", attr->name); - } - } - -@@ -5129,6 +5129,9 @@ func_prototype_no_attrs: - struct hlsl_ir_var *var; - struct hlsl_type *type; - -+ /* Functions are unconditionally inlined. */ -+ modifiers &= ~HLSL_MODIFIER_INLINE; -+ - if (modifiers & ~HLSL_MODIFIERS_MAJORITY_MASK) - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, - "Only majority modifiers are allowed on functions."); -@@ -5970,6 +5973,10 @@ var_modifiers: - { - $$ = add_modifiers(ctx, $2, HLSL_STORAGE_IN | HLSL_STORAGE_OUT, &@1); - } -+ | KW_INLINE var_modifiers -+ { -+ $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_INLINE, &@1); -+ } - - - complex_initializer: -@@ -6108,19 +6115,39 @@ jump_statement: - } - - selection_statement: -- KW_IF '(' expr ')' if_body -+ attribute_list_optional KW_IF '(' expr ')' if_body - { -- struct hlsl_ir_node *condition = node_from_block($3); -+ struct hlsl_ir_node *condition = node_from_block($4); -+ const struct parse_attribute_list *attributes = &$1; - struct hlsl_ir_node *instr; -+ unsigned int i; -+ -+ if (attribute_list_has_duplicates(attributes)) -+ hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Found duplicate attribute."); -+ -+ for (i = 0; i < attributes->count; ++i) -+ { -+ const struct hlsl_attribute *attr = attributes->attrs[i]; -+ -+ if (!strcmp(attr->name, "branch") -+ || !strcmp(attr->name, "flatten")) -+ { -+ hlsl_warning(ctx, &@1, VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE, "Unhandled attribute '%s'.", attr->name); -+ } -+ else -+ { -+ hlsl_warning(ctx, &@1, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Unrecognized attribute '%s'.", attr->name); -+ } -+ } - -- if (!(instr = hlsl_new_if(ctx, condition, $5.then_block, $5.else_block, &@1))) -+ if (!(instr = hlsl_new_if(ctx, condition, $6.then_block, $6.else_block, &@2))) - { -- destroy_block($5.then_block); -- destroy_block($5.else_block); -+ destroy_block($6.then_block); -+ destroy_block($6.else_block); - YYABORT; - } -- destroy_block($5.then_block); -- destroy_block($5.else_block); -+ destroy_block($6.then_block); -+ destroy_block($6.else_block); - if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1) - { - struct vkd3d_string_buffer *string; -@@ -6130,7 +6157,7 @@ selection_statement: - "if condition type %s is not scalar.", string->buffer); - hlsl_release_string_buffer(ctx, string); - } -- $$ = $3; -+ $$ = $4; - hlsl_block_add_instr($$, instr); - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index bfa605f4ba7..bae8e5f9a5f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -321,9 +321,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, s - if (!semantic->name) - return; - -- vector_type_src = hlsl_get_vector_type(ctx, type->base_type, -- (ctx->profile->major_version < 4) ? 4 : hlsl_type_minor_size(type)); - vector_type_dst = hlsl_get_vector_type(ctx, type->base_type, hlsl_type_minor_size(type)); -+ vector_type_src = vector_type_dst; -+ if (ctx->profile->major_version < 4 && ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX) -+ vector_type_src = hlsl_get_vector_type(ctx, type->base_type, 4); - - for (i = 0; i < hlsl_type_major_size(type); ++i) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index fa605f185ae..9b3084538ba 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -204,11 +204,6 @@ static inline bool register_is_undef(const struct vkd3d_shader_register *reg) - return reg->type == VKD3DSPR_UNDEF; - } - --static inline bool register_is_constant(const struct vkd3d_shader_register *reg) --{ -- return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); --} -- - static inline bool register_is_constant_or_undef(const struct vkd3d_shader_register *reg) - { - return register_is_constant(reg) || register_is_undef(reg); -@@ -2599,8 +2594,8 @@ static struct vkd3d_push_constant_buffer_binding *spirv_compiler_find_push_const - return NULL; - } - --static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *compiler, -- const struct vkd3d_shader_resource *resource, const struct vkd3d_shader_sampler *sampler) -+static bool spirv_compiler_has_combined_sampler_for_resource(const struct spirv_compiler *compiler, -+ const struct vkd3d_shader_register_range *range) - { - const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; - const struct vkd3d_shader_combined_resource_sampler *combined_sampler; -@@ -2609,10 +2604,35 @@ static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *com - if (!shader_interface->combined_sampler_count) - return false; - -- if (resource && (resource->reg.reg.type == VKD3DSPR_UAV || resource->range.last != resource->range.first)) -+ if (range->last != range->first) -+ return false; -+ -+ for (i = 0; i < shader_interface->combined_sampler_count; ++i) -+ { -+ combined_sampler = &shader_interface->combined_samplers[i]; -+ -+ if (!spirv_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility)) -+ continue; -+ -+ if ((combined_sampler->resource_space == range->space -+ && combined_sampler->resource_index == range->first)) -+ return true; -+ } -+ -+ return false; -+} -+ -+static bool spirv_compiler_has_combined_sampler_for_sampler(const struct spirv_compiler *compiler, -+ const struct vkd3d_shader_register_range *range) -+{ -+ const struct vkd3d_shader_interface_info *shader_interface = &compiler->shader_interface; -+ const struct vkd3d_shader_combined_resource_sampler *combined_sampler; -+ unsigned int i; -+ -+ if (!shader_interface->combined_sampler_count) - return false; - -- if (sampler && sampler->range.first != sampler->range.last) -+ if (range->last != range->first) - return false; - - for (i = 0; i < shader_interface->combined_sampler_count; ++i) -@@ -2622,10 +2642,8 @@ static bool spirv_compiler_has_combined_sampler(const struct spirv_compiler *com - if (!spirv_compiler_check_shader_visibility(compiler, combined_sampler->shader_visibility)) - continue; - -- if ((!resource || (combined_sampler->resource_space == resource->range.space -- && combined_sampler->resource_index == resource->range.first)) -- && (!sampler || (combined_sampler->sampler_space == sampler->range.space -- && combined_sampler->sampler_index == sampler->range.first))) -+ if (combined_sampler->sampler_space == range->space -+ && combined_sampler->sampler_index == range->first) - return true; - } - -@@ -2643,6 +2661,16 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_error(struct spirv_compiler * - compiler->failed = true; - } - -+static void VKD3D_PRINTF_FUNC(3, 4) spirv_compiler_warning(struct spirv_compiler *compiler, -+ enum vkd3d_shader_error error, const char *format, ...) -+{ -+ va_list args; -+ -+ va_start(args, format); -+ vkd3d_shader_vwarning(compiler->message_context, &compiler->location, error, format, args); -+ va_end(args); -+} -+ - static struct vkd3d_string_buffer *vkd3d_shader_register_range_string(struct spirv_compiler *compiler, - const struct vkd3d_shader_register_range *range) - { -@@ -5538,8 +5566,8 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * - return var_id; - } - --static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, unsigned int size, -- const struct vkd3d_shader_register_range *range, const struct vkd3d_shader_register *reg) -+static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, -+ const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t vec4_id, array_type_id, length_id, struct_id, var_id; -@@ -5548,13 +5576,20 @@ static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, - struct vkd3d_descriptor_variable_info var_info; - struct vkd3d_symbol reg_symbol; - -+ struct vkd3d_shader_register reg = -+ { -+ .type = VKD3DSPR_CONSTBUFFER, -+ .idx[0].offset = register_id, -+ .idx_count = 1, -+ }; -+ - if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range))) - { - /* Push constant buffers are handled in - * spirv_compiler_emit_push_constant_buffers(). - */ - unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t); -- push_cb->reg = *reg; -+ push_cb->reg = reg; - push_cb->size = size; - if (cb_size_in_bytes > push_cb->pc.size) - { -@@ -5575,9 +5610,9 @@ static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, - vkd3d_spirv_build_op_name(builder, struct_id, "cb%u_struct", size); - - var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, struct_id, -- reg, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); -+ ®, range, VKD3D_SHADER_RESOURCE_BUFFER, false, &var_info); - -- vkd3d_symbol_make_register(®_symbol, reg); -+ vkd3d_symbol_make_register(®_symbol, ®); - vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, - VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); - reg_symbol.descriptor_array = var_info.array_symbol; -@@ -5585,16 +5620,6 @@ static void spirv_compiler_emit_constant_buffer(struct spirv_compiler *compiler, - spirv_compiler_put_symbol(compiler, ®_symbol); - } - --static void spirv_compiler_emit_dcl_constant_buffer(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- const struct vkd3d_shader_constant_buffer *cb = &instruction->declaration.cb; -- -- assert(!(instruction->flags & ~VKD3DSI_INDEXED_DYNAMIC)); -- -- spirv_compiler_emit_constant_buffer(compiler, cb->size, &cb->range, &cb->src.reg); --} -- - static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) - { -@@ -5628,29 +5653,34 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi - spirv_compiler_put_symbol(compiler, ®_symbol); - } - --static void spirv_compiler_emit_dcl_sampler(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) -+static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compiler, -+ const struct vkd3d_shader_register_range *range, unsigned int register_id) - { -- const struct vkd3d_shader_sampler *sampler = &instruction->declaration.sampler; - const SpvStorageClass storage_class = SpvStorageClassUniformConstant; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; -- const struct vkd3d_shader_register *reg = &sampler->src.reg; - struct vkd3d_descriptor_variable_info var_info; - struct vkd3d_symbol reg_symbol; - uint32_t type_id, var_id; - -- vkd3d_symbol_make_sampler(®_symbol, reg); -- reg_symbol.info.sampler.range = sampler->range; -+ const struct vkd3d_shader_register reg = -+ { -+ .type = VKD3DSPR_SAMPLER, -+ .idx[0].offset = register_id, -+ .idx_count = 1, -+ }; -+ -+ vkd3d_symbol_make_sampler(®_symbol, ®); -+ reg_symbol.info.sampler.range = *range; - spirv_compiler_put_symbol(compiler, ®_symbol); - -- if (spirv_compiler_has_combined_sampler(compiler, NULL, sampler)) -+ if (spirv_compiler_has_combined_sampler_for_sampler(compiler, range)) - return; - - type_id = vkd3d_spirv_get_op_type_sampler(builder); -- var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, -- &sampler->range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info); -+ var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, -+ range, VKD3D_SHADER_RESOURCE_NONE, false, &var_info); - -- vkd3d_symbol_make_register(®_symbol, reg); -+ vkd3d_symbol_make_register(®_symbol, ®); - vkd3d_symbol_set_register_info(®_symbol, var_id, storage_class, - VKD3D_SHADER_COMPONENT_FLOAT, VKD3DSP_WRITEMASK_ALL); - reg_symbol.descriptor_array = var_info.array_symbol; -@@ -5832,20 +5862,30 @@ static void spirv_compiler_emit_combined_sampler_declarations(struct spirv_compi - } - - static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *compiler, -- const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, -- enum vkd3d_data_type resource_data_type, unsigned int structure_stride, bool raw) -+ const struct vkd3d_shader_register_range *range, unsigned int register_id, -+ unsigned int sample_count, bool is_uav, enum vkd3d_shader_resource_type resource_type, -+ enum vkd3d_shader_resource_data_type resource_data_type, unsigned int structure_stride, bool raw) - { - struct vkd3d_descriptor_variable_info var_info, counter_var_info = {0}; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - SpvStorageClass storage_class = SpvStorageClassUniformConstant; - uint32_t counter_type_id, type_id, var_id, counter_var_id = 0; -- const struct vkd3d_shader_register *reg = &resource->reg.reg; - const struct vkd3d_spirv_resource_type *resource_type_info; - enum vkd3d_shader_component_type sampled_type; - struct vkd3d_symbol resource_symbol; -- bool is_uav; - -- is_uav = reg->type == VKD3DSPR_UAV; -+ struct vkd3d_shader_register reg = -+ { -+ .type = is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, -+ .idx[0].offset = register_id, -+ .idx_count = 1, -+ }; -+ -+ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1) -+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY && sample_count == 1) -+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; -+ - if (!(resource_type_info = spirv_compiler_enable_resource_type(compiler, - resource_type, is_uav))) - { -@@ -5853,11 +5893,11 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - return; - } - -- sampled_type = vkd3d_component_type_from_data_type(resource_data_type); -+ sampled_type = vkd3d_component_type_from_resource_data_type(resource_data_type); - -- if (spirv_compiler_has_combined_sampler(compiler, resource, NULL)) -+ if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) - { -- spirv_compiler_emit_combined_sampler_declarations(compiler, reg, &resource->range, -+ spirv_compiler_emit_combined_sampler_declarations(compiler, ®, range, - resource_type, sampled_type, structure_stride, raw, resource_type_info); - return; - } -@@ -5880,19 +5920,18 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - } - else - { -- type_id = spirv_compiler_get_image_type_id(compiler, reg, &resource->range, -+ type_id = spirv_compiler_get_image_type_id(compiler, ®, range, - resource_type_info, sampled_type, structure_stride || raw, 0); - } - -- var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, -- &resource->range, resource_type, false, &var_info); -+ var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, ®, -+ range, resource_type, false, &var_info); - - if (is_uav) - { - const struct vkd3d_shader_descriptor_info1 *d; - -- d = spirv_compiler_get_descriptor_info(compiler, -- VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, &resource->range); -+ d = spirv_compiler_get_descriptor_info(compiler, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, range); - - if (!(d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ)) - vkd3d_spirv_build_op_decorate(builder, var_id, SpvDecorationNonReadable, NULL, 0); -@@ -5924,15 +5963,15 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - type_id = struct_id; - } - -- counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, type_id, reg, -- &resource->range, resource_type, true, &counter_var_info); -+ counter_var_id = spirv_compiler_build_descriptor_variable(compiler, storage_class, -+ type_id, ®, range, resource_type, true, &counter_var_info); - } - } - -- vkd3d_symbol_make_resource(&resource_symbol, reg); -+ vkd3d_symbol_make_resource(&resource_symbol, ®); - resource_symbol.id = var_id; - resource_symbol.descriptor_array = var_info.array_symbol; -- resource_symbol.info.resource.range = resource->range; -+ resource_symbol.info.resource.range = *range; - resource_symbol.info.resource.sampled_type = sampled_type; - resource_symbol.info.resource.type_id = type_id; - resource_symbol.info.resource.resource_type_info = resource_type_info; -@@ -5945,58 +5984,6 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - spirv_compiler_put_symbol(compiler, &resource_symbol); - } - --static void spirv_compiler_emit_dcl_resource(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic; -- enum vkd3d_shader_resource_type resource_type = semantic->resource_type; -- uint32_t flags = instruction->flags; -- -- /* We don't distinguish between APPEND and COUNTER UAVs. */ -- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER; -- if (flags) -- FIXME("Unhandled UAV flags %#x.\n", flags); -- -- if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && semantic->sample_count == 1) -- resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -- else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY && semantic->sample_count == 1) -- resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; -- -- spirv_compiler_emit_resource_declaration(compiler, &semantic->resource, -- resource_type, semantic->resource_data_type[0], 0, false); --} -- --static void spirv_compiler_emit_dcl_resource_raw(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- const struct vkd3d_shader_raw_resource *resource = &instruction->declaration.raw_resource; -- uint32_t flags = instruction->flags; -- -- /* We don't distinguish between APPEND and COUNTER UAVs. */ -- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER; -- if (flags) -- FIXME("Unhandled UAV flags %#x.\n", flags); -- -- spirv_compiler_emit_resource_declaration(compiler, &resource->resource, -- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, true); --} -- --static void spirv_compiler_emit_dcl_resource_structured(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) --{ -- const struct vkd3d_shader_structured_resource *resource = &instruction->declaration.structured_resource; -- unsigned int stride = resource->byte_stride; -- uint32_t flags = instruction->flags; -- -- /* We don't distinguish between APPEND and COUNTER UAVs. */ -- flags &= ~VKD3DSUF_ORDER_PRESERVING_COUNTER; -- if (flags) -- FIXME("Unhandled UAV flags %#x.\n", flags); -- -- spirv_compiler_emit_resource_declaration(compiler, &resource->resource, -- VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, stride / 4, false); --} -- - static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler, - const struct vkd3d_shader_register *reg, unsigned int size, unsigned int structure_stride) - { -@@ -7466,7 +7453,13 @@ static int spirv_compiler_emit_control_flow_instruction(struct spirv_compiler *c - assert(compiler->control_flow_depth); - assert(cf_info->current_block == VKD3D_BLOCK_SWITCH); - -- assert(src->swizzle == VKD3D_SHADER_NO_SWIZZLE && src->reg.type == VKD3DSPR_IMMCONST); -+ if (src->swizzle != VKD3D_SHADER_SWIZZLE(X, X, X, X)) -+ { -+ WARN("Unexpected src swizzle %#x.\n", src->swizzle); -+ spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE, -+ "The swizzle for a switch case value is not scalar."); -+ } -+ assert(src->reg.type == VKD3DSPR_IMMCONST); - value = *src->reg.u.immconst_uint; - - if (!vkd3d_array_reserve((void **)&cf_info->u.switch_.case_blocks, &cf_info->u.switch_.case_blocks_size, -@@ -9174,27 +9167,9 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - case VKD3DSIH_DCL_INDEXABLE_TEMP: - spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); - break; -- case VKD3DSIH_DCL_CONSTANT_BUFFER: -- spirv_compiler_emit_dcl_constant_buffer(compiler, instruction); -- break; - case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: - spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); - break; -- case VKD3DSIH_DCL_SAMPLER: -- spirv_compiler_emit_dcl_sampler(compiler, instruction); -- break; -- case VKD3DSIH_DCL: -- case VKD3DSIH_DCL_UAV_TYPED: -- spirv_compiler_emit_dcl_resource(compiler, instruction); -- break; -- case VKD3DSIH_DCL_RESOURCE_RAW: -- case VKD3DSIH_DCL_UAV_RAW: -- spirv_compiler_emit_dcl_resource_raw(compiler, instruction); -- break; -- case VKD3DSIH_DCL_RESOURCE_STRUCTURED: -- case VKD3DSIH_DCL_UAV_STRUCTURED: -- spirv_compiler_emit_dcl_resource_structured(compiler, instruction); -- break; - case VKD3DSIH_DCL_TGSM_RAW: - spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction); - break; -@@ -9490,8 +9465,16 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - case VKD3DSIH_CUT_STREAM: - spirv_compiler_emit_cut_stream(compiler, instruction); - break; -+ case VKD3DSIH_DCL: -+ case VKD3DSIH_DCL_CONSTANT_BUFFER: - case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: -+ case VKD3DSIH_DCL_RESOURCE_RAW: -+ case VKD3DSIH_DCL_RESOURCE_STRUCTURED: -+ case VKD3DSIH_DCL_SAMPLER: - case VKD3DSIH_DCL_TEMPS: -+ case VKD3DSIH_DCL_UAV_RAW: -+ case VKD3DSIH_DCL_UAV_STRUCTURED: -+ case VKD3DSIH_DCL_UAV_TYPED: - case VKD3DSIH_HS_DECLS: - case VKD3DSIH_NOP: - /* nothing to do */ -@@ -9503,24 +9486,48 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - return ret; - } - --static void spirv_compiler_emit_sm1_constant_buffer(struct spirv_compiler *compiler, -- const struct vkd3d_shader_desc *desc, enum vkd3d_shader_d3dbc_constant_register set, -- enum vkd3d_data_type data_type) -+static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler) - { -- struct vkd3d_shader_register_range range = {.space = 0, .first = set, .last = set}; -- uint32_t count = desc->flat_constant_count[set].external; -- struct vkd3d_shader_register reg = -+ unsigned int i; -+ -+ for (i = 0; i < compiler->scan_descriptor_info->descriptor_count; ++i) - { -- .type = VKD3DSPR_CONSTBUFFER, -- .idx[0].offset = set, /* register ID */ -- .idx[1].offset = set, /* register index */ -- .idx[2].offset = count, /* size */ -- .idx_count = 3, -- .data_type = data_type, -- }; -+ const struct vkd3d_shader_descriptor_info1 *descriptor = &compiler->scan_descriptor_info->descriptors[i]; -+ struct vkd3d_shader_register_range range; -+ -+ range.first = descriptor->register_index; -+ if (descriptor->count == ~0u) -+ range.last = ~0u; -+ else -+ range.last = descriptor->register_index + descriptor->count - 1; -+ range.space = descriptor->register_space; -+ -+ switch (descriptor->type) -+ { -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: -+ spirv_compiler_emit_sampler_declaration(compiler, &range, descriptor->register_id); -+ break; -+ -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: -+ spirv_compiler_emit_cbv_declaration(compiler, &range, descriptor->register_id, descriptor->buffer_size); -+ break; - -- if (count) -- spirv_compiler_emit_constant_buffer(compiler, count, &range, ®); -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: -+ spirv_compiler_emit_resource_declaration(compiler, &range, descriptor->register_id, -+ descriptor->sample_count, false, descriptor->resource_type, descriptor->resource_data_type, -+ descriptor->structure_stride / 4, descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER); -+ break; -+ -+ case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: -+ spirv_compiler_emit_resource_declaration(compiler, &range, descriptor->register_id, -+ descriptor->sample_count, true, descriptor->resource_type, descriptor->resource_data_type, -+ descriptor->structure_stride / 4, descriptor->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER); -+ break; -+ -+ default: -+ vkd3d_unreachable(); -+ } -+ } - } - - static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, -@@ -9538,12 +9545,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - if (parser->shader_desc.temp_count) - spirv_compiler_emit_temps(compiler, parser->shader_desc.temp_count); - -- spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, -- VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER, VKD3D_DATA_FLOAT); -- spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, -- VKD3D_SHADER_D3DBC_INT_CONSTANT_REGISTER, VKD3D_DATA_INT); -- spirv_compiler_emit_sm1_constant_buffer(compiler, &parser->shader_desc, -- VKD3D_SHADER_D3DBC_BOOL_CONSTANT_REGISTER, VKD3D_DATA_UINT); -+ spirv_compiler_emit_descriptor_declarations(compiler); - - compiler->location.column = 0; - compiler->location.line = 1; -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 550f9b27cc7..7949be150bf 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -507,7 +507,7 @@ enum vkd3d_sm4_input_primitive_type - - enum vkd3d_sm4_swizzle_type - { -- VKD3D_SM4_SWIZZLE_NONE = 0x0, -+ VKD3D_SM4_SWIZZLE_NONE = 0x0, /* swizzle bitfield contains a mask */ - VKD3D_SM4_SWIZZLE_VEC4 = 0x1, - VKD3D_SM4_SWIZZLE_SCALAR = 0x2, - }; -@@ -707,6 +707,19 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, - VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z; - } - -+static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode, -+ uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) -+{ -+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, -+ (struct vkd3d_shader_src_param *)&ins->src[0]); -+ if (ins->src[0].reg.type != VKD3DSPR_IMMCONST) -+ { -+ FIXME("Switch case value is not a 32-bit constant.\n"); -+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_CASE_VALUE, -+ "Switch case value is not a 32-bit immediate constant register."); -+ } -+} -+ - static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, - const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { -@@ -1215,7 +1228,8 @@ static const struct vkd3d_sm4_opcode_info opcode_table[] = - {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, - {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", - shader_sm4_read_conditional_op}, -- {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u"}, -+ {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", -+ shader_sm4_read_case_condition}, - {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, - {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", - shader_sm4_read_conditional_op}, -@@ -2012,6 +2026,7 @@ static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_pa - static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, - const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param) - { -+ unsigned int dimension, mask; - DWORD token; - - if (*ptr >= end) -@@ -2027,37 +2042,63 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons - return false; - } - -- if (src_param->reg.type == VKD3DSPR_IMMCONST || src_param->reg.type == VKD3DSPR_IMMCONST64) -+ switch ((dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT)) - { -- src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; -- } -- else -- { -- enum vkd3d_sm4_swizzle_type swizzle_type = -- (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT; -+ case VKD3D_SM4_DIMENSION_NONE: -+ case VKD3D_SM4_DIMENSION_SCALAR: -+ src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ break; - -- switch (swizzle_type) -+ case VKD3D_SM4_DIMENSION_VEC4: - { -- case VKD3D_SM4_SWIZZLE_NONE: -- if (shader_sm4_is_scalar_register(&src_param->reg)) -- src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -- else -+ enum vkd3d_sm4_swizzle_type swizzle_type = -+ (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT; -+ -+ switch (swizzle_type) -+ { -+ case VKD3D_SM4_SWIZZLE_NONE: - src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; -- break; - -- case VKD3D_SM4_SWIZZLE_SCALAR: -- src_param->swizzle = (token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT; -- src_param->swizzle = (src_param->swizzle & 0x3) * 0x01010101; -- break; -+ mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT; -+ /* Mask seems only to be used for vec4 constants and is always zero. */ -+ if (!register_is_constant(&src_param->reg)) -+ { -+ FIXME("Source mask %#x is not for a constant.\n", mask); -+ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK, -+ "Unhandled mask %#x for a non-constant source register.", mask); -+ } -+ else if (mask) -+ { -+ FIXME("Unhandled mask %#x.\n", mask); -+ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK, -+ "Unhandled source register mask %#x.", mask); -+ } - -- case VKD3D_SM4_SWIZZLE_VEC4: -- src_param->swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT); -- break; -+ break; - -- default: -- FIXME("Unhandled swizzle type %#x.\n", swizzle_type); -- break; -+ case VKD3D_SM4_SWIZZLE_SCALAR: -+ src_param->swizzle = (token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT; -+ src_param->swizzle = (src_param->swizzle & 0x3) * 0x01010101; -+ break; -+ -+ case VKD3D_SM4_SWIZZLE_VEC4: -+ src_param->swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT); -+ break; -+ -+ default: -+ FIXME("Unhandled swizzle type %#x.\n", swizzle_type); -+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE, -+ "Source register swizzle type %#x is invalid.", swizzle_type); -+ break; -+ } -+ break; - } -+ -+ default: -+ FIXME("Unhandled dimension %#x.\n", dimension); -+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION, -+ "Source register dimension %#x is invalid.", dimension); -+ break; - } - - if (register_is_input_output(&src_param->reg) && !shader_sm4_validate_input_output_register(priv, -@@ -2070,7 +2111,9 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons - static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, - const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param) - { -+ enum vkd3d_sm4_swizzle_type swizzle_type; - enum vkd3d_shader_src_modifier modifier; -+ unsigned int dimension, swizzle; - DWORD token; - - if (*ptr >= end) -@@ -2092,10 +2135,53 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons - return false; - } - -- dst_param->write_mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT; -+ switch ((dimension = (token & VKD3D_SM4_DIMENSION_MASK) >> VKD3D_SM4_DIMENSION_SHIFT)) -+ { -+ case VKD3D_SM4_DIMENSION_NONE: -+ dst_param->write_mask = 0; -+ break; -+ -+ case VKD3D_SM4_DIMENSION_SCALAR: -+ dst_param->write_mask = VKD3DSP_WRITEMASK_0; -+ break; -+ -+ case VKD3D_SM4_DIMENSION_VEC4: -+ swizzle_type = (token & VKD3D_SM4_SWIZZLE_TYPE_MASK) >> VKD3D_SM4_SWIZZLE_TYPE_SHIFT; -+ switch (swizzle_type) -+ { -+ case VKD3D_SM4_SWIZZLE_NONE: -+ dst_param->write_mask = (token & VKD3D_SM4_WRITEMASK_MASK) >> VKD3D_SM4_WRITEMASK_SHIFT; -+ break; -+ -+ case VKD3D_SM4_SWIZZLE_VEC4: -+ swizzle = swizzle_from_sm4((token & VKD3D_SM4_SWIZZLE_MASK) >> VKD3D_SM4_SWIZZLE_SHIFT); -+ if (swizzle != VKD3D_SHADER_NO_SWIZZLE) -+ { -+ FIXME("Unhandled swizzle %#x.\n", swizzle); -+ vkd3d_shader_parser_warning(&priv->p, VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_SWIZZLE, -+ "Unhandled destination register swizzle %#x.", swizzle); -+ } -+ dst_param->write_mask = VKD3DSP_WRITEMASK_ALL; -+ break; -+ -+ default: -+ FIXME("Unhandled swizzle type %#x.\n", swizzle_type); -+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE, -+ "Destination register swizzle type %#x is invalid.", swizzle_type); -+ break; -+ } -+ break; -+ -+ default: -+ FIXME("Unhandled dimension %#x.\n", dimension); -+ vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION, -+ "Destination register dimension %#x is invalid.", dimension); -+ break; -+ } -+ - if (data_type == VKD3D_DATA_DOUBLE) - dst_param->write_mask = vkd3d_write_mask_64_from_32(dst_param->write_mask); -- /* Scalar registers are declared with no write mask in shader bytecode. */ -+ /* 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; - dst_param->modifiers = 0; -@@ -3715,8 +3801,10 @@ static void sm4_src_from_constant_value(struct sm4_src_register *src, - src->reg.dim = VKD3D_SM4_DIMENSION_VEC4; - for (i = 0; i < 4; ++i) - { -- if (map_writemask & (1u << i)) -+ if ((map_writemask & (1u << i)) && (j < width)) - src->reg.immconst_uint[i] = value->u[j++].u; -+ else -+ src->reg.immconst_uint[i] = 0; - } - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index bf925a44690..84614a4eb79 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -78,9 +78,14 @@ enum vkd3d_shader_error - VKD3D_SHADER_ERROR_TPF_TOO_MANY_REGISTERS = 1004, - VKD3D_SHADER_ERROR_TPF_INVALID_IO_REGISTER = 1005, - VKD3D_SHADER_ERROR_TPF_INVALID_INDEX_RANGE_DCL = 1006, -+ VKD3D_SHADER_ERROR_TPF_INVALID_CASE_VALUE = 1007, -+ VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DIMENSION = 1008, -+ VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_SWIZZLE = 1009, - - VKD3D_SHADER_WARNING_TPF_MASK_NOT_CONTIGUOUS = 1300, - VKD3D_SHADER_WARNING_TPF_UNHANDLED_INDEX_RANGE_MASK = 1301, -+ VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_MASK = 1302, -+ VKD3D_SHADER_WARNING_TPF_UNHANDLED_REGISTER_SWIZZLE = 1303, - - VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_BINDING_NOT_FOUND = 2000, - VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE = 2001, -@@ -88,6 +93,8 @@ enum vkd3d_shader_error - VKD3D_SHADER_ERROR_SPV_DESCRIPTOR_IDX_UNSUPPORTED = 2003, - VKD3D_SHADER_ERROR_SPV_STENCIL_EXPORT_UNSUPPORTED = 2004, - -+ VKD3D_SHADER_WARNING_SPV_INVALID_SWIZZLE = 2300, -+ - VKD3D_SHADER_ERROR_RS_OUT_OF_MEMORY = 3000, - VKD3D_SHADER_ERROR_RS_INVALID_VERSION = 3001, - VKD3D_SHADER_ERROR_RS_INVALID_ROOT_PARAMETER_TYPE = 3002, -@@ -140,6 +147,7 @@ enum vkd3d_shader_error - VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE = 5302, - VKD3D_SHADER_WARNING_HLSL_IMAGINARY_NUMERIC_RESULT = 5303, - VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304, -+ VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305, - - VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, - -@@ -1012,6 +1020,11 @@ static inline bool vkd3d_shader_register_is_patch_constant(const struct vkd3d_sh - return reg->type == VKD3DSPR_PATCHCONST; - } - -+static inline bool register_is_constant(const struct vkd3d_shader_register *reg) -+{ -+ return (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_IMMCONST64); -+} -+ - struct vkd3d_shader_location - { - const char *source_name; -@@ -1310,6 +1323,30 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( - } - } - -+static inline enum vkd3d_shader_component_type vkd3d_component_type_from_resource_data_type( -+ enum vkd3d_shader_resource_data_type data_type) -+{ -+ switch (data_type) -+ { -+ case VKD3D_SHADER_RESOURCE_DATA_FLOAT: -+ case VKD3D_SHADER_RESOURCE_DATA_UNORM: -+ case VKD3D_SHADER_RESOURCE_DATA_SNORM: -+ return VKD3D_SHADER_COMPONENT_FLOAT; -+ case VKD3D_SHADER_RESOURCE_DATA_UINT: -+ return VKD3D_SHADER_COMPONENT_UINT; -+ case VKD3D_SHADER_RESOURCE_DATA_INT: -+ return VKD3D_SHADER_COMPONENT_INT; -+ case VKD3D_SHADER_RESOURCE_DATA_DOUBLE: -+ case VKD3D_SHADER_RESOURCE_DATA_CONTINUED: -+ return VKD3D_SHADER_COMPONENT_DOUBLE; -+ default: -+ FIXME("Unhandled data type %#x.\n", data_type); -+ /* fall-through */ -+ case VKD3D_SHADER_RESOURCE_DATA_MIXED: -+ return VKD3D_SHADER_COMPONENT_UINT; -+ } -+} -+ - enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, - unsigned int index); - -diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index 8b5f7899cf3..42a98763438 100644 ---- a/libs/vkd3d/libs/vkd3d/command.c -+++ b/libs/vkd3d/libs/vkd3d/command.c -@@ -3225,7 +3225,10 @@ static void command_list_add_descriptor_heap(struct d3d12_command_list *list, st - { - /* Descriptors can be written after binding. */ - FIXME("Flushing descriptor updates while list %p is not closed.\n", list); -- command_list_flush_vk_heap_updates(list); -+ vkd3d_mutex_lock(&heap->vk_sets_mutex); -+ d3d12_desc_flush_vk_heap_updates_locked(heap, list->device); -+ vkd3d_mutex_unlock(&heap->vk_sets_mutex); -+ return; - } - list->descriptor_heaps[list->descriptor_heap_count++] = heap; - } --- -2.40.1 - diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-a597dc8755af5d2ef4826f1b570927379af.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-a597dc8755af5d2ef4826f1b570927379af.patch deleted file mode 100644 index a504c197..00000000 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-a597dc8755af5d2ef4826f1b570927379af.patch +++ /dev/null @@ -1,1608 +0,0 @@ -From f8bcf91aa485c43f4e5080bdf21f3c399e15a186 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 31 Aug 2023 09:08:26 +1000 -Subject: [PATCH] Updated vkd3d to a597dc8755af5d2ef4826f1b570927379afc5824. - ---- - libs/vkd3d/include/vkd3d_shader.h | 2 + - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 11 +- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 620 +++++++++++++++++- - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 75 ++- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 13 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 316 ++++----- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 25 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 13 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 3 - - .../libs/vkd3d-shader/vkd3d_shader_private.h | 10 + - 11 files changed, 848 insertions(+), 242 deletions(-) - -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index cfe54dbff53..d329e205fd1 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -1463,6 +1463,8 @@ enum vkd3d_shader_sysval_semantic - VKD3D_SHADER_SV_TESS_FACTOR_TRIINT = 0x0e, - VKD3D_SHADER_SV_TESS_FACTOR_LINEDET = 0x0f, - VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN = 0x10, -+ /** Render target; SV_Target in Direct3D shader model 6 shaders. */ -+ VKD3D_SHADER_SV_TARGET = 0x40, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SYSVAL_SEMANTIC), - }; -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 99a5bd7a438..2b02d51f59a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1638,17 +1638,12 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe - - if (var->is_param && var->is_uniform) - { -- struct vkd3d_string_buffer *name; -+ char *new_name; - -- if (!(name = hlsl_get_string_buffer(ctx))) -- { -- buffer->status = VKD3D_ERROR_OUT_OF_MEMORY; -+ if (!(new_name = hlsl_sprintf_alloc(ctx, "$%s", var->name))) - return; -- } -- vkd3d_string_buffer_printf(name, "$%s", var->name); - vkd3d_free((char *)var->name); -- var->name = hlsl_strdup(ctx, name->buffer); -- hlsl_release_string_buffer(ctx, name); -+ var->name = new_name; - } - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index f9efe47f95d..666d8b08614 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -22,6 +22,7 @@ - #define VKD3D_SM6_VERSION_MINOR(version) (((version) >> 0) & 0xf) - - #define BITCODE_MAGIC VKD3D_MAKE_TAG('B', 'C', 0xc0, 0xde) -+#define DXIL_OP_MAX_OPERANDS 17 - - enum bitcode_block_id - { -@@ -138,6 +139,11 @@ enum bitcode_value_symtab_code - VST_CODE_BBENTRY = 2, - }; - -+enum dx_intrinsic_opcode -+{ -+ DX_STORE_OUTPUT = 5, -+}; -+ - struct sm6_pointer_info - { - const struct sm6_type *type; -@@ -242,6 +248,8 @@ struct sm6_function - - struct sm6_block *blocks[1]; - size_t block_count; -+ -+ size_t value_count; - }; - - struct dxil_block -@@ -287,12 +295,15 @@ struct sm6_parser - struct sm6_symbol *global_symbols; - size_t global_symbol_count; - -+ struct vkd3d_shader_dst_param *output_params; -+ - struct sm6_function *functions; - size_t function_count; - - struct sm6_value *values; - size_t value_count; - size_t value_capacity; -+ size_t cur_max_value; - - struct vkd3d_shader_parser p; - }; -@@ -316,6 +327,8 @@ struct dxil_global_abbrev - struct dxil_abbrev abbrev; - }; - -+static const uint64_t CALL_CONV_FLAG_EXPLICIT_TYPE = 1ull << 15; -+ - static size_t size_add_with_overflow_check(size_t a, size_t b) - { - size_t i = a + b; -@@ -1261,6 +1274,16 @@ static inline bool sm6_type_is_integer(const struct sm6_type *type) - return type->class == TYPE_CLASS_INTEGER; - } - -+static inline bool sm6_type_is_i8(const struct sm6_type *type) -+{ -+ return type->class == TYPE_CLASS_INTEGER && type->u.width == 8; -+} -+ -+static inline bool sm6_type_is_i32(const struct sm6_type *type) -+{ -+ return type->class == TYPE_CLASS_INTEGER && type->u.width == 32; -+} -+ - static inline bool sm6_type_is_floating_point(const struct sm6_type *type) - { - return type->class == TYPE_CLASS_FLOAT; -@@ -1341,6 +1364,30 @@ static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type - return NULL; - } - -+/* Never returns null for elem_idx 0. */ -+static const struct sm6_type *sm6_type_get_scalar_type(const struct sm6_type *type, unsigned int elem_idx) -+{ -+ switch (type->class) -+ { -+ case TYPE_CLASS_ARRAY: -+ case TYPE_CLASS_VECTOR: -+ if (elem_idx >= type->u.array.count) -+ return NULL; -+ return sm6_type_get_scalar_type(type->u.array.elem_type, 0); -+ -+ case TYPE_CLASS_POINTER: -+ return sm6_type_get_scalar_type(type->u.pointer.type, 0); -+ -+ case TYPE_CLASS_STRUCT: -+ if (elem_idx >= type->u.struc->elem_count) -+ return NULL; -+ return sm6_type_get_scalar_type(type->u.struc->elem_types[elem_idx], 0); -+ -+ default: -+ return type; -+ } -+} -+ - static const struct sm6_type *sm6_parser_get_type(struct sm6_parser *sm6, uint64_t type_id) - { - if (type_id >= sm6->type_count) -@@ -1443,9 +1490,32 @@ static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm - return NULL; - } - -+static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg) -+{ -+ if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) -+ return UINT_MAX; -+ -+ if (reg->immconst_type == VKD3D_IMMCONST_VEC4) -+ WARN("Returning vec4.x.\n"); -+ -+ if (reg->type == VKD3DSPR_IMMCONST64) -+ { -+ if (reg->u.immconst_uint64[0] > UINT_MAX) -+ FIXME("Truncating 64-bit value.\n"); -+ return reg->u.immconst_uint64[0]; -+ } -+ -+ return reg->u.immconst_uint[0]; -+} -+ -+static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) -+{ -+ return value->value_type == VALUE_TYPE_FUNCTION; -+} -+ - static inline bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn) - { -- assert(fn->value_type == VALUE_TYPE_FUNCTION); -+ assert(sm6_value_is_function_dcl(fn)); - return fn->u.function.is_prototype && !strncmp(fn->u.function.name, "dx.op.", 6); - } - -@@ -1455,6 +1525,60 @@ static inline struct sm6_value *sm6_parser_get_current_value(const struct sm6_pa - return &sm6->values[sm6->value_count]; - } - -+static inline bool sm6_value_is_register(const struct sm6_value *value) -+{ -+ return value->value_type == VALUE_TYPE_REG; -+} -+ -+static inline bool sm6_value_is_constant(const struct sm6_value *value) -+{ -+ return sm6_value_is_register(value) && register_is_constant(&value->u.reg); -+} -+ -+static inline bool sm6_value_is_undef(const struct sm6_value *value) -+{ -+ return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF; -+} -+ -+static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) -+{ -+ if (!sm6_value_is_constant(value)) -+ return UINT_MAX; -+ return register_get_uint_value(&value->u.reg); -+} -+ -+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) -+ { -+ ERR("Failed to allocate src params.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -+ "Out of memory allocating instruction src paramaters."); -+ return NULL; -+ } -+ ins->src = params; -+ ins->src_count = count; -+ return params; -+} -+ -+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) -+ { -+ ERR("Failed to allocate dst params.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -+ "Out of memory allocating instruction dst paramaters."); -+ return NULL; -+ } -+ ins->dst = params; -+ ins->dst_count = count; -+ return params; -+} -+ - static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type) - { - if (type->class == TYPE_CLASS_INTEGER) -@@ -1488,6 +1612,47 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type - return VKD3D_DATA_UINT; - } - -+static inline void dst_param_init_scalar(struct vkd3d_shader_dst_param *param, unsigned int component_idx) -+{ -+ param->write_mask = 1u << component_idx; -+ param->modifiers = 0; -+ param->shift = 0; -+} -+ -+static inline void src_param_init(struct vkd3d_shader_src_param *param) -+{ -+ param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ param->modifiers = VKD3DSPSM_NONE; -+} -+ -+static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) -+{ -+ src_param_init(param); -+ param->reg = src->u.reg; -+} -+ -+static void register_address_init(struct vkd3d_shader_register *reg, const struct sm6_value *address, -+ unsigned int idx, struct sm6_parser *sm6) -+{ -+ assert(idx < ARRAY_SIZE(reg->idx)); -+ if (sm6_value_is_constant(address)) -+ { -+ reg->idx[idx].offset = sm6_value_get_constant_uint(address); -+ } -+ else if (sm6_value_is_undef(address)) -+ { -+ reg->idx[idx].offset = 0; -+ } -+ else -+ { -+ struct vkd3d_shader_src_param *rel_addr = shader_parser_get_src_params(&sm6->p, 1); -+ if (rel_addr) -+ src_param_init_from_value(rel_addr, address); -+ reg->idx[idx].offset = 0; -+ reg->idx[idx].rel_addr = rel_addr; -+ } -+} -+ - /* Recurse through the block tree while maintaining a current value count. The current - * count is the sum of the global count plus all declarations within the current function. - * Store into value_capacity the highest count seen. */ -@@ -1513,6 +1678,7 @@ static size_t sm6_parser_compute_max_value_count(struct sm6_parser *sm6, - * overestimate the value count somewhat, but this should be no problem. */ - value_count = size_add_with_overflow_check(value_count, max(block->record_count, 1u) - 1); - sm6->value_capacity = max(sm6->value_capacity, value_count); -+ sm6->functions[sm6->function_count].value_count = value_count; - /* The value count returns to its previous value after handling a function. */ - if (value_count < SIZE_MAX) - value_count = old_value_count; -@@ -1524,6 +1690,77 @@ static size_t sm6_parser_compute_max_value_count(struct sm6_parser *sm6, - return value_count; - } - -+static size_t sm6_parser_get_value_index(struct sm6_parser *sm6, uint64_t idx) -+{ -+ size_t i; -+ -+ /* The value relative index is 32 bits. */ -+ if (idx > UINT32_MAX) -+ WARN("Ignoring upper 32 bits of relative index.\n"); -+ i = (uint32_t)sm6->value_count - (uint32_t)idx; -+ -+ /* This may underflow to produce a forward reference, but it must not exceeed the final value count. */ -+ if (i >= sm6->cur_max_value) -+ { -+ WARN("Invalid value index %"PRIx64" at %zu.\n", idx, sm6->value_count); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Invalid value relative index %u.", (unsigned int)idx); -+ return SIZE_MAX; -+ } -+ if (i == sm6->value_count) -+ { -+ WARN("Invalid value self-reference at %zu.\n", sm6->value_count); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Invalid value self-reference."); -+ return SIZE_MAX; -+ } -+ -+ return i; -+} -+ -+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) -+{ -+ unsigned int idx; -+ uint64_t val_ref; -+ size_t operand; -+ -+ idx = *rec_idx; -+ if (!dxil_record_validate_operand_min_count(record, idx + 1, sm6)) -+ return SIZE_MAX; -+ val_ref = record->operands[idx++]; -+ -+ operand = sm6_parser_get_value_index(sm6, val_ref); -+ if (operand == SIZE_MAX) -+ return SIZE_MAX; -+ -+ if (operand >= sm6->value_count) -+ { -+ 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; -+ } -+ 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; -+} -+ -+static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm6, -+ const struct dxil_record *record, const struct sm6_type *type, unsigned int *rec_idx) -+{ -+ size_t operand = sm6_parser_get_value_idx_by_ref(sm6, record, type, rec_idx); -+ return operand == SIZE_MAX ? NULL : &sm6->values[operand]; -+} -+ - static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxil_record *record) - { - const unsigned int max_count = 15; -@@ -1816,6 +2053,81 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) - return VKD3D_OK; - } - -+static void dst_param_io_init(struct vkd3d_shader_dst_param *param, -+ const struct signature_element *e, enum vkd3d_shader_register_type reg_type) -+{ -+ enum vkd3d_shader_component_type component_type; -+ -+ param->write_mask = e->mask; -+ param->modifiers = 0; -+ param->shift = 0; -+ /* DXIL types do not have signedness. Load signed elements as unsigned. */ -+ component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type; -+ shader_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0); -+} -+ -+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) -+{ -+ struct vkd3d_shader_dst_param *param; -+ const struct signature_element *e; -+ unsigned int i; -+ -+ for (i = 0; i < s->element_count; ++i) -+ { -+ e = &s->elements[i]; -+ -+ param = ¶ms[i]; -+ dst_param_io_init(param, e, reg_type); -+ param->reg.idx[0].offset = i; -+ param->reg.idx_count = 1; -+ } -+} -+ -+static void sm6_parser_emit_signature(struct sm6_parser *sm6, const struct shader_signature *s, -+ enum vkd3d_shader_opcode handler_idx, enum vkd3d_shader_opcode siv_handler_idx, -+ struct vkd3d_shader_dst_param *params) -+{ -+ struct vkd3d_shader_instruction *ins; -+ struct vkd3d_shader_dst_param *param; -+ const struct signature_element *e; -+ unsigned int i; -+ -+ for (i = 0; i < s->element_count; ++i) -+ { -+ e = &s->elements[i]; -+ -+ /* Do not check e->used_mask because in some cases it is zero for used elements. -+ * TODO: scan ahead for used I/O elements. */ -+ -+ if (e->sysval_semantic != VKD3D_SHADER_SV_NONE && e->sysval_semantic != VKD3D_SHADER_SV_TARGET) -+ { -+ ins = sm6_parser_add_instruction(sm6, siv_handler_idx); -+ param = &ins->declaration.register_semantic.reg; -+ ins->declaration.register_semantic.sysval_semantic = vkd3d_siv_from_sysval(e->sysval_semantic); -+ } -+ else -+ { -+ ins = sm6_parser_add_instruction(sm6, handler_idx); -+ param = &ins->declaration.dst; -+ } -+ -+ *param = params[i]; -+ } -+} -+ -+static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) -+{ -+ sm6_parser_init_signature(sm6, output_signature, -+ (sm6->p.shader_version.type == VKD3D_SHADER_TYPE_PIXEL) ? VKD3DSPR_COLOROUT : VKD3DSPR_OUTPUT, -+ sm6->output_params); -+} -+ -+static void sm6_parser_emit_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) -+{ -+ sm6_parser_emit_signature(sm6, output_signature, VKD3DSIH_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT_SIV, sm6->output_params); -+} -+ - static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6) - { - size_t i, count = sm6->function_count; -@@ -1838,6 +2150,258 @@ static struct sm6_block *sm6_block_create() - return block; - } - -+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) -+{ -+ 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]); -+ -+ 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); -+ 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); -+ return; -+ } -+ -+ value = operands[3]; -+ if (!sm6_value_is_register(value)) -+ { -+ WARN("Source value is not a register.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Expected store operation source to be a register."); -+ return; -+ } -+ -+ shader_instruction_init(ins, VKD3DSIH_MOV); -+ -+ if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) -+ return; -+ dst_param_init_scalar(dst_param, column_index); -+ dst_param->reg = sm6->output_params[row_index].reg; -+ if (e->register_count > 1) -+ register_address_init(&dst_param->reg, operands[1], 0, sm6); -+ -+ if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) -+ src_param_init_from_value(src_param, value); -+} -+ -+struct sm6_dx_opcode_info -+{ -+ const char ret_type; -+ const char *operand_info; -+ void (*handler)(struct sm6_parser *, struct sm6_block *, enum dx_intrinsic_opcode, -+ const struct sm6_value **, struct vkd3d_shader_instruction *); -+}; -+ -+/* -+ 8 -> int8 -+ i -> int32 -+ v -> void -+ o -> overloaded -+ */ -+static const struct sm6_dx_opcode_info sm6_dx_op_table[] = -+{ -+ [DX_STORE_OUTPUT ] = {'v', "ii8o", sm6_parser_emit_dx_store_output}, -+}; -+ -+static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_type *type, char info_type) -+{ -+ switch (info_type) -+ { -+ case 0: -+ FIXME("Invalid operand count.\n"); -+ return false; -+ case '8': -+ return sm6_type_is_i8(type); -+ case 'i': -+ return sm6_type_is_i32(type); -+ case 'v': -+ return !type; -+ case 'o': -+ /* TODO: some type checking may be possible */ -+ return true; -+ default: -+ FIXME("Unhandled operand code '%c'.\n", info_type); -+ return false; -+ } -+} -+ -+static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const char *name, -+ const struct sm6_value **operands, unsigned int operand_count, struct sm6_value *dst) -+{ -+ const struct sm6_dx_opcode_info *info; -+ unsigned int i; -+ -+ info = &sm6_dx_op_table[op]; -+ -+ if (!sm6_parser_validate_operand_type(sm6, dst->type, info->ret_type)) -+ { -+ 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 -+ * a data type for the SSA result. */ -+ } -+ -+ for (i = 0; i < operand_count; ++i) -+ { -+ const struct sm6_value *value = operands[i]; -+ if (!sm6_value_is_register(value) || !sm6_parser_validate_operand_type(sm6, value->type, info->operand_info[i])) -+ { -+ 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, -+ "Operand %u for call to dx intrinsic function '%s' is invalid.", i + 1, name); -+ return false; -+ } -+ } -+ if (info->operand_info[operand_count]) -+ { -+ WARN("Missing operands for dx intrinsic id %u, '%s'.\n", op, name); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, -+ "Call to dx intrinsic function '%s' has missing operands.", name); -+ return false; -+ } -+ -+ return true; -+} -+ -+static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, -+ struct sm6_value *dst) -+{ -+ const struct sm6_type *type; -+ -+ ins->handler_idx = VKD3DSIH_NOP; -+ -+ if (!dst->type) -+ return; -+ -+ type = sm6_type_get_scalar_type(dst->type, 0); -+ shader_register_init(&dst->u.reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0); -+ /* dst->is_undefined is not set here because it flags only explicitly undefined values. */ -+} -+ -+static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, struct sm6_block *code_block, enum dx_intrinsic_opcode op, -+ const char *name, const struct sm6_value **operands, unsigned int operand_count, -+ struct vkd3d_shader_instruction *ins, struct sm6_value *dst) -+{ -+ if (op >= ARRAY_SIZE(sm6_dx_op_table) || !sm6_dx_op_table[op].operand_info) -+ { -+ FIXME("Unhandled dx intrinsic function id %u, '%s'.\n", op, name); -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC, -+ "Call to intrinsic function %s is unhandled.", name); -+ sm6_parser_emit_unhandled(sm6, ins, dst); -+ return; -+ } -+ -+ if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst)) -+ sm6_dx_op_table[op].handler(sm6, code_block, op, operands, ins); -+ else -+ sm6_parser_emit_unhandled(sm6, ins, dst); -+} -+ -+static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record, -+ struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) -+{ -+ const struct sm6_value *operands[DXIL_OP_MAX_OPERANDS]; -+ const struct sm6_value *fn_value, *op_value; -+ unsigned int i = 1, j, operand_count; -+ const struct sm6_type *type = NULL; -+ uint64_t call_conv; -+ -+ if (!dxil_record_validate_operand_min_count(record, 2, sm6)) -+ return; -+ -+ /* TODO: load the 1-based attributes index from record->operands[0] and validate against attribute count. */ -+ -+ if ((call_conv = record->operands[i++]) & CALL_CONV_FLAG_EXPLICIT_TYPE) -+ type = sm6_parser_get_type(sm6, record->operands[i++]); -+ if (call_conv &= ~CALL_CONV_FLAG_EXPLICIT_TYPE) -+ WARN("Ignoring calling convention %#"PRIx64".\n", call_conv); -+ -+ if (!(fn_value = sm6_parser_get_value_by_ref(sm6, record, NULL, &i))) -+ return; -+ if (!sm6_value_is_function_dcl(fn_value)) -+ { -+ WARN("Function target value is not a function declaration.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Function call target value is not a function declaration."); -+ return; -+ } -+ -+ if (type && type != fn_value->type->u.pointer.type) -+ WARN("Explicit call type does not match function type.\n"); -+ type = fn_value->type->u.pointer.type; -+ -+ if (!sm6_type_is_void(type->u.function->ret_type)) -+ dst->type = type->u.function->ret_type; -+ -+ operand_count = type->u.function->param_count; -+ if (operand_count > ARRAY_SIZE(operands)) -+ { -+ WARN("Ignoring %zu operands.\n", operand_count - ARRAY_SIZE(operands)); -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, -+ "Ignoring %zu operands for function call.", operand_count - ARRAY_SIZE(operands)); -+ operand_count = ARRAY_SIZE(operands); -+ } -+ -+ for (j = 0; j < operand_count; ++j) -+ { -+ if (!(operands[j] = sm6_parser_get_value_by_ref(sm6, record, type->u.function->param_types[j], &i))) -+ return; -+ } -+ if ((j = record->operand_count - i)) -+ { -+ WARN("Ignoring %u operands beyond the function parameter list.\n", j); -+ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, -+ "Ignoring %u function call operands beyond the parameter list.", j); -+ } -+ -+ if (!fn_value->u.function.is_prototype) -+ { -+ FIXME("Unhandled call to local function.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Call to a local function is unsupported."); -+ return; -+ } -+ if (!sm6_value_is_dx_intrinsic_dcl(fn_value)) -+ WARN("External function is not a dx intrinsic.\n"); -+ -+ if (!operand_count) -+ { -+ WARN("Missing dx intrinsic function id.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, -+ "The id for a dx intrinsic function is missing."); -+ return; -+ } -+ -+ op_value = operands[0]; -+ if (!sm6_value_is_constant(op_value) || !sm6_type_is_integer(op_value->type)) -+ { -+ WARN("dx intrinsic function id is not a constant int.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Expected a constant integer dx intrinsic function id."); -+ return; -+ } -+ sm6_parser_decode_dx_op(sm6, code_block, register_get_uint_value(&op_value->u.reg), -+ fn_value->u.function.name, &operands[1], operand_count - 1, ins, dst); -+} -+ - 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) - { -@@ -1855,15 +2419,10 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - { - struct vkd3d_shader_instruction *ins; - const struct dxil_record *record; -+ bool ret_found, is_terminator; - struct sm6_block *code_block; - struct sm6_value *dst; - size_t i, block_idx; -- bool ret_found; -- enum -- { -- RESULT_VALUE, -- RESULT_TERMINATE, -- } result_type; - - if (sm6->function_count) - { -@@ -1907,10 +2466,20 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - } - code_block = function->blocks[0]; - -+ sm6->cur_max_value = function->value_count; -+ - for (i = 1, block_idx = 0, ret_found = false; i < block->record_count; ++i) - { - sm6->p.location.column = i; - -+ if (!code_block) -+ { -+ WARN("Invalid block count %zu.\n", function->block_count); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, -+ "Invalid block count %zu.", function->block_count); -+ return VKD3D_ERROR_INVALID_SHADER; -+ } -+ - /* block->record_count - 1 is the instruction count, but some instructions - * can emit >1 IR instruction, so extra may be used. */ - if (!vkd3d_array_reserve((void **)&code_block->instructions, &code_block->instruction_capacity, -@@ -1926,14 +2495,17 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - dst = sm6_parser_get_current_value(sm6); - dst->type = NULL; - dst->value_type = VALUE_TYPE_REG; -- result_type = RESULT_VALUE; -+ is_terminator = false; - - record = block->records[i]; - switch (record->code) - { -+ case FUNC_CODE_INST_CALL: -+ sm6_parser_emit_call(sm6, record, code_block, ins, dst); -+ break; - case FUNC_CODE_INST_RET: - sm6_parser_emit_ret(sm6, record, code_block, ins); -- result_type = RESULT_TERMINATE; -+ is_terminator = true; - ret_found = true; - break; - default: -@@ -1941,7 +2513,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - return VKD3D_ERROR_INVALID_SHADER; - } - -- if (result_type == RESULT_TERMINATE) -+ if (sm6->p.failed) -+ 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; -@@ -1950,6 +2526,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const - code_block->instruction_count += ins->handler_idx != VKD3DSIH_NOP; - else - assert(ins->handler_idx == VKD3DSIH_NOP); -+ - sm6->value_count += !!dst->type; - } - -@@ -1996,6 +2573,8 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st - switch (block->id) - { - case CONSTANTS_BLOCK: -+ function = &sm6->functions[sm6->function_count]; -+ sm6->cur_max_value = function->value_count; - return sm6_parser_constants_init(sm6, block); - - case FUNCTION_BLOCK: -@@ -2103,6 +2682,7 @@ static const struct vkd3d_shader_parser_ops sm6_parser_ops = - static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t *byte_code, size_t byte_code_size, - const char *source_name, struct vkd3d_shader_message_context *message_context) - { -+ const struct shader_signature *output_signature = &sm6->p.shader_desc.output_signature; - const struct vkd3d_shader_location location = {.source_name = source_name}; - uint32_t version_token, dxil_version, token_count, magic; - unsigned int chunk_offset, chunk_size; -@@ -2258,6 +2838,14 @@ 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))) -+ { -+ ERR("Failed to allocate output parameters.\n"); -+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -+ "Out of memory allocating output parameters."); -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ } -+ - function_count = dxil_block_compute_function_count(&sm6->root_block); - if (!(sm6->functions = vkd3d_calloc(function_count, sizeof(*sm6->functions)))) - { -@@ -2288,6 +2876,8 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t - return ret; - } - -+ sm6_parser_init_output_signature(sm6, output_signature); -+ - if ((ret = sm6_parser_module_init(sm6, &sm6->root_block, 0)) < 0) - { - if (ret == VKD3D_ERROR_OUT_OF_MEMORY) -@@ -2296,11 +2886,17 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, const uint32_t - else if (ret == VKD3D_ERROR_INVALID_SHADER) - vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, - "DXIL module is invalid."); -- else -- vkd3d_unreachable(); - return ret; - } - -+ if (!sm6_parser_require_space(sm6, output_signature->element_count)) -+ { -+ vkd3d_shader_error(message_context, &location, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -+ "Out of memory emitting shader signature declarations."); -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ } -+ sm6_parser_emit_output_signature(sm6, output_signature); -+ - for (i = 0; i < sm6->function_count; ++i) - { - if (!sm6_block_emit_instructions(sm6->functions[i].blocks[0], sm6)) -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 8b706e1e667..b8cf6813f67 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -72,6 +72,27 @@ void hlsl_fixme(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, c - ctx->result = VKD3D_ERROR_NOT_IMPLEMENTED; - } - -+char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) -+{ -+ struct vkd3d_string_buffer *string; -+ va_list args; -+ char *ret; -+ -+ if (!(string = hlsl_get_string_buffer(ctx))) -+ return NULL; -+ va_start(args, fmt); -+ if (vkd3d_string_buffer_vprintf(string, fmt, args) < 0) -+ { -+ va_end(args); -+ hlsl_release_string_buffer(ctx, string); -+ return NULL; -+ } -+ va_end(args); -+ ret = hlsl_strdup(ctx, string->buffer); -+ hlsl_release_string_buffer(ctx, string); -+ return ret; -+} -+ - bool hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl, bool local_var) - { - struct hlsl_scope *scope = ctx->cur_scope; -@@ -1039,11 +1060,10 @@ struct hlsl_ir_var *hlsl_new_synthetic_var(struct hlsl_ctx *ctx, const char *tem - { - struct vkd3d_string_buffer *string; - struct hlsl_ir_var *var; -- static LONG counter; - - if (!(string = hlsl_get_string_buffer(ctx))) - return NULL; -- vkd3d_string_buffer_printf(string, "<%s-%u>", template, InterlockedIncrement(&counter)); -+ vkd3d_string_buffer_printf(string, "<%s-%u>", template, ctx->internal_name_counter++); - var = hlsl_new_synthetic_var_named(ctx, string->buffer, type, loc, true); - hlsl_release_string_buffer(ctx, string); - return var; -@@ -2968,6 +2988,16 @@ void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function - struct hlsl_ir_function *func; - struct rb_entry *func_entry; - -+ if (ctx->internal_func_name) -+ { -+ char *internal_name; -+ -+ if (!(internal_name = hlsl_strdup(ctx, ctx->internal_func_name))) -+ return; -+ vkd3d_free(name); -+ name = internal_name; -+ } -+ - func_entry = rb_get(&ctx->functions, name); - if (func_entry) - { -@@ -3499,3 +3529,44 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d - hlsl_ctx_cleanup(&ctx); - return ret; - } -+ -+struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl) -+{ -+ const struct hlsl_ir_function_decl *saved_cur_function = ctx->cur_function; -+ struct vkd3d_shader_code code = {.code = hlsl, .size = strlen(hlsl)}; -+ const char *saved_internal_func_name = ctx->internal_func_name; -+ struct vkd3d_string_buffer *internal_name; -+ struct hlsl_ir_function_decl *func; -+ void *saved_scanner = ctx->scanner; -+ int ret; -+ -+ TRACE("name %s, hlsl %s.\n", debugstr_a(name), debugstr_a(hlsl)); -+ -+ /* The actual name of the function is mangled with a unique prefix, both to -+ * allow defining multiple variants of a function with the same name, and to -+ * avoid polluting the user name space. */ -+ -+ if (!(internal_name = hlsl_get_string_buffer(ctx))) -+ return NULL; -+ vkd3d_string_buffer_printf(internal_name, "<%s-%u>", name, ctx->internal_name_counter++); -+ -+ /* Save and restore everything that matters. -+ * Note that saving the scope stack is hard, and shouldn't be necessary. */ -+ -+ ctx->scanner = NULL; -+ ctx->internal_func_name = internal_name->buffer; -+ ctx->cur_function = NULL; -+ ret = hlsl_lexer_compile(ctx, &code); -+ ctx->scanner = saved_scanner; -+ ctx->internal_func_name = saved_internal_func_name; -+ ctx->cur_function = saved_cur_function; -+ if (ret) -+ { -+ ERR("Failed to compile intrinsic, error %u.\n", ret); -+ hlsl_release_string_buffer(ctx, internal_name); -+ return NULL; -+ } -+ func = hlsl_get_func_decl(ctx, internal_name->buffer); -+ hlsl_release_string_buffer(ctx, internal_name); -+ return func; -+} -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 070fec74326..73b08ee3ea0 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -798,6 +798,9 @@ struct hlsl_ctx - /* Pointer to the current function; changes as the parser reads the code. */ - const struct hlsl_ir_function_decl *cur_function; - -+ /* Counter for generating unique internal variable names. */ -+ unsigned int internal_name_counter; -+ - /* Default matrix majority for matrix types. Can be set by a pragma within the HLSL source. */ - unsigned int matrix_majority; - -@@ -834,6 +837,12 @@ struct hlsl_ctx - * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ - uint32_t thread_count[3]; - -+ /* In some cases we generate opcodes by parsing an HLSL function and then -+ * invoking it. If not NULL, this field is the name of the function that we -+ * are currently parsing, "mangled" with an internal prefix to avoid -+ * polluting the user namespace. */ -+ const char *internal_func_name; -+ - /* Whether the parser is inside a state block (effects' metadata) inside a variable declaration. */ - uint32_t in_state_block : 1; - /* Whether the numthreads() attribute has been provided in the entry-point function. */ -@@ -1069,6 +1078,8 @@ static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) - } - } - -+char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) VKD3D_PRINTF_FUNC(2, 3); -+ - const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); - const char *debug_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type); - const char *debug_hlsl_writemask(unsigned int writemask); -@@ -1258,6 +1269,8 @@ bool hlsl_sm4_register_from_semantic(struct hlsl_ctx *ctx, const struct hlsl_sem - bool output, enum vkd3d_shader_register_type *type, enum vkd3d_sm4_swizzle_type *swizzle_type, bool *has_idx); - int hlsl_sm4_write(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, struct vkd3d_shader_code *out); - -+struct hlsl_ir_function_decl *hlsl_compile_internal_function(struct hlsl_ctx *ctx, const char *name, const char *hlsl); -+ - int hlsl_lexer_compile(struct hlsl_ctx *ctx, const struct vkd3d_shader_code *hlsl); - - #endif -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 43ea4b4d038..161d1ab42c3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -2330,6 +2330,92 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, - return args.decl; - } - -+static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; -+ -+ return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc); -+} -+ -+static bool add_user_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, -+ const struct parse_initializer *args, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_ir_node *call; -+ unsigned int i; -+ -+ assert(args->args_count == func->parameters.count); -+ -+ for (i = 0; i < func->parameters.count; ++i) -+ { -+ struct hlsl_ir_var *param = func->parameters.vars[i]; -+ struct hlsl_ir_node *arg = args->args[i]; -+ -+ if (!hlsl_types_are_equal(arg->data_type, param->data_type)) -+ { -+ struct hlsl_ir_node *cast; -+ -+ if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) -+ return false; -+ args->args[i] = cast; -+ arg = cast; -+ } -+ -+ if (param->storage_modifiers & HLSL_STORAGE_IN) -+ { -+ struct hlsl_ir_node *store; -+ -+ if (!(store = hlsl_new_simple_store(ctx, param, arg))) -+ return false; -+ hlsl_block_add_instr(args->instrs, store); -+ } -+ } -+ -+ if (!(call = hlsl_new_call(ctx, func, loc))) -+ return false; -+ hlsl_block_add_instr(args->instrs, call); -+ -+ for (i = 0; i < func->parameters.count; ++i) -+ { -+ struct hlsl_ir_var *param = func->parameters.vars[i]; -+ struct hlsl_ir_node *arg = args->args[i]; -+ -+ if (param->storage_modifiers & HLSL_STORAGE_OUT) -+ { -+ struct hlsl_ir_load *load; -+ -+ if (arg->data_type->modifiers & HLSL_MODIFIER_CONST) -+ hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, -+ "Output argument to \"%s\" is const.", func->func->name); -+ -+ if (!(load = hlsl_new_var_load(ctx, param, &arg->loc))) -+ return false; -+ hlsl_block_add_instr(args->instrs, &load->node); -+ -+ if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) -+ return false; -+ } -+ } -+ -+ if (func->return_var) -+ { -+ struct hlsl_ir_load *load; -+ -+ if (!(load = hlsl_new_var_load(ctx, func->return_var, loc))) -+ return false; -+ hlsl_block_add_instr(args->instrs, &load->node); -+ } -+ else -+ { -+ struct hlsl_ir_node *expr; -+ -+ if (!(expr = hlsl_new_void_expr(ctx, loc))) -+ return false; -+ hlsl_block_add_instr(args->instrs, expr); -+ } -+ -+ return true; -+} -+ - static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, - const struct parse_initializer *params, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) - { -@@ -2948,14 +3034,17 @@ static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, - static bool intrinsic_lit(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -- struct hlsl_ir_node *n_l_neg, *n_h_neg, *specular_or, *specular_pow, *load; -- struct hlsl_ir_node *n_l, *n_h, *m, *diffuse, *zero, *store, *init; -- struct hlsl_constant_value init_value; -- struct hlsl_ir_load *var_load; -- struct hlsl_deref var_deref; -- struct hlsl_type *ret_type; -- struct hlsl_ir_var *var; -- struct hlsl_block block; -+ struct hlsl_ir_function_decl *func; -+ -+ static const char body[] = -+ "float4 lit(float n_l, float n_h, float m)\n" -+ "{\n" -+ " float4 ret;\n" -+ " ret.xw = 1.0;\n" -+ " ret.y = max(n_l, 0);\n" -+ " ret.z = (n_l < 0 || n_h < 0) ? 0 : pow(n_h, m);\n" -+ " return ret;\n" -+ "}"; - - if (params->args[0]->data_type->class != HLSL_CLASS_SCALAR - || params->args[1]->data_type->class != HLSL_CLASS_SCALAR -@@ -2965,70 +3054,10 @@ static bool intrinsic_lit(struct hlsl_ctx *ctx, - return false; - } - -- if (!(n_l = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) -- return false; -- -- if (!(n_h = intrinsic_float_convert_arg(ctx, params, params->args[1], loc))) -- return false; -- -- if (!(m = intrinsic_float_convert_arg(ctx, params, params->args[2], loc))) -- return false; -- -- ret_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); -- -- if (!(var = hlsl_new_synthetic_var(ctx, "lit", ret_type, loc))) -- return false; -- hlsl_init_simple_deref_from_var(&var_deref, var); -- -- init_value.u[0].f = 1.0f; -- init_value.u[1].f = 0.0f; -- init_value.u[2].f = 0.0f; -- init_value.u[3].f = 1.0f; -- if (!(init = hlsl_new_constant(ctx, ret_type, &init_value, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, init); -- -- if (!(store = hlsl_new_simple_store(ctx, var, init))) -- return false; -- hlsl_block_add_instr(params->instrs, store); -- -- if (!(zero = hlsl_new_float_constant(ctx, 0.0f, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, zero); -- -- /* Diffuse component. */ -- if (!(diffuse = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MAX, n_l, zero, loc))) -+ if (!(func = hlsl_compile_internal_function(ctx, "lit", body))) - return false; - -- if (!hlsl_new_store_component(ctx, &block, &var_deref, 1, diffuse)) -- return false; -- hlsl_block_add_block(params->instrs, &block); -- -- /* Specular component. */ -- if (!(n_h_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_h, zero, loc))) -- return false; -- -- if (!(n_l_neg = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, n_l, zero, loc))) -- return false; -- -- if (!(specular_or = add_binary_logical_expr(ctx, params->instrs, HLSL_OP2_LOGIC_OR, n_l_neg, n_h_neg, loc))) -- return false; -- -- if (!(specular_pow = add_pow_expr(ctx, params->instrs, n_h, m, loc))) -- return false; -- -- if (!(load = hlsl_add_conditional(ctx, params->instrs, specular_or, zero, specular_pow))) -- return false; -- -- if (!hlsl_new_store_component(ctx, &block, &var_deref, 2, load)) -- return false; -- hlsl_block_add_block(params->instrs, &block); -- -- if (!(var_load = hlsl_new_var_load(ctx, var, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, &var_load->node); -- -- return true; -+ return add_user_call(ctx, func, params, loc); - } - - static bool intrinsic_log(struct hlsl_ctx *ctx, -@@ -3336,58 +3365,29 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, - static bool intrinsic_smoothstep(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -- struct hlsl_ir_node *min_arg, *max_arg, *x_arg, *p, *p_num, *p_denom, *res, *one, *minus_two, *three; -- -- if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) -- return false; -- -- min_arg = params->args[0]; -- max_arg = params->args[1]; -- x_arg = params->args[2]; -- -- if (!(min_arg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, min_arg, loc))) -- return false; -- -- if (!(p_num = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, x_arg, min_arg, loc))) -- return false; -- -- if (!(p_denom = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, max_arg, min_arg, loc))) -- return false; -- -- if (!(one = hlsl_new_float_constant(ctx, 1.0, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, one); -- -- if (!(p_denom = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, one, p_denom, loc))) -- return false; -- -- if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p_num, p_denom, loc))) -- return false; -- -- if (!(p = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, p, loc))) -- return false; -- -- if (!(minus_two = hlsl_new_float_constant(ctx, -2.0, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, minus_two); -- -- if (!(three = hlsl_new_float_constant(ctx, 3.0, loc))) -- return false; -- hlsl_block_add_instr(params->instrs, three); -+ struct hlsl_ir_function_decl *func; -+ struct hlsl_type *type; -+ char *body; - -- if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, minus_two, p, loc))) -- return false; -+ static const char template[] = -+ "%s smoothstep(%s low, %s high, %s x)\n" -+ "{\n" -+ " %s p = saturate((x - low) / (high - low));\n" -+ " return (p * p) * (3 - 2 * p);\n" -+ "}"; - -- if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, three, res, loc))) -+ if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc))) - return false; -+ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->dimx, type->dimy); - -- if (!(p = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p, p, loc))) -+ if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name, type->name, type->name))) - return false; -- -- if (!(res = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, p, res, loc))) -+ func = hlsl_compile_internal_function(ctx, "smoothstep", body); -+ vkd3d_free(body); -+ if (!func) - return false; - -- return true; -+ return add_user_call(ctx, func, params, loc); - } - - static bool intrinsic_sqrt(struct hlsl_ctx *ctx, -@@ -3478,6 +3478,12 @@ static bool intrinsic_tex3D(struct hlsl_ctx *ctx, - return intrinsic_tex(ctx, params, loc, "tex3D", HLSL_SAMPLER_DIM_3D); - } - -+static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, -+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE); -+} -+ - static bool intrinsic_transpose(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -3648,6 +3654,7 @@ intrinsic_functions[] = - {"step", 2, true, intrinsic_step}, - {"tex2D", -1, false, intrinsic_tex2D}, - {"tex3D", -1, false, intrinsic_tex3D}, -+ {"texCUBE", -1, false, intrinsic_texCUBE}, - {"transpose", 1, true, intrinsic_transpose}, - {"trunc", 1, true, intrinsic_trunc}, - }; -@@ -3659,13 +3666,6 @@ static int intrinsic_function_name_compare(const void *a, const void *b) - return strcmp(a, func->name); - } - --static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) --{ -- struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; -- -- return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc); --} -- - static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name, - struct parse_initializer *args, const struct vkd3d_shader_location *loc) - { -@@ -3674,78 +3674,8 @@ static struct hlsl_block *add_call(struct hlsl_ctx *ctx, const char *name, - - if ((decl = find_function_call(ctx, name, args, loc))) - { -- struct hlsl_ir_node *call; -- unsigned int i; -- -- assert(args->args_count == decl->parameters.count); -- -- for (i = 0; i < decl->parameters.count; ++i) -- { -- struct hlsl_ir_var *param = decl->parameters.vars[i]; -- struct hlsl_ir_node *arg = args->args[i]; -- -- if (!hlsl_types_are_equal(arg->data_type, param->data_type)) -- { -- struct hlsl_ir_node *cast; -- -- if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) -- goto fail; -- args->args[i] = cast; -- arg = cast; -- } -- -- if (param->storage_modifiers & HLSL_STORAGE_IN) -- { -- struct hlsl_ir_node *store; -- -- if (!(store = hlsl_new_simple_store(ctx, param, arg))) -- goto fail; -- hlsl_block_add_instr(args->instrs, store); -- } -- } -- -- if (!(call = hlsl_new_call(ctx, decl, loc))) -+ if (!add_user_call(ctx, decl, args, loc)) - goto fail; -- hlsl_block_add_instr(args->instrs, call); -- -- for (i = 0; i < decl->parameters.count; ++i) -- { -- struct hlsl_ir_var *param = decl->parameters.vars[i]; -- struct hlsl_ir_node *arg = args->args[i]; -- -- if (param->storage_modifiers & HLSL_STORAGE_OUT) -- { -- struct hlsl_ir_load *load; -- -- if (arg->data_type->modifiers & HLSL_MODIFIER_CONST) -- hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, -- "Output argument to \"%s\" is const.", decl->func->name); -- -- if (!(load = hlsl_new_var_load(ctx, param, &arg->loc))) -- goto fail; -- hlsl_block_add_instr(args->instrs, &load->node); -- -- if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node)) -- goto fail; -- } -- } -- -- if (decl->return_var) -- { -- struct hlsl_ir_load *load; -- -- if (!(load = hlsl_new_var_load(ctx, decl->return_var, loc))) -- goto fail; -- hlsl_block_add_instr(args->instrs, &load->node); -- } -- else -- { -- struct hlsl_ir_node *expr; -- -- if (!(expr = hlsl_new_void_expr(ctx, loc))) -- goto fail; -- hlsl_block_add_instr(args->instrs, expr); -- } - } - else if ((intrinsic = bsearch(name, intrinsic_functions, ARRAY_SIZE(intrinsic_functions), - sizeof(*intrinsic_functions), intrinsic_function_name_compare))) -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index bae8e5f9a5f..710d2908166 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -163,10 +163,10 @@ static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der - * work. */ - static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_var *temp) - { -- struct vkd3d_string_buffer *name; - struct hlsl_ir_var *uniform; - struct hlsl_ir_node *store; - struct hlsl_ir_load *load; -+ char *new_name; - - /* Use the synthetic name for the temp, rather than the uniform, so that we - * can write the uniform name into the shader reflection data. */ -@@ -180,11 +180,9 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - uniform->is_param = temp->is_param; - uniform->buffer = temp->buffer; - -- if (!(name = hlsl_get_string_buffer(ctx))) -+ if (!(new_name = hlsl_sprintf_alloc(ctx, "", temp->name))) - return; -- vkd3d_string_buffer_printf(name, "", temp->name); -- temp->name = hlsl_strdup(ctx, name->buffer); -- hlsl_release_string_buffer(ctx, name); -+ temp->name = new_name; - - if (!(load = hlsl_new_var_load(ctx, uniform, &temp->loc))) - return; -@@ -235,16 +233,15 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir - uint32_t index, bool output, const struct vkd3d_shader_location *loc) - { - struct hlsl_semantic new_semantic; -- struct vkd3d_string_buffer *name; - struct hlsl_ir_var *ext_var; -+ char *new_name; - -- if (!(name = hlsl_get_string_buffer(ctx))) -+ if (!(new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", output ? "output" : "input", semantic->name, index))) - return NULL; -- vkd3d_string_buffer_printf(name, "<%s-%s%u>", output ? "output" : "input", semantic->name, index); - - LIST_FOR_EACH_ENTRY(ext_var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { -- if (!ascii_strcasecmp(ext_var->name, name->buffer)) -+ if (!ascii_strcasecmp(ext_var->name, new_name)) - { - if (output) - { -@@ -271,25 +268,23 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir - } - } - -- hlsl_release_string_buffer(ctx, name); -+ vkd3d_free(new_name); - return ext_var; - } - } - - if (!(new_semantic.name = hlsl_strdup(ctx, semantic->name))) - { -- hlsl_release_string_buffer(ctx, name); -+ vkd3d_free(new_name); - return NULL; - } - new_semantic.index = index; -- if (!(ext_var = hlsl_new_var(ctx, hlsl_strdup(ctx, name->buffer), type, loc, &new_semantic, -- modifiers, NULL))) -+ if (!(ext_var = hlsl_new_var(ctx, new_name, type, loc, &new_semantic, modifiers, NULL))) - { -- hlsl_release_string_buffer(ctx, name); -+ vkd3d_free(new_name); - hlsl_cleanup_semantic(&new_semantic); - return NULL; - } -- hlsl_release_string_buffer(ctx, name); - if (output) - ext_var->is_output_semantic = 1; - else -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 705905f7888..6d7c89653e3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -296,7 +296,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali - return VKD3D_OK; - } - --static void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, -+void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count) - { - reg->type = reg_type; -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 9b3084538ba..f93960d6d54 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -4792,13 +4792,16 @@ static bool is_dual_source_blending(const struct spirv_compiler *compiler) - - static void calculate_clip_or_cull_distance_mask(const struct signature_element *e, uint32_t *mask) - { -+ unsigned int write_mask; -+ - if (e->semantic_index >= sizeof(*mask) * CHAR_BIT / VKD3D_VEC4_SIZE) - { - FIXME("Invalid semantic index %u for clip/cull distance.\n", e->semantic_index); - return; - } - -- *mask |= (e->mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); -+ write_mask = e->mask >> vkd3d_write_mask_get_component_idx(e->mask); -+ *mask |= (write_mask & VKD3DSP_WRITEMASK_ALL) << (VKD3D_VEC4_SIZE * e->semantic_index); - } - - /* Emits arrayed SPIR-V built-in variables. */ -@@ -4962,7 +4965,6 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - component_type = builtin->component_type; - if (!builtin->spirv_array_size) - output_component_count = builtin->component_count; -- component_idx = 0; - } - else - { -@@ -4976,14 +4978,9 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, - || needs_private_io_variable(builtin)) - { - use_private_variable = true; -- reg_write_mask = write_mask; -- } -- else -- { -- component_idx = vkd3d_write_mask_get_component_idx(write_mask); -- reg_write_mask = write_mask >> component_idx; - } - -+ reg_write_mask = write_mask >> component_idx; - vkd3d_symbol_make_register(®_symbol, reg); - - if (rb_get(&compiler->symbol_table, ®_symbol)) -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 2bc8613f2ef..a70894a160d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -1771,9 +1771,6 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, - { - void *params; - -- if (!count) -- return NULL; -- - if (count > allocator->count - allocator->index) - { - struct vkd3d_shader_param_node *next = shader_param_allocator_node_create(allocator); -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 84614a4eb79..eab1c730ae9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -173,12 +173,14 @@ enum vkd3d_shader_error - VKD3D_SHADER_ERROR_DXIL_INVALID_FUNCTION_DCL = 8009, - VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID = 8010, - VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011, -+ VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND = 8012, - - VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, - VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, - VKD3D_SHADER_WARNING_DXIL_INVALID_BLOCK_LENGTH = 8302, - VKD3D_SHADER_WARNING_DXIL_INVALID_MODULE_LENGTH = 8303, - VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS = 8304, -+ VKD3D_SHADER_WARNING_DXIL_UNHANDLED_INTRINSIC = 8305, - - VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, - }; -@@ -556,6 +558,11 @@ enum vkd3d_data_type - VKD3D_DATA_UINT8, - }; - -+static inline bool data_type_is_integer(enum vkd3d_data_type data_type) -+{ -+ return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT; -+} -+ - enum vkd3d_immconst_type - { - VKD3D_IMMCONST_SCALAR, -@@ -734,6 +741,9 @@ struct vkd3d_shader_register - } u; - }; - -+void shader_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, -+ enum vkd3d_data_type data_type, unsigned int idx_count); -+ - struct vkd3d_shader_dst_param - { - struct vkd3d_shader_register reg; --- -2.40.1 - diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-ee28861837c825818ace2e1e50825ade87a.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-ee28861837c825818ace2e1e50825ade87a.patch deleted file mode 100644 index b94ea1b4..00000000 --- a/patches/vkd3d-latest/0006-Updated-vkd3d-to-ee28861837c825818ace2e1e50825ade87a.patch +++ /dev/null @@ -1,432 +0,0 @@ -From d781aee2d58e59b61a34fefef0a4ce4b527a6c99 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Sat, 16 Sep 2023 07:19:25 +1000 -Subject: [PATCH] Updated vkd3d to ee28861837c825818ace2e1e50825ade87a9c723. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 4 - - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 3 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 9 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 56 +++++++++- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 100 ++++++++++++++++++ - libs/vkd3d/libs/vkd3d-shader/spirv.c | 10 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 25 +++++ - .../libs/vkd3d-shader/vkd3d_shader_main.c | 3 +- - 9 files changed, 197 insertions(+), 15 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index d72402eb250..f0c386f1b3a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -714,7 +714,7 @@ static void shader_dump_decl_usage(struct vkd3d_d3d_asm_compiler *compiler, - break; - - case VKD3D_DECL_USAGE_TEXCOORD: -- shader_addline(buffer, "texture%u", semantic->usage_idx); -+ shader_addline(buffer, "texcoord%u", semantic->usage_idx); - break; - - case VKD3D_DECL_USAGE_TANGENT: -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 2b02d51f59a..d5104ae9b79 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -1982,10 +1982,6 @@ static void write_sm1_sampler_dcl(struct hlsl_ctx *ctx, struct vkd3d_bytecode_bu - - switch (sampler_dim) - { -- case HLSL_SAMPLER_DIM_1D: -- res_type = VKD3D_SM1_RESOURCE_TEXTURE_1D; -- break; -- - case HLSL_SAMPLER_DIM_2D: - res_type = VKD3D_SM1_RESOURCE_TEXTURE_2D; - break; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index b8cf6813f67..5fe9047bf25 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -2486,7 +2486,8 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) - [HLSL_OP2_RSHIFT] = ">>", - - [HLSL_OP3_DP2ADD] = "dp2add", -- [HLSL_OP3_LERP] = "lerp", -+ [HLSL_OP3_MOVC] = "movc", -+ [HLSL_OP3_TERNARY] = "ternary", - }; - - return op_names[op]; -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index 73b08ee3ea0..2cde5d58eba 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -550,8 +550,15 @@ enum hlsl_ir_expr_op - HLSL_OP2_NEQUAL, - HLSL_OP2_RSHIFT, - -+ /* DP2ADD(a, b, c) computes the scalar product of a.xy and b.xy, -+ * then adds c. */ - HLSL_OP3_DP2ADD, -- HLSL_OP3_LERP, -+ /* MOVC(a, b, c) returns c if a is bitwise zero and b otherwise. -+ * TERNARY(a, b, c) returns c if a == 0 and b otherwise. -+ * They differ for floating point numbers, because -+ * -0.0 == 0.0, but it is not bitwise zero. */ -+ HLSL_OP3_MOVC, -+ HLSL_OP3_TERNARY, - }; - - #define HLSL_MAX_OPERANDS 3 -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 161d1ab42c3..fb6d485ea69 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -2913,6 +2913,7 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer - const struct vkd3d_shader_location *loc) - { - struct hlsl_ir_node *x, *y, *div, *abs, *frac, *neg_frac, *ge, *select, *zero; -+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; - static const struct hlsl_constant_value zero_value; - - if (!(x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) -@@ -2940,7 +2941,10 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer - if (!(ge = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_GEQUAL, div, zero, loc))) - return false; - -- if (!(select = hlsl_add_conditional(ctx, params->instrs, ge, frac, neg_frac))) -+ operands[0] = ge; -+ operands[1] = frac; -+ operands[2] = neg_frac; -+ if (!(select = add_expr(ctx, params->instrs, HLSL_OP3_TERNARY, operands, x->data_type, loc))) - return false; - - return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, select, y, loc); -@@ -3453,7 +3457,42 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * - - if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, hlsl_sampler_dim_count(dim)), loc))) -- coords = params->args[1]; -+ { -+ return false; -+ } -+ -+ /* tex1D() functions never produce 1D resource declarations. For newer profiles half offset -+ is used for the second coordinate, while older ones appear to replicate first coordinate.*/ -+ if (dim == HLSL_SAMPLER_DIM_1D) -+ { -+ struct hlsl_ir_load *load; -+ struct hlsl_ir_node *half; -+ struct hlsl_ir_var *var; -+ unsigned int idx = 0; -+ -+ if (!(var = hlsl_new_synthetic_var(ctx, "coords", hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 2), loc))) -+ return false; -+ -+ initialize_var_components(ctx, params->instrs, var, &idx, coords); -+ if (shader_profile_version_ge(ctx, 4, 0)) -+ { -+ if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc))) -+ return false; -+ hlsl_block_add_instr(params->instrs, half); -+ -+ initialize_var_components(ctx, params->instrs, var, &idx, half); -+ } -+ else -+ initialize_var_components(ctx, params->instrs, var, &idx, coords); -+ -+ if (!(load = hlsl_new_var_load(ctx, var, loc))) -+ return false; -+ hlsl_block_add_instr(params->instrs, &load->node); -+ -+ coords = &load->node; -+ -+ dim = HLSL_SAMPLER_DIM_2D; -+ } - - load_params.coords = coords; - load_params.resource = params->args[0]; -@@ -3466,6 +3505,12 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * - return true; - } - -+static bool intrinsic_tex1D(struct hlsl_ctx *ctx, -+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ return intrinsic_tex(ctx, params, loc, "tex1D", HLSL_SAMPLER_DIM_1D); -+} -+ - static bool intrinsic_tex2D(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -3652,6 +3697,7 @@ intrinsic_functions[] = - {"smoothstep", 3, true, intrinsic_smoothstep}, - {"sqrt", 1, true, intrinsic_sqrt}, - {"step", 2, true, intrinsic_step}, -+ {"tex1D", -1, false, intrinsic_tex1D}, - {"tex2D", -1, false, intrinsic_tex2D}, - {"tex3D", -1, false, intrinsic_tex3D}, - {"texCUBE", -1, false, intrinsic_texCUBE}, -@@ -6555,6 +6601,7 @@ conditional_expr: - struct hlsl_ir_node *cond = node_from_block($1); - struct hlsl_ir_node *first = node_from_block($3); - struct hlsl_ir_node *second = node_from_block($5); -+ struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = { 0 }; - struct hlsl_type *common_type; - - hlsl_block_add_block($1, $3); -@@ -6571,7 +6618,10 @@ conditional_expr: - if (!(second = add_implicit_conversion(ctx, $1, second, common_type, &@5))) - YYABORT; - -- if (!hlsl_add_conditional(ctx, $1, cond, first, second)) -+ args[0] = cond; -+ args[1] = first; -+ args[2] = second; -+ if (!add_expr(ctx, $1, HLSL_OP3_TERNARY, args, common_type, &@1)) - YYABORT; - $$ = $1; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 710d2908166..be024842164 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -934,6 +934,55 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h - return &coords_load->node; - } - -+/* hlsl_ir_swizzle nodes that directly point to a matrix value are only a parse-time construct that -+ * represents matrix swizzles (e.g. mat._m01_m23) before we know if they will be used in the lhs of -+ * an assignment or as a value made from different components of the matrix. The former cases should -+ * have already been split into several separate assignments, but the latter are lowered by this -+ * pass. */ -+static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -+{ -+ struct hlsl_ir_swizzle *swizzle; -+ struct hlsl_ir_load *var_load; -+ struct hlsl_deref var_deref; -+ struct hlsl_type *matrix_type; -+ struct hlsl_ir_var *var; -+ unsigned int x, y, k, i; -+ -+ if (instr->type != HLSL_IR_SWIZZLE) -+ return false; -+ swizzle = hlsl_ir_swizzle(instr); -+ matrix_type = swizzle->val.node->data_type; -+ if (matrix_type->class != HLSL_CLASS_MATRIX) -+ return false; -+ -+ if (!(var = hlsl_new_synthetic_var(ctx, "matrix-swizzle", instr->data_type, &instr->loc))) -+ return false; -+ hlsl_init_simple_deref_from_var(&var_deref, var); -+ -+ for (i = 0; i < instr->data_type->dimx; ++i) -+ { -+ struct hlsl_block store_block; -+ struct hlsl_ir_node *load; -+ -+ y = (swizzle->swizzle >> (8 * i + 4)) & 0xf; -+ x = (swizzle->swizzle >> 8 * i) & 0xf; -+ k = y * matrix_type->dimx + x; -+ -+ if (!(load = hlsl_add_load_component(ctx, block, swizzle->val.node, k, &instr->loc))) -+ return false; -+ -+ if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, load)) -+ return false; -+ hlsl_block_add_block(block, &store_block); -+ } -+ -+ if (!(var_load = hlsl_new_var_load(ctx, var, &instr->loc))) -+ return false; -+ hlsl_block_add_instr(block, &var_load->node); -+ -+ return true; -+} -+ - /* hlsl_ir_index nodes are a parse-time construct used to represent array indexing and struct - * record access before knowing if they will be used in the lhs of an assignment --in which case - * they are lowered into a deref-- or as the load of an element within a larger value. -@@ -2391,6 +2440,54 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void * - return true; - } - -+/* Use 'movc' for the ternary operator. */ -+static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], *replacement; -+ struct hlsl_ir_node *zero, *cond, *first, *second; -+ struct hlsl_constant_value zero_value = { 0 }; -+ struct hlsl_ir_expr *expr; -+ struct hlsl_type *type; -+ -+ if (instr->type != HLSL_IR_EXPR) -+ return false; -+ -+ expr = hlsl_ir_expr(instr); -+ if (expr->op != HLSL_OP3_TERNARY) -+ return false; -+ -+ cond = expr->operands[0].node; -+ first = expr->operands[1].node; -+ second = expr->operands[2].node; -+ -+ if (cond->data_type->base_type == HLSL_TYPE_FLOAT) -+ { -+ if (!(zero = hlsl_new_constant(ctx, cond->data_type, &zero_value, &instr->loc))) -+ return false; -+ list_add_tail(&instr->entry, &zero->entry); -+ -+ memset(operands, 0, sizeof(operands)); -+ operands[0] = zero; -+ operands[1] = cond; -+ type = cond->data_type; -+ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->dimx, type->dimy); -+ if (!(cond = hlsl_new_expr(ctx, HLSL_OP2_NEQUAL, operands, type, &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &cond->entry); -+ } -+ -+ memset(operands, 0, sizeof(operands)); -+ operands[0] = cond; -+ operands[1] = first; -+ operands[2] = second; -+ if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_MOVC, operands, first->data_type, &instr->loc))) -+ return false; -+ list_add_before(&instr->entry, &replacement->entry); -+ -+ hlsl_replace_node(instr, replacement); -+ return true; -+} -+ - static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) - { - struct hlsl_type *type = instr->data_type, *arg_type; -@@ -4247,6 +4344,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - - while (hlsl_transform_ir(ctx, lower_calls, body, NULL)); - -+ lower_ir(ctx, lower_matrix_swizzles, body); - hlsl_transform_ir(ctx, lower_index_loads, body, NULL); - - LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) -@@ -4349,6 +4447,8 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry - hlsl_transform_ir(ctx, track_object_components_usage, body, NULL); - sort_synthetic_separated_samplers_first(ctx); - -+ if (profile->major_version >= 4) -+ hlsl_transform_ir(ctx, lower_ternary, body, NULL); - if (profile->major_version < 4) - { - hlsl_transform_ir(ctx, lower_division, body, NULL); -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index f93960d6d54..95f6914acb7 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -5564,7 +5564,7 @@ static uint32_t spirv_compiler_build_descriptor_variable(struct spirv_compiler * - } - - static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, -- const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size) -+ const struct vkd3d_shader_register_range *range, unsigned int register_id, unsigned int size_in_bytes) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t vec4_id, array_type_id, length_id, struct_id, var_id; -@@ -5572,6 +5572,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - struct vkd3d_push_constant_buffer_binding *push_cb; - struct vkd3d_descriptor_variable_info var_info; - struct vkd3d_symbol reg_symbol; -+ unsigned int size; - - struct vkd3d_shader_register reg = - { -@@ -5580,18 +5581,19 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - .idx_count = 1, - }; - -+ size = size_in_bytes / (VKD3D_VEC4_SIZE * sizeof(uint32_t)); -+ - if ((push_cb = spirv_compiler_find_push_constant_buffer(compiler, range))) - { - /* Push constant buffers are handled in - * spirv_compiler_emit_push_constant_buffers(). - */ -- unsigned int cb_size_in_bytes = size * VKD3D_VEC4_SIZE * sizeof(uint32_t); - push_cb->reg = reg; - push_cb->size = size; -- if (cb_size_in_bytes > push_cb->pc.size) -+ if (size_in_bytes > push_cb->pc.size) - { - WARN("Constant buffer size %u exceeds push constant size %u.\n", -- cb_size_in_bytes, push_cb->pc.size); -+ size_in_bytes, push_cb->pc.size); - } - return; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index 7949be150bf..045fb6c5f64 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -4341,6 +4341,26 @@ static void write_sm4_binary_op_with_two_destinations(const struct tpf_writer *t - write_sm4_instruction(tpf, &instr); - } - -+static void write_sm4_ternary_op(const struct tpf_writer *tpf, enum vkd3d_sm4_opcode opcode, -+ const struct hlsl_ir_node *dst, const struct hlsl_ir_node *src1, const struct hlsl_ir_node *src2, -+ const struct hlsl_ir_node *src3) -+{ -+ struct sm4_instruction instr; -+ -+ memset(&instr, 0, sizeof(instr)); -+ instr.opcode = opcode; -+ -+ sm4_dst_from_node(&instr.dsts[0], dst); -+ instr.dst_count = 1; -+ -+ sm4_src_from_node(&instr.srcs[0], src1, instr.dsts[0].writemask); -+ sm4_src_from_node(&instr.srcs[1], src2, instr.dsts[0].writemask); -+ sm4_src_from_node(&instr.srcs[2], src3, instr.dsts[0].writemask); -+ instr.src_count = 3; -+ -+ write_sm4_instruction(tpf, &instr); -+} -+ - static void write_sm4_ld(const struct tpf_writer *tpf, const struct hlsl_ir_node *dst, - const struct hlsl_deref *resource, const struct hlsl_ir_node *coords, - const struct hlsl_ir_node *sample_index, const struct hlsl_ir_node *texel_offset, -@@ -4702,6 +4722,7 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex - { - const struct hlsl_ir_node *arg1 = expr->operands[0].node; - const struct hlsl_ir_node *arg2 = expr->operands[1].node; -+ const struct hlsl_ir_node *arg3 = expr->operands[2].node; - const struct hlsl_type *dst_type = expr->node.data_type; - struct vkd3d_string_buffer *dst_type_string; - -@@ -5127,6 +5148,10 @@ static void write_sm4_expr(const struct tpf_writer *tpf, const struct hlsl_ir_ex - &expr->node, arg1, arg2); - break; - -+ case HLSL_OP3_MOVC: -+ write_sm4_ternary_op(tpf, VKD3D_SM4_OP_MOVC, &expr->node, arg1, arg2, arg3); -+ break; -+ - default: - hlsl_fixme(tpf->ctx, &expr->node.loc, "SM4 %s expression.", debug_hlsl_expr_op(expr->op)); - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index a70894a160d..9d8fa82fb86 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -705,7 +705,8 @@ static void vkd3d_shader_scan_add_uav_flag(const struct vkd3d_shader_scan_contex - - for (i = 0; i < context->scan_descriptor_info->descriptor_count; ++i) - { -- if (context->scan_descriptor_info->descriptors[i].register_id == range_id) -+ if (context->scan_descriptor_info->descriptors[i].type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV -+ && context->scan_descriptor_info->descriptors[i].register_id == range_id) - { - context->scan_descriptor_info->descriptors[i].flags |= flag; - break; --- -2.40.1 - diff --git a/staging/upstream-commit b/staging/upstream-commit index 993dbcf3..128ac7b3 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -cf5e073d14925d3cdd489a869e3c2c5317b1ff38 +6558611fa2d24447297cb62d168b924c33839c43