From e1dea6b9ac7cee6d814c28b2fd248b6d72bd305d Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 16 Sep 2025 08:43:30 +1000 Subject: [PATCH] vkd3d-latest patchset Squash --- ...-44fffee5e1331e1c7e10489d84723c3b9da.patch | 102 - ...-e69f3da089d472b723b016ef67c04c0f954.patch | 8556 +++++++++++++++++ ...-3b41d99fa9e80dda5844738a226f70f14f7.patch | 1929 ---- ...-d0098b0d5968d1969ec622b91fd360fd0ae.patch | 133 - ...-158f8b3cf6ff528eb6897baf04db80f0db2.patch | 1759 ---- ...-979d7e4b85f2fb8db60219f4a2673fc8071.patch | 365 - ...-d6bed4be377432e4c54e23abcd7863fefbe.patch | 1757 ---- ...-2aefcf5d99cfb4836c3c6178be74061277b.patch | 175 - ...-0096ae43e114e5bab8a6ff1093b509588a4.patch | 1133 --- ...-6607b94ad7ce77907a912923f39e6371d23.patch | 126 - ...-de2095fda435c5ed47e946cf4e18c68b148.patch | 1793 ---- 11 files changed, 8556 insertions(+), 9272 deletions(-) delete mode 100644 patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch create mode 100644 patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch delete mode 100644 patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch delete mode 100644 patches/vkd3d-latest/0003-Updated-vkd3d-to-d0098b0d5968d1969ec622b91fd360fd0ae.patch delete mode 100644 patches/vkd3d-latest/0004-Updated-vkd3d-to-158f8b3cf6ff528eb6897baf04db80f0db2.patch delete mode 100644 patches/vkd3d-latest/0005-Updated-vkd3d-to-979d7e4b85f2fb8db60219f4a2673fc8071.patch delete mode 100644 patches/vkd3d-latest/0006-Updated-vkd3d-to-d6bed4be377432e4c54e23abcd7863fefbe.patch delete mode 100644 patches/vkd3d-latest/0007-Updated-vkd3d-to-2aefcf5d99cfb4836c3c6178be74061277b.patch delete mode 100644 patches/vkd3d-latest/0008-Updated-vkd3d-to-0096ae43e114e5bab8a6ff1093b509588a4.patch delete mode 100644 patches/vkd3d-latest/0009-Updated-vkd3d-to-6607b94ad7ce77907a912923f39e6371d23.patch delete mode 100644 patches/vkd3d-latest/0010-Updated-vkd3d-to-de2095fda435c5ed47e946cf4e18c68b148.patch diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch deleted file mode 100644 index 0dcc2761..00000000 --- a/patches/vkd3d-latest/0001-Updated-vkd3d-to-44fffee5e1331e1c7e10489d84723c3b9da.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 52953d19dee2161be20f9afb641e9b3d01cb8f2e Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Mon, 26 May 2025 07:03:34 +1000 -Subject: [PATCH] Updated vkd3d to 44fffee5e1331e1c7e10489d84723c3b9dad7e17. - ---- - dlls/msado15/tests/msado15.c | 2 +- - libs/vkd3d/include/private/vkd3d_common.h | 2 +- - libs/vkd3d/include/private/vkd3d_version.h | 2 +- - libs/vkd3d/libs/vkd3d-common/blob.c | 1 + - libs/vkd3d/libs/vkd3d-shader/preproc.l | 1 + - libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c | 2 ++ - libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 2 ++ - 7 files changed, 9 insertions(+), 3 deletions(-) - -diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c -index 03eaab92b39..3f4b55d2916 100644 ---- a/dlls/msado15/tests/msado15.c -+++ b/dlls/msado15/tests/msado15.c -@@ -2023,8 +2023,8 @@ START_TEST(msado15) - setup_database(); - - test_Connection(); -- test_Connection_Open(); - test_ConnectionPoint(); -+ test_Connection_Open(); - test_ADORecordsetConstruction(FALSE); - test_ADORecordsetConstruction(TRUE); - test_Fields(); -diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h -index 08341304eea..0501e6a06c2 100644 ---- a/libs/vkd3d/include/private/vkd3d_common.h -+++ b/libs/vkd3d/include/private/vkd3d_common.h -@@ -279,7 +279,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) - { - #ifdef _MSC_VER - return __popcnt(v); --#elif defined(__MINGW32__) -+#elif defined(HAVE_BUILTIN_POPCOUNT) - return __builtin_popcount(v); - #else - v -= (v >> 1) & 0x55555555; -diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h -index 0edc4428022..687751d6a5f 100644 ---- a/libs/vkd3d/include/private/vkd3d_version.h -+++ b/libs/vkd3d/include/private/vkd3d_version.h -@@ -1 +1 @@ --#define VKD3D_VCS_ID " (Wine bundled)" -+#define VKD3D_VCS_ID " (git a8ca1f95)" -diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c -index f60ef7db769..c2c6ad67804 100644 ---- a/libs/vkd3d/libs/vkd3d-common/blob.c -+++ b/libs/vkd3d/libs/vkd3d-common/blob.c -@@ -20,6 +20,7 @@ - #define WIDL_C_INLINE_WRAPPERS - #endif - #define COBJMACROS -+ - #define CONST_VTABLE - #include "vkd3d.h" - #include "vkd3d_blob.h" -diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l -index a8c0db358bc..5c56fba0229 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/preproc.l -+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l -@@ -20,6 +20,7 @@ - - %{ - -+#include "preproc.h" - #include "preproc.tab.h" - - #undef ERROR /* defined in wingdi.h */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 5fcc836aae1..d1992c9d446 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -23,6 +23,8 @@ - #include - #include - -+/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */ -+ - static inline int char_to_int(char c) - { - if ('0' <= c && c <= '9') -diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -index f2967835b62..f804c1f0c24 100644 ---- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -+++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -@@ -19,6 +19,8 @@ - #include "vkd3d_utils_private.h" - #undef D3D12CreateDevice - -+/* VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG"); */ -+ - static const char *debug_d3d_blob_part(D3D_BLOB_PART part) - { - switch (part) --- -2.51.0 - diff --git a/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch b/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch new file mode 100644 index 00000000..4a3ecb3e --- /dev/null +++ b/patches/vkd3d-latest/0001-Updated-vkd3d-to-e69f3da089d472b723b016ef67c04c0f954.patch @@ -0,0 +1,8556 @@ +From d88e0f20906e9f5d91c0f68de9251f61ec7cb487 Mon Sep 17 00:00:00 2001 +From: Alistair Leslie-Hughes +Date: Mon, 26 May 2025 07:03:34 +1000 +Subject: [PATCH] Updated vkd3d to e69f3da089d472b723b016ef67c04c0f954fa792. + +--- + dlls/msado15/tests/msado15.c | 2 +- + libs/vkd3d/include/private/spirv_grammar.h | 561 +------- + libs/vkd3d/include/private/vkd3d_common.h | 4 +- + libs/vkd3d/include/private/vkd3d_version.h | 2 +- + libs/vkd3d/include/vkd3d_shader.h | 38 +- + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 46 +- + libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 36 +- + libs/vkd3d/libs/vkd3d-shader/dxil.c | 151 ++- + libs/vkd3d/libs/vkd3d-shader/fx.c | 2 +- + libs/vkd3d/libs/vkd3d-shader/glsl.c | 74 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.c | 70 + + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 16 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 +- + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 60 +- + libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 752 ++++++++--- + .../libs/vkd3d-shader/hlsl_constant_ops.c | 243 ++-- + libs/vkd3d/libs/vkd3d-shader/ir.c | 1132 ++++++++++------- + libs/vkd3d/libs/vkd3d-shader/msl.c | 45 +- + libs/vkd3d/libs/vkd3d-shader/preproc.l | 13 +- + libs/vkd3d/libs/vkd3d-shader/spirv.c | 319 ++--- + libs/vkd3d/libs/vkd3d-shader/tpf.c | 43 +- + .../libs/vkd3d-shader/vkd3d_shader_main.c | 222 +--- + .../libs/vkd3d-shader/vkd3d_shader_private.h | 94 +- + .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 17 +- + libs/vkd3d/libs/vkd3d/command.c | 2 +- + libs/vkd3d/libs/vkd3d/state.c | 6 +- + libs/vkd3d/libs/vkd3d/utils.c | 3 +- + 28 files changed, 2184 insertions(+), 1772 deletions(-) + +diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c +index 03eaab92b39..3f4b55d2916 100644 +--- a/dlls/msado15/tests/msado15.c ++++ b/dlls/msado15/tests/msado15.c +@@ -2023,8 +2023,8 @@ START_TEST(msado15) + setup_database(); + + test_Connection(); +- test_Connection_Open(); + test_ConnectionPoint(); ++ test_Connection_Open(); + test_ADORecordsetConstruction(FALSE); + test_ADORecordsetConstruction(TRUE); + test_Fields(); +diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h +index 34cadd9bd58..2aac5a6558c 100644 +--- a/libs/vkd3d/include/private/spirv_grammar.h ++++ b/libs/vkd3d/include/private/spirv_grammar.h +@@ -43,12 +43,10 @@ enum spirv_parser_operand_type + SPIRV_PARSER_OPERAND_TYPE_ADDRESSING_MODEL, + SPIRV_PARSER_OPERAND_TYPE_BUILT_IN, + SPIRV_PARSER_OPERAND_TYPE_CAPABILITY, +- SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE, + SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, + SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, + SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE, + SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, +- SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT, + SPIRV_PARSER_OPERAND_TYPE_DECORATION, + SPIRV_PARSER_OPERAND_TYPE_DIM, + SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE, +@@ -84,7 +82,6 @@ enum spirv_parser_operand_type + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + SPIRV_PARSER_OPERAND_TYPE_LOAD_CACHE_CONTROL, + SPIRV_PARSER_OPERAND_TYPE_LOOP_CONTROL, +- SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, + SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, + SPIRV_PARSER_OPERAND_TYPE_MEMORY_MODEL, + SPIRV_PARSER_OPERAND_TYPE_MEMORY_SEMANTICS, +@@ -149,7 +146,7 @@ spirv_parser_operand_type_info[] = + }, + [SPIRV_PARSER_OPERAND_TYPE_BUILT_IN] = + { +- "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 126, ++ "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 116, + (struct spirv_parser_enumerant[]) + { + {0, "Position"}, +@@ -210,9 +207,6 @@ spirv_parser_operand_type_info[] = + {0x1156, "DeviceIndex"}, + {0x1158, "ViewIndex"}, + {0x115c, "ShadingRateKHR"}, +- {0x118c, "TileOffsetQCOM"}, +- {0x118d, "TileDimensionQCOM"}, +- {0x118e, "TileApronSizeQCOM"}, + {0x1380, "BaryCoordNoPerspAMD"}, + {0x1381, "BaryCoordNoPerspCentroidAMD"}, + {0x1382, "BaryCoordNoPerspSampleAMD"}, +@@ -264,25 +258,18 @@ spirv_parser_operand_type_info[] = + {0x14e0, "HitMicroTriangleVertexBarycentricsNV"}, + {0x14e7, "IncomingRayFlagsKHR"}, + {0x14e8, "RayGeometryIndexKHR"}, +- {0x14ef, "HitIsSphereNV"}, +- {0x14f0, "HitIsLSSNV"}, +- {0x14f1, "HitSpherePositionNV"}, + {0x14fe, "WarpsPerSMNV"}, + {0x14ff, "SMCountNV"}, + {0x1500, "WarpIDNV"}, + {0x1501, "SMIDNV"}, +- {0x1514, "HitLSSPositionsNV"}, + {0x151d, "HitKindFrontFacingMicroTriangleNV"}, + {0x151e, "HitKindBackFacingMicroTriangleNV"}, +- {0x152c, "HitSphereRadiusNV"}, +- {0x152d, "HitLSSRadiiNV"}, +- {0x153c, "ClusterIDNV"}, + {0x1785, "CullMaskKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_CAPABILITY] = + { +- "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 261, ++ "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 245, + (struct spirv_parser_enumerant[]) + { + {0, "Matrix"}, +@@ -393,7 +380,6 @@ spirv_parser_operand_type_info[] = + {0x1184, "TextureSampleWeightedQCOM"}, + {0x1185, "TextureBoxFilterQCOM"}, + {0x1186, "TextureBlockMatchQCOM"}, +- {0x118f, "TileShadingQCOM"}, + {0x1192, "TextureBlockMatch2QCOM"}, + {0x1390, "Float16ImageAMD"}, + {0x1391, "ImageGatherBiasLodAMD"}, +@@ -404,9 +390,6 @@ spirv_parser_operand_type_info[] = + {0x13bf, "ShaderClockKHR"}, + {0x13cb, "ShaderEnqueueAMDX"}, + {0x13df, "QuadControlKHR"}, +- {0x13fc, "BFloat16TypeKHR"}, +- {0x13fd, "BFloat16DotProductKHR"}, +- {0x13fe, "BFloat16CooperativeMatrixKHR"}, + {0x1481, "SampleMaskOverrideCoverageNV"}, + {0x1483, "GeometryShaderPassthroughNV"}, + {0x1486, "ShaderViewportIndexLayerEXT"}, +@@ -452,19 +435,14 @@ spirv_parser_operand_type_info[] = + {0x1507, "ShaderInvocationReorderNV"}, + {0x150e, "BindlessTextureNV"}, + {0x150f, "RayQueryPositionFetchKHR"}, +- {0x1512, "CooperativeVectorNV"}, + {0x151c, "AtomicFloat16VectorNV"}, + {0x1521, "RayTracingDisplacementMicromapNV"}, + {0x1526, "RawAccessChainsNV"}, +- {0x152a, "RayTracingSpheresGeometryNV"}, +- {0x152b, "RayTracingLinearSweptSpheresGeometryNV"}, + {0x1536, "CooperativeMatrixReductionsNV"}, + {0x1537, "CooperativeMatrixConversionsNV"}, + {0x1538, "CooperativeMatrixPerElementOperationsNV"}, + {0x1539, "CooperativeMatrixTensorAddressingNV"}, + {0x153a, "CooperativeMatrixBlockLoadsNV"}, +- {0x153b, "CooperativeVectorTrainingNV"}, +- {0x153d, "RayTracingClusterAccelerationStructureNV"}, + {0x153f, "TensorAddressingNV"}, + {0x15c0, "SubgroupShuffleINTEL"}, + {0x15c1, "SubgroupBufferBlockIOINTEL"}, +@@ -529,47 +507,18 @@ spirv_parser_operand_type_info[] = + {0x1800, "ArithmeticFenceEXT"}, + {0x1806, "FPGAClusterAttributesV2INTEL"}, + {0x1811, "FPGAKernelAttributesv2INTEL"}, +- {0x1812, "TaskSequenceINTEL"}, + {0x1819, "FPMaxErrorINTEL"}, + {0x181b, "FPGALatencyControlINTEL"}, + {0x181e, "FPGAArgumentInterfacesINTEL"}, + {0x182b, "GlobalVariableHostAccessINTEL"}, + {0x182d, "GlobalVariableFPGADecorationsINTEL"}, + {0x184c, "SubgroupBufferPrefetchINTEL"}, +- {0x1854, "Subgroup2DBlockIOINTEL"}, +- {0x1855, "Subgroup2DBlockTransformINTEL"}, +- {0x1856, "Subgroup2DBlockTransposeINTEL"}, +- {0x185c, "SubgroupMatrixMultiplyAccumulateINTEL"}, +- {0x1861, "TernaryBitwiseFunctionINTEL"}, + {0x1900, "GroupUniformArithmeticKHR"}, +- {0x1919, "TensorFloat32RoundingINTEL"}, + {0x191b, "MaskedGatherScatterINTEL"}, + {0x1929, "CacheControlsINTEL"}, + {0x193c, "RegisterLimitsINTEL"}, + } + }, +- [SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE] = +- { +- "ComponentType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 15, +- (struct spirv_parser_enumerant[]) +- { +- {0, "Float16NV"}, +- {0x1, "Float32NV"}, +- {0x2, "Float64NV"}, +- {0x3, "SignedInt8NV"}, +- {0x4, "SignedInt16NV"}, +- {0x5, "SignedInt32NV"}, +- {0x6, "SignedInt64NV"}, +- {0x7, "UnsignedInt8NV"}, +- {0x8, "UnsignedInt16NV"}, +- {0x9, "UnsignedInt32NV"}, +- {0xa, "UnsignedInt64NV"}, +- {0x3ba247f8, "SignedInt8PackedNV"}, +- {0x3ba247f9, "UnsignedInt8PackedNV"}, +- {0x3ba247fa, "FloatE4M3NV"}, +- {0x3ba247fb, "FloatE5M2NV"}, +- } +- }, + [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT] = + { + "CooperativeMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, +@@ -614,17 +563,6 @@ spirv_parser_operand_type_info[] = + {0x2, "MatrixAccumulatorKHR"}, + } + }, +- [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT] = +- { +- "CooperativeVectorMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, +- (struct spirv_parser_enumerant[]) +- { +- {0, "RowMajorNV"}, +- {0x1, "ColumnMajorNV"}, +- {0x2, "InferencingOptimalNV"}, +- {0x3, "TrainingOptimalNV"}, +- } +- }, + [SPIRV_PARSER_OPERAND_TYPE_DECORATION] = + { + "Decoration", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 142, +@@ -1240,7 +1178,7 @@ spirv_parser_operand_type_info[] = + }, + [SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE] = + { +- "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 96, ++ "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 94, + (struct spirv_parser_enumerant[]) + { + { +@@ -1389,16 +1327,6 @@ spirv_parser_operand_type_info[] = + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, +- {0x1189, "NonCoherentTileAttachmentReadQCOM"}, +- { +- 0x118a, "TileShadingRateQCOM", 3, +- (enum spirv_parser_operand_type[]) +- { +- SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, +- SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, +- SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, +- } +- }, + {0x1399, "EarlyAndLateFragmentTestsAMD"}, + {0x13a3, "StencilRefReplacingEXT"}, + {0x13cd, "CoalescingAMDX"}, +@@ -1628,11 +1556,7 @@ spirv_parser_operand_type_info[] = + }, + [SPIRV_PARSER_OPERAND_TYPE_FPENCODING] = + { +- "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 1, +- (struct spirv_parser_enumerant[]) +- { +- {0, "BFloat16KHR"}, +- } ++ "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM + }, + [SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE] = + { +@@ -1757,7 +1681,7 @@ spirv_parser_operand_type_info[] = + }, + [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE] = + { +- "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 26, ++ "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 20, + (struct spirv_parser_enumerant[]) + { + {0, "SnormInt8"}, +@@ -1777,15 +1701,9 @@ spirv_parser_operand_type_info[] = + {0xe, "Float"}, + {0xf, "UnormInt24"}, + {0x10, "UnormInt101010_2"}, +- {0x11, "UnormInt10X6EXT"}, + {0x13, "UnsignedIntRaw10EXT"}, + {0x14, "UnsignedIntRaw12EXT"}, + {0x15, "UnormInt2_101010EXT"}, +- {0x16, "UnsignedInt10X6EXT"}, +- {0x17, "UnsignedInt12X4EXT"}, +- {0x18, "UnsignedInt14X2EXT"}, +- {0x19, "UnormInt12X4EXT"}, +- {0x1a, "UnormInt14X2EXT"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_ORDER] = +@@ -2146,28 +2064,6 @@ spirv_parser_operand_type_info[] = + }, + } + }, +- [SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS] = +- { +- "MatrixMultiplyAccumulateOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 15, +- (struct spirv_parser_enumerant[]) +- { +- {0, "None"}, +- {0x1, "MatrixASignedComponentsINTEL"}, +- {0x2, "MatrixBSignedComponentsINTEL"}, +- {0x4, "MatrixCBFloat16INTEL"}, +- {0x8, "MatrixResultBFloat16INTEL"}, +- {0x10, "MatrixAPackedInt8INTEL"}, +- {0x20, "MatrixBPackedInt8INTEL"}, +- {0x40, "MatrixAPackedInt4INTEL"}, +- {0x80, "MatrixBPackedInt4INTEL"}, +- {0x100, "MatrixATF32INTEL"}, +- {0x200, "MatrixBTF32INTEL"}, +- {0x400, "MatrixAPackedFloat16INTEL"}, +- {0x800, "MatrixBPackedFloat16INTEL"}, +- {0x1000, "MatrixAPackedBFloat16INTEL"}, +- {0x2000, "MatrixBPackedBFloat16INTEL"}, +- } +- }, + [SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS] = + { + "MemoryAccess", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 9, +@@ -2405,7 +2301,7 @@ spirv_parser_operand_type_info[] = + }, + [SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE] = + { +- "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 14, ++ "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 13, + (struct spirv_parser_enumerant[]) + { + {0, "Unknown"}, +@@ -2421,12 +2317,11 @@ spirv_parser_operand_type_info[] = + {0xa, "WGSL"}, + {0xb, "Slang"}, + {0xc, "Zig"}, +- {0xd, "Rust"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS] = + { +- "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 28, ++ "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 27, + (struct spirv_parser_enumerant[]) + { + {0, "UniformConstant"}, +@@ -2443,7 +2338,6 @@ spirv_parser_operand_type_info[] = + {0xb, "Image"}, + {0xc, "StorageBuffer"}, + {0x104c, "TileImageEXT"}, +- {0x118b, "TileAttachmentQCOM"}, + {0x13cc, "NodePayloadAMDX"}, + {0x14d0, "CallableDataKHR"}, + {0x14d1, "IncomingCallableDataKHR"}, +@@ -6996,78 +6890,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_IMAGE_OPERANDS, '?'}, + } + }, +- { +- 0x14a8, "OpTypeCooperativeVectorNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x14a9, "OpCooperativeVectorMatrixMulNV", 13, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, +- {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, +- } +- }, +- { +- 0x14aa, "OpCooperativeVectorOuterProductAccumulateNV", 7, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, +- } +- }, +- { +- 0x14ab, "OpCooperativeVectorReduceSumAccumulateNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x14ac, "OpCooperativeVectorMatrixMulAddNV", 16, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, +- {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, +- } +- }, + { + 0x14ad, "OpCooperativeMatrixConvertNV", 3, + (struct spirv_parser_instruction_operand[]) +@@ -7138,27 +6960,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, +- { +- 0x14b6, "OpCooperativeVectorLoadNV", 5, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, +- } +- }, +- { +- 0x14b7, "OpCooperativeVectorStoreNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, +- } +- }, + { + 0x14d6, "OpReportIntersectionKHR", 4, + (struct spirv_parser_instruction_operand[]) +@@ -7249,25 +7050,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, +- { +- 0x14e1, "OpRayQueryGetClusterIdNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x14e2, "OpHitObjectGetClusterIdNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, + { + 0x14ee, "OpTypeCooperativeMatrixNV", 5, + (struct spirv_parser_instruction_operand[]) +@@ -7580,130 +7362,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, '?'}, + } + }, +- { +- 0x1533, "OpRayQueryGetIntersectionSpherePositionNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1534, "OpRayQueryGetIntersectionSphereRadiusNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1535, "OpRayQueryGetIntersectionLSSPositionsNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1536, "OpRayQueryGetIntersectionLSSRadiiNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1537, "OpRayQueryGetIntersectionLSSHitValueNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1538, "OpHitObjectGetSpherePositionNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1539, "OpHitObjectGetSphereRadiusNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x153a, "OpHitObjectGetLSSPositionsNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x153b, "OpHitObjectGetLSSRadiiNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x153c, "OpHitObjectIsSphereHitNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x153d, "OpHitObjectIsLSSHitNV", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x153e, "OpRayQueryIsSphereHitNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x153f, "OpRayQueryIsLSSHitNV", 4, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, + { + 0x15c3, "OpSubgroupShuffleINTEL", 4, + (struct spirv_parser_instruction_operand[]) +@@ -7962,9 +7620,10 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x15e9, "OpAsmTargetINTEL", 2, ++ 0x15e9, "OpAsmTargetINTEL", 3, + (struct spirv_parser_instruction_operand[]) + { ++ {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } +@@ -9237,7 +8896,7 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 8, ++ 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +@@ -9248,6 +8907,7 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, ++ {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { +@@ -9279,7 +8939,7 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x16d3, "OpArbitraryFloatCastToIntINTEL", 8, ++ 0x16d3, "OpArbitraryFloatCastToIntINTEL", 7, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +@@ -9289,7 +8949,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { +@@ -9803,7 +9462,7 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x16fa, "OpArbitraryFloatPowNINTEL", 10, ++ 0x16fa, "OpArbitraryFloatPowNINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +@@ -9815,7 +9474,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { +@@ -9851,12 +9509,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x1723, "OpFixedSqrtINTEL", 8, ++ 0x1723, "OpFixedSqrtINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9865,12 +9524,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x1724, "OpFixedRecipINTEL", 8, ++ 0x1724, "OpFixedRecipINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9879,12 +9539,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x1725, "OpFixedRsqrtINTEL", 8, ++ 0x1725, "OpFixedRsqrtINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9893,12 +9554,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x1726, "OpFixedSinINTEL", 8, ++ 0x1726, "OpFixedSinINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9907,12 +9569,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x1727, "OpFixedCosINTEL", 8, ++ 0x1727, "OpFixedCosINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9921,12 +9584,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x1728, "OpFixedSinCosINTEL", 8, ++ 0x1728, "OpFixedSinCosINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9935,12 +9599,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x1729, "OpFixedSinPiINTEL", 8, ++ 0x1729, "OpFixedSinPiINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9949,12 +9614,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x172a, "OpFixedCosPiINTEL", 8, ++ 0x172a, "OpFixedCosPiINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9963,12 +9629,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x172b, "OpFixedSinCosPiINTEL", 8, ++ 0x172b, "OpFixedSinCosPiINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9977,12 +9644,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x172c, "OpFixedLogINTEL", 8, ++ 0x172c, "OpFixedLogINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -9991,12 +9659,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x172d, "OpFixedExpINTEL", 8, ++ 0x172d, "OpFixedExpINTEL", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +@@ -10043,12 +9712,13 @@ spirv_parser_opcode_info[] = + } + }, + { +- 0x173d, "OpFPGARegINTEL", 3, ++ 0x173d, "OpFPGARegINTEL", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, ++ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { +@@ -10311,50 +9981,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, +- { +- 0x1813, "OpTaskSequenceCreateINTEL", 7, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, +- } +- }, +- { +- 0x1814, "OpTaskSequenceAsyncINTEL", 2, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, +- } +- }, +- { +- 0x1815, "OpTaskSequenceGetINTEL", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1816, "OpTaskSequenceReleaseINTEL", 1, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1837, "OpTypeTaskSequenceINTEL", 1, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- } +- }, + { + 0x184d, "OpSubgroupBlockPrefetchINTEL", 3, + (struct spirv_parser_instruction_operand[]) +@@ -10364,110 +9990,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, + } + }, +- { +- 0x1857, "OpSubgroup2DBlockLoadINTEL", 10, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1858, "OpSubgroup2DBlockLoadTransformINTEL", 10, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x1859, "OpSubgroup2DBlockLoadTransposeINTEL", 10, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x185a, "OpSubgroup2DBlockPrefetchINTEL", 9, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x185b, "OpSubgroup2DBlockStoreINTEL", 10, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, +- { +- 0x185d, "OpSubgroupMatrixMultiplyAccumulateINTEL", 7, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, '?'}, +- } +- }, +- { +- 0x1862, "OpBitwiseFunctionINTEL", 6, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, + { + 0x1901, "OpGroupIMulKHR", 5, + (struct spirv_parser_instruction_operand[]) +@@ -10556,15 +10078,6 @@ spirv_parser_opcode_info[] = + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, +- { +- 0x191a, "OpRoundFToTF32INTEL", 3, +- (struct spirv_parser_instruction_operand[]) +- { +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, +- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, +- } +- }, + { + 0x191c, "OpMaskedGatherINTEL", 6, + (struct spirv_parser_instruction_operand[]) +diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h +index 08341304eea..8b63acf68e1 100644 +--- a/libs/vkd3d/include/private/vkd3d_common.h ++++ b/libs/vkd3d/include/private/vkd3d_common.h +@@ -38,6 +38,8 @@ + #include + #endif + ++#define VKD3D_SHADER_API_VERSION_CURRENT VKD3D_SHADER_API_VERSION_1_17 ++ + #ifndef ARRAY_SIZE + # define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + #endif +@@ -279,7 +281,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) + { + #ifdef _MSC_VER + return __popcnt(v); +-#elif defined(__MINGW32__) ++#elif defined(HAVE_BUILTIN_POPCOUNT) + return __builtin_popcount(v); + #else + v -= (v >> 1) & 0x55555555; +diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h +index 0edc4428022..687751d6a5f 100644 +--- a/libs/vkd3d/include/private/vkd3d_version.h ++++ b/libs/vkd3d/include/private/vkd3d_version.h +@@ -1 +1 @@ +-#define VKD3D_VCS_ID " (Wine bundled)" ++#define VKD3D_VCS_ID " (git a8ca1f95)" +diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h +index d82869e79ea..3a2f54c8f22 100644 +--- a/libs/vkd3d/include/vkd3d_shader.h ++++ b/libs/vkd3d/include/vkd3d_shader.h +@@ -120,6 +120,11 @@ enum vkd3d_shader_structure_type + * \since 1.15 + */ + VKD3D_SHADER_STRUCTURE_TYPE_SCAN_HULL_SHADER_TESSELLATION_INFO, ++ /** ++ * The structure is a vkd3d_shader_scan_thread_group_size_info structure. ++ * \since 1.18 ++ */ ++ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, + + VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), + }; +@@ -417,10 +422,17 @@ struct vkd3d_shader_code + { + /** + * Pointer to the code. Note that textual formats are not null-terminated. +- * Therefore \a size should not include a null terminator, when this +- * structure is passed as input to a vkd3d-shader function, and the +- * allocated string will not include a null terminator when this structure +- * is used as output. ++ * Therefore \a size should not include a null terminator when this ++ * structure is passed as input to a vkd3d-shader function, and \a size ++ * will not include a null terminator when this structure is used as ++ * output. ++ * ++ * For convenience, vkd3d_shader_preprocess() and vkd3d_shader_compile() ++ * will append a null terminator past the end of their output when ++ * outputting textual formats like VKD3D_SHADER_TARGET_D3D_ASM. This makes ++ * it safe to call functions like strlen() on \a code for such output, ++ * although doing so will obviously not account for any embedded null ++ * characters that may be present. + */ + const void *code; + /** Size of \a code, in bytes. */ +@@ -2282,6 +2294,24 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info + enum vkd3d_shader_tessellator_partitioning partitioning; + }; + ++/** ++ * A chained structure describing the thread group size in a compute shader. ++ * ++ * This structure extends vkd3d_shader_compile_info. ++ * ++ * \since 1.18 ++ */ ++struct vkd3d_shader_scan_thread_group_size_info ++{ ++ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO. */ ++ enum vkd3d_shader_structure_type type; ++ /** Optional pointer to a structure containing further parameters. */ ++ const void *next; ++ ++ /** The thread group size in the x/y/z direction. */ ++ unsigned int x, y, z; ++}; ++ + /** + * Data type of a shader varying, returned as part of struct + * vkd3d_shader_signature_element. +diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c +index f60ef7db769..c2c6ad67804 100644 +--- a/libs/vkd3d/libs/vkd3d-common/blob.c ++++ b/libs/vkd3d/libs/vkd3d-common/blob.c +@@ -20,6 +20,7 @@ + #define WIDL_C_INLINE_WRAPPERS + #endif + #define COBJMACROS ++ + #define CONST_VTABLE + #include "vkd3d.h" + #include "vkd3d_blob.h" +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +index 6425a8f62d2..e2fb8b12998 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +@@ -390,27 +390,10 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, + + static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type) + { +- static const char *const data_type_names[] = +- { +- [VSIR_DATA_BOOL ] = "bool", +- [VSIR_DATA_F16 ] = "half", +- [VSIR_DATA_F32 ] = "float", +- [VSIR_DATA_F64 ] = "double", +- [VSIR_DATA_I32 ] = "int", +- [VSIR_DATA_U8 ] = "uint8", +- [VSIR_DATA_U16 ] = "uint16", +- [VSIR_DATA_U32 ] = "uint", +- [VSIR_DATA_U64 ] = "uint64", +- [VSIR_DATA_SNORM ] = "snorm", +- [VSIR_DATA_UNORM ] = "unorm", +- [VSIR_DATA_OPAQUE ] = "opaque", +- [VSIR_DATA_MIXED ] = "mixed", +- [VSIR_DATA_CONTINUED] = "", +- [VSIR_DATA_UNUSED ] = "", +- }; ++ const char *name; + +- if (type < ARRAY_SIZE(data_type_names)) +- vkd3d_string_buffer_printf(&compiler->buffer, "%s", data_type_names[type]); ++ if ((name = vsir_data_type_get_name(type, NULL))) ++ vkd3d_string_buffer_printf(&compiler->buffer, "%s", name); + else + vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", + compiler->colours.error, type, compiler->colours.reset); +@@ -851,7 +834,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + && reg->type != VKD3DSPR_NULL + && reg->type != VKD3DSPR_DEPTHOUT) + { +- if (offset != ~0u) ++ if (reg->idx_count) + { + bool is_sm_5_1 = vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1); + +@@ -879,10 +862,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const + /* For descriptors in sm < 5.1 we move the reg->idx values up one slot + * to normalise with 5.1. + * Here we should ignore it if it's a descriptor in sm < 5.1. */ +- if (reg->idx[1].offset != ~0u && (!is_descriptor || is_sm_5_1)) ++ if (reg->idx_count > 1 && (!is_descriptor || is_sm_5_1)) + shader_print_subscript(compiler, reg->idx[1].offset, reg->idx[1].rel_addr); + +- if (reg->idx[2].offset != ~0u) ++ if (reg->idx_count > 2) + shader_print_subscript(compiler, reg->idx[2].offset, reg->idx[2].rel_addr); + } + } +@@ -974,6 +957,22 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, + vkd3d_string_buffer_printf(buffer, ">%s", suffix); + } + ++static void shader_print_indexable_temp_data_type(struct vkd3d_d3d_asm_compiler *compiler, ++ const struct vkd3d_shader_indexable_temp *t) ++{ ++ struct vkd3d_string_buffer *buffer = &compiler->buffer; ++ ++ if (!(compiler->flags & VSIR_ASM_FLAG_DUMP_TYPES)) ++ return; ++ ++ if (t->component_count > 1) ++ vkd3d_string_buffer_printf(buffer, " component_count); ++ else ++ vkd3d_string_buffer_printf(buffer, " data_type); ++ vkd3d_string_buffer_printf(buffer, ">"); ++} ++ + static void shader_print_write_mask(struct vkd3d_d3d_asm_compiler *compiler, + const char *prefix, uint32_t mask, const char *suffix) + { +@@ -1528,6 +1527,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, + vkd3d_string_buffer_printf(buffer, " %sx%u%s", compiler->colours.reg, + ins->declaration.indexable_temp.register_idx, compiler->colours.reset); + shader_print_subscript(compiler, ins->declaration.indexable_temp.register_size, NULL); ++ shader_print_indexable_temp_data_type(compiler, &ins->declaration.indexable_temp); + shader_print_uint_literal(compiler, ", ", ins->declaration.indexable_temp.component_count, ""); + if (ins->declaration.indexable_temp.alignment) + shader_print_uint_literal(compiler, ", align ", ins->declaration.indexable_temp.alignment, ""); +diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +index 751e5578276..a9195b3454a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c ++++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +@@ -246,6 +246,7 @@ struct vkd3d_shader_sm1_parser + bool abort; + + struct vkd3d_shader_parser p; ++ struct vsir_program *program; + + struct + { +@@ -468,7 +469,7 @@ static bool has_relative_address(uint32_t param) + static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( + const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode) + { +- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm1->program->shader_version; + const struct vkd3d_sm1_opcode_info *info; + unsigned int i = 0; + +@@ -542,9 +543,9 @@ static enum vkd3d_shader_register_type parse_register_type( + } + + if (d3dbc_type == VKD3D_SM1_REG_ADDR) +- return sm1->p.program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; ++ return sm1->program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; + if (d3dbc_type == VKD3D_SM1_REG_TEXCRDOUT) +- return vkd3d_shader_ver_ge(&sm1->p.program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; ++ return vkd3d_shader_ver_ge(&sm1->program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; + + for (unsigned int i = 0; i < ARRAY_SIZE(register_types); ++i) + { +@@ -660,7 +661,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp + const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval, + unsigned int register_index, bool is_dcl, unsigned int mask) + { +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + struct shader_signature *signature; + struct signature_element *element; + +@@ -702,7 +703,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp + static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, + unsigned int register_index, unsigned int mask) + { +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + struct shader_signature *signature; + struct signature_element *element; + +@@ -749,7 +750,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, + static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, + const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) + { +- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm1->program->shader_version; + unsigned int register_index = reg->idx_count > 0 ? reg->idx[0].offset : 0; + + switch (reg->type) +@@ -844,7 +845,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * + static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1, + const struct vkd3d_shader_semantic *semantic) + { +- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm1->program->shader_version; + const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg; + enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; + unsigned int mask = semantic->resource.reg.write_mask; +@@ -906,7 +907,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, + static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, + const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def) + { +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + uint32_t register_index = reg->idx[0].offset; + + switch (reg->type) +@@ -955,7 +956,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, + * VS >= 2.0 have relative addressing (with token) + * VS >= 1.0 < 2.0 have relative addressing (without token) + * The version check below should work in general. */ +- if (sm1->p.program->shader_version.major < 2) ++ if (sm1->program->shader_version.major < 2) + { + *addr_token = (1u << 31) + | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2) +@@ -984,7 +985,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co + /* Version 2.0+ shaders may contain address tokens, but fortunately they + * have a useful length mask - use it here. Version 1.x shaders contain no + * such tokens. */ +- if (sm1->p.program->shader_version.major >= 2) ++ if (sm1->program->shader_version.major >= 2) + { + length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; + *ptr += length; +@@ -1019,7 +1020,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_read_param(sm1, ptr, &token, &addr_token); + if (has_relative_address(token)) + { +- if (!(src_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) ++ if (!(src_rel_addr = vsir_program_get_src_params(sm1->program, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); +@@ -1040,7 +1041,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_read_param(sm1, ptr, &token, &addr_token); + if (has_relative_address(token)) + { +- if (!(dst_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) ++ if (!(dst_rel_addr = vsir_program_get_src_params(sm1->program, 1))) + { + vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, + "Out of memory."); +@@ -1052,9 +1053,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const + shader_sm1_parse_dst_param(sm1, token, dst_rel_addr, dst_param); + + if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE) +- sm1->p.program->has_point_size = true; ++ sm1->program->has_point_size = true; + if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_FOG) +- sm1->p.program->has_fog = true; ++ sm1->program->has_fog = true; + } + + static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, +@@ -1214,7 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str + { + struct vkd3d_shader_src_param *src_params, *predicate; + const struct vkd3d_sm1_opcode_info *opcode_info; +- struct vsir_program *program = sm1->p.program; ++ struct vsir_program *program = sm1->program; + unsigned int vsir_dst_count, vsir_src_count; + struct vkd3d_shader_dst_param *dst_param; + const uint32_t **ptr = &sm1->ptr; +@@ -1446,7 +1447,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st + code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED, normalisation_level)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name); ++ vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name); ++ sm1->program = program; + sm1->ptr = sm1->start; + + return VKD3D_OK; +@@ -1952,7 +1954,7 @@ static void d3dbc_write_vsir_dcl(struct d3dbc_compiler *d3dbc, const struct vkd3 + + reg_id = semantic->resource.reg.reg.idx[0].offset; + +- if (semantic->resource.reg.reg.type != VKD3DSPR_SAMPLER) ++ if (semantic->resource.reg.reg.type != VKD3DSPR_COMBINED_SAMPLER) + { + vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_TYPE, + "dcl instruction with register type %u.", semantic->resource.reg.reg.type); +diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c +index c448e000cf9..fb2cde4501a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/dxil.c ++++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c +@@ -892,6 +892,8 @@ struct sm6_parser + const uint32_t *ptr, *start, *end; + unsigned int bitpos; + ++ struct vsir_program *program; ++ + struct dxil_block root_block; + struct dxil_block *current_block; + +@@ -2437,7 +2439,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ + { + struct vkd3d_shader_src_param *params; + +- if (!(params = vsir_program_get_src_params(sm6->p.program, count))) ++ if (!(params = vsir_program_get_src_params(sm6->program, count))) + { + ERR("Failed to allocate src params.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -2454,7 +2456,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ + { + struct vkd3d_shader_dst_param *params; + +- if (!(params = vsir_program_get_dst_params(sm6->p.program, count))) ++ if (!(params = vsir_program_get_dst_params(sm6->program, count))) + { + ERR("Failed to allocate dst params.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -2473,7 +2475,7 @@ static void register_init_with_id(struct vkd3d_shader_register *reg, + reg->idx[0].offset = id; + } + +-static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) ++static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type, struct sm6_parser *dxil) + { + if (type->class == TYPE_CLASS_INTEGER) + { +@@ -2490,7 +2492,8 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) + case 64: + return VSIR_DATA_U64; + default: +- FIXME("Unhandled width %u.\n", type->u.width); ++ vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, ++ "Unhandled integer width %u.", type->u.width); + return VSIR_DATA_U32; + } + } +@@ -2505,12 +2508,14 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) + case 64: + return VSIR_DATA_F64; + default: +- FIXME("Unhandled width %u.\n", type->u.width); ++ vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, ++ "Unhandled floating-point width %u.", type->u.width); + return VSIR_DATA_F32; + } + } + +- FIXME("Unhandled type %u.\n", type->class); ++ vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, ++ "Unhandled type %#x.", type->class); + return VSIR_DATA_U32; + } + +@@ -2597,7 +2602,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str + enum vsir_data_type data_type; + + scalar_type = sm6_type_get_scalar_type(value->type, 0); +- data_type = vsir_data_type_from_dxil(scalar_type); ++ data_type = vsir_data_type_from_dxil(scalar_type, sm6); + + switch (value->value_type) + { +@@ -2756,7 +2761,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, + } + else + { +- struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1); ++ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->program, 1); + if (rel_addr) + src_param_init_from_value(rel_addr, address, sm6); + idx->offset = 0; +@@ -3224,7 +3229,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + "Out of memory allocating an immediate constant buffer of count %u.", count); + return VKD3D_ERROR_OUT_OF_MEMORY; + } +- if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb)) ++ if (!shader_instruction_array_add_icb(&sm6->program->instructions, icb)) + { + ERR("Failed to store icb object.\n"); + vkd3d_free(icb); +@@ -3237,7 +3242,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co + dst->u.data = icb; + + icb->register_idx = sm6->icb_count++; +- icb->data_type = vsir_data_type_from_dxil(elem_type); ++ icb->data_type = vsir_data_type_from_dxil(elem_type, sm6); + icb->element_count = type->u.array.count; + icb->component_count = 1; + icb->is_null = !operands; +@@ -3653,7 +3658,7 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al + + static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra) + { +- struct vkd3d_shader_instruction_array *instructions = &sm6->p.program->instructions; ++ struct vkd3d_shader_instruction_array *instructions = &sm6->program->instructions; + + if (!shader_instruction_array_reserve(instructions, instructions->count + extra)) + { +@@ -3663,14 +3668,15 @@ static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_pars + return &instructions->elements[instructions->count]; + } + +-/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */ + static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_parser *sm6, +- enum vkd3d_shader_opcode handler_idx) ++ enum vkd3d_shader_opcode op) + { +- struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); +- VKD3D_ASSERT(ins); +- vsir_instruction_init(ins, &sm6->p.location, handler_idx); +- ++sm6->p.program->instructions.count; ++ struct vkd3d_shader_instruction *ins; ++ ++ if (!(ins = vsir_program_append(sm6->program))) ++ return NULL; ++ vsir_instruction_init(ins, &sm6->p.location, op); ++ + return ins; + } + +@@ -3690,7 +3696,15 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru + unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init, + struct vkd3d_shader_instruction *ins, struct sm6_value *dst) + { +- enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type); ++ enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type, sm6); ++ ++ if (!(sm6->program->global_flags & VKD3DSGF_FORCE_NATIVE_LOW_PRECISION)) ++ { ++ if (data_type == VSIR_DATA_F16) ++ data_type = VSIR_DATA_F32; ++ else if (data_type == VSIR_DATA_U16) ++ data_type = VSIR_DATA_U32; ++ } + + if (ins) + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP); +@@ -3969,7 +3983,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm + + static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + { +- struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions); ++ struct vsir_program_iterator it = vsir_program_iterator(&sm6->program->instructions); + size_t i, count, base_value_idx = sm6->value_count; + const struct dxil_block *block = &sm6->root_block; + struct vkd3d_shader_instruction *ins; +@@ -4009,8 +4023,7 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) + return VKD3D_ERROR_INVALID_SHADER; + if ((version = record->operands[0]) != 1) + { +- FIXME("Unsupported format version %#"PRIx64".\n", version); +- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED_BITCODE_FORMAT, ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, + "Bitcode format version %#"PRIx64" is unsupported.", version); + return VKD3D_ERROR_INVALID_SHADER; + } +@@ -4125,7 +4138,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( + static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, + bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) + { +- enum vkd3d_shader_type shader_type = sm6->p.program->shader_version.type; ++ enum vkd3d_shader_type shader_type = sm6->program->shader_version.type; + enum vkd3d_shader_register_type io_reg_type; + bool is_patch_constant, is_control_point; + struct vkd3d_shader_dst_param *param; +@@ -4175,7 +4188,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade + if (is_control_point) + { + if (reg_type == VKD3DSPR_OUTPUT) +- param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->p.program); ++ param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->program); + param->reg.idx[count++].offset = 0; + } + +@@ -4190,7 +4203,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade + + static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) + { +- if (!(sm6->output_params = vsir_program_get_dst_params(sm6->p.program, output_signature->element_count))) ++ if (!(sm6->output_params = vsir_program_get_dst_params(sm6->program, output_signature->element_count))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate output parameters."); +@@ -4204,7 +4217,7 @@ static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct + + static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) + { +- if (!(sm6->input_params = vsir_program_get_dst_params(sm6->p.program, input_signature->element_count))) ++ if (!(sm6->input_params = vsir_program_get_dst_params(sm6->program, input_signature->element_count))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate input parameters."); +@@ -4219,9 +4232,9 @@ static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct + static int sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, + const struct shader_signature *patch_constant_signature) + { +- bool is_input = sm6->p.program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; ++ bool is_input = sm6->program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; + +- if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->p.program, ++ if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->program, + patch_constant_signature->element_count))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, +@@ -5180,7 +5193,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr + + type = sm6_type_get_scalar_type(dst->type, 0); + VKD3D_ASSERT(type); +- src_param->reg.data_type = vsir_data_type_from_dxil(type); ++ src_param->reg.data_type = vsir_data_type_from_dxil(type, sm6); + if (data_type_is_64_bit(src_param->reg.data_type)) + src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); + else +@@ -5407,7 +5420,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri + row_index = sm6_value_get_constant_uint(operands[0], sm6); + column_index = sm6_value_get_constant_uint(operands[2], sm6); + +- signature = &sm6->p.program->input_signature; ++ signature = &sm6->program->input_signature; + if (row_index >= signature->element_count) + { + WARN("Invalid row index %u.\n", row_index); +@@ -5638,7 +5651,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin + bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT; + bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT; + struct vkd3d_shader_instruction *ins = state->ins; +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + unsigned int count, row_index, column_index; + const struct vkd3d_shader_dst_param *params; + struct vkd3d_shader_src_param *src_param; +@@ -6148,7 +6161,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ + static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, + const struct sm6_value **operands, struct function_emission_state *state) + { +- const struct shader_signature *signature = &sm6->p.program->input_signature; ++ const struct shader_signature *signature = &sm6->program->input_signature; + struct vkd3d_shader_instruction *ins = state->ins; + struct vkd3d_shader_src_param *src_param; + unsigned int element_idx; +@@ -6207,7 +6220,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr + { + bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT; + struct vkd3d_shader_instruction *ins = state->ins; +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_dst_param *dst_param; + const struct shader_signature *signature; +@@ -8206,7 +8219,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun + static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, + struct sm6_function *function) + { +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + struct vkd3d_shader_instruction *ins; + size_t i, block_idx, block_count; + const struct dxil_record *record; +@@ -8586,8 +8599,9 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) + + static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6) + { +- struct vsir_program *program = sm6->p.program; +- unsigned int i; ++ struct vsir_program *program = sm6->program; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int i, j; + + program->block_count = function->block_count; + +@@ -8605,10 +8619,11 @@ static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *fun + sm6_parser_emit_label(sm6, block->id); + sm6_block_emit_phi(block, sm6); + +- memcpy(&program->instructions.elements[program->instructions.count], block->instructions, +- block->instruction_count * sizeof(*block->instructions)); +- program->instructions.count += block->instruction_count; +- ++ for (j = 0; j < block->instruction_count; ++j) ++ { ++ ins = vsir_program_append(program); ++ *ins = block->instructions[j]; ++ } + sm6_block_emit_terminator(block, sm6); + } + +@@ -9510,8 +9525,8 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, + struct vkd3d_shader_instruction *ins; + const struct sm6_metadata_node *node; + const struct sm6_metadata_value *m; ++ enum vkd3d_result ret = VKD3D_OK; + struct sm6_descriptor_info *d; +- enum vkd3d_result ret; + unsigned int i; + + for (i = 0; i < descriptor_node->operand_count; ++i) +@@ -9560,9 +9575,10 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, + return VKD3D_ERROR_INVALID_SHADER; + } + +- if (!(ins = sm6_parser_require_space(sm6, 1))) ++ if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_NOP))) + { +- ERR("Failed to allocate instruction.\n"); ++ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, ++ "Out of memory emitting shader instructions."); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + +@@ -9570,32 +9586,34 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, + { + case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: + if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0) +- return ret; ++ goto done; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: + if ((ret = sm6_parser_resources_load_srv(sm6, node, d, ins)) < 0) +- return ret; ++ goto done; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: + if ((ret = sm6_parser_resources_load_uav(sm6, node, d, ins)) < 0) +- return ret; ++ goto done; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: + if ((ret = sm6_parser_resources_load_sampler(sm6, node, d, ins)) < 0) +- return ret; ++ goto done; + break; + default: +- FIXME("Unsupported descriptor type %u.\n", type); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, +- "Resource descriptor type %u is unsupported.", type); +- return VKD3D_ERROR_INVALID_SHADER; ++ "Resource descriptor type %#x is unsupported.", type); ++ ret = VKD3D_ERROR_INVALID_SHADER; ++ goto done; + } + + ++sm6->descriptor_count; +- ++sm6->p.program->instructions.count; + } + +- return VKD3D_OK; ++done: ++ if (ret < 0) ++ vsir_instruction_init(ins, &ins->location, VSIR_OP_NOP); ++ return ret; + } + + static enum vkd3d_result sm6_parser_resources_init(struct sm6_parser *sm6) +@@ -9711,7 +9729,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const + { + unsigned int i, j, column_count, operand_count, index; + const struct sm6_metadata_node *node, *element_node; +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + struct signature_element *elements, *e; + unsigned int values[10]; + bool native_16bit; +@@ -9930,7 +9948,7 @@ invalid: + static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m, + enum vkd3d_tessellator_domain tessellator_domain) + { +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + enum vkd3d_result ret; + + if (!sm6_metadata_value_is_node(m)) +@@ -9985,12 +10003,12 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm + + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_GLOBAL_FLAGS); + ins->declaration.global_flags = global_flags; +- sm6->p.program->global_flags = global_flags; ++ sm6->program->global_flags = global_flags; + } + + static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m) + { +- struct vkd3d_shader_version *version = &sm6->p.program->shader_version; ++ struct vkd3d_shader_version *version = &sm6->program->shader_version; + const struct sm6_metadata_node *node; + struct vkd3d_shader_instruction *ins; + unsigned int group_sizes[3]; +@@ -10044,7 +10062,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co + ins->declaration.thread_group_size.x = group_sizes[0]; + ins->declaration.thread_group_size.y = group_sizes[1]; + ins->declaration.thread_group_size.z = group_sizes[2]; +- sm6->p.program->thread_group_size = ins->declaration.thread_group_size; ++ sm6->program->thread_group_size = ins->declaration.thread_group_size; + + return VKD3D_OK; + } +@@ -10082,7 +10100,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, + + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_DOMAIN); + ins->declaration.tessellator_domain = tessellator_domain; +- sm6->p.program->tess_domain = tessellator_domain; ++ sm6->program->tess_domain = tessellator_domain; + } + + static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, +@@ -10111,7 +10129,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_PARTITIONING); + ins->declaration.tessellator_partitioning = tessellator_partitioning; + +- sm6->p.program->tess_partitioning = tessellator_partitioning; ++ sm6->program->tess_partitioning = tessellator_partitioning; + } + + static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, +@@ -10129,7 +10147,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); + ins->declaration.tessellator_output_primitive = primitive; + +- sm6->p.program->tess_output_primitive = primitive; ++ sm6->program->tess_output_primitive = primitive; + } + + static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m) +@@ -10241,8 +10259,8 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s + } + + sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); +- sm6->p.program->input_primitive = input_primitive; +- sm6->p.program->input_control_point_count = input_control_point_count; ++ sm6->program->input_primitive = input_primitive; ++ sm6->program->input_control_point_count = input_control_point_count; + + i = operands[1]; + /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */ +@@ -10253,7 +10271,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s + "Geometry shader output vertex count %u is invalid.", i); + } + sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i); +- sm6->p.program->vertices_out_count = i; ++ sm6->program->vertices_out_count = i; + + if (operands[2] > 1) + { +@@ -10271,7 +10289,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s + output_primitive = VKD3D_PT_TRIANGLELIST; + } + sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); +- sm6->p.program->output_topology = output_primitive; ++ sm6->program->output_topology = output_primitive; + + i = operands[4]; + if (!i || i > MAX_GS_INSTANCE_COUNT) +@@ -10326,7 +10344,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa + + sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); + sm6_parser_validate_control_point_count(sm6, operands[1], true, "Domain shader input"); +- sm6->p.program->input_control_point_count = operands[1]; ++ sm6->program->input_control_point_count = operands[1]; + + return operands[0]; + } +@@ -10334,7 +10352,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa + static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, + const struct sm6_metadata_value *m) + { +- struct vsir_program *program = sm6->p.program; ++ struct vsir_program *program = sm6->program; + const struct sm6_metadata_node *node; + unsigned int operands[6] = {0}; + unsigned int i; +@@ -10727,9 +10745,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro + if (!vsir_program_init(program, compile_info, &version, + (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS, VSIR_NORMALISED_SM6)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name); ++ vkd3d_shader_parser_init(&sm6->p, message_context, compile_info->source_name); + sm6->ptr = &sm6->start[1]; + sm6->bitpos = 2; ++ sm6->program = program; + + switch (program->shader_version.type) + { +diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c +index 676c501bb08..a14346a45d2 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/fx.c ++++ b/libs/vkd3d/libs/vkd3d-shader/fx.c +@@ -4205,7 +4205,7 @@ static void fx_parse_shader_blob(struct fx_parser *parser, enum vkd3d_shader_sou + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, + }; + + info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; +diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c +index dfe0a40ddf0..b2679beff9f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/glsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c +@@ -288,6 +288,14 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, + shader_glsl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); + break; + ++ case VKD3DSPR_SAMPLEMASK: ++ if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled sample coverage mask in shader type #%x.", ++ gen->program->shader_version.type); ++ vkd3d_string_buffer_printf(buffer, "o_mask"); ++ break; ++ + default: + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled register type %#x.", reg->type); +@@ -792,7 +800,7 @@ static void shader_glsl_print_texel_offset(struct vkd3d_string_buffer *buffer, s + + static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) + { +- unsigned int resource_id, resource_idx, resource_space, sample_count; ++ unsigned int coord_size, resource_id, resource_idx, resource_space, sample_count; + const struct glsl_resource_type_info *resource_type_info; + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; +@@ -800,11 +808,9 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ + enum vsir_data_type data_type; + struct glsl_src coord; + struct glsl_dst dst; +- uint32_t coord_mask; ++ bool array, offset; + +- if (vkd3d_shader_instruction_has_texel_offset(ins)) +- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +- "Internal compiler error: Unhandled texel fetch offset."); ++ offset = vkd3d_shader_instruction_has_texel_offset(ins); + + if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, +@@ -831,20 +837,22 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ + + if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) + { +- coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); ++ coord_size = resource_type_info->coord_size; ++ array = resource_type_info->array; + } + else + { + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); +- coord_mask = vkd3d_write_mask_from_component_count(2); ++ coord_size = 2; ++ array = false; + } + + glsl_dst_init(&dst, gen, ins, &ins->dst[0]); +- glsl_src_init(&coord, gen, &ins->src[0], coord_mask); ++ glsl_src_init(&coord, gen, &ins->src[0], vkd3d_write_mask_from_component_count(coord_size)); + fetch = vkd3d_string_buffer_get(&gen->string_buffers); + +- vkd3d_string_buffer_printf(fetch, "texelFetch("); ++ vkd3d_string_buffer_printf(fetch, "texelFetch%s(", offset ? "Offset" : ""); + shader_glsl_print_combined_sampler_name(fetch, gen, resource_idx, + resource_space, VKD3D_SHADER_DUMMY_SAMPLER_INDEX, 0); + vkd3d_string_buffer_printf(fetch, ", %s", coord.str->buffer); +@@ -860,6 +868,11 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ + else + shader_glsl_print_src(fetch, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, ins->src[2].reg.data_type); + } ++ if (offset) ++ { ++ vkd3d_string_buffer_printf(fetch, ", "); ++ shader_glsl_print_texel_offset(fetch, gen, coord_size - array, &ins->texel_offset); ++ } + vkd3d_string_buffer_printf(fetch, ")"); + shader_glsl_print_swizzle(fetch, ins->src[1].swizzle, ins->dst[0].write_mask); + +@@ -1281,6 +1294,13 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st + vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_VertexID, 0, 0, 0))"); + break; + ++ case VKD3D_SHADER_SV_INSTANCE_ID: ++ if (version->type != VKD3D_SHADER_TYPE_VERTEX) ++ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, ++ "Internal compiler error: Unhandled SV_INSTANCE_ID in shader type #%x.", version->type); ++ vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_InstanceID, 0, 0, 0))"); ++ break; ++ + case VKD3D_SHADER_SV_IS_FRONT_FACE: + if (version->type != VKD3D_SHADER_TYPE_PIXEL) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, +@@ -1429,6 +1449,12 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen) + shader_glsl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, ";\n"); + } ++ ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) ++ { ++ shader_glsl_print_indent(buffer, gen->indent); ++ vkd3d_string_buffer_printf(gen->buffer, "gl_SampleMask[0] = floatBitsToInt(o_mask);\n"); ++ } + } + + static void shader_glsl_ret(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) +@@ -1475,6 +1501,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VSIR_OP_CONTINUE: + shader_glsl_continue(gen); + break; ++ case VSIR_OP_COS: ++ shader_glsl_intrinsic(gen, ins, "cos"); ++ break; + case VSIR_OP_DCL_INDEXABLE_TEMP: + shader_glsl_dcl_indexable_temp(gen, ins); + break; +@@ -1495,6 +1524,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VSIR_OP_DP4: + shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); + break; ++ case VSIR_OP_DSX: ++ shader_glsl_intrinsic(gen, ins, "dFdx"); ++ break; ++ case VSIR_OP_DSY: ++ shader_glsl_intrinsic(gen, ins, "dFdy"); ++ break; + case VSIR_OP_ELSE: + shader_glsl_else(gen, ins); + break; +@@ -1531,6 +1566,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + break; + case VSIR_OP_GEO: + case VSIR_OP_IGE: ++ case VSIR_OP_UGE: + shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); + break; + case VSIR_OP_IF: +@@ -1620,6 +1656,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VSIR_OP_RSQ: + shader_glsl_intrinsic(gen, ins, "inversesqrt"); + break; ++ case VSIR_OP_SIN: ++ shader_glsl_intrinsic(gen, ins, "sin"); ++ break; + case VSIR_OP_SQRT: + shader_glsl_intrinsic(gen, ins, "sqrt"); + break; +@@ -1629,6 +1668,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, + case VSIR_OP_SWITCH: + shader_glsl_switch(gen, ins); + break; ++ case VSIR_OP_UDIV_SIMPLE: ++ shader_glsl_binop(gen, ins, "/"); ++ break; ++ case VSIR_OP_UREM: ++ shader_glsl_binop(gen, ins, "%"); ++ break; + case VSIR_OP_XOR: + shader_glsl_binop(gen, ins, "^"); + break; +@@ -2318,6 +2363,8 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) + vkd3d_string_buffer_printf(buffer, "vec4 %s_in[%u];\n", gen->prefix, gen->limits.input_count); + if (gen->limits.output_count) + vkd3d_string_buffer_printf(buffer, "vec4 %s_out[%u];\n", gen->prefix, gen->limits.output_count); ++ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) ++ vkd3d_string_buffer_printf(gen->buffer, "float o_mask;\n"); + if (program->temp_count) + vkd3d_string_buffer_printf(buffer, "vec4 r[%u];\n", program->temp_count); + vkd3d_string_buffer_printf(buffer, "\n"); +@@ -2328,7 +2375,6 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc + struct vkd3d_string_buffer *buffer = gen->buffer; + struct vkd3d_shader_instruction *ins; + struct vsir_program_iterator it; +- void *code; + + MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); + +@@ -2357,13 +2403,7 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc + if (gen->failed) + return VKD3D_ERROR_INVALID_SHADER; + +- if ((code = vkd3d_malloc(buffer->buffer_size))) +- { +- memcpy(code, buffer->buffer, buffer->content_size); +- out->size = buffer->content_size; +- out->code = code; +- } +- else return VKD3D_ERROR_OUT_OF_MEMORY; ++ vkd3d_shader_code_from_string_buffer(out, buffer); + + return VKD3D_OK; + } +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +index 62335086e20..d8eb18e39c7 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c +@@ -1809,6 +1809,76 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v + return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); + } + ++bool hlsl_constant_is_zero(struct hlsl_ir_constant *c) ++{ ++ struct hlsl_type *data_type = c->node.data_type; ++ unsigned int k; ++ ++ for (k = 0; k < data_type->e.numeric.dimx; ++k) ++ { ++ switch (data_type->e.numeric.type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ if (c->value.u[k].f != 0.0f) ++ return false; ++ break; ++ ++ case HLSL_TYPE_DOUBLE: ++ if (c->value.u[k].d != 0.0) ++ return false; ++ break; ++ ++ case HLSL_TYPE_UINT: ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_BOOL: ++ case HLSL_TYPE_MIN16UINT: ++ if (c->value.u[k].u != 0) ++ return false; ++ break; ++ } ++ } ++ ++ return true; ++} ++ ++bool hlsl_constant_is_one(struct hlsl_ir_constant *c) ++{ ++ struct hlsl_type *data_type = c->node.data_type; ++ unsigned int k; ++ ++ for (k = 0; k < data_type->e.numeric.dimx; ++k) ++ { ++ switch (data_type->e.numeric.type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ if (c->value.u[k].f != 1.0f) ++ return false; ++ break; ++ ++ case HLSL_TYPE_DOUBLE: ++ if (c->value.u[k].d != 1.0) ++ return false; ++ break; ++ ++ case HLSL_TYPE_UINT: ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_MIN16UINT: ++ if (c->value.u[k].u != 1) ++ return false; ++ break; ++ ++ case HLSL_TYPE_BOOL: ++ if (c->value.u[k].u != ~0) ++ return false; ++ break; ++ } ++ } ++ ++ return true; ++} ++ + static struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +index d67f820fe8b..a3e8ccc1e2a 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h +@@ -233,6 +233,9 @@ struct hlsl_type + /* Offset where the type's description starts in the output bytecode, in bytes. */ + size_t bytecode_offset; + ++ /* Offset where the type's packed description starts in the output bytecode, in bytes. */ ++ size_t packed_bytecode_offset; ++ + bool is_typedef; + + uint32_t is_minimum_precision : 1; +@@ -1184,8 +1187,8 @@ struct hlsl_ctx + } constant_defs; + /* 'c' registers where the constants expected by SM2 sincos are stored. */ + struct hlsl_reg d3dsincosconst1, d3dsincosconst2; +- /* Number of allocated SSA IDs, used in translation to vsir. */ +- unsigned int ssa_count; ++ /* Number of allocated registers, used in translation to vsir. */ ++ unsigned int ssa_count, temp_count, indexable_temp_count; + + /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in + * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ +@@ -1541,6 +1544,12 @@ static inline bool hlsl_var_has_buffer_offset_register_reservation(struct hlsl_c + return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; + } + ++static inline bool hlsl_is_comparison_op(enum hlsl_ir_expr_op op) ++{ ++ return op == HLSL_OP2_EQUAL || op == HLSL_OP2_GEQUAL ++ || op == HLSL_OP2_LESS || op == HLSL_OP2_NEQUAL; ++} ++ + 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); +@@ -1693,6 +1702,9 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, + struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, + struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct hlsl_ir_node *arg3); + ++bool hlsl_constant_is_zero(struct hlsl_ir_constant *c); ++bool hlsl_constant_is_one(struct hlsl_ir_constant *c); ++ + void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); + + struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +index 0cdebb8a657..da9f0d39136 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l +@@ -346,7 +346,7 @@ while {return KW_WHILE; } + {ANY} {} + + {ANY} { +- return yytext[0]; ++ return (unsigned char)yytext[0]; + } + + %% +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +index 024d96c5663..d83ad9fe7d8 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y +@@ -3983,6 +3983,53 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); + } + ++static bool intrinsic_frexp(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_type *type, *uint_dim_type, *int_dim_type, *bool_dim_type; ++ struct hlsl_ir_function_decl *func; ++ char *body; ++ ++ static const char template[] = ++ "%s frexp(%s x, out %s exp)\n" ++ "{\n" ++ /* If x is zero, always return zero for exp and mantissa. */ ++ " %s is_nonzero_mask = x != 0.0;\n" ++ " %s bits = asuint(x);\n" ++ /* Subtract 126, not 127, to increase the exponent */ ++ " %s exp_int = asint((bits & 0x7f800000u) >> 23) - 126;\n" ++ /* Clear the given exponent and replace it with the bit pattern ++ * for 2^-1 */ ++ " %s mantissa = asfloat((bits & 0x007fffffu) | 0x3f000000);\n" ++ " exp = is_nonzero_mask * %s(exp_int);\n" ++ " return is_nonzero_mask * mantissa;\n" ++ "}\n"; ++ ++ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) ++ return false; ++ type = params->args[0]->data_type; ++ ++ if (type->e.numeric.type == HLSL_TYPE_DOUBLE) ++ { ++ hlsl_fixme(ctx, loc, "frexp() on doubles."); ++ return false; ++ } ++ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy); ++ uint_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); ++ int_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_INT, type->e.numeric.dimx, type->e.numeric.dimy); ++ bool_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); ++ ++ if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name, ++ bool_dim_type->name, uint_dim_type->name, int_dim_type->name, type->name, type->name))) ++ return false; ++ func = hlsl_compile_internal_function(ctx, "frexp", body); ++ vkd3d_free(body); ++ if (!func) ++ return false; ++ ++ return !!add_user_call(ctx, func, params, false, loc); ++} ++ + static bool intrinsic_fwidth(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -4701,7 +4748,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * + } + + if (!strcmp(name, "tex2Dbias") +- || !strcmp(name, "tex2Dlod")) ++ || !strcmp(name, "tex2Dlod") ++ || !strcmp(name, "texCUBEbias")) + { + struct hlsl_ir_node *lod, *c; + +@@ -4853,6 +4901,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, + return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE); + } + ++static bool intrinsic_texCUBEbias(struct hlsl_ctx *ctx, ++ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) ++{ ++ return intrinsic_tex(ctx, params, loc, "texCUBEbias", HLSL_SAMPLER_DIM_CUBE); ++} ++ + static bool intrinsic_texCUBEgrad(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) + { +@@ -5283,6 +5337,7 @@ intrinsic_functions[] = + {"floor", 1, true, intrinsic_floor}, + {"fmod", 2, true, intrinsic_fmod}, + {"frac", 1, true, intrinsic_frac}, ++ {"frexp", 2, true, intrinsic_frexp}, + {"fwidth", 1, true, intrinsic_fwidth}, + {"isinf", 1, true, intrinsic_isinf}, + {"ldexp", 2, true, intrinsic_ldexp}, +@@ -5327,6 +5382,7 @@ intrinsic_functions[] = + {"tex3Dgrad", 4, false, intrinsic_tex3Dgrad}, + {"tex3Dproj", 2, false, intrinsic_tex3Dproj}, + {"texCUBE", -1, false, intrinsic_texCUBE}, ++ {"texCUBEbias", 2, false, intrinsic_texCUBEbias}, + {"texCUBEgrad", 4, false, intrinsic_texCUBEgrad}, + {"texCUBEproj", 2, false, intrinsic_texCUBEproj}, + {"transpose", 1, true, intrinsic_transpose}, +@@ -8059,7 +8115,7 @@ resource_format: + { + uint32_t modifiers = $1; + +- if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, false, &@1))) ++ if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) + YYABORT; + } + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +index 0b3dee4d2ce..eaf7d7a3d63 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +@@ -175,12 +175,29 @@ static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) + } + } + ++static unsigned int struct_field_get_packed_offset(const struct hlsl_type *record, unsigned int field_idx) ++{ ++ unsigned int offset = 0; ++ ++ VKD3D_ASSERT(record->class == HLSL_CLASS_STRUCT); ++ VKD3D_ASSERT(field_idx < record->e.record.field_count); ++ ++ for (unsigned int i = 0; i < field_idx; ++i) ++ { ++ struct hlsl_struct_field *field = &record->e.record.fields[i]; ++ offset = align(offset, hlsl_type_get_packed_alignment(field->type)) + hlsl_type_get_packed_size(field->type); ++ } ++ ++ return align(offset, hlsl_type_get_packed_alignment(record->e.record.fields[field_idx].type)); ++} ++ ++ + static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx, + struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx, + struct hlsl_type *type, const struct vkd3d_shader_location *loc) + { + struct hlsl_ir_node *idx_offset = NULL, *c; +- unsigned int field_idx, offset, size, i; ++ unsigned int field_idx, offset, size; + + switch (type->class) + { +@@ -203,15 +220,7 @@ static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hls + + case HLSL_CLASS_STRUCT: + field_idx = hlsl_ir_constant(idx)->value.u[0].u; +- for (i = 0, offset = 0; i < field_idx; ++i) +- { +- struct hlsl_struct_field *field = &type->e.record.fields[i]; +- +- offset = align(offset, hlsl_type_get_packed_alignment(field->type)) +- + hlsl_type_get_packed_size(field->type); +- } +- +- offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type)); ++ offset = struct_field_get_packed_offset(type, field_idx); + idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); + break; + +@@ -5029,8 +5038,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); +- if (expr->op != HLSL_OP2_EQUAL && expr->op != HLSL_OP2_NEQUAL && expr->op != HLSL_OP2_LESS +- && expr->op != HLSL_OP2_GEQUAL) ++ if (!hlsl_is_comparison_op(expr->op)) + return false; + + arg1 = expr->operands[0].node; +@@ -5906,11 +5914,13 @@ static void mark_vars_usage(struct hlsl_ctx *ctx) + + struct register_allocator + { ++ /* Type of registers we are allocating (not counting indexable temps). */ ++ enum vkd3d_shader_register_type type; ++ + struct allocation + { + uint32_t reg; + unsigned int writemask; +- unsigned int first_write, last_read; + + /* Two allocations with different mode can't share the same register. */ + int mode; +@@ -5920,11 +5930,7 @@ struct register_allocator + } *allocations; + size_t count, capacity; + +- /* Indexable temps are allocated separately and always keep their index regardless of their +- * lifetime. */ +- uint32_t indexable_count; +- +- /* Total number of registers allocated so far. Used to declare sm4 temp count. */ ++ /* Total number of registers allocated so far. */ + uint32_t reg_count; + + /* Special flag so allocations that can share registers prioritize those +@@ -5936,7 +5942,7 @@ struct register_allocator + }; + + static unsigned int get_available_writemask(const struct register_allocator *allocator, +- unsigned int first_write, unsigned int last_read, uint32_t reg_idx, int mode, bool vip) ++ uint32_t reg_idx, int mode, bool vip) + { + unsigned int writemask = VKD3DSP_WRITEMASK_ALL; + size_t i; +@@ -5945,12 +5951,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all + { + const struct allocation *allocation = &allocator->allocations[i]; + +- /* We do not overlap if first write == last read: +- * this is the case where we are allocating the result of that +- * expression, e.g. "add r0, r0, r1". */ +- +- if (allocation->reg == reg_idx +- && first_write < allocation->last_read && last_read > allocation->first_write) ++ if (allocation->reg == reg_idx) + { + writemask &= ~allocation->writemask; + if (allocation->mode != mode) +@@ -5967,7 +5968,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all + } + + static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *allocator, uint32_t reg_idx, +- unsigned int writemask, unsigned int first_write, unsigned int last_read, int mode, bool vip) ++ unsigned int writemask, int mode, bool vip) + { + struct allocation *allocation; + +@@ -5978,8 +5979,6 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a + allocation = &allocator->allocations[allocator->count++]; + allocation->reg = reg_idx; + allocation->writemask = writemask; +- allocation->first_write = first_write; +- allocation->last_read = last_read; + allocation->mode = mode; + allocation->vip = vip; + +@@ -5998,8 +5997,7 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a + * 'vip' can be used so that no new allocations can be made in the given register + * unless they are 'vip' as well. */ + static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_allocator *allocator, +- unsigned int first_write, unsigned int last_read, unsigned int reg_size, +- unsigned int component_count, int mode, bool force_align, bool vip) ++ unsigned int reg_size, unsigned int component_count, int mode, bool force_align, bool vip) + { + struct hlsl_reg ret = {.allocation_size = 1, .allocated = true}; + unsigned int required_size = force_align ? 4 : reg_size; +@@ -6012,62 +6010,34 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a + { + for (uint32_t reg_idx = 0; reg_idx < allocator->reg_count; ++reg_idx) + { +- unsigned int available_writemask = get_available_writemask(allocator, +- first_write, last_read, reg_idx, mode, vip); ++ unsigned int available_writemask = get_available_writemask(allocator, reg_idx, mode, vip); + + if (vkd3d_popcount(available_writemask) >= pref) + { + unsigned int writemask = hlsl_combine_writemasks(available_writemask, + vkd3d_write_mask_from_component_count(reg_size)); + +- ret.type = VKD3DSPR_TEMP; ++ ret.type = allocator->type; + ret.id = reg_idx; + ret.writemask = hlsl_combine_writemasks(writemask, + vkd3d_write_mask_from_component_count(component_count)); + +- record_allocation(ctx, allocator, reg_idx, writemask, first_write, last_read, mode, vip); ++ record_allocation(ctx, allocator, reg_idx, writemask, mode, vip); + return ret; + } + } + } + +- ret.type = VKD3DSPR_TEMP; ++ ret.type = allocator->type; + ret.id = allocator->reg_count; + ret.writemask = vkd3d_write_mask_from_component_count(component_count); + record_allocation(ctx, allocator, allocator->reg_count, +- vkd3d_write_mask_from_component_count(reg_size), first_write, last_read, mode, vip); ++ vkd3d_write_mask_from_component_count(reg_size), mode, vip); + return ret; + } + +-/* Allocate a register with writemask, while reserving reg_writemask. */ +-static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx, +- struct register_allocator *allocator, unsigned int first_write, unsigned int last_read, +- uint32_t reg_writemask, uint32_t writemask, int mode, bool vip) +-{ +- struct hlsl_reg ret = {0}; +- uint32_t reg_idx; +- +- VKD3D_ASSERT((reg_writemask & writemask) == writemask); +- +- for (reg_idx = 0;; ++reg_idx) +- { +- if ((get_available_writemask(allocator, first_write, last_read, +- reg_idx, mode, vip) & reg_writemask) == reg_writemask) +- break; +- } +- +- record_allocation(ctx, allocator, reg_idx, reg_writemask, first_write, last_read, mode, vip); +- +- ret.type = VKD3DSPR_TEMP; +- ret.id = reg_idx; +- ret.allocation_size = 1; +- ret.writemask = writemask; +- ret.allocated = true; +- return ret; +-} +- +-static bool is_range_available(const struct register_allocator *allocator, unsigned int first_write, +- unsigned int last_read, uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) ++static bool is_range_available(const struct register_allocator *allocator, ++ uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) + { + unsigned int last_reg_mask = (1u << (reg_size % 4)) - 1; + unsigned int writemask; +@@ -6075,18 +6045,18 @@ static bool is_range_available(const struct register_allocator *allocator, unsig + + for (i = 0; i < (reg_size / 4); ++i) + { +- writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + i, mode, vip); ++ writemask = get_available_writemask(allocator, reg_idx + i, mode, vip); + if (writemask != VKD3DSP_WRITEMASK_ALL) + return false; + } +- writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + (reg_size / 4), mode, vip); ++ writemask = get_available_writemask(allocator, reg_idx + (reg_size / 4), mode, vip); + if ((writemask & last_reg_mask) != last_reg_mask) + return false; + return true; + } + +-static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allocator *allocator, +- unsigned int first_write, unsigned int last_read, unsigned int reg_size, int mode, bool vip) ++static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, ++ struct register_allocator *allocator, unsigned int reg_size, int mode, bool vip) + { + struct hlsl_reg ret = {0}; + uint32_t reg_idx; +@@ -6094,35 +6064,33 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo + + for (reg_idx = 0;; ++reg_idx) + { +- if (is_range_available(allocator, first_write, last_read, reg_idx, reg_size, mode, vip)) ++ if (is_range_available(allocator, reg_idx, reg_size, mode, vip)) + break; + } + + for (i = 0; i < reg_size / 4; ++i) +- record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, first_write, last_read, mode, vip); ++ record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, mode, vip); + if (reg_size % 4) +- record_allocation(ctx, allocator, reg_idx + (reg_size / 4), +- (1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip); ++ record_allocation(ctx, allocator, reg_idx + (reg_size / 4), (1u << (reg_size % 4)) - 1, mode, vip); + +- ret.type = VKD3DSPR_TEMP; ++ ret.type = allocator->type; + ret.id = reg_idx; + ret.allocation_size = align(reg_size, 4) / 4; + ret.allocated = true; + return ret; + } + +-static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, struct register_allocator *allocator, +- unsigned int first_write, unsigned int last_read, const struct hlsl_type *type) ++static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, ++ struct register_allocator *allocator, const struct hlsl_type *type) + { + unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; + + /* FIXME: We could potentially pack structs or arrays more efficiently... */ + + if (type->class <= HLSL_CLASS_VECTOR) +- return allocate_register(ctx, allocator, first_write, last_read, +- type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); ++ return allocate_register(ctx, allocator, type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); + else +- return allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); ++ return allocate_range(ctx, allocator, reg_size, 0, false); + } + + static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) +@@ -6287,10 +6255,9 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) + } + } + +-static void allocate_instr_temp_register(struct hlsl_ctx *ctx, +- struct hlsl_ir_node *instr, struct register_allocator *allocator) ++static void allocate_instr_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr) + { +- unsigned int reg_writemask = 0, dst_writemask = 0; ++ unsigned int dst_writemask = 0; + bool is_per_component = false; + + if (instr->reg.allocated || !instr->last_read) +@@ -6302,12 +6269,10 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, + { + case HLSL_OP1_COS_REDUCED: + dst_writemask = VKD3DSP_WRITEMASK_0; +- reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_0; + break; + + case HLSL_OP1_SIN_REDUCED: + dst_writemask = VKD3DSP_WRITEMASK_1; +- reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_1; + break; + + case HLSL_OP1_EXP2: +@@ -6329,12 +6294,22 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, + + VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); + +- if (reg_writemask) +- instr->reg = allocate_register_with_masks(ctx, allocator, +- instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false); ++ if (dst_writemask) ++ { ++ instr->reg.writemask = dst_writemask; ++ instr->reg.allocation_size = 1; ++ instr->reg.allocated = true; ++ instr->reg.type = VKD3DSPR_TEMP; ++ instr->reg.id = ctx->temp_count++; ++ } + else if (is_per_component) +- instr->reg = allocate_numeric_registers_for_type(ctx, allocator, +- instr->index, instr->last_read, instr->data_type); ++ { ++ instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); ++ instr->reg.allocation_size = 1; ++ instr->reg.allocated = true; ++ instr->reg.type = VKD3DSPR_TEMP; ++ instr->reg.id = ctx->temp_count++; ++ } + else + { + instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); +@@ -6344,40 +6319,46 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, + instr->reg.id = ctx->ssa_count++; + } + +- TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, +- debug_register(instr->reg, instr->data_type), instr->index, instr->last_read); ++ TRACE("Allocated anonymous expression @%u to %s.\n", instr->index, ++ debug_register(instr->reg, instr->data_type)); + } + +-static void allocate_variable_temp_register(struct hlsl_ctx *ctx, +- struct hlsl_ir_var *var, struct register_allocator *allocator) ++static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) + { ++ struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; ++ + if (var->is_input_semantic || var->is_output_semantic || var->is_uniform) + return; + +- if (!var->regs[HLSL_REGSET_NUMERIC].allocated && var->last_read) ++ if (!reg->allocated && var->last_read) + { + if (var->indexable) + { +- var->regs[HLSL_REGSET_NUMERIC].id = allocator->indexable_count++; +- var->regs[HLSL_REGSET_NUMERIC].allocation_size = 1; +- var->regs[HLSL_REGSET_NUMERIC].writemask = 0; +- var->regs[HLSL_REGSET_NUMERIC].allocated = true; ++ reg->id = ctx->indexable_temp_count++; ++ reg->allocation_size = 1; ++ reg->writemask = 0; ++ reg->allocated = true; + +- TRACE("Allocated %s to x%u[].\n", var->name, var->regs[HLSL_REGSET_NUMERIC].id); ++ TRACE("Allocated %s to x%u[].\n", var->name, reg->id); + } + else + { +- var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator, +- var->first_write, var->last_read, var->data_type); ++ reg->type = VKD3DSPR_TEMP; ++ reg->id = ctx->temp_count; ++ reg->allocation_size = align(var->data_type->reg_size[HLSL_REGSET_NUMERIC], 4) / 4; ++ if (var->data_type->class <= HLSL_CLASS_VECTOR) ++ reg->writemask = vkd3d_write_mask_from_component_count(var->data_type->e.numeric.dimx); ++ reg->allocated = true; + +- TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, +- debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); ++ ctx->temp_count += reg->allocation_size; ++ ++ TRACE("Allocated %s to %s.\n", var->name, ++ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); + } + } + } + +-static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, +- struct hlsl_block *block, struct register_allocator *allocator) ++static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block) + { + struct hlsl_ir_node *instr; + +@@ -6387,15 +6368,15 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, + if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) + continue; + +- allocate_instr_temp_register(ctx, instr, allocator); ++ allocate_instr_temp_register(ctx, instr); + + switch (instr->type) + { + case HLSL_IR_IF: + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); +- allocate_temp_registers_recurse(ctx, &iff->then_block, allocator); +- allocate_temp_registers_recurse(ctx, &iff->else_block, allocator); ++ allocate_temp_registers_recurse(ctx, &iff->then_block); ++ allocate_temp_registers_recurse(ctx, &iff->else_block); + break; + } + +@@ -6404,21 +6385,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, + struct hlsl_ir_load *load = hlsl_ir_load(instr); + /* We need to at least allocate a variable for undefs. + * FIXME: We should probably find a way to remove them instead. */ +- allocate_variable_temp_register(ctx, load->src.var, allocator); ++ allocate_variable_temp_register(ctx, load->src.var); + break; + } + + case HLSL_IR_LOOP: + { + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); +- allocate_temp_registers_recurse(ctx, &loop->body, allocator); ++ allocate_temp_registers_recurse(ctx, &loop->body); + break; + } + + case HLSL_IR_STORE: + { + struct hlsl_ir_store *store = hlsl_ir_store(instr); +- allocate_variable_temp_register(ctx, store->lhs.var, allocator); ++ allocate_variable_temp_register(ctx, store->lhs.var); + break; + } + +@@ -6429,7 +6410,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, + + LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) + { +- allocate_temp_registers_recurse(ctx, &c->body, allocator); ++ allocate_temp_registers_recurse(ctx, &c->body); + } + break; + } +@@ -6553,8 +6534,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, + break; + } + +- constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); +- constant->reg.type = VKD3DSPR_CONST; ++ constant->reg = allocate_numeric_registers_for_type(ctx, allocator, type); + TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type)); + + for (unsigned int x = 0, i = 0; x < 4; ++x) +@@ -6651,16 +6631,14 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl + { + type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); + +- ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); +- ctx->d3dsincosconst1.type = VKD3DSPR_CONST; ++ ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, type); + TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type)); + record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc); + record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc); + record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 2, 2.60416674e-03f, &instr->loc); + record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 3, 2.60416680e-04f, &instr->loc); + +- ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); +- ctx->d3dsincosconst2.type = VKD3DSPR_CONST; ++ ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, type); + TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type)); + record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc); + record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc); +@@ -6674,8 +6652,7 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl + + static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *body) + { +- struct register_allocator allocator_used = {0}; +- struct register_allocator allocator = {0}; ++ struct register_allocator allocator = {.type = VKD3DSPR_CONST}, allocator_used = {.type = VKD3DSPR_CONST}; + struct hlsl_ir_var *var; + + sort_uniforms_by_bind_count(ctx, HLSL_REGSET_NUMERIC); +@@ -6698,15 +6675,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo + { + if (i < bind_count) + { +- if (get_available_writemask(&allocator_used, 1, UINT_MAX, +- reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) ++ if (get_available_writemask(&allocator_used, reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, + "Overlapping register() reservations on 'c%u'.", reg_idx + i); + } +- record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); ++ record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); + } +- record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); ++ record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); + } + + var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; +@@ -6730,8 +6706,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo + + if (!var->regs[HLSL_REGSET_NUMERIC].allocated) + { +- var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false); +- var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; ++ var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, alloc_size, 0, false); + TRACE("Allocated %s to %s.\n", var->name, + debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); + } +@@ -6748,12 +6723,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo + * index to all (simultaneously live) variables or intermediate values. Agnostic + * as to how many registers are actually available for the current backend, and + * does not handle constants. */ +-static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) ++static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) + { +- struct register_allocator allocator = {0}; + struct hlsl_scope *scope; + struct hlsl_ir_var *var; + ++ ctx->indexable_temp_count = 0; ++ + /* Reset variable temp register allocations. */ + LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) + { +@@ -6771,25 +6747,13 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block + { + if (var->is_output_semantic) + { +- record_allocation(ctx, &allocator, 0, VKD3DSP_WRITEMASK_ALL, +- var->first_write, UINT_MAX, 0, false); ++ ctx->temp_count = 1; + break; + } + } + } + +- allocate_temp_registers_recurse(ctx, body, &allocator); +- vkd3d_free(allocator.allocations); +- +- if (allocator.indexable_count) +- TRACE("Declaration of %s function required %u temp registers, and %u indexable temps.\n", +- ctx->is_patch_constant_func ? "patch constant" : "main", +- allocator.reg_count, allocator.indexable_count); +- else +- TRACE("Declaration of %s function required %u temp registers.\n", +- ctx->is_patch_constant_func ? "patch constant" : "main", allocator.reg_count); +- +- return allocator.reg_count; ++ allocate_temp_registers_recurse(ctx, body); + } + + static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, +@@ -6928,9 +6892,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var + if (special_interpolation) + mode = VKD3DSIM_NONE; + +- var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, ++ var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, + reg_size, component_count, mode, var->force_align, vip_allocation); +- var->regs[HLSL_REGSET_NUMERIC].type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; + + TRACE("Allocated %s to %s (mode %d).\n", var->name, + debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); +@@ -6945,11 +6908,17 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *seman + bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; + struct hlsl_ir_var *var; + ++ in_prim_allocator.type = VKD3DSPR_INPUT; + in_prim_allocator.prioritize_smaller_writemasks = true; ++ patch_constant_out_patch_allocator.type = VKD3DSPR_INPUT; + patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; ++ input_allocator.type = VKD3DSPR_INPUT; + input_allocator.prioritize_smaller_writemasks = true; + for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) ++ { ++ output_allocators[i].type = VKD3DSPR_OUTPUT; + output_allocators[i].prioritize_smaller_writemasks = true; ++ } + + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) + { +@@ -8266,6 +8235,282 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) + lower_ir(ctx, lower_index_loads, body); + } + ++static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op) ++{ ++ switch (op) ++ { ++ case HLSL_OP2_EQUAL: ++ return HLSL_OP2_NEQUAL; ++ ++ case HLSL_OP2_GEQUAL: ++ return HLSL_OP2_LESS; ++ ++ case HLSL_OP2_LESS: ++ return HLSL_OP2_GEQUAL; ++ ++ case HLSL_OP2_NEQUAL: ++ return HLSL_OP2_EQUAL; ++ ++ default: ++ vkd3d_unreachable(); ++ } ++} ++ ++static bool fold_unary_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *res = NULL; ++ struct hlsl_ir_expr *expr, *x; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return false; ++ ++ if (instr->data_type->class > HLSL_CLASS_VECTOR) ++ return false; ++ ++ expr = hlsl_ir_expr(instr); ++ if (!expr->operands[0].node) ++ return false; ++ ++ if (expr->operands[0].node->type != HLSL_IR_EXPR) ++ return false; ++ x = hlsl_ir_expr(expr->operands[0].node); ++ ++ switch (expr->op) ++ { ++ case HLSL_OP1_ABS: ++ if (x->op == HLSL_OP1_ABS) ++ { ++ /* ||x|| -> |x| */ ++ hlsl_replace_node(instr, &x->node); ++ return true; ++ } ++ ++ if (x->op == HLSL_OP1_NEG) ++ { ++ /* |-x| -> |x| */ ++ hlsl_src_remove(&expr->operands[0]); ++ hlsl_src_from_node(&expr->operands[0], x->operands[0].node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_BIT_NOT: ++ if (x->op == HLSL_OP1_BIT_NOT) ++ { ++ /* ~(~x) -> x */ ++ hlsl_replace_node(instr, x->operands[0].node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_CEIL: ++ case HLSL_OP1_FLOOR: ++ if (x->op == HLSL_OP1_CEIL || x->op == HLSL_OP1_FLOOR) ++ { ++ /* f(g(x)) -> g(x), where f(), g() are floor() or ceil() functions. */ ++ hlsl_replace_node(instr, &x->node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_NEG: ++ if (x->op == HLSL_OP1_NEG) ++ { ++ /* -(-x) -> x */ ++ hlsl_replace_node(instr, x->operands[0].node); ++ return true; ++ } ++ break; ++ ++ case HLSL_OP1_LOGIC_NOT: ++ if (x->op == HLSL_OP1_LOGIC_NOT) ++ { ++ /* !!x -> x */ ++ hlsl_replace_node(instr, x->operands[0].node); ++ return true; ++ } ++ ++ if (hlsl_is_comparison_op(x->op) ++ && hlsl_base_type_is_integer(x->operands[0].node->data_type->e.numeric.type) ++ && hlsl_base_type_is_integer(x->operands[1].node->data_type->e.numeric.type)) ++ { ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {x->operands[0].node, x->operands[1].node}; ++ struct hlsl_block block; ++ ++ hlsl_block_init(&block); ++ ++ /* !(x == y) -> x != y, !(x < y) -> x >= y, etc. */ ++ res = hlsl_block_add_expr(ctx, &block, invert_comparison_op(x->op), ++ operands, instr->data_type, &instr->loc); ++ ++ list_move_before(&instr->entry, &block.instrs); ++ hlsl_replace_node(instr, res); ++ return true; ++ } ++ ++ break; ++ ++ default: ++ break; ++ } ++ ++ return false; ++} ++ ++static bool nodes_are_equivalent(const struct hlsl_ir_node *c1, const struct hlsl_ir_node *c2) ++{ ++ if (c1 == c2) ++ return true; ++ ++ if (c1->type == HLSL_IR_SWIZZLE && c2->type == HLSL_IR_SWIZZLE ++ && hlsl_types_are_equal(c1->data_type, c2->data_type)) ++ { ++ const struct hlsl_ir_swizzle *s1 = hlsl_ir_swizzle(c1), *s2 = hlsl_ir_swizzle(c2); ++ ++ VKD3D_ASSERT(c1->data_type->class <= HLSL_CLASS_VECTOR); ++ ++ if (s1->val.node == s2->val.node && s1->u.vector == s2->u.vector) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* Replaces all conditionals in an expression chain of the form (cond ? x : y) ++ * with x or y, assuming cond = cond_value. */ ++static struct hlsl_ir_node *evaluate_conditionals_recurse(struct hlsl_ctx *ctx, ++ struct hlsl_block *block, const struct hlsl_ir_node *cond, bool cond_value, ++ struct hlsl_ir_node *instr, const struct vkd3d_shader_location *loc) ++{ ++ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; ++ struct hlsl_ir_expr *expr; ++ struct hlsl_ir_node *res; ++ bool progress = false; ++ unsigned int i; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return NULL; ++ expr = hlsl_ir_expr(instr); ++ ++ if (expr->op == HLSL_OP3_TERNARY && nodes_are_equivalent(cond, expr->operands[0].node)) ++ { ++ struct hlsl_ir_node *x = cond_value ? expr->operands[1].node : expr->operands[2].node; ++ ++ res = evaluate_conditionals_recurse(ctx, block, cond, cond_value, x, loc); ++ return res ? res : x; ++ } ++ ++ for (i = 0; i < HLSL_MAX_OPERANDS; ++i) ++ { ++ if (!expr->operands[i].node) ++ break; ++ ++ operands[i] = evaluate_conditionals_recurse(ctx, block, cond, cond_value, expr->operands[i].node, loc); ++ ++ if (operands[i]) ++ progress = true; ++ else ++ operands[i] = expr->operands[i].node; ++ } ++ ++ if (progress) ++ return hlsl_block_add_expr(ctx, block, expr->op, operands, expr->node.data_type, loc); ++ ++ return NULL; ++} ++ ++static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) ++{ ++ struct hlsl_ir_node *c, *x, *y, *res_x, *res_y; ++ struct hlsl_ir_node *res = NULL; ++ struct hlsl_ir_expr *expr, *ec; ++ struct hlsl_block block; ++ ++ if (instr->type != HLSL_IR_EXPR) ++ return false; ++ ++ if (instr->data_type->class > HLSL_CLASS_VECTOR) ++ return false; ++ ++ expr = hlsl_ir_expr(instr); ++ if (expr->op != HLSL_OP3_TERNARY) ++ return false; ++ ++ c = expr->operands[0].node; ++ x = expr->operands[1].node; ++ y = expr->operands[2].node; ++ ++ VKD3D_ASSERT(c->data_type->e.numeric.type == HLSL_TYPE_BOOL); ++ ++ if (nodes_are_equivalent(x, y)) ++ { ++ /* c ? x : x -> x */ ++ hlsl_replace_node(instr, x); ++ return true; ++ } ++ ++ if (c->type == HLSL_IR_CONSTANT) ++ { ++ if (hlsl_constant_is_zero(hlsl_ir_constant(c))) ++ { ++ /* false ? x : y -> y */ ++ hlsl_replace_node(instr, y); ++ return true; ++ } ++ ++ if (hlsl_constant_is_one(hlsl_ir_constant(c))) ++ { ++ /* true ? x : y -> x */ ++ hlsl_replace_node(instr, x); ++ return true; ++ } ++ } ++ ++ hlsl_block_init(&block); ++ ++ if (x->type == HLSL_IR_CONSTANT && y->type == HLSL_IR_CONSTANT ++ && hlsl_types_are_equal(c->data_type, x->data_type) ++ && hlsl_types_are_equal(c->data_type, y->data_type)) ++ { ++ if (hlsl_constant_is_one(hlsl_ir_constant(x)) && hlsl_constant_is_zero(hlsl_ir_constant(y))) ++ { ++ /* c ? true : false -> c */ ++ res = c; ++ goto done; ++ } ++ ++ if (hlsl_constant_is_zero(hlsl_ir_constant(x)) && hlsl_constant_is_one(hlsl_ir_constant(y))) ++ { ++ /* c ? false : true -> !c */ ++ res = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); ++ goto done; ++ } ++ } ++ ++ ec = c->type == HLSL_IR_EXPR ? hlsl_ir_expr(c) : NULL; ++ if (ec && ec->op == HLSL_OP1_LOGIC_NOT) ++ { ++ /* !c ? x : y -> c ? y : x */ ++ res = hlsl_add_conditional(ctx, &block, ec->operands[0].node, y, x); ++ goto done; ++ } ++ ++ res_x = evaluate_conditionals_recurse(ctx, &block, c, true, x, &instr->loc); ++ res_y = evaluate_conditionals_recurse(ctx, &block, c, false, y, &instr->loc); ++ if (res_x || res_y) ++ res = hlsl_add_conditional(ctx, &block, c, res_x ? res_x : x, res_y ? res_y : y); ++ ++done: ++ if (res) ++ { ++ list_move_before(&instr->entry, &block.instrs); ++ hlsl_replace_node(instr, res); ++ return true; ++ } ++ ++ hlsl_block_cleanup(&block); ++ return false; ++} + + static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) + { +@@ -8275,6 +8520,8 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) + { + progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); + progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); ++ progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); ++ progress |= hlsl_transform_ir(ctx, fold_conditional_identities, block, NULL); + progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); + progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); + +@@ -8448,6 +8695,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog + if (!ascii_strcasecmp(var->semantic.name, "PSIZE") && output + && program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX) + { ++ program->has_point_size = true; + if (var->data_type->e.numeric.dimx > 1) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, + "PSIZE output must have only 1 component in this shader model."); +@@ -8570,9 +8818,8 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c + case HLSL_TYPE_DOUBLE: + return VSIR_DATA_F64; + case HLSL_TYPE_FLOAT: +- return VSIR_DATA_F32; + case HLSL_TYPE_HALF: +- return VSIR_DATA_F16; ++ return VSIR_DATA_F32; + case HLSL_TYPE_INT: + return VSIR_DATA_I32; + case HLSL_TYPE_UINT: +@@ -8703,7 +8950,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, + semantic->resource_type = resource_type; + + dst_param = &semantic->resource.reg; +- vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1); ++ vsir_register_init(&dst_param->reg, VKD3DSPR_COMBINED_SAMPLER, VSIR_DATA_F32, 1); + dst_param->reg.dimension = VSIR_DIMENSION_NONE; + dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index + i; + dst_param->write_mask = 0; +@@ -9467,8 +9714,6 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr + break; + + case HLSL_OP3_CMP: +- if (!hlsl_type_is_floating_point(type)) +- goto err; + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true); + break; + +@@ -9930,10 +10175,14 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co + struct hlsl_ir_function_decl *func, struct list *semantic_vars, + struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) + { ++ struct hlsl_ir_var *var; + struct hlsl_block block; ++ struct hlsl_reg *reg; ++ unsigned int *count; + + program->ssa_count = 0; +- program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); ++ program->temp_count = 0; ++ allocate_temp_registers(ctx, body, semantic_vars); + if (ctx->result) + return; + +@@ -9944,7 +10193,19 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co + + sm1_generate_vsir_block(ctx, body, program); + ++ count = &program->flat_constant_count[VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER]; ++ LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) ++ { ++ if (!var->is_uniform) ++ continue; ++ ++ if (!(reg = &var->regs[HLSL_REGSET_NUMERIC])->allocation_size) ++ continue; ++ ++ *count = max(*count, reg->id + reg->allocation_size); ++ } + program->ssa_count = ctx->ssa_count; ++ program->temp_count = ctx->temp_count; + + if (ctx->result) + return; +@@ -11437,6 +11698,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + const struct vkd3d_shader_version *version = &program->shader_version; + const struct hlsl_ir_node *sample_index = load->sample_index.node; + const struct hlsl_ir_node *texel_offset = load->texel_offset.node; ++ const struct hlsl_ir_node *byte_offset = load->byte_offset.node; + const struct hlsl_ir_node *coords = load->coords.node; + unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; + const struct hlsl_deref *resource = &load->resource; +@@ -11444,20 +11706,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + enum hlsl_sampler_dim dim = load->sampling_dim; + bool tgsm = load->resource.var->is_tgsm; + struct vkd3d_shader_instruction *ins; ++ bool multisampled, raw, structured; + enum vkd3d_shader_opcode opcode; +- bool multisampled, raw; + + VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD); + +- if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) +- { +- hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads."); +- return false; +- } +- + multisampled = resource_type->class == HLSL_CLASS_TEXTURE + && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS + || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); ++ structured = resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + + if (!tgsm) + { +@@ -11468,15 +11725,19 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); + return false; + } ++ VKD3D_ASSERT(!(structured && multisampled)); + +- if (uav) ++ if (structured) ++ opcode = VSIR_OP_LD_STRUCTURED; ++ else if (uav) + opcode = VSIR_OP_LD_UAV_TYPED; + else if (raw) + opcode = VSIR_OP_LD_RAW; + else + opcode = multisampled ? VSIR_OP_LD2DMS : VSIR_OP_LD; + +- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled))) ++ if (!(ins = generate_vsir_add_program_instruction(ctx, program, ++ &instr->loc, opcode, 1, 2 + multisampled + structured))) + return false; + + if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset)) +@@ -11504,10 +11765,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, + vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, coords_writemask); + + if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, +- &ins->src[1], resource, ins->dst[0].write_mask, &instr->loc)) ++ &ins->src[structured ? 2 : 1], resource, ins->dst[0].write_mask, &instr->loc)) + return false; + +- if (multisampled) ++ if (structured) ++ { ++ VKD3D_ASSERT(byte_offset); ++ vsir_src_from_hlsl_node(&ins->src[1], ctx, byte_offset, VKD3DSP_WRITEMASK_ALL); ++ } ++ else if (multisampled) + { + if (sample_index->type == HLSL_IR_CONSTANT) + vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, +@@ -12093,16 +12359,15 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se + struct hlsl_block block = {0}; + struct hlsl_scope *scope; + struct hlsl_ir_var *var; +- uint32_t temp_count; + + ctx->is_patch_constant_func = func == ctx->patch_constant_func; + + compute_liveness(ctx, body); + mark_indexable_vars(ctx, body); +- temp_count = allocate_temp_registers(ctx, body, semantic_vars); ++ allocate_temp_registers(ctx, body, semantic_vars); + if (ctx->result) + return; +- program->temp_count = max(program->temp_count, temp_count); ++ program->temp_count = max(program->temp_count, ctx->temp_count); + + hlsl_block_init(&block); + +@@ -12113,8 +12378,8 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se + sm4_generate_vsir_instr_dcl_semantic(ctx, program, var, &block, &var->loc); + } + +- if (temp_count) +- sm4_generate_vsir_instr_dcl_temps(ctx, program, temp_count, &block, &func->loc); ++ if (ctx->temp_count) ++ sm4_generate_vsir_instr_dcl_temps(ctx, program, ctx->temp_count, &block, &func->loc); + + LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) + { +@@ -12427,7 +12692,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, + return; + } + +- ins->declaration.cb.size = cbuffer->size; ++ ins->declaration.cb.size = align(cbuffer->size, 4) * sizeof(float); + + src_param = &ins->declaration.cb.src; + vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 0); +@@ -12592,6 +12857,9 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + { + switch (component_type->sampler_dim) + { ++ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: ++ opcode = VSIR_OP_DCL_RESOURCE_STRUCTURED; ++ break; + case HLSL_SAMPLER_DIM_RAW_BUFFER: + opcode = VSIR_OP_DCL_RESOURCE_RAW; + break; +@@ -12647,7 +12915,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, + else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + { + ins->structured = true; +- ins->resource_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; ++ ins->resource_stride = hlsl_type_get_packed_size(component_type->e.resource.format); + ins->declaration.structured_resource.byte_stride = ins->resource_stride; + } + else +@@ -12784,6 +13052,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, + } + + program->ssa_count = 0; ++ program->temp_count = 0; + + if (version->type == VKD3D_SHADER_TYPE_HULL) + generate_vsir_add_program_instruction(ctx, program, +@@ -12801,6 +13070,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, + generate_vsir_scan_global_flags(ctx, program, semantic_vars, func); + + program->ssa_count = ctx->ssa_count; ++ program->temp_count = ctx->temp_count; + } + + /* For some reason, for matrices, values from default value initializers end +@@ -12915,14 +13185,16 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) + + static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) + { ++ bool structured = type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; ++ + switch (type->class) + { + case HLSL_CLASS_SAMPLER: + return D3D_SIT_SAMPLER; + case HLSL_CLASS_TEXTURE: +- return D3D_SIT_TEXTURE; ++ return structured ? D3D_SIT_STRUCTURED : D3D_SIT_TEXTURE; + case HLSL_CLASS_UAV: +- return D3D_SIT_UAV_RWTYPED; ++ return structured ? D3D_SIT_UAV_RWSTRUCTURED : D3D_SIT_UAV_RWTYPED; + default: + break; + } +@@ -12998,7 +13270,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) + vkd3d_unreachable(); + } + +-static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type) ++static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, ++ struct hlsl_type *type, bool structured) + { + const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type); + const char *name = array_type->name ? array_type->name : ""; +@@ -13007,7 +13280,10 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b + size_t name_offset = 0; + size_t i; + +- if (type->bytecode_offset) ++ if (!structured && type->bytecode_offset) ++ return; ++ ++ if (structured && type->packed_bytecode_offset) + return; + + if (profile->major_version >= 5) +@@ -13029,7 +13305,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b + continue; + + field->name_bytecode_offset = put_string(buffer, field->name); +- write_sm4_type(ctx, buffer, field->type); ++ write_sm4_type(ctx, buffer, field->type, structured); + ++field_count; + } + +@@ -13038,15 +13314,29 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b + for (i = 0; i < array_type->e.record.field_count; ++i) + { + struct hlsl_struct_field *field = &array_type->e.record.fields[i]; ++ unsigned int field_type_offset, offset; + + if (!field->type->reg_size[HLSL_REGSET_NUMERIC]) + continue; + + put_u32(buffer, field->name_bytecode_offset); +- put_u32(buffer, field->type->bytecode_offset); +- put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float)); ++ ++ if (!structured) ++ field_type_offset = field->type->bytecode_offset; ++ else ++ field_type_offset = field->type->packed_bytecode_offset; ++ put_u32(buffer, field_type_offset); ++ ++ if (!structured) ++ offset = field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float); ++ else ++ offset = struct_field_get_packed_offset(array_type, i); ++ put_u32(buffer, offset); + } +- type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); ++ if (!structured) ++ type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); ++ else ++ type->packed_bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); + put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type))); + put_u32(buffer, vkd3d_make_u32(array_size, field_count)); + put_u32(buffer, fields_offset); +@@ -13054,7 +13344,11 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b + else + { + VKD3D_ASSERT(array_type->class <= HLSL_CLASS_LAST_NUMERIC); +- type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); ++ if (!structured) ++ type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); ++ else ++ type->packed_bytecode_offset = put_u32(buffer, ++ vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); + put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx)); + put_u32(buffer, vkd3d_make_u32(array_size, 0)); + put_u32(buffer, 1); +@@ -13073,9 +13367,9 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b + static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef) + { + uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t); +- size_t cbuffers_offset, resources_offset, creator_offset, string_offset; +- unsigned int cbuffer_count = 0, extern_resources_count, i, j; ++ size_t buffers_offset, resources_offset, creator_offset, string_offset; + size_t cbuffer_position, resource_position, creator_position; ++ unsigned int buffer_count = 0, extern_resources_count, i, j; + const struct hlsl_profile_info *profile = ctx->profile; + struct vkd3d_bytecode_buffer buffer = {0}; + struct extern_resource *extern_resources; +@@ -13097,10 +13391,20 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) + { + if (cbuffer->reg.allocated) +- ++cbuffer_count; ++ ++buffer_count; ++ } ++ ++ for (i = 0; i < extern_resources_count; ++i) ++ { ++ const struct extern_resource *resource = &extern_resources[i]; ++ ++ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ continue; ++ ++ ++buffer_count; + } + +- put_u32(&buffer, cbuffer_count); ++ put_u32(&buffer, buffer_count); + cbuffer_position = put_u32(&buffer, 0); + put_u32(&buffer, extern_resources_count); + resource_position = put_u32(&buffer, 0); +@@ -13141,12 +13445,19 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + put_u32(&buffer, sm4_resource_type(resource->component_type)); + if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) + { ++ bool structured = resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + unsigned int dimx = resource->component_type->e.resource.format->e.numeric.dimx; + + put_u32(&buffer, sm4_data_type(resource->component_type)); + put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type)); +- put_u32(&buffer, ~0u); /* FIXME: multisample count */ +- flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; ++ ++ if (structured) ++ put_u32(&buffer, hlsl_type_get_packed_size(resource->component_type->e.resource.format)); ++ else ++ put_u32(&buffer, ~0u); /* FIXME: multisample count */ ++ ++ if (!structured) ++ flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; + } + else + { +@@ -13175,8 +13486,8 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + + /* Buffers. */ + +- cbuffers_offset = bytecode_align(&buffer); +- set_u32(&buffer, cbuffer_position, cbuffers_offset); ++ buffers_offset = bytecode_align(&buffer); ++ set_u32(&buffer, cbuffer_position, buffers_offset); + LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) + { + unsigned int var_count = 0; +@@ -13198,6 +13509,24 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER); + } + ++ for (i = 0; i < extern_resources_count; ++i) ++ { ++ const struct extern_resource *resource = &extern_resources[i]; ++ struct hlsl_type *resource_type; ++ ++ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ continue; ++ ++ resource_type = resource->component_type->e.resource.format; ++ ++ put_u32(&buffer, 0); /* name */ ++ put_u32(&buffer, 1); /* var count */ ++ put_u32(&buffer, 0); /* variable offset */ ++ put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); /* size */ ++ put_u32(&buffer, 0); /* FIXME: flags */ ++ put_u32(&buffer, D3D_CT_RESOURCE_BIND_INFO); ++ } ++ + i = 0; + LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) + { +@@ -13205,7 +13534,18 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + continue; + + string_offset = put_string(&buffer, cbuffer->name); +- set_u32(&buffer, cbuffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); ++ set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); ++ } ++ ++ for (j = 0; j < extern_resources_count; ++j) ++ { ++ const struct extern_resource *resource = &extern_resources[j]; ++ ++ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ continue; ++ ++ string_offset = put_string(&buffer, resource->name); ++ set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); + } + + i = 0; +@@ -13216,7 +13556,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + if (!cbuffer->reg.allocated) + continue; + +- set_u32(&buffer, cbuffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); ++ set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { +@@ -13255,7 +13595,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + + string_offset = put_string(&buffer, var->name); + set_u32(&buffer, var_offset, string_offset); +- write_sm4_type(ctx, &buffer, var->data_type); ++ write_sm4_type(ctx, &buffer, var->data_type, false); + set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset); + + if (var->default_values) +@@ -13298,6 +13638,42 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd + } + } + ++ for (j = 0; j < extern_resources_count; ++j) ++ { ++ const struct extern_resource *resource = &extern_resources[j]; ++ struct hlsl_type *resource_type; ++ size_t vars_start; ++ ++ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) ++ continue; ++ ++ resource_type = resource->component_type->e.resource.format; ++ ++ vars_start = bytecode_align(&buffer); ++ ++ set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); ++ ++ put_u32(&buffer, 0); /* name */ ++ put_u32(&buffer, 0); /* offset */ ++ put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); ++ put_u32(&buffer, D3D_SVF_USED); ++ put_u32(&buffer, 0); /* type */ ++ put_u32(&buffer, 0); /* default value */ ++ ++ if (profile->major_version >= 5) ++ { ++ put_u32(&buffer, ~0u); /* texture start */ ++ put_u32(&buffer, 0); /* texture count */ ++ put_u32(&buffer, ~0u); /* sampler start */ ++ put_u32(&buffer, 0); /* sampler count */ ++ } ++ ++ string_offset = put_string(&buffer, "$Element"); ++ set_u32(&buffer, vars_start, string_offset); ++ write_sm4_type(ctx, &buffer, resource_type, true); ++ set_u32(&buffer, vars_start + 4 * sizeof(uint32_t), resource_type->packed_bytecode_offset); ++ } ++ + creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL)); + set_u32(&buffer, creator_position, creator_offset); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +index d339a06e6c7..252ed51a4e4 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c ++++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +@@ -250,6 +250,36 @@ static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + return true; + } + ++static bool fold_cos(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, ++ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) ++{ ++ enum hlsl_base_type type = dst_type->e.numeric.type; ++ unsigned int k; ++ ++ VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); ++ ++ for (k = 0; k < dst_type->e.numeric.dimx; ++k) ++ { ++ switch (type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ dst->u[k].f = cosf(src->value.u[k].f); ++ break; ++ ++ case HLSL_TYPE_DOUBLE: ++ dst->u[k].d = cos(src->value.u[k].d); ++ break; ++ ++ default: ++ FIXME("Fold 'cos' for type %s.\n", debug_hlsl_type(ctx, dst_type)); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) + { +@@ -478,6 +508,48 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons + return true; + } + ++static bool fold_reinterpret(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, ++ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) ++{ ++ unsigned int k; ++ ++ for (k = 0; k < dst_type->e.numeric.dimx; ++k) ++ { ++ dst->u[k] = src->value.u[k]; ++ } ++ ++ return true; ++} ++ ++static bool fold_round(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, ++ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) ++{ ++ enum hlsl_base_type type = dst_type->e.numeric.type; ++ unsigned int k; ++ ++ VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); ++ ++ for (k = 0; k < dst_type->e.numeric.dimx; ++k) ++ { ++ switch (type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ /* Somewhat unfortunately, constant folded round() rounds ++ * halfway cases towards positive infinity, as opposed to ++ * nearest even like vsir/TPF round_ne. */ ++ dst->u[k].f = floorf(src->value.u[k].f + 0.5f); ++ break; ++ ++ default: ++ FIXME("Fold 'round' for type %s.\n", debug_hlsl_type(ctx, dst_type)); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) + { +@@ -544,6 +616,36 @@ static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons + return true; + } + ++static bool fold_sin(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, ++ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) ++{ ++ enum hlsl_base_type type = dst_type->e.numeric.type; ++ unsigned int k; ++ ++ VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); ++ ++ for (k = 0; k < dst_type->e.numeric.dimx; ++k) ++ { ++ switch (type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ dst->u[k].f = sinf(src->value.u[k].f); ++ break; ++ ++ case HLSL_TYPE_DOUBLE: ++ dst->u[k].d = sin(src->value.u[k].d); ++ break; ++ ++ default: ++ FIXME("Fold 'sin' for type %s.\n", debug_hlsl_type(ctx, dst_type)); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) + { +@@ -974,6 +1076,44 @@ static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c + return true; + } + ++static bool fold_mad(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, ++ const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3) ++{ ++ enum hlsl_base_type type = dst_type->e.numeric.type; ++ unsigned int k; ++ ++ VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type); ++ VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type); ++ VKD3D_ASSERT(type == src3->node.data_type->e.numeric.type); ++ ++ for (k = 0; k < dst_type->e.numeric.dimx; ++k) ++ { ++ switch (type) ++ { ++ case HLSL_TYPE_FLOAT: ++ case HLSL_TYPE_HALF: ++ dst->u[k].f = fmaf(src1->value.u[k].f, src2->value.u[k].f, src3->value.u[k].f); ++ break; ++ ++ case HLSL_TYPE_DOUBLE: ++ dst->u[k].d = fma(src1->value.u[k].d, src2->value.u[k].d, src3->value.u[k].d); ++ break; ++ ++ case HLSL_TYPE_INT: ++ case HLSL_TYPE_MIN16UINT: ++ case HLSL_TYPE_UINT: ++ dst->u[k].u = src1->value.u[k].u * src2->value.u[k].u + src3->value.u[k].u; ++ break; ++ ++ default: ++ FIXME("Fold 'mad' for type %s.\n", debug_hlsl_type(ctx, dst_type)); ++ return false; ++ } ++ } ++ ++ return true; ++} ++ + static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) + { +@@ -1263,6 +1403,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_ceil(ctx, &res, instr->data_type, arg1); + break; + ++ case HLSL_OP1_COS: ++ success = fold_cos(ctx, &res, instr->data_type, arg1); ++ break; ++ + case HLSL_OP1_EXP2: + success = fold_exp2(ctx, &res, instr->data_type, arg1); + break; +@@ -1291,6 +1435,14 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc); + break; + ++ case HLSL_OP1_REINTERPRET: ++ success = fold_reinterpret(ctx, &res, instr->data_type, arg1); ++ break; ++ ++ case HLSL_OP1_ROUND: ++ success = fold_round(ctx, &res, instr->data_type, arg1); ++ break; ++ + case HLSL_OP1_RSQ: + success = fold_rsq(ctx, &res, instr->data_type, arg1, &instr->loc); + break; +@@ -1299,6 +1451,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_sat(ctx, &res, instr->data_type, arg1); + break; + ++ case HLSL_OP1_SIN: ++ success = fold_sin(ctx, &res, instr->data_type, arg1); ++ break; ++ + case HLSL_OP1_SQRT: + success = fold_sqrt(ctx, &res, instr->data_type, arg1, &instr->loc); + break; +@@ -1373,6 +1529,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3); + break; + ++ case HLSL_OP3_MAD: ++ success = fold_mad(ctx, &res, instr->data_type, arg1, arg2, arg3); ++ break; ++ + case HLSL_OP3_TERNARY: + success = fold_ternary(ctx, &res, instr->data_type, arg1, arg2, arg3); + break; +@@ -1393,74 +1553,6 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, + return success; + } + +-static bool constant_is_zero(struct hlsl_ir_constant *const_arg) +-{ +- struct hlsl_type *data_type = const_arg->node.data_type; +- unsigned int k; +- +- for (k = 0; k < data_type->e.numeric.dimx; ++k) +- { +- switch (data_type->e.numeric.type) +- { +- case HLSL_TYPE_FLOAT: +- case HLSL_TYPE_HALF: +- if (const_arg->value.u[k].f != 0.0f) +- return false; +- break; +- +- case HLSL_TYPE_DOUBLE: +- if (const_arg->value.u[k].d != 0.0) +- return false; +- break; +- +- case HLSL_TYPE_UINT: +- case HLSL_TYPE_INT: +- case HLSL_TYPE_BOOL: +- case HLSL_TYPE_MIN16UINT: +- if (const_arg->value.u[k].u != 0) +- return false; +- break; +- } +- } +- return true; +-} +- +-static bool constant_is_one(struct hlsl_ir_constant *const_arg) +-{ +- struct hlsl_type *data_type = const_arg->node.data_type; +- unsigned int k; +- +- for (k = 0; k < data_type->e.numeric.dimx; ++k) +- { +- switch (data_type->e.numeric.type) +- { +- case HLSL_TYPE_FLOAT: +- case HLSL_TYPE_HALF: +- if (const_arg->value.u[k].f != 1.0f) +- return false; +- break; +- +- case HLSL_TYPE_DOUBLE: +- if (const_arg->value.u[k].d != 1.0) +- return false; +- break; +- +- case HLSL_TYPE_UINT: +- case HLSL_TYPE_INT: +- case HLSL_TYPE_MIN16UINT: +- if (const_arg->value.u[k].u != 1) +- return false; +- break; +- +- case HLSL_TYPE_BOOL: +- if (const_arg->value.u[k].u != ~0) +- return false; +- break; +- } +- } +- return true; +-} +- + bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) + { + struct hlsl_ir_constant *const_arg = NULL; +@@ -1502,26 +1594,26 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in + switch (expr->op) + { + case HLSL_OP2_ADD: +- if (constant_is_zero(const_arg)) ++ if (hlsl_constant_is_zero(const_arg)) + res_node = mut_arg; + break; + + case HLSL_OP2_MUL: +- if (constant_is_one(const_arg)) ++ if (hlsl_constant_is_one(const_arg)) + res_node = mut_arg; + break; + + case HLSL_OP2_LOGIC_AND: +- if (constant_is_zero(const_arg)) ++ if (hlsl_constant_is_zero(const_arg)) + res_node = &const_arg->node; +- else if (constant_is_one(const_arg)) ++ else if (hlsl_constant_is_one(const_arg)) + res_node = mut_arg; + break; + + case HLSL_OP2_LOGIC_OR: +- if (constant_is_zero(const_arg)) ++ if (hlsl_constant_is_zero(const_arg)) + res_node = mut_arg; +- else if (constant_is_one(const_arg)) ++ else if (hlsl_constant_is_one(const_arg)) + res_node = &const_arg->node; + break; + +@@ -1649,6 +1741,9 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst + if (instr->data_type->class > HLSL_CLASS_VECTOR) + return false; + ++ if (expr->operands[2].node) ++ return false; ++ + hlsl_block_init(&block); + + arg1 = expr->operands[0].node; +diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c +index 23e059a3490..29bf62709eb 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/ir.c ++++ b/libs/vkd3d/libs/vkd3d-shader/ir.c +@@ -27,8 +27,53 @@ struct vsir_transformation_context + uint64_t config_flags; + const struct vkd3d_shader_compile_info *compile_info; + struct vkd3d_shader_message_context *message_context; ++ struct vkd3d_shader_location null_location; + }; + ++static void vsir_transformation_context_init(struct vsir_transformation_context *ctx, ++ struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, ++ struct vkd3d_shader_message_context *message_context) ++{ ++ *ctx = (struct vsir_transformation_context) ++ { ++ .result = VKD3D_OK, ++ .program = program, ++ .config_flags = config_flags, ++ .compile_info = compile_info, ++ .message_context = message_context, ++ .null_location = {.source_name = compile_info->source_name}, ++ }; ++}; ++ ++const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error) ++{ ++ static const char * const names[] = ++ { ++ [VSIR_DATA_BOOL ] = "bool", ++ [VSIR_DATA_F16 ] = "half", ++ [VSIR_DATA_F32 ] = "float", ++ [VSIR_DATA_F64 ] = "double", ++ [VSIR_DATA_I16 ] = "i16", ++ [VSIR_DATA_I32 ] = "int", ++ [VSIR_DATA_I64 ] = "i64", ++ [VSIR_DATA_U8 ] = "uint8", ++ [VSIR_DATA_U16 ] = "uint16", ++ [VSIR_DATA_U32 ] = "uint", ++ [VSIR_DATA_U64 ] = "uint64", ++ [VSIR_DATA_SNORM ] = "snorm", ++ [VSIR_DATA_UNORM ] = "unorm", ++ [VSIR_DATA_OPAQUE ] = "opaque", ++ [VSIR_DATA_MIXED ] = "mixed", ++ [VSIR_DATA_CONTINUED] = "", ++ [VSIR_DATA_UNUSED ] = "", ++ }; ++ ++ if ((size_t)t < ARRAY_SIZE(names)) ++ return names[t] ? names[t] : error; ++ ++ return error; ++} ++ + const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) + { + static const char * const names[] = +@@ -373,6 +418,183 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) + return error; + } + ++static struct vkd3d_shader_param_node *shader_param_allocator_node_create( ++ struct vkd3d_shader_param_allocator *allocator) ++{ ++ struct vkd3d_shader_param_node *node; ++ ++ if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride])))) ++ return NULL; ++ node->next = NULL; ++ ++ return node; ++} ++ ++static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, size_t count, size_t stride) ++{ ++ allocator->count = max(count, MAX_REG_OUTPUT); ++ allocator->stride = stride; ++ allocator->head = NULL; ++ allocator->current = NULL; ++ allocator->index = allocator->count; ++} ++ ++static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator) ++{ ++ struct vkd3d_shader_param_node *current = allocator->head; ++ ++ while (current) ++ { ++ struct vkd3d_shader_param_node *next = current->next; ++ vkd3d_free(current); ++ current = next; ++ } ++} ++ ++void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) ++{ ++ void *params; ++ ++ if (!allocator->current || count > allocator->count - allocator->index) ++ { ++ struct vkd3d_shader_param_node *next; ++ ++ allocator->count = max(allocator->count, count); ++ if (!(next = shader_param_allocator_node_create(allocator))) ++ return NULL; ++ if (allocator->current) ++ allocator->current->next = next; ++ else ++ allocator->head = next; ++ allocator->current = next; ++ allocator->index = 0; ++ } ++ ++ params = &allocator->current->param[allocator->index * allocator->stride]; ++ allocator->index += count; ++ ++ return params; ++} ++ ++bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *array, size_t reserve) ++{ ++ if (!vkd3d_array_reserve((void **)&array->elements, &array->capacity, reserve, sizeof(*array->elements))) ++ { ++ ERR("Failed to allocate instructions.\n"); ++ return false; ++ } ++ ++ return true; ++} ++ ++bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *array, size_t idx, size_t count) ++{ ++ VKD3D_ASSERT(idx <= array->count); ++ ++ if (!shader_instruction_array_reserve(array, array->count + count)) ++ return false; ++ ++ memmove(&array->elements[idx + count], &array->elements[idx], (array->count - idx) * sizeof(*array->elements)); ++ memset(&array->elements[idx], 0, count * sizeof(*array->elements)); ++ array->count += count; ++ ++ return true; ++} ++ ++bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *array, ++ struct vkd3d_shader_immediate_constant_buffer *icb) ++{ ++ if (!vkd3d_array_reserve((void **)&array->icbs, &array->icb_capacity, array->icb_count + 1, sizeof(*array->icbs))) ++ return false; ++ ++ array->icbs[array->icb_count++] = icb; ++ ++ return true; ++} ++ ++static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( ++ struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count); ++ ++static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, ++ struct vkd3d_shader_instruction_array *array) ++{ ++ size_t i; ++ ++ for (i = 0; i < reg->idx_count; ++i) ++ { ++ if (!reg->idx[i].rel_addr) ++ continue; ++ ++ if (!(reg->idx[i].rel_addr = shader_instruction_array_clone_src_params(array, reg->idx[i].rel_addr, 1))) ++ return false; ++ } ++ ++ return true; ++} ++ ++static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( ++ struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_dst_param *params, size_t count) ++{ ++ struct vkd3d_shader_dst_param *dst_params; ++ size_t i; ++ ++ if (!(dst_params = shader_dst_param_allocator_get(&array->dst_params, count))) ++ return NULL; ++ ++ memcpy(dst_params, params, count * sizeof(*params)); ++ for (i = 0; i < count; ++i) ++ { ++ if (!shader_register_clone_relative_addresses(&dst_params[i].reg, array)) ++ return NULL; ++ } ++ ++ return dst_params; ++} ++ ++static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( ++ struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count) ++{ ++ struct vkd3d_shader_src_param *src_params; ++ size_t i; ++ ++ if (!(src_params = shader_src_param_allocator_get(&array->src_params, count))) ++ return NULL; ++ ++ memcpy(src_params, params, count * sizeof(*params)); ++ for (i = 0; i < count; ++i) ++ { ++ if (!shader_register_clone_relative_addresses(&src_params[i].reg, array)) ++ return NULL; ++ } ++ ++ return src_params; ++} ++ ++static void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *array) ++{ ++ unsigned int i; ++ ++ vkd3d_free(array->elements); ++ shader_param_allocator_destroy(&array->dst_params); ++ shader_param_allocator_destroy(&array->src_params); ++ for (i = 0; i < array->icb_count; ++i) ++ { ++ vkd3d_free(array->icbs[i]); ++ } ++ vkd3d_free(array->icbs); ++} ++ ++static bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *array, size_t reserve) ++{ ++ memset(array, 0, sizeof(*array)); ++ /* Size the parameter initial allocations so they are large enough for most shaders. The ++ * code path for chained allocations will be tested if a few shaders need to use it. */ ++ shader_param_allocator_init(&array->dst_params, reserve - reserve / 8u, sizeof(struct vkd3d_shader_dst_param)); ++ shader_param_allocator_init(&array->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); ++ ++ return shader_instruction_array_reserve(array, reserve); ++} ++ + static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, + unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) + { +@@ -864,6 +1086,23 @@ static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *i + vsir_instruction_init(ins, &location, VSIR_OP_NOP); + } + ++/* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the ++ * destination is in use. This seems like a reasonable requirement given how this is currently used. */ ++static bool vsir_program_iterator_clone_instruction(struct vsir_program_iterator *dst_it, ++ const struct vkd3d_shader_instruction *src) ++{ ++ struct vkd3d_shader_instruction *dst = vsir_program_iterator_current(dst_it); ++ ++ *dst = *src; ++ ++ if (dst->dst_count && !(dst->dst = shader_instruction_array_clone_dst_params(dst_it->array, ++ dst->dst, dst->dst_count))) ++ return false; ++ ++ return !dst->src_count || !!(dst->src = shader_instruction_array_clone_src_params(dst_it->array, ++ dst->src, dst->src_count)); ++} ++ + static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, + enum vsir_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap) + { +@@ -1669,10 +1908,22 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr + + switch (ins->opcode) + { ++ case VSIR_OP_IFC: ++ ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); ++ break; ++ ++ case VSIR_OP_SINCOS: ++ ret = vsir_program_lower_sm1_sincos(program, &it); ++ break; ++ + case VSIR_OP_TEXCRD: + ret = vsir_program_lower_texcrd(program, ins, message_context); + break; + ++ case VSIR_OP_TEXKILL: ++ ret = vsir_program_lower_texkill(program, &it, &tmp_idx); ++ break; ++ + case VSIR_OP_TEXLD: + if (program->shader_version.major == 1) + ret = vsir_program_lower_texld_sm1(program, ins, message_context); +@@ -1682,6 +1933,14 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr + ret = vsir_program_lower_texld(program, ins, message_context); + break; + ++ case VSIR_OP_TEXLDD: ++ ret = vsir_program_lower_texldd(program, ins); ++ break; ++ ++ case VSIR_OP_TEXLDL: ++ ret = vsir_program_lower_texldl(program, ins); ++ break; ++ + default: + ret = VKD3D_OK; + break; +@@ -1698,7 +1957,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + struct vsir_transformation_context *ctx) + { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- struct vkd3d_shader_message_context *message_context = ctx->message_context; + struct vkd3d_shader_instruction *ins; + unsigned int tmp_idx = ~0u; + enum vkd3d_result ret; +@@ -1707,16 +1965,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + { + switch (ins->opcode) + { +- case VSIR_OP_IFC: +- if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0) +- return ret; +- break; +- +- case VSIR_OP_TEXKILL: +- if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) +- return ret; +- break; +- + case VSIR_OP_MAD: + if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) + return ret; +@@ -1725,6 +1973,8 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + case VSIR_OP_DCL: + case VSIR_OP_DCL_CONSTANT_BUFFER: + case VSIR_OP_DCL_GLOBAL_FLAGS: ++ case VSIR_OP_DCL_INPUT_PRIMITIVE: ++ case VSIR_OP_DCL_OUTPUT_TOPOLOGY: + case VSIR_OP_DCL_SAMPLER: + case VSIR_OP_DCL_TEMPS: + case VSIR_OP_DCL_TESSELLATOR_DOMAIN: +@@ -1765,25 +2015,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr + break; + + case VSIR_OP_SINCOS: +- if (ins->dst_count == 1) +- { +- if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) +- return ret; +- } +- else +- { +- if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) +- return ret; +- } +- break; +- +- case VSIR_OP_TEXLDD: +- if ((ret = vsir_program_lower_texldd(program, ins)) < 0) +- return ret; +- break; +- +- case VSIR_OP_TEXLDL: +- if ((ret = vsir_program_lower_texldl(program, ins)) < 0) ++ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) + return ret; + break; + +@@ -1823,16 +2055,19 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; ++ struct vkd3d_shader_location loc; + +- ins = vsir_program_iterator_tail(&it); +- if (ins && ins->opcode == VSIR_OP_RET) ++ if (!(ins = vsir_program_iterator_tail(&it))) ++ loc = ctx->null_location; ++ else if (ins->opcode == VSIR_OP_RET) + return VKD3D_OK; ++ else ++ loc = ins->location; + + if (!(ins = vsir_program_append(program))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); ++ vsir_instruction_init(ins, &loc, VSIR_OP_RET); + + return VKD3D_OK; + } +@@ -1923,7 +2158,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra + struct vsir_transformation_context *ctx) + { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_location loc = ctx->null_location; + struct vkd3d_shader_instruction *ins; + unsigned int i; + +@@ -1937,15 +2172,16 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) ++ { ++ loc = ins->location; + break; ++ } + } + +- vsir_program_iterator_prev(&it); +- if (!vsir_program_iterator_insert_after(&it, 1)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = vsir_program_iterator_next(&it); + +- vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = 0; + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; +@@ -2162,10 +2398,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program + continue; + + loc = ins->location; +- vsir_program_iterator_prev(&it); +- if (!vsir_program_iterator_insert_after(&it, uninit_varying_count)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, uninit_varying_count))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = vsir_program_iterator_next(&it); + + for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) + { +@@ -2200,8 +2434,6 @@ struct hull_flattener + { + struct vsir_program *program; + +- unsigned int instance_count; +- unsigned int phase_body_idx; + enum vkd3d_shader_opcode phase; + struct vkd3d_shader_location last_ret_location; + unsigned int *ssa_map; +@@ -2213,68 +2445,6 @@ static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flat + return flattener->phase == VSIR_OP_HS_FORK_PHASE || flattener->phase == VSIR_OP_HS_JOIN_PHASE; + } + +-struct shader_phase_location +-{ +- unsigned int index; +- unsigned int instance_count; +- unsigned int instruction_count; +-}; +- +-struct shader_phase_location_array +-{ +- /* Unlikely worst case: one phase for each component of each output register. */ +- struct shader_phase_location locations[MAX_REG_OUTPUT * VKD3D_VEC4_SIZE]; +- unsigned int count; +-}; +- +-static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index, +- struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations) +-{ +- struct shader_phase_location *loc; +- bool b; +- +- if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) +- { +- b = flattener_is_in_fork_or_join_phase(normaliser); +- /* Reset the phase info. */ +- normaliser->phase_body_idx = ~0u; +- normaliser->phase = ins->opcode; +- normaliser->instance_count = 1; +- /* Leave the first occurrence and delete the rest. */ +- if (b) +- vkd3d_shader_instruction_make_nop(ins); +- return; +- } +- else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT +- || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) +- { +- normaliser->instance_count = ins->declaration.count + !ins->declaration.count; +- vkd3d_shader_instruction_make_nop(ins); +- return; +- } +- +- if (normaliser->phase == VSIR_OP_INVALID || vsir_instruction_is_dcl(ins)) +- return; +- +- if (normaliser->phase_body_idx == ~0u) +- normaliser->phase_body_idx = index; +- +- if (ins->opcode == VSIR_OP_RET) +- { +- normaliser->last_ret_location = ins->location; +- vkd3d_shader_instruction_make_nop(ins); +- if (locations->count >= ARRAY_SIZE(locations->locations)) +- { +- FIXME("Insufficient space for phase location.\n"); +- return; +- } +- loc = &locations->locations[locations->count++]; +- loc->index = normaliser->phase_body_idx; +- loc->instance_count = normaliser->instance_count; +- loc->instruction_count = index - normaliser->phase_body_idx; +- } +-} +- + static void flattener_fixup_ssa_register(struct hull_flattener *normaliser, + struct vkd3d_shader_register *reg, unsigned int instance_id) + { +@@ -2337,54 +2507,109 @@ static void flattener_fixup_registers(struct hull_flattener *normaliser, + flattener_fixup_register_indices(normaliser, &ins->dst[i].reg, instance_id); + } + +-static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser, +- struct shader_phase_location_array *locations) ++static enum vkd3d_result flattener_replicate_location(struct hull_flattener *normaliser, ++ struct vsir_program_iterator *it, size_t instance_count, size_t instruction_count) + { +- struct vkd3d_shader_instruction_array *instructions = &normaliser->program->instructions; +- struct shader_phase_location *loc; +- unsigned int i, j, k, end, count; +- +- for (i = 0, count = 0; i < locations->count; ++i) +- count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count; ++ struct vsir_program_iterator dst_it, src_it, first_it; ++ struct vkd3d_shader_instruction *ins; ++ unsigned int i, j; ++ size_t count; + +- if (!shader_instruction_array_reserve(instructions, instructions->count + count)) ++ VKD3D_ASSERT(instance_count); ++ count = (instance_count - 1) * instruction_count; ++ if (!vsir_program_iterator_insert_before(it, &first_it, count)) + return VKD3D_ERROR_OUT_OF_MEMORY; +- end = instructions->count; +- instructions->count += count; + +- for (i = locations->count; i > 0; --i) ++ /* Make a copy of the non-dcl instructions for each instance. */ ++ dst_it = first_it; ++ for (i = 1; i < instance_count; ++i) + { +- loc = &locations->locations[i - 1]; +- j = loc->index + loc->instruction_count; +- memmove(&instructions->elements[j + count], &instructions->elements[j], +- (end - j) * sizeof(*instructions->elements)); +- end = j; +- count -= (loc->instance_count - 1) * loc->instruction_count; +- loc->index += count; ++ src_it = *it; ++ for (j = 0; j < instruction_count; ++j) ++ { ++ if (!vsir_program_iterator_clone_instruction(&dst_it, vsir_program_iterator_current(&src_it))) ++ return VKD3D_ERROR_OUT_OF_MEMORY; ++ ++ vsir_program_iterator_next(&dst_it); ++ vsir_program_iterator_next(&src_it); ++ } ++ } ++ /* Replace each reference to the instance id with a constant instance id. */ ++ *it = first_it; ++ for (i = 0; i < instance_count; ++i) ++ { ++ if (i) ++ memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); ++ ++ for (j = 0; j < instruction_count; ++j) ++ { ++ ins = vsir_program_iterator_current(it); ++ flattener_fixup_registers(normaliser, ins, i); ++ vsir_program_iterator_next(it); ++ } + } + +- for (i = 0, count = 0; i < locations->count; ++i) ++ return VKD3D_OK; ++} ++ ++static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser) ++{ ++ struct vsir_program_iterator it = vsir_program_iterator(&normaliser->program->instructions); ++ struct vsir_program_iterator phase_body_it; ++ struct vkd3d_shader_instruction *ins; ++ bool b, phase_body_it_valid = false; ++ unsigned int instruction_count = 0; ++ unsigned int instance_count = 0; ++ enum vkd3d_result res; ++ ++ normaliser->phase = VSIR_OP_INVALID; ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- loc = &locations->locations[i]; +- /* Make a copy of the non-dcl instructions for each instance. */ +- for (j = 1; j < loc->instance_count; ++j) ++ if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) + { +- for (k = 0; k < loc->instruction_count; ++k) +- { +- if (!shader_instruction_array_clone_instruction(instructions, +- loc->index + loc->instruction_count * j + k, loc->index + k)) +- return VKD3D_ERROR_OUT_OF_MEMORY; +- } ++ b = flattener_is_in_fork_or_join_phase(normaliser); ++ /* Reset the phase info. */ ++ phase_body_it_valid = false; ++ normaliser->phase = ins->opcode; ++ instance_count = 1; ++ instruction_count = 0; ++ /* Leave the first occurrence and delete the rest. */ ++ if (b) ++ vkd3d_shader_instruction_make_nop(ins); ++ continue; ++ } ++ else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT ++ || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) ++ { ++ instance_count = ins->declaration.count + !ins->declaration.count; ++ vkd3d_shader_instruction_make_nop(ins); ++ ++instruction_count; ++ continue; + } +- /* Replace each reference to the instance id with a constant instance id. */ +- for (j = 0; j < loc->instance_count; ++j) ++ ++ if (normaliser->phase == VSIR_OP_INVALID) ++ continue; ++ ++ if (!phase_body_it_valid && !vsir_instruction_is_dcl(ins)) + { +- if (j != 0) +- memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); ++ phase_body_it_valid = true; ++ phase_body_it = it; ++ instruction_count = 0; ++ } + +- for (k = 0; k < loc->instruction_count; ++k) +- flattener_fixup_registers(normaliser, +- &instructions->elements[loc->index + loc->instruction_count * j + k], j); ++ if (ins->opcode == VSIR_OP_RET) ++ { ++ normaliser->last_ret_location = ins->location; ++ vkd3d_shader_instruction_make_nop(ins); ++ it = phase_body_it; ++ if ((res = flattener_replicate_location(normaliser, &it, ++ instance_count, instruction_count)) < 0) ++ return res; ++ phase_body_it_valid = false; ++ } ++ else ++ { ++ ++instruction_count; + } + } + +@@ -2394,19 +2619,10 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali + static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { +- struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- struct shader_phase_location_array locations; + struct hull_flattener flattener = {program}; + struct vkd3d_shader_instruction *ins; + enum vkd3d_result result = VKD3D_OK; +- unsigned int i; + +- flattener.phase = VSIR_OP_INVALID; +- locations.count = 0; +- for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) +- { +- flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations); +- } + bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); + bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); + +@@ -2414,8 +2630,7 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro + if (!(flattener.ssa_map = vkd3d_calloc(flattener.orig_ssa_count, sizeof(*flattener.ssa_map)))) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- result = flattener_flatten_phases(&flattener, &locations); +- ++ result = flattener_flatten_phases(&flattener); + vkd3d_free(flattener.ssa_map); + flattener.ssa_map = NULL; + +@@ -2481,8 +2696,8 @@ static void shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param + } + + static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser, +- const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst, +- const struct vkd3d_shader_location *location) ++ const struct shader_signature *s, unsigned int input_control_point_count, ++ struct vsir_program_iterator *dst_it, const struct vkd3d_shader_location *location) + { + struct vkd3d_shader_instruction *ins; + const struct signature_element *e; +@@ -2491,17 +2706,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + for (i = 0; i < s->element_count; ++i) + count += !!s->elements[i].used_mask; + +- if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(dst_it, count))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- +- memmove(&normaliser->instructions.elements[dst + count], &normaliser->instructions.elements[dst], +- (normaliser->instructions.count - dst) * sizeof(*normaliser->instructions.elements)); +- normaliser->instructions.count += count; +- +- ins = &normaliser->instructions.elements[dst]; + vsir_instruction_init(ins, location, VSIR_OP_HS_CONTROL_POINT_PHASE); + +- ++ins; ++ ins = vsir_program_iterator_next(dst_it); + + for (i = 0; i < s->element_count; ++i) + { +@@ -2533,7 +2742,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p + ins->src[0].reg.idx[0].rel_addr = normaliser->outpointid_param; + ins->src[0].reg.idx[1].offset = e->register_index; + +- ++ins; ++ ins = vsir_program_iterator_next(dst_it); + } + + vsir_instruction_init(ins, location, VSIR_OP_RET); +@@ -2605,8 +2814,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i + case VSIR_OP_HS_JOIN_PHASE: + /* ins may be relocated if the instruction array expands. */ + location = ins->location; +- ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature, +- input_control_point_count, i, &location); ++ ret = control_point_normaliser_emit_hs_input(&normaliser, ++ &program->input_signature, input_control_point_count, &it, &location); + program->instructions = normaliser.instructions; + program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; + return ret; +@@ -4233,9 +4442,11 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs + struct vsir_transformation_context *ctx) + { + unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label; +- size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ size_t ins_capacity = 0, ins_count = 0, map_capacity = 0, map_count = 0; + struct vkd3d_shader_instruction *instructions = NULL; + struct lower_switch_to_if_ladder_block_mapping *block_map = NULL; ++ struct vkd3d_shader_instruction *ins; + + VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); + +@@ -4245,9 +4456,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs + /* First subpass: convert SWITCH_MONOLITHIC instructions to + * selection ladders, keeping a map between blocks before and + * after the subpass. */ +- for (i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + unsigned int case_count, j, default_label; + + switch (ins->opcode) +@@ -4800,8 +5010,8 @@ struct vsir_cfg + { + struct vkd3d_shader_message_context *message_context; + struct vsir_program *program; +- size_t function_begin; +- size_t function_end; ++ struct vsir_program_iterator function_begin; ++ struct vsir_program_iterator function_end; + struct vsir_block *blocks; + struct vsir_block *entry; + size_t block_count; +@@ -5046,10 +5256,11 @@ static void vsir_cfg_dump_structured_program(struct vsir_cfg *cfg) + } + + static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program *program, +- struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, +- size_t *pos) ++ struct vkd3d_shader_message_context *message_context, ++ struct vsir_cfg_emit_target *target, struct vsir_program_iterator *it) + { + struct vsir_block *current_block = NULL; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_result ret; + size_t i; + +@@ -5058,7 +5269,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program + cfg->program = program; + cfg->block_count = program->block_count; + cfg->target = target; +- cfg->function_begin = *pos; ++ cfg->function_begin = *it; + + vsir_block_list_init(&cfg->order); + +@@ -5068,12 +5279,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program + if (TRACE_ON()) + vkd3d_string_buffer_init(&cfg->debug_buffer); + +- for (i = *pos; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) + { +- struct vkd3d_shader_instruction *instruction = &program->instructions.elements[i]; + bool finish = false; + +- switch (instruction->opcode) ++ switch (ins->opcode) + { + case VSIR_OP_PHI: + case VSIR_OP_SWITCH_MONOLITHIC: +@@ -5081,7 +5291,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program + + case VSIR_OP_LABEL: + { +- unsigned int label = label_from_src_param(&instruction->src[0]); ++ unsigned int label = label_from_src_param(&ins->src[0]); + + VKD3D_ASSERT(!current_block); + VKD3D_ASSERT(label > 0); +@@ -5090,7 +5300,8 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program + VKD3D_ASSERT(current_block->label == 0); + if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0) + goto fail; +- current_block->begin = &program->instructions.elements[i + 1]; ++ current_block->begin = vsir_program_iterator_next(it); ++ vsir_program_iterator_prev(it); + if (!cfg->entry) + cfg->entry = current_block; + break; +@@ -5099,7 +5310,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program + case VSIR_OP_BRANCH: + case VSIR_OP_RET: + VKD3D_ASSERT(current_block); +- current_block->end = instruction; ++ current_block->end = ins; + current_block = NULL; + break; + +@@ -5118,8 +5329,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program + break; + } + +- *pos = i; +- cfg->function_end = *pos; ++ cfg->function_end = *it; + + for (i = 0; i < cfg->block_count; ++i) + { +@@ -6616,13 +6826,13 @@ static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg) + } + + static enum vkd3d_result vsir_program_structurize_function(struct vsir_program *program, +- struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, +- size_t *pos) ++ struct vkd3d_shader_message_context *message_context, ++ struct vsir_cfg_emit_target *target, struct vsir_program_iterator *it) + { + enum vkd3d_result ret; + struct vsir_cfg cfg; + +- if ((ret = vsir_cfg_init(&cfg, program, message_context, target, pos)) < 0) ++ if ((ret = vsir_cfg_init(&cfg, program, message_context, target, it)) < 0) + return ret; + + vsir_cfg_compute_dominators(&cfg); +@@ -6653,10 +6863,11 @@ out: + static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + struct vsir_cfg_emit_target target = {0}; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_result ret; +- size_t i; + + VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); + +@@ -6666,19 +6877,17 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, + if (!reserve_instructions(&target.instructions, &target.ins_capacity, program->instructions.count)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- for (i = 0; i < program->instructions.count;) ++ for (ins = vsir_program_iterator_head(&it); ins;) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + switch (ins->opcode) + { + case VSIR_OP_LABEL: + VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); + TRACE("Structurizing a non-hull shader.\n"); +- if ((ret = vsir_program_structurize_function(program, message_context, +- &target, &i)) < 0) ++ if ((ret = vsir_program_structurize_function(program, message_context, &target, &it)) < 0) + goto fail; +- VKD3D_ASSERT(i == program->instructions.count); ++ ins = vsir_program_iterator_current(&it); ++ VKD3D_ASSERT(!ins); + break; + + case VSIR_OP_HS_CONTROL_POINT_PHASE: +@@ -6687,17 +6896,17 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, + VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); + TRACE("Structurizing phase %u of a hull shader.\n", ins->opcode); + target.instructions[target.ins_count++] = *ins; +- ++i; +- if ((ret = vsir_program_structurize_function(program, message_context, +- &target, &i)) < 0) ++ vsir_program_iterator_next(&it); ++ if ((ret = vsir_program_structurize_function(program, message_context, &target, &it)) < 0) + goto fail; ++ ins = vsir_program_iterator_current(&it); + break; + + default: + if (!reserve_instructions(&target.instructions, &target.ins_capacity, target.ins_count + 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + target.instructions[target.ins_count++] = *ins; +- ++i; ++ ins = vsir_program_iterator_next(&it); + break; + } + } +@@ -6742,8 +6951,10 @@ static void register_map_undominated_use(struct vkd3d_shader_register *reg, stru + static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct vsir_cfg *cfg) + { + struct vsir_program *program = cfg->program; ++ struct vkd3d_shader_instruction *ins, *end; + struct ssas_to_temps_alloc alloc = {0}; + struct vsir_block **origin_blocks; ++ struct vsir_program_iterator it; + unsigned int j; + size_t i; + +@@ -6761,7 +6972,6 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v + for (i = 0; i < cfg->block_count; ++i) + { + struct vsir_block *block = &cfg->blocks[i]; +- struct vkd3d_shader_instruction *ins; + + if (block->label == 0) + continue; +@@ -6779,7 +6989,6 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v + for (i = 0; i < cfg->block_count; ++i) + { + struct vsir_block *block = &cfg->blocks[i]; +- struct vkd3d_shader_instruction *ins; + + if (block->label == 0) + continue; +@@ -6796,10 +7005,10 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v + + TRACE("Emitting temps for %u values with undominated usage.\n", alloc.next_temp_idx - program->temp_count); + +- for (i = cfg->function_begin; i < cfg->function_end; ++i) ++ it = cfg->function_begin; ++ end = vsir_program_iterator_current(&cfg->function_end); ++ for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + for (j = 0; j < ins->dst_count; ++j) + materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst[j].reg); + +@@ -6815,14 +7024,13 @@ done: + return VKD3D_OK; + } + +-static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function( +- struct vsir_program *program, struct vkd3d_shader_message_context *message_context, +- size_t *pos) ++static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function(struct vsir_program *program, ++ struct vkd3d_shader_message_context *message_context, struct vsir_program_iterator *it) + { + enum vkd3d_result ret; + struct vsir_cfg cfg; + +- if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, pos)) < 0) ++ if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, it)) < 0) + return ret; + + vsir_cfg_compute_dominators(&cfg); +@@ -6837,25 +7045,25 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_f + static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_result ret; +- size_t i; + + VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); + +- for (i = 0; i < program->instructions.count;) ++ for (ins = vsir_program_iterator_head(&it); ins;) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + switch (ins->opcode) + { + case VSIR_OP_LABEL: + VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); + TRACE("Materializing undominated SSAs in a non-hull shader.\n"); + if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( +- program, message_context, &i)) < 0) ++ program, message_context, &it)) < 0) + return ret; +- VKD3D_ASSERT(i == program->instructions.count); ++ ins = vsir_program_iterator_current(&it); ++ VKD3D_ASSERT(!ins); + break; + + case VSIR_OP_HS_CONTROL_POINT_PHASE: +@@ -6863,14 +7071,15 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru + case VSIR_OP_HS_JOIN_PHASE: + VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); + TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->opcode); +- ++i; ++ vsir_program_iterator_next(&it); + if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( +- program, message_context, &i)) < 0) ++ program, message_context, &it)) < 0) + return ret; ++ ins = vsir_program_iterator_current(&it); + break; + + default: +- ++i; ++ ins = vsir_program_iterator_next(&it); + break; + } + } +@@ -6881,7 +7090,6 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru + static bool use_flat_interpolation(const struct vsir_program *program, + struct vkd3d_shader_message_context *message_context, bool *flat) + { +- static const struct vkd3d_shader_location no_loc; + const struct vkd3d_shader_parameter1 *parameter; + + *flat = false; +@@ -6891,13 +7099,13 @@ static bool use_flat_interpolation(const struct vsir_program *program, + + if (parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unsupported flat interpolation parameter type %#x.", parameter->type); + return false; + } + if (parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid flat interpolation parameter data type %#x.", parameter->data_type); + return false; + } +@@ -6938,7 +7146,6 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) + { + struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; +- static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; + + static const struct +@@ -6959,10 +7166,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + + if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) + { +- vsir_program_iterator_prev(it); +- if (!vsir_program_iterator_insert_after(it, 1)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = vsir_program_iterator_next(it); + + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); + ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; +@@ -6972,10 +7177,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + return VKD3D_OK; + } + +- vsir_program_iterator_prev(it); +- if (!vsir_program_iterator_insert_after(it, 3)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 3))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = vsir_program_iterator_next(it); + + switch (ref->data_type) + { +@@ -6994,7 +7197,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr + break; + + case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4: +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, + "Alpha test reference data type must be a single component."); + return VKD3D_ERROR_INVALID_ARGUMENT; + +@@ -7036,7 +7239,6 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + struct vkd3d_shader_message_context *message_context = ctx->message_context; + const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL; + uint32_t colour_signature_idx, colour_temp = ~0u; +- static const struct vkd3d_shader_location no_loc; + enum vkd3d_shader_comparison_func compare_func; + struct vkd3d_shader_instruction *ins; + int ret; +@@ -7054,13 +7256,13 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro + + if (func->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unsupported alpha test function parameter type %#x.", func->type); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + if (func->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid alpha test function parameter data type %#x.", func->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -7117,10 +7319,8 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog + struct vkd3d_shader_instruction *ins; + unsigned int output_idx = 0; + +- vsir_program_iterator_prev(it); +- if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, vkd3d_popcount(mask) + 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = vsir_program_iterator_next(it); + + for (unsigned int i = 0; i < 8; ++i) + { +@@ -7166,7 +7366,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; + const struct vkd3d_shader_parameter1 *mask_parameter = NULL; + uint32_t position_signature_idx, position_temp, mask; +- static const struct vkd3d_shader_location no_loc; + struct signature_element *clip_element; + struct vkd3d_shader_instruction *ins; + unsigned int plane_count; +@@ -7188,13 +7387,13 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + + if (mask_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unsupported clip plane mask parameter type %#x.", mask_parameter->type); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + if (mask_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid clip plane mask parameter data type %#x.", mask_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -7207,7 +7406,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + { + if (signature->elements[i].sysval_semantic == VKD3D_SHADER_SV_CLIP_DISTANCE) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, ++ vkd3d_shader_error(ctx->message_context, &ctx->null_location, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, + "Clip planes cannot be used if the shader writes clip distance."); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -7215,7 +7414,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr + + if (!vsir_signature_find_sysval(signature, VKD3D_SHADER_SV_POSITION, 0, &position_signature_idx)) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, ++ vkd3d_shader_error(ctx->message_context, &ctx->null_location, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, + "Shader does not write position."); + return VKD3D_ERROR_INVALID_SHADER; + } +@@ -7288,10 +7487,8 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr + const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; + struct vkd3d_shader_instruction *ins; + +- vsir_program_iterator_prev(it); +- if (!vsir_program_iterator_insert_after(it, 1)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = vsir_program_iterator_next(it); + + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); +@@ -7307,7 +7504,6 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro + { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + const struct vkd3d_shader_parameter1 *size_parameter = NULL; +- static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; + + if (program->has_point_size) +@@ -7329,7 +7525,7 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro + + if (size_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid point size parameter data type %#x.", size_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -7356,7 +7552,6 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + { + const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); +- static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; + + if (!program->has_point_size) +@@ -7380,14 +7575,14 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra + + if (min_parameter && min_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid minimum point size parameter data type %#x.", min_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + + if (max_parameter && max_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid maximum point size parameter data type %#x.", max_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -7530,7 +7725,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2; + const struct vkd3d_shader_parameter1 *sprite_parameter = NULL; +- static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_location loc = ctx->null_location; + struct vkd3d_shader_instruction *ins; + bool used_texcoord = false; + unsigned int coord_temp; +@@ -7552,13 +7747,13 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + + if (sprite_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unsupported point sprite parameter type %#x.", sprite_parameter->type); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + if (sprite_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid point sprite parameter data type %#x.", sprite_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -7578,7 +7773,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) ++ { ++ loc = ins->location; + break; ++ } + } + + it2 = it; +@@ -7613,12 +7811,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + + if (used_texcoord) + { +- vsir_program_iterator_prev(&it); +- if (!vsir_program_iterator_insert_after(&it, 2)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 2))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ins = vsir_program_iterator_next(&it); + +- vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + dst_param_init_temp_float4(&ins->dst[0], coord_temp); + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; + vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); +@@ -7626,7 +7822,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + ins = vsir_program_iterator_next(&it); + +- vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + dst_param_init_temp_float4(&ins->dst[0], coord_temp); + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; + vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); +@@ -7668,15 +7864,12 @@ static enum vkd3d_result vsir_program_add_fog_input(struct vsir_program *program + } + + static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_fragment_mode mode, +- uint32_t fog_signature_idx, uint32_t colour_signature_idx, uint32_t colour_temp, +- size_t *ret_pos, struct vkd3d_shader_message_context *message_context) ++ struct vsir_program_iterator *it, enum vkd3d_shader_fog_fragment_mode mode, uint32_t fog_signature_idx, ++ uint32_t colour_signature_idx, uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) + { +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; +- struct vkd3d_shader_location loc = ret->location; ++ struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); ++ struct vkd3d_shader_location loc = ins->location; + uint32_t ssa_factor = program->ssa_count++; +- size_t pos = ret - instructions->elements; +- struct vkd3d_shader_instruction *ins; + uint32_t ssa_temp, ssa_temp2; + + switch (mode) +@@ -7687,16 +7880,11 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * add sr0, FOG_END, -vFOG.x + * mul_sat srFACTOR, sr0, FOG_SCALE + */ +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- *ret_pos = pos + 4; + + ssa_temp = program->ssa_count++; + +- ins = &program->instructions.elements[pos]; +- + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); +@@ -7705,12 +7893,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + ins->src[1].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_factor); + ins->dst[0].modifiers = VKD3DSPDM_SATURATE; + src_param_init_ssa_float(&ins->src[0], ssa_temp); + src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); ++ ins = vsir_program_iterator_next(it); ++ + break; + + case VKD3D_SHADER_FOG_FRAGMENT_EXP: +@@ -7719,16 +7910,11 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * mul sr0, FOG_SCALE, vFOG.x + * exp_sat srFACTOR, -sr0 + */ +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- *ret_pos = pos + 4; + + ssa_temp = program->ssa_count++; + +- ins = &program->instructions.elements[pos]; +- + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); +@@ -7736,12 +7922,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + ins->src[1].reg.idx[0].offset = fog_signature_idx; + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); + dst_param_init_ssa_float(&ins->dst[0], ssa_factor); + ins->dst[0].modifiers = VKD3DSPDM_SATURATE; + src_param_init_ssa_float(&ins->src[0], ssa_temp); + ins->src[0].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + break; + + case VKD3D_SHADER_FOG_FRAGMENT_EXP2: +@@ -7751,17 +7939,12 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * mul sr1, sr0, sr0 + * exp_sat srFACTOR, -sr1 + */ +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 5)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 5))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- *ret_pos = pos + 5; + + ssa_temp = program->ssa_count++; + ssa_temp2 = program->ssa_count++; + +- ins = &program->instructions.elements[pos]; +- + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); +@@ -7769,17 +7952,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + ins->src[1].reg.idx[0].offset = fog_signature_idx; + ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); + dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); + src_param_init_ssa_float(&ins->src[0], ssa_temp); + src_param_init_ssa_float(&ins->src[1], ssa_temp); ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); + dst_param_init_ssa_float(&ins->dst[0], ssa_factor); + ins->dst[0].modifiers = VKD3DSPDM_SATURATE; + src_param_init_ssa_float(&ins->src[0], ssa_temp2); + ins->src[0].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + break; + + default: +@@ -7792,18 +7978,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + * mad oC0, sr0, srFACTOR, FOG_COLOUR + */ + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); + dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); + src_param_init_temp_float4(&ins->src[0], colour_temp); + src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); + ins->src[1].modifiers = VKD3DSPSM_NEG; ++ ins = vsir_program_iterator_next(it); + +- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3); ++ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3); + dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, + program->output_signature.elements[colour_signature_idx].mask); + src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); + src_param_init_ssa_float(&ins->src[1], ssa_factor); + src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ++ ins = vsir_program_iterator_next(it); + + return VKD3D_OK; + } +@@ -7811,14 +7999,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro + static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + uint32_t colour_signature_idx, fog_signature_idx, colour_temp; + const struct vkd3d_shader_parameter1 *mode_parameter = NULL; +- static const struct vkd3d_shader_location no_loc; + const struct signature_element *fog_element; + enum vkd3d_shader_fog_fragment_mode mode; + struct vkd3d_shader_instruction *ins; +- size_t new_pos; + int ret; + + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) +@@ -7832,13 +8019,13 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p + + if (mode_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unsupported fog fragment mode parameter type %#x.", mode_parameter->type); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + if (mode_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid fog fragment mode parameter data type %#x.", mode_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -7859,19 +8046,16 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p + * through the whole shader and convert it to a temp. */ + colour_temp = program->temp_count++; + +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + + if (ins->opcode == VSIR_OP_RET) + { +- if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, +- colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) ++ if ((ret = insert_fragment_fog_before_ret(program, &it, mode, fog_signature_idx, ++ colour_signature_idx, colour_temp, message_context)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -7927,21 +8111,16 @@ static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *progra + return VKD3D_OK; + } + +-static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, +- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp, +- uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos) ++static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, struct vsir_program_iterator *it, ++ enum vkd3d_shader_fog_source source, uint32_t temp, uint32_t fog_signature_idx, uint32_t source_signature_idx) + { + const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; +- struct vkd3d_shader_instruction_array *instructions = &program->instructions; ++ struct vkd3d_shader_instruction *ret = vsir_program_iterator_current(it); + const struct vkd3d_shader_location loc = ret->location; +- size_t pos = ret - instructions->elements; + struct vkd3d_shader_instruction *ins; + +- if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 2))) + return VKD3D_ERROR_OUT_OF_MEMORY; +- ret = NULL; +- +- ins = &program->instructions.elements[pos]; + + /* Write the fog output. */ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); +@@ -7951,26 +8130,26 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); + else /* Position or specular W. */ + ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); +- ++ins; ++ ins = vsir_program_iterator_next(it); + + /* Write the position or specular output. */ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + dst_param_init_output(&ins->dst[0], vsir_data_type_from_component_type(e->component_type), + source_signature_idx, e->mask); + src_param_init_temp_float4(&ins->src[0], temp); +- ++ins; ++ ins = vsir_program_iterator_next(it); + +- *ret_pos = pos + 2; + return VKD3D_OK; + } + + static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program, + struct vsir_transformation_context *ctx) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_message_context *message_context = ctx->message_context; + const struct vkd3d_shader_parameter1 *source_parameter = NULL; + uint32_t fog_signature_idx, source_signature_idx, temp; +- static const struct vkd3d_shader_location no_loc; ++ struct vkd3d_shader_instruction *ins; + enum vkd3d_shader_fog_source source; + const struct signature_element *e; + +@@ -7982,13 +8161,13 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro + + if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unsupported fog source parameter type %#x.", source_parameter->type); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + { +- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, ++ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid fog source parameter data type %#x.", source_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } +@@ -8010,7 +8189,7 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro + if (!vsir_signature_find_sysval(&program->output_signature, + VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx)) + { +- vkd3d_shader_error(ctx->message_context, &no_loc, ++ vkd3d_shader_error(ctx->message_context, &ctx->null_location, + VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); + return VKD3D_ERROR_INVALID_SHADER; + } +@@ -8027,22 +8206,18 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro + + /* Insert a fog write before each ret, and convert either specular or + * position output to a temp. */ +- for (size_t i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + if (vsir_instruction_is_dcl(ins)) + continue; + + if (ins->opcode == VSIR_OP_RET) + { +- size_t new_pos; + int ret; + +- if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp, +- fog_signature_idx, source_signature_idx, &new_pos)) < 0) ++ if ((ret = insert_vertex_fog_before_ret(program, &it, source, temp, ++ fog_signature_idx, source_signature_idx)) < 0) + return ret; +- i = new_pos; + continue; + } + +@@ -8450,7 +8625,7 @@ struct liveness_tracker + bool fixed_mask; + uint8_t mask; + unsigned int first_write, last_access; +- } *ssa_regs; ++ } *ssa_regs, *temp_regs; + }; + + static void liveness_track_src(struct liveness_tracker *tracker, +@@ -8464,6 +8639,8 @@ static void liveness_track_src(struct liveness_tracker *tracker, + + if (src->reg.type == VKD3DSPR_SSA) + tracker->ssa_regs[src->reg.idx[0].offset].last_access = index; ++ else if (src->reg.type == VKD3DSPR_TEMP) ++ tracker->temp_regs[src->reg.idx[0].offset].last_access = index; + } + + static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst, +@@ -8479,6 +8656,8 @@ static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_sh + + if (dst->reg.type == VKD3DSPR_SSA) + reg = &tracker->ssa_regs[dst->reg.idx[0].offset]; ++ else if (dst->reg.type == VKD3DSPR_TEMP) ++ reg = &tracker->temp_regs[dst->reg.idx[0].offset]; + else + return; + +@@ -8565,20 +8744,22 @@ static void liveness_tracker_cleanup(struct liveness_tracker *tracker) + + static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + struct liveness_tracker_reg *regs; + unsigned int loop_depth = 0; + unsigned int loop_start = 0; ++ unsigned int i; + + memset(tracker, 0, sizeof(*tracker)); + +- if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) ++ if (!(regs = vkd3d_calloc(program->ssa_count + program->temp_count, sizeof(*regs)))) + return VKD3D_ERROR_OUT_OF_MEMORY; + tracker->ssa_regs = regs; ++ tracker->temp_regs = ®s[program->ssa_count]; + +- for (unsigned int i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) + { +- const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + if (ins->opcode == VSIR_OP_LOOP || ins->opcode == VSIR_OP_REP) + { + if (!loop_depth++) +@@ -8604,8 +8785,7 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv + * should be illegal for an SSA value to be read in a block + * containing L.) + * We don't try to perform this optimization yet, in the name of +- * maximal simplicity, and also because this code is intended to +- * be extended to non-SSA values. */ ++ * maximal simplicity. */ + for (unsigned int j = 0; j < program->ssa_count; ++j) + { + struct liveness_tracker_reg *reg = &tracker->ssa_regs[j]; +@@ -8615,6 +8795,16 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv + if (reg->last_access < i) + reg->last_access = i; + } ++ ++ for (unsigned int j = 0; j < program->temp_count; ++j) ++ { ++ struct liveness_tracker_reg *reg = &tracker->temp_regs[j]; ++ ++ if (reg->first_write > loop_start) ++ reg->first_write = loop_start; ++ if (reg->last_access < i) ++ reg->last_access = i; ++ } + } + } + +@@ -8634,8 +8824,8 @@ struct temp_allocator + { + uint8_t allocated_mask; + uint32_t temp_id; +- } *ssa_regs; +- size_t allocated_ssa_count; ++ } *ssa_regs, *temp_regs; ++ size_t allocated_ssa_count, allocated_temp_count; + enum vkd3d_result result; + }; + +@@ -8662,16 +8852,30 @@ static uint8_t get_available_writemask(const struct temp_allocator *allocator, + return writemask; + } + ++ for (size_t i = 0; i < allocator->allocated_temp_count; ++i) ++ { ++ const struct temp_allocator_reg *reg = &allocator->temp_regs[i]; ++ const struct liveness_tracker_reg *liveness_reg = &tracker->temp_regs[i]; ++ ++ if (reg->temp_id == temp_id ++ && first_write < liveness_reg->last_access ++ && last_access > liveness_reg->first_write) ++ writemask &= ~reg->allocated_mask; ++ ++ if (!writemask) ++ return writemask; ++ } ++ + return writemask; + } + + static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker, +- struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg, uint32_t base_id) ++ struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg) + { + if (!liveness_reg->written) + return false; + +- for (uint32_t id = base_id;; ++id) ++ for (uint32_t id = 0;; ++id) + { + uint8_t available_mask = get_available_writemask(allocator, tracker, + liveness_reg->first_write, liveness_reg->last_access, id); +@@ -8688,13 +8892,21 @@ static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liv + else + { + /* For SSA values the mask is always zero-based and contiguous. +- * We don't correctly handle cases where it's not, currently. */ +- VKD3D_ASSERT((liveness_reg->mask | (liveness_reg->mask - 1)) == liveness_reg->mask); +- +- if (vkd3d_popcount(available_mask) >= vkd3d_popcount(liveness_reg->mask)) ++ * For TEMP values we assume the register was allocated that way, ++ * but it may only be partially used. ++ * We currently only handle cases where the mask is zero-based and ++ * contiguous, so we need to fill in the missing components to ++ * ensure this. */ ++ uint8_t mask = (1u << (vkd3d_log2i(liveness_reg->mask) + 1)) - 1; ++ ++ if (vkd3d_popcount(available_mask) >= vkd3d_popcount(mask)) + { ++ if (mask != liveness_reg->mask) ++ WARN("Allocating a mask %#x with used components %#x; this is not optimized.\n", ++ mask, liveness_reg->mask); ++ + reg->temp_id = id; +- reg->allocated_mask = vsir_combine_write_masks(available_mask, liveness_reg->mask); ++ reg->allocated_mask = vsir_combine_write_masks(available_mask, mask); + return true; + } + } +@@ -8713,6 +8925,8 @@ static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3 + + if (src->reg.type == VKD3DSPR_SSA) + reg = &allocator->ssa_regs[src->reg.idx[0].offset]; ++ else if (src->reg.type == VKD3DSPR_TEMP) ++ reg = &allocator->temp_regs[src->reg.idx[0].offset]; + else + return; + +@@ -8792,6 +9006,7 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, + struct vkd3d_shader_dst_param *dst, const struct vkd3d_shader_instruction *ins) + { + struct temp_allocator_reg *reg; ++ uint32_t remapped_mask; + + for (unsigned int k = 0; k < dst->reg.idx_count; ++k) + { +@@ -8801,15 +9016,18 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, + + if (dst->reg.type == VKD3DSPR_SSA) + reg = &allocator->ssa_regs[dst->reg.idx[0].offset]; ++ else if (dst->reg.type == VKD3DSPR_TEMP) ++ reg = &allocator->temp_regs[dst->reg.idx[0].offset]; + else + return; + + dst->reg.type = VKD3DSPR_TEMP; + dst->reg.dimension = VSIR_DIMENSION_VEC4; + dst->reg.idx[0].offset = reg->temp_id; +- if (reg->allocated_mask != dst->write_mask) ++ remapped_mask = vsir_combine_write_masks(reg->allocated_mask, dst->write_mask); ++ if (dst->write_mask != remapped_mask) + { +- dst->write_mask = reg->allocated_mask; ++ dst->write_mask = remapped_mask; + + if (vsir_opcode_is_double(ins->opcode)) + { +@@ -8825,47 +9043,90 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, + if (vsir_src_is_masked(ins->opcode, i)) + { + if (src->reg.type == VKD3DSPR_IMMCONST) +- vsir_remap_immconst(src, dst->write_mask); ++ vsir_remap_immconst(src, reg->allocated_mask); + else if (src->reg.type == VKD3DSPR_IMMCONST64) +- vsir_remap_immconst64(src, dst->write_mask); ++ vsir_remap_immconst64(src, reg->allocated_mask); + else +- src->swizzle = vsir_map_swizzle(src->swizzle, dst->write_mask); ++ src->swizzle = vsir_map_swizzle(src->swizzle, reg->allocated_mask); + } + } + } + } + ++/* This pass does two things: ++ * ++ * - converts SSA registers (sr#) into temp registers (r#); ++ * ++ * - contracts temp registers with non-overlapping ranges by reallocating them ++ * into the same register. ++ * ++ * These are done at the same time so that SSA and temp registers with ++ * non-overlapping liveness can share the same register. ++ * ++ * The temp contraction is not particularly sophisticated. In particular, it ++ * does not detect cases where a single temp register has multiple disjoint ++ * ranges of liveness, and it also assumes that the components used by a single ++ * registers is zero-based and contiguous. ++ * The intent for temp contraction is that HLSL will output each distinct ++ * variable to a unique temp ID. */ + enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + const unsigned int prev_temp_count = program->temp_count; + struct temp_allocator allocator = {0}; ++ struct vkd3d_shader_instruction *ins; + struct temp_allocator_reg *regs; + struct liveness_tracker tracker; + enum vkd3d_result ret; + +- if (!program->ssa_count) ++ if (!program->ssa_count && !prev_temp_count) + return VKD3D_OK; + + if ((ret = track_liveness(program, &tracker))) + return ret; + +- if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) ++ if (!(regs = vkd3d_calloc(program->ssa_count + prev_temp_count, sizeof(*regs)))) + { + liveness_tracker_cleanup(&tracker); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + allocator.message_context = message_context; + allocator.ssa_regs = regs; ++ allocator.temp_regs = regs + program->ssa_count; ++ ++ program->temp_count = 0; ++ ++ /* Reallocate temps first. We do this specifically to make sure that r0 is ++ * the first register to be allocated, and thus will be reallocated in ++ * place, and left alone. ++ * This is necessary because, in pixel shader model 1.x, r0 doubles as the ++ * output register, and needs to remain at r0. (Note that we need to already ++ * have the output in r0, rather than e.g. putting it in o0 and converting ++ * it to r0 after this pass, so that we know when r0 is live.) */ ++ for (unsigned int i = 0; i < prev_temp_count; ++i) ++ { ++ const struct liveness_tracker_reg *liveness_reg = &tracker.temp_regs[i]; ++ struct temp_allocator_reg *reg = &allocator.temp_regs[i]; ++ ++ if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg)) ++ { ++ TRACE("Reallocated r%u%s for r%u (liveness %u-%u).\n", ++ reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, ++ liveness_reg->first_write, liveness_reg->last_access); ++ program->temp_count = max(program->temp_count, reg->temp_id + 1); ++ } ++ ++allocator.allocated_temp_count; ++ } + + for (unsigned int i = 0; i < program->ssa_count; ++i) + { + const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i]; + struct temp_allocator_reg *reg = &allocator.ssa_regs[i]; + +- if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count)) ++ if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg)) + { +- TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n", ++ TRACE("Allocated r%u%s for sr%u (liveness %u-%u).\n", + reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, + liveness_reg->first_write, liveness_reg->last_access); + program->temp_count = max(program->temp_count, reg->temp_id + 1); +@@ -8873,10 +9134,8 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + ++allocator.allocated_ssa_count; + } + +- for (unsigned int i = 0; i < program->instructions.count; ++i) ++ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { +- const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; +- + /* Make sure we do the srcs first; setting the dst writemask may need + * to remap their swizzles. */ + for (unsigned int j = 0; j < ins->src_count; ++j) +@@ -8902,11 +9161,14 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) + { ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_location location; ++ struct vkd3d_shader_instruction *ins; + unsigned int temp_count = 0; + +- for (int i = program->instructions.count - 1; i >= 0; --i) ++ for (ins = vsir_program_iterator_tail(&it); ins; ins = vsir_program_iterator_prev(&it)) + { +- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; ++ location = ins->location; + + if (ins->opcode == VSIR_OP_DCL_TEMPS) + { +@@ -8922,11 +9184,11 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + { + /* The phase didn't have a dcl_temps instruction, but we added + * temps here, so we need to insert one. */ +- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) ++ if (!vsir_program_iterator_insert_after(&it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- ins = &program->instructions.elements[i + 1]; +- vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS); ++ ins = vsir_program_iterator_next(&it); ++ vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); + ins->declaration.count = temp_count; + temp_count = 0; + continue; +@@ -8947,13 +9209,13 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + + if (temp_count && program->shader_version.major >= 4) + { +- struct vkd3d_shader_instruction *ins; ++ ins = vsir_program_iterator_head(&it); ++ location = ins->location; + +- if (!shader_instruction_array_insert_at(&program->instructions, 0, 1)) ++ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + +- ins = &program->instructions.elements[0]; +- vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS); ++ vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); + ins->declaration.count = temp_count; + } + +@@ -8965,7 +9227,7 @@ struct validation_context + struct vkd3d_shader_message_context *message_context; + const struct vsir_program *program; + size_t instruction_idx; +- struct vkd3d_shader_location null_location; ++ struct vkd3d_shader_location location; + bool invalid_instruction_idx; + enum vkd3d_result status; + bool dcl_temps_found; +@@ -9024,13 +9286,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c + + if (ctx->invalid_instruction_idx) + { +- vkd3d_shader_error(ctx->message_context, &ctx->null_location, error, "%s", buf.buffer); ++ vkd3d_shader_error(ctx->message_context, &ctx->location, error, "%s", buf.buffer); + WARN("VSIR validation error: %s\n", buf.buffer); + } + else + { +- const struct vkd3d_shader_instruction *ins = &ctx->program->instructions.elements[ctx->instruction_idx]; +- vkd3d_shader_error(ctx->message_context, &ins->location, error, ++ vkd3d_shader_error(ctx->message_context, &ctx->location, error, + "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); + WARN("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); + } +@@ -9459,7 +9720,8 @@ static void vsir_validate_label_register(struct validation_context *ctx, + + if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for a LABEL register.", reg->data_type); ++ "Invalid data type \"%s\" (%#x) for a LABEL register.", ++ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); + + if (reg->dimension != VSIR_DIMENSION_NONE) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, +@@ -9538,7 +9800,8 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, + + if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for a SAMPLER register.", reg->data_type); ++ "Invalid data type \"%s\" (%#x) for a SAMPLER register.", ++ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); + + /* VEC4 is allowed in gather operations. */ + if (reg->dimension == VSIR_DIMENSION_SCALAR) +@@ -9564,7 +9827,8 @@ static void vsir_validate_resource_register(struct validation_context *ctx, + + if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for a RESOURCE register.", reg->data_type); ++ "Invalid data type \"%s\" (%#x) for a RESOURCE register.", ++ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); + + if (reg->dimension != VSIR_DIMENSION_VEC4) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, +@@ -9590,8 +9854,8 @@ static void vsir_validate_uav_register(struct validation_context *ctx, + + if (reg->data_type != VSIR_DATA_UNUSED) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for a UAV register.", +- reg->data_type); ++ "Invalid data type \"%s\" (%#x) for a UAV register.", ++ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); + + /* NONE is allowed in counter operations. */ + if (reg->dimension == VSIR_DIMENSION_SCALAR) +@@ -9663,9 +9927,10 @@ static void vsir_validate_ssa_register(struct validation_context *ctx, + + if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for a SSA register: " +- "it has already been seen with data type %#x at instruction %zu.", +- reg->data_type, data->data_type, data->first_seen); ++ "Invalid data type \"%s\" (%#x) for SSA register %u: " ++ "it has already been seen with data type \"%s\" (%#x) at instruction %zu.", ++ vsir_data_type_get_name(reg->data_type, ""), reg->data_type, reg->idx[0].offset, ++ vsir_data_type_get_name(data->data_type, ""), data->data_type, data->first_seen); + } + } + +@@ -9913,7 +10178,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, + + default: + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for destination with saturate modifier.", dst->reg.data_type); ++ "Invalid data type \"%s\" (%#x) for destination with saturate modifier.", ++ vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); + break; + + } +@@ -9932,7 +10198,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, + case 15: + if (dst->reg.data_type != VSIR_DATA_F32) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for destination with shift.", dst->reg.data_type); ++ "Invalid data type \"%s\" (%#x) for destination with shift.", ++ vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); + break; + + default: +@@ -10070,7 +10337,8 @@ static void vsir_validate_src_param(struct validation_context *ctx, + { + if (!(src_modifier_data[src->modifiers].data_type_mask & (1u << src->reg.data_type))) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, +- "Source has invalid modifier %#x for data type %u.", src->modifiers, src->reg.data_type); ++ "Source has invalid modifier %#x for data type \"%s\" (%#x).", ++ src->modifiers, vsir_data_type_get_name(src->reg.data_type, ""), src->reg.data_type); + } + + switch (src->reg.type) +@@ -10722,7 +10990,7 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, + static void vsir_validate_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) + { +- enum vsir_data_type dst_data_type; ++ enum vsir_data_type dst_data_type, src_data_type; + unsigned int i; + + if (instruction->dst_count < 1) +@@ -10735,16 +11003,18 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, + + if (!types[dst_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for elementwise operation \"%s\" (%#x).", +- dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ "Invalid data type \"%s\" (%#x) for elementwise operation \"%s\" (%#x).", ++ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + + for (i = 0; i < instruction->src_count; ++i) + { +- if (instruction->src[i].reg.data_type != dst_data_type) ++ if ((src_data_type = instruction->src[i].reg.data_type) != dst_data_type) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Data type %#x for operand %u doesn't match the destination data type %#x " ++ "Data type \"%s\" (%#x) for operand %u doesn't match the destination data type \"%s\" (%#x) " + "for elementwise operation \"%s\" (%#x).", +- instruction->src[i].reg.data_type, i, dst_data_type, ++ vsir_data_type_get_name(src_data_type, ""), src_data_type, i, ++ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + } + } +@@ -10801,7 +11071,7 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context + static void vsir_validate_comparison_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) + { +- enum vsir_data_type dst_data_type, src_data_type; ++ enum vsir_data_type dst_data_type, src_data_type, data_type; + unsigned int i; + + if (instruction->dst_count < 1) +@@ -10811,8 +11081,9 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, + + if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for result of comparison operation \"%s\" (%#x).", +- dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ "Invalid data type \"%s\" (%#x) for result of comparison operation \"%s\" (%#x).", ++ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + + if (instruction->src_count == 0) + return; +@@ -10824,16 +11095,18 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, + + if (!types[src_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid data type %#x for comparison operation \"%s\" (%#x).", +- src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ "Invalid data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", ++ vsir_data_type_get_name(src_data_type, ""), src_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + + for (i = 1; i < instruction->src_count; ++i) + { +- if (instruction->src[i].reg.data_type != src_data_type) ++ if ((data_type = instruction->src[i].reg.data_type) != src_data_type) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Data type %#x for operand %u doesn't match the first operands data type %#x " +- "for comparison operation \"%s\" (%#x).", +- instruction->src[i].reg.data_type, i, src_data_type, ++ "Data type \"%s\" (%#x) for operand %u doesn't match the first " ++ "operands data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", ++ vsir_data_type_get_name(data_type, ""), data_type, i, ++ vsir_data_type_get_name(src_data_type, ""), src_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + } + } +@@ -10891,19 +11164,21 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, + + if (!src_types[src_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid source data type %#x for cast operation \"%s\" (%#x).", +- src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ "Invalid source data type \"%s\" (%#x) for cast operation \"%s\" (%#x).", ++ vsir_data_type_get_name(src_data_type, ""), src_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + + if (!dst_types[dst_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid destination data type %#x for cast operation \"%s\" (%#x).", +- dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ "Invalid destination data type \"%s\" (%#x) for cast operation \"%s\" (%#x).", ++ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + } + + static void vsir_validate_shift_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) + { +- enum vsir_data_type data_type; ++ enum vsir_data_type dst_data_type, src_data_type; + + static const bool types[] = + { +@@ -10912,24 +11187,27 @@ static void vsir_validate_shift_operation(struct validation_context *ctx, + [VSIR_DATA_U64] = true, + }; + +- data_type = instruction->dst[0].reg.data_type; +- if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) ++ dst_data_type = instruction->dst[0].reg.data_type; ++ if ((size_t)dst_data_type >= ARRAY_SIZE(types) || !types[dst_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid destination data type %#x for shift operation \"%s\" (%#x).", +- data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ "Invalid destination data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", ++ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + +- if (instruction->src[0].reg.data_type != data_type) ++ if ((src_data_type = instruction->src[0].reg.data_type) != dst_data_type) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Data type %#x for source operand 0 doesn't match destination data type %#x " ++ "Data type \"%s\" (%#x) for source operand 0 doesn't match destination data type \"%s\" (%#x) " + "for shift operation \"%s\" (%#x).", +- instruction->src[0].reg.data_type, data_type, ++ vsir_data_type_get_name(src_data_type, ""), src_data_type, ++ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + +- data_type = instruction->src[1].reg.data_type; +- if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) ++ src_data_type = instruction->src[1].reg.data_type; ++ if ((size_t)src_data_type >= ARRAY_SIZE(types) || !types[src_data_type]) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid source operand 1 data type %#x for shift operation \"%s\" (%#x).", +- data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); ++ "Invalid source operand 1 data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", ++ vsir_data_type_get_name(src_data_type, ""), src_data_type, ++ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + } + + static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) +@@ -11624,7 +11902,8 @@ static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validat + enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; + + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, +- "Invalid destination data type %#x for operation \"%s\" (%#x) with flags %#x.", dst_data_type, ++ "Invalid destination data type \"%s\" (%#x) for operation \"%s\" (%#x) with flags %#x.", ++ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode, instruction->flags); + } + +@@ -11842,14 +12121,12 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ + [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, + }; + +-static void vsir_validate_instruction(struct validation_context *ctx) ++static void vsir_validate_instruction(struct validation_context *ctx, ++ const struct vkd3d_shader_instruction *instruction) + { + const struct vkd3d_shader_version *version = &ctx->program->shader_version; +- const struct vkd3d_shader_instruction *instruction; + size_t i; + +- instruction = &ctx->program->instructions.elements[ctx->instruction_idx]; +- + for (i = 0; i < instruction->dst_count; ++i) + vsir_validate_dst_param(ctx, &instruction->dst[i]); + +@@ -11927,7 +12204,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c + { + .message_context = message_context, + .program = program, +- .null_location = {.source_name = source_name}, ++ .location = {.source_name = source_name}, + .status = VKD3D_OK, + .phase = VSIR_OP_INVALID, + .invalid_instruction_idx = true, +@@ -11938,6 +12215,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c + .inner_tess_idxs[0] = ~0u, + .inner_tess_idxs[1] = ~0u, + }; ++ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); ++ struct vkd3d_shader_instruction *ins; + unsigned int i; + + if (!(config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) +@@ -12046,11 +12325,17 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c + + ctx.invalid_instruction_idx = false; + +- for (ctx.instruction_idx = 0; ctx.instruction_idx < program->instructions.count +- && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ctx.instruction_idx) +- vsir_validate_instruction(&ctx); ++ ctx.instruction_idx = 0; ++ for (ins = vsir_program_iterator_head(&it); ins && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ ins = vsir_program_iterator_next(&it)) ++ { ++ ctx.location = ins->location; ++ vsir_validate_instruction(&ctx, ins); ++ ++ctx.instruction_idx; ++ } + + ctx.invalid_instruction_idx = true; ++ ctx.location = (struct vkd3d_shader_location){.source_name = source_name}; + + if (ctx.depth != 0) + validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "%zu nested blocks were not closed.", ctx.depth); +@@ -12113,14 +12398,9 @@ static void vsir_transform_( + enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) + { +- struct vsir_transformation_context ctx = +- { +- .result = VKD3D_OK, +- .program = program, +- .config_flags = config_flags, +- .compile_info = compile_info, +- .message_context = message_context, +- }; ++ struct vsir_transformation_context ctx; ++ ++ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); + + /* For vsir_program_ensure_diffuse(). */ + if (program->shader_version.major <= 2) +@@ -12138,15 +12418,9 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin + enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) + { +- struct vsir_transformation_context ctx = +- { +- .result = VKD3D_OK, +- .program = program, +- .config_flags = config_flags, +- .compile_info = compile_info, +- .message_context = message_context, +- }; ++ struct vsir_transformation_context ctx; + ++ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); + vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); + if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) + vsir_transform(&ctx, vsir_program_normalise_ps1_output); +@@ -12160,15 +12434,9 @@ enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_ + enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) + { +- struct vsir_transformation_context ctx = +- { +- .result = VKD3D_OK, +- .program = program, +- .config_flags = config_flags, +- .compile_info = compile_info, +- .message_context = message_context, +- }; ++ struct vsir_transformation_context ctx; + ++ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); + vsir_transform(&ctx, vsir_program_lower_instructions); + + if (program->shader_version.major >= 6) +diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c +index c6e048adb20..9150e77e2c6 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/msl.c ++++ b/libs/vkd3d/libs/vkd3d-shader/msl.c +@@ -943,8 +943,8 @@ static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct ms + + static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { ++ unsigned int resource_id, resource_idx, resource_space, sample_count; + const struct msl_resource_type_info *resource_type_info; +- unsigned int resource_id, resource_idx, resource_space; + const struct vkd3d_shader_descriptor_info1 *descriptor; + const struct vkd3d_shader_descriptor_binding *binding; + enum vkd3d_shader_resource_type resource_type; +@@ -969,6 +969,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + { + resource_type = descriptor->resource_type; + resource_space = descriptor->register_space; ++ sample_count = descriptor->sample_count; + data_type = descriptor->resource_data_type; + } + else +@@ -977,6 +978,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; ++ sample_count = 1; + data_type = VSIR_DATA_F32; + } + +@@ -988,6 +990,16 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Texel fetches from resource type %#x are not supported.", resource_type); + ++ if (sample_count == 1) ++ { ++ /* Similar to the SPIR-V and GLSL targets, we map multi-sample ++ * textures with sample count 1 to their single-sample equivalents. */ ++ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS) ++ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; ++ else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) ++ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; ++ } ++ + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +@@ -1030,6 +1042,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct + vkd3d_string_buffer_printf(read, ", "); + if (ins->opcode != VSIR_OP_LD2DMS) + msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32); ++ else if (sample_count == 1) ++ /* If the resource isn't a true multisample resource, this is the ++ * "lod" parameter instead of the "sample" parameter. */ ++ vkd3d_string_buffer_printf(read, "0"); + else + msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); + } +@@ -1294,6 +1310,11 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh + data_type = VSIR_DATA_F32; + } + ++ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS ++ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, ++ "Storing to resource type %#x is not supported.", resource_type); ++ + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, +@@ -1414,6 +1435,12 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc + static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) + { + const char *type = ins->declaration.indexable_temp.component_count == 4 ? "vkd3d_vec4" : "vkd3d_scalar"; ++ ++ if (ins->declaration.indexable_temp.initialiser) ++ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, ++ "Internal compiler error: Unhandled initialiser for indexable temporary %u.", ++ ins->declaration.indexable_temp.register_idx); ++ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "%s x%u[%u];\n", type, + ins->declaration.indexable_temp.register_idx, +@@ -1516,6 +1543,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d + break; + case VSIR_OP_GEO: + case VSIR_OP_IGE: ++ case VSIR_OP_UGE: + msl_relop(gen, ins, ">="); + break; + case VSIR_OP_IF: +@@ -1995,6 +2023,7 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) + static void msl_generate_entrypoint(struct msl_generator *gen) + { + enum vkd3d_shader_type type = gen->program->shader_version.type; ++ bool output = true; + + switch (type) + { +@@ -2006,13 +2035,21 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + vkd3d_string_buffer_printf(gen->buffer, "[[early_fragment_tests]]\n"); + vkd3d_string_buffer_printf(gen->buffer, "fragment "); + break; ++ case VKD3D_SHADER_TYPE_COMPUTE: ++ vkd3d_string_buffer_printf(gen->buffer, "kernel "); ++ output = false; ++ break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled shader type %#x.", type); + return; + } + +- vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix); ++ if (output) ++ vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out ", gen->prefix); ++ else ++ vkd3d_string_buffer_printf(gen->buffer, "void "); ++ vkd3d_string_buffer_printf(gen->buffer, "shader_entry(\n"); + + if (gen->program->descriptors.descriptor_count) + { +@@ -2054,7 +2091,9 @@ static void msl_generate_entrypoint(struct msl_generator *gen) + + msl_generate_entrypoint_epilogue(gen); + +- vkd3d_string_buffer_printf(gen->buffer, " return output;\n}\n"); ++ if (output) ++ vkd3d_string_buffer_printf(gen->buffer, " return output;\n"); ++ vkd3d_string_buffer_printf(gen->buffer, "}\n"); + } + + static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out) +diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l +index a8c0db358bc..f9b1d67ac36 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/preproc.l ++++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l +@@ -20,6 +20,7 @@ + + %{ + ++#include "preproc.h" + #include "preproc.tab.h" + + #undef ERROR /* defined in wingdi.h */ +@@ -823,7 +824,6 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, + static const struct vkd3d_shader_preprocess_info default_preprocess_info = {0}; + struct preproc_ctx ctx = {0}; + char *source_name = NULL; +- void *output_code; + unsigned int i; + + vkd3d_string_buffer_init(&ctx.buffer); +@@ -900,16 +900,9 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, + return VKD3D_ERROR_INVALID_SHADER; + } + +- if (!(output_code = vkd3d_malloc(ctx.buffer.content_size))) +- { +- vkd3d_string_buffer_cleanup(&ctx.buffer); +- return VKD3D_ERROR_OUT_OF_MEMORY; +- } +- memcpy(output_code, ctx.buffer.buffer, ctx.buffer.content_size); +- out->size = ctx.buffer.content_size; +- out->code = output_code; + vkd3d_string_buffer_trace(&ctx.buffer); +- vkd3d_string_buffer_cleanup(&ctx.buffer); ++ ++ vkd3d_shader_code_from_string_buffer(out, &ctx.buffer); + return VKD3D_OK; + + fail: +diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c +index 97c0d0e73a8..8bc851f9c5b 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/spirv.c ++++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c +@@ -2518,7 +2518,7 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build + GLSLstd450NClamp, operands, ARRAY_SIZE(operands)); + } + +-static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, ++static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder *builder, + enum vkd3d_shader_component_type component_type, unsigned int component_count) + { + uint32_t scalar_id, type_id; +@@ -2553,8 +2553,9 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, + case VKD3D_SHADER_COMPONENT_DOUBLE: + type_id = vkd3d_spirv_get_op_type_float(builder, 64); + break; ++ case VKD3D_SHADER_COMPONENT_INT64: + case VKD3D_SHADER_COMPONENT_UINT64: +- type_id = vkd3d_spirv_get_op_type_int(builder, 64, 0); ++ type_id = vkd3d_spirv_get_op_type_int(builder, 64, component_type == VKD3D_SHADER_COMPONENT_INT64); + break; + default: + FIXME("Unhandled component type %#x.\n", component_type); +@@ -2564,7 +2565,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, + else + { + VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); +- scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ scalar_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); + } + +@@ -2573,13 +2574,13 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, + return type_id; + } + +-static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, ++static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, + enum vsir_data_type data_type, unsigned int component_count) + { + enum vkd3d_shader_component_type component_type; + + component_type = vkd3d_component_type_from_data_type(data_type); +- return vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ return spirv_get_type_id_for_component_type(builder, component_type, component_count); + } + + static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, +@@ -3656,7 +3657,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, + unsigned int i; + + VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_VEC4_SIZE); +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + + switch (component_type) + { +@@ -3683,7 +3684,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, + } + else + { +- scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ scalar_type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + for (i = 0; i < component_count; ++i) + component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, values[i]); + return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count); +@@ -3698,9 +3699,10 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, + unsigned int i; + + VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + +- if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64) ++ if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_INT64 ++ && component_type != VKD3D_SHADER_COMPONENT_UINT64) + { + FIXME("Unhandled component_type %#x.\n", component_type); + return vkd3d_spirv_get_op_undef(builder, type_id); +@@ -3712,7 +3714,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, + } + else + { +- scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ scalar_type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + for (i = 0; i < component_count; ++i) + component_ids[i] = vkd3d_spirv_get_op_constant64(builder, scalar_type_id, values[i]); + return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count); +@@ -3772,9 +3774,7 @@ static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compil + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + +- return vkd3d_spirv_get_type_id(builder, +- vkd3d_component_type_from_data_type(reg->data_type), +- vsir_write_mask_component_count(write_mask)); ++ return spirv_get_type_id(builder, reg->data_type, vsir_write_mask_component_count(write_mask)); + } + + static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler, +@@ -3901,7 +3901,7 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil + uint32_t type_id, length_id, ptr_type_id; + unsigned int i; + +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + for (i = 0; i < length_count; ++i) + { + if (!array_lengths[i]) +@@ -4000,8 +4000,8 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile + info = get_spec_constant_info(name); + default_value = info ? info->default_value.u : 0; + +- scalar_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1); +- vector_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); ++ scalar_type_id = spirv_get_type_id(builder, type, 1); ++ vector_type_id = spirv_get_type_id(builder, type, component_count); + + for (unsigned int i = 0; i < component_count; ++i) + { +@@ -4050,7 +4050,7 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi + unsigned int index = parameter - compiler->program->parameters; + uint32_t type_id, ptr_id, ptr_type_id; + +- type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); ++ type_id = spirv_get_type_id(builder, type, component_count); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); + ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, + compiler->spirv_parameter_info[index].buffer_id, +@@ -4114,7 +4114,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp + + VKD3D_ASSERT(val_component_idx < val_component_count); + +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + if (val_component_count == 1) + { + for (i = 0; i < component_count; ++i) +@@ -4147,10 +4147,11 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c + addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); + if (reg_index->offset) + { +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); +- addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, +- addr_id, spirv_compiler_get_constant_uint(compiler, reg_index->offset)); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); ++ addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, addr_id, ++ spirv_compiler_get_constant_uint(compiler, reg_index->offset)); + } ++ + return addr_id; + } + +@@ -4296,7 +4297,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2]; + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); + if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) + { + index_ids[0] = compiler->descriptor_offsets_member_id; +@@ -4369,7 +4370,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp + if (index_count) + { + component_count = vsir_write_mask_component_count(register_info->write_mask); +- type_id = vkd3d_spirv_get_type_id(builder, register_info->component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, register_info->component_type, component_count); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id); + register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, + register_info->id, indexes, index_count); +@@ -4428,7 +4429,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, + && (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask))) + return val_id; + +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + + if (component_count == 1) + { +@@ -4479,7 +4480,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil + components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i); + } + +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + return vkd3d_spirv_build_op_vector_shuffle(builder, + type_id, vector1_id, vector2_id, components, component_count); + } +@@ -4494,10 +4495,11 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, + + VKD3D_ASSERT(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); + op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; ++ + return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, +- data_type == VSIR_DATA_U64 ++ data_type_is_64_bit(data_type) + ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) + : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); + } +@@ -4510,7 +4512,8 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, + + true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); + false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); ++ + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); + } + +@@ -4523,7 +4526,8 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile + true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, + component_count); + false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_U64, component_count); ++ + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); + } + +@@ -4535,7 +4539,8 @@ static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compile + + true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); + false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); ++ + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); + } + +@@ -4547,7 +4552,8 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil + + true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); + false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F64, component_count); ++ + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); + } + +@@ -4614,7 +4620,8 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, + + VKD3D_ASSERT(reg->type == VKD3DSPR_UNDEF); + +- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count); ++ type_id = spirv_get_type_id(builder, reg->data_type, component_count); ++ + return vkd3d_spirv_get_op_undef(builder, type_id); + } + +@@ -4646,7 +4653,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, + component_idx, reg->type, reg->idx[0].offset, reg_info->write_mask); + } + +- type_id = vkd3d_spirv_get_type_id(builder, reg_info->component_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, reg_info->component_type, 1); + reg_id = reg_info->id; + if (reg_component_count != 1) + { +@@ -4663,7 +4670,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, + { + if (reg_info->component_type != VKD3D_SHADER_COMPONENT_UINT) + { +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + val_id = spirv_compiler_emit_int_to_bool(compiler, +@@ -4671,7 +4678,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, + } + else + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + } +@@ -4691,7 +4698,7 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil + + component_type = vkd3d_component_type_from_data_type(icb->data_type); + component_count = icb->component_count; +- elem_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, icb->data_type, component_count); ++ elem_type_id = spirv_get_type_id(builder, icb->data_type, component_count); + length_id = spirv_compiler_get_constant_uint(compiler, element_count); + type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id); + +@@ -4722,6 +4729,7 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil + &icb->data[component_count * i]); + break; + case VSIR_DATA_F64: ++ case VSIR_DATA_I64: + case VSIR_DATA_U64: + { + uint64_t *data = (uint64_t *)icb->data; +@@ -4777,7 +4785,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + + if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + return vkd3d_spirv_get_op_undef(builder, type_id); + } + spirv_compiler_emit_dereference_register(compiler, reg, ®_info); +@@ -4796,7 +4804,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + } + else + { +- type_id = vkd3d_spirv_get_type_id(builder, ++ type_id = spirv_get_type_id_for_component_type(builder, + reg_info.component_type, vsir_write_mask_component_count(reg_info.write_mask)); + val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); + swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; +@@ -4811,7 +4819,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + { + if (reg_info.component_type != VKD3D_SHADER_COMPONENT_UINT) + { +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + val_id = spirv_compiler_emit_int_to_bool(compiler, +@@ -4819,7 +4827,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, + } + else + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + } +@@ -4923,7 +4931,7 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, + + if (vsir_write_mask_component_count(dst_write_mask) > 1) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); + component_idx = vsir_write_mask_get_component_idx(write_mask); + component_idx -= vsir_write_mask_get_component_idx(dst_write_mask); +@@ -4951,7 +4959,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, + + if (dst_component_count == 1 && component_count != 1) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, + vsir_write_mask_get_component_idx(dst_write_mask)); + write_mask &= dst_write_mask; +@@ -4966,7 +4974,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, + + if (dst_component_count != component_count) + { +- type_id = vkd3d_spirv_get_type_id(builder, component_type, dst_component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, dst_component_count); + dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); + + VKD3D_ASSERT(component_count <= ARRAY_SIZE(components)); +@@ -5018,7 +5026,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, + if (component_type == VKD3D_SHADER_COMPONENT_BOOL) + val_id = spirv_compiler_emit_bool_to_int(compiler, + vsir_write_mask_component_count(src_write_mask), val_id, false); +- type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, ++ type_id = spirv_get_type_id_for_component_type(builder, reg_info.component_type, + vsir_write_mask_component_count(src_write_mask)); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + component_type = reg_info.component_type; +@@ -5101,7 +5109,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, dst_type_id, val_id; + +- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); + if (component_count > 1) + { + val_id = vkd3d_spirv_build_op_composite_construct(builder, +@@ -5112,7 +5120,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp + val_id = *component_ids; + } + +- dst_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); ++ dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); + if (dst_type_id != type_id) + val_id = vkd3d_spirv_build_op_bitcast(builder, dst_type_id, val_id); + +@@ -5281,9 +5289,8 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * + vkd3d_spirv_add_iface_variable(builder, base_var_id); + spirv_compiler_decorate_builtin(compiler, base_var_id, base); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); +- base_id = vkd3d_spirv_build_op_load(builder, +- type_id, base_var_id, SpvMemoryAccessMaskNone); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); ++ base_id = vkd3d_spirv_build_op_load(builder, type_id, base_var_id, SpvMemoryAccessMaskNone); + + return vkd3d_spirv_build_op_isub(builder, type_id, index_id, base_id); + } +@@ -5311,17 +5318,16 @@ static uint32_t sv_front_face_fixup(struct spirv_compiler *compiler, + } + + /* frag_coord.w = 1.0f / frag_coord.w */ +-static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, +- uint32_t frag_coord_id) ++static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, uint32_t frag_coord_id) + { + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, w_id; + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); + w_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, frag_coord_id, 3); +- w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, +- spirv_compiler_get_constant_float(compiler, 1.0f), w_id); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); ++ w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, spirv_compiler_get_constant_float(compiler, 1.0f), w_id); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); ++ + return vkd3d_spirv_build_op_composite_insert1(builder, type_id, w_id, frag_coord_id, 3); + } + +@@ -5527,7 +5533,8 @@ static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *co + uint32_t type_id, id; + + id = spirv_compiler_get_invocation_id(compiler); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); ++ + return vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); + } + +@@ -5867,7 +5874,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + vsir_register_init(&dst_reg, reg_type, VSIR_DATA_F32, 1); + dst_reg.idx[0].offset = element_idx; + +- type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, input_component_count); + + val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone); + +@@ -5876,7 +5883,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, + + if (component_type != VKD3D_SHADER_COMPONENT_FLOAT) + { +- float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, input_component_count); ++ float_type_id = spirv_get_type_id_for_component_type(builder, ++ VKD3D_SHADER_COMPONENT_FLOAT, input_component_count); + val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id); + } + +@@ -6225,7 +6233,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + + if (output_info->component_type != VKD3D_SHADER_COMPONENT_FLOAT) + { +- type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); + } + +@@ -6250,7 +6258,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + output_id = output_info->id; + if (output_index_id) + { +- type_id = vkd3d_spirv_get_type_id(builder, ++ type_id = spirv_get_type_id_for_component_type(builder, + output_info->component_type, vsir_write_mask_component_count(dst_write_mask)); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); + output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id); +@@ -6263,7 +6271,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi + return; + } + +- type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); + mask = output_info->array_element_mask; + array_idx = spirv_compiler_get_output_array_index(compiler, output); +@@ -6305,7 +6313,7 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler * + function_id = compiler->epilogue_function_id; + + void_id = vkd3d_spirv_get_op_type_void(builder); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); ++ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 4); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); + for (i = 0, count = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i) + { +@@ -6536,7 +6544,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil + vkd3d_spirv_begin_function_stream_insertion(builder, function_location); + + component_type = vkd3d_component_type_from_data_type(temp->data_type); +- type_id = vkd3d_spirv_get_type_id(builder, component_type, temp->component_count); ++ type_id = spirv_get_type_id(builder, temp->data_type, temp->component_count); + length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size); + type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); +@@ -6577,7 +6585,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com + if (!(member_ids = vkd3d_calloc(count, sizeof(*member_ids)))) + return; + +- vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); ++ vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); + + for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) + { +@@ -6594,7 +6602,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com + + if (compiler->offset_info.descriptor_table_count) + { +- uint32_t type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ uint32_t type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); + length_id = spirv_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count); + member_ids[j] = vkd3d_spirv_build_op_type_array(builder, type_id, length_id); + vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4); +@@ -6788,7 +6796,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, + return; + } + +- vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); ++ vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); + length_id = spirv_compiler_get_constant_uint(compiler, size); + array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); + vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16); +@@ -6927,7 +6935,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler + vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); + } + +- sampled_type_id = vkd3d_spirv_get_type_id(builder, data_type, 1); ++ sampled_type_id = spirv_get_type_id_for_component_type(builder, data_type, 1); + return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, + 2, resource_type_info->arrayed, resource_type_info->ms, + reg->type == VKD3DSPR_UAV ? 2 : 1, format); +@@ -7053,7 +7061,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + { + uint32_t array_type_id, struct_id; + +- type_id = vkd3d_spirv_get_type_id(builder, sampled_type, 1); ++ type_id = spirv_get_type_id(builder, descriptor->resource_data_type, 1); + + array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); + vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); +@@ -7094,7 +7102,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp + { + VKD3D_ASSERT(structure_stride); /* counters are valid only for structured buffers */ + +- counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ counter_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); + if (spirv_compiler_is_opengl_target(compiler)) + { + vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage); +@@ -7158,7 +7166,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler + if (alignment) + TRACE("Ignoring alignment %u.\n", alignment); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + length_id = spirv_compiler_get_constant_uint(compiler, size); + array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); + +@@ -7209,10 +7217,9 @@ static void spirv_compiler_emit_output_vertex_count(struct spirv_compiler *compi + SpvExecutionModeOutputVertices, instruction->declaration.count); + } + +-static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) ++static void spirv_compiler_emit_input_primitive(struct spirv_compiler *compiler) + { +- enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; ++ enum vkd3d_primitive_type primitive_type = compiler->program->input_primitive; + SpvExecutionMode mode; + + switch (primitive_type) +@@ -7233,7 +7240,8 @@ static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compi + mode = SpvExecutionModeInputTrianglesAdjacency; + break; + default: +- FIXME("Unhandled primitive type %#x.\n", primitive_type); ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, ++ "Unhandled input primitive type %#x.", primitive_type); + return; + } + +@@ -7263,10 +7271,9 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) + } + } + +-static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compiler, +- const struct vkd3d_shader_instruction *instruction) ++static void spirv_compiler_emit_output_topology(struct spirv_compiler *compiler) + { +- enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; ++ enum vkd3d_primitive_type primitive_type = compiler->program->output_topology; + SpvExecutionMode mode; + + switch (primitive_type) +@@ -7282,7 +7289,8 @@ static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compi + mode = SpvExecutionModeOutputTriangleStrip; + break; + default: +- ERR("Unexpected primitive type %#x.\n", primitive_type); ++ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, ++ "Unhandled output topology %#x.", primitive_type); + return; + } + +@@ -7624,11 +7632,12 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, + /* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */ + val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); + } +- else if (dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) ++ else if (dst->reg.data_type == VSIR_DATA_I16 || dst->reg.data_type == VSIR_DATA_I32 ++ || dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) + { + val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); + } +- else if (dst->reg.data_type == VSIR_DATA_U64) ++ else if (dst->reg.data_type == VSIR_DATA_I64 || dst->reg.data_type == VSIR_DATA_U64) + { + val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); + } +@@ -7724,7 +7733,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]); + +- if (dst[0].reg.data_type == VSIR_DATA_U64) ++ if (data_type_is_64_bit(dst[0].reg.data_type)) + uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count); + else + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); +@@ -7839,7 +7848,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp + unsigned int i, component_count; + enum GLSLstd450 glsl_inst; + +- if (src[0].reg.data_type == VSIR_DATA_U64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI ++ if (data_type_is_64_bit(src[0].reg.data_type) && (instruction->opcode == VSIR_OP_FIRSTBIT_HI + || instruction->opcode == VSIR_OP_FIRSTBIT_LO || instruction->opcode == VSIR_OP_FIRSTBIT_SHI)) + { + /* At least some drivers support this anyway, but if validation is enabled it will fail. */ +@@ -7878,7 +7887,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp + component_count = vsir_write_mask_component_count(dst->write_mask); + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT32_MAX, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpIEqual, +- vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), val_id, uint_max_id); ++ spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), ++ val_id, uint_max_id); + rev_val_id = vkd3d_spirv_build_op_isub(builder, type_id, + spirv_compiler_get_constant_uint_vector(compiler, 31, component_count), val_id); + val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, rev_val_id); +@@ -7928,7 +7938,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, + dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); + src_id = spirv_compiler_get_register_id(compiler, &src->reg); + +- type_id = vkd3d_spirv_get_type_id(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone); + dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); + +@@ -7957,7 +7967,7 @@ general_implementation: + val_id = spirv_compiler_emit_load_src(compiler, src, write_mask); + if (dst->reg.data_type != src->reg.data_type) + { +- val_id = vkd3d_spirv_build_op_bitcast(builder, vkd3d_spirv_get_type_id_for_data_type(builder, ++ val_id = vkd3d_spirv_build_op_bitcast(builder, spirv_get_type_id(builder, + dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)), val_id); + } + spirv_compiler_emit_store_dst(compiler, dst, val_id); +@@ -7983,8 +7993,8 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, + { + if (instruction->opcode == VSIR_OP_CMP) + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, +- vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), condition_id, +- spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); ++ spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), ++ condition_id, spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); + else + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); +@@ -8010,7 +8020,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, + src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); + + component_count = vsir_write_mask_component_count(dst->write_mask); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + + condition_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); +@@ -8046,7 +8056,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, + for (i = 0; i < ARRAY_SIZE(src_ids); ++i) + src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); + +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + + val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpDot, type_id, src_ids[0], src_ids[1]); +@@ -8092,7 +8102,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, + unsigned int i, component_count; + + component_count = vsir_write_mask_component_count(dst->write_mask); +- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); + + for (i = 0; i < ARRAY_SIZE(src_ids); ++i) + src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); +@@ -8146,7 +8156,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, + component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); + + int_max_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, INT_MAX); +- condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); + +@@ -8199,7 +8209,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, + val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); + + uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); +- condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); + +@@ -8224,7 +8234,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, + + src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id); + if (instruction->flags & VKD3DSI_PRECISE_XYZW) + vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); +@@ -8248,8 +8258,8 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp + VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); + + component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); +- size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20; ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); ++ size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; + mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); + size_id = spirv_compiler_get_constant_uint(compiler, size); + +@@ -8305,8 +8315,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, + unsigned int i, j; + + instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); +- scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); ++ scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); + + /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ + VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); +@@ -8338,8 +8348,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, + unsigned int i, j; + + instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); +- scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); ++ scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + zero_id = spirv_compiler_get_constant_float(compiler, 0.0f); + + /* FIXME: Consider a single PackHalf2x16 instruction per 2 components. */ +@@ -8418,7 +8428,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co + src0_id = spirv_compiler_emit_load_src(compiler, &src[0], write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], write_mask); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, + op, type_id, src0_id, src1_id); + +@@ -8470,7 +8480,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil + src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); + + result_id = spirv_compiler_emit_bool_to_float(compiler, component_count, result_id, false); +@@ -8999,7 +9009,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, + + spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); + +- type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); + coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); + if (image.resource_type_info->resource_type != VKD3D_SHADER_RESOURCE_BUFFER && !multisample) +@@ -9045,7 +9055,7 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, + spirv_compiler_prepare_image(compiler, &image, + &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); + val_id = vkd3d_spirv_build_op_image_query_lod(builder, + type_id, image.sampled_image_id, coordinate_id); +@@ -9115,7 +9125,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, + instruction, image.resource_type_info); + } + +- sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); + VKD3D_ASSERT(image_operand_count <= ARRAY_SIZE(image_operands)); + val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, +@@ -9160,7 +9170,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, + instruction, image.resource_type_info); + } + +- sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); ++ sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, 1); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); + dref_id = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); + val_id = vkd3d_spirv_build_op_image_sample_dref(builder, op, sampled_type_id, +@@ -9219,7 +9229,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, + instruction, image.resource_type_info); + } + +- sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); + coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; + coordinate_id = spirv_compiler_emit_load_src(compiler, addr, coordinate_mask); + if (image_flags & VKD3D_IMAGE_FLAG_DEPTH) +@@ -9301,10 +9311,10 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler + + if (storage_buffer_uav) + { +- texel_type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ texel_type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, + type_id, resource_symbol->info.resource.structure_stride, + &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); +@@ -9336,11 +9346,11 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler + + spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, + type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); + +- texel_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ texel_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); + VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); + for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) + { +@@ -9379,7 +9389,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, + if (!spirv_compiler_get_register_info(compiler, &resource->reg, ®_info)) + return; + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, + type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); +@@ -9438,10 +9448,10 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * + + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + { +- type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, + type_id, resource_symbol->info.resource.structure_stride, + &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); +@@ -9469,7 +9479,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * + } + else + { +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, + type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); +@@ -9512,7 +9522,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, + if (!spirv_compiler_get_register_info(compiler, &dst->reg, ®_info)) + return; + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); + base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, + type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); +@@ -9570,7 +9580,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, + + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + { +- type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); + indices[0] = spirv_compiler_get_constant_uint(compiler, 0); +@@ -9585,7 +9595,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, + else + { + spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); +- type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); + coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); + +@@ -9613,7 +9623,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, + + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + { +- type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); + coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); + indices[0] = spirv_compiler_get_constant_uint(compiler, 0); +@@ -9658,7 +9668,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c + counter_id = resource_symbol->info.resource.uav_counter_id; + VKD3D_ASSERT(counter_id); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + + if (resource_symbol->info.resource.uav_counter_array) + { +@@ -9820,7 +9830,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil + } + } + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + if (structure_stride || raw) + { + VKD3D_ASSERT(!raw != !structure_stride); +@@ -9845,7 +9855,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil + if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) + { + component_type = resource_symbol->info.resource.sampled_type; +- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); + operands[0] = spirv_compiler_get_constant_uint(compiler, 0); + operands[1] = coordinate_id; +@@ -9854,7 +9864,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil + else + { + component_type = image.sampled_type; +- type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, 1); + ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id); + sample_id = spirv_compiler_get_constant_uint(compiler, 0); + pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, +@@ -9907,7 +9917,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, + { + resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0); + write_mask = VKD3DSP_WRITEMASK_0; + } +@@ -9917,7 +9927,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, + + spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); + write_mask = VKD3DSP_WRITEMASK_0; + } +@@ -9927,7 +9937,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, + stride_id = spirv_compiler_get_constant_uint(compiler, image.structure_stride); + constituents[0] = vkd3d_spirv_build_op_udiv(builder, type_id, val_id, stride_id); + constituents[1] = stride_id; +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); + val_id = vkd3d_spirv_build_op_composite_construct(builder, + type_id, constituents, ARRAY_SIZE(constituents)); + write_mask |= VKD3DSP_WRITEMASK_1; +@@ -9966,14 +9976,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, + size_component_count = image.resource_type_info->coordinate_component_count; + if (image.resource_type_info->dim == SpvDimCube) + --size_component_count; +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count); + + supports_mipmaps = src[1].reg.type != VKD3DSPR_UAV && !image.resource_type_info->ms; + if (supports_mipmaps) + { + lod_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); + val_id = vkd3d_spirv_build_op_image_query_size_lod(builder, type_id, image.image_id, lod_id); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + miplevel_count_id = vkd3d_spirv_build_op_image_query_levels(builder, type_id, image.image_id); + } + else +@@ -9987,14 +9997,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, + for (i = 0; i < 3 - size_component_count; ++i) + constituents[i + 1] = spirv_compiler_get_constant_uint(compiler, 0); + constituents[i + 1] = miplevel_count_id; +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_composite_construct(builder, + type_id, constituents, i + 2); + + if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) + { + component_type = VKD3D_SHADER_COMPONENT_FLOAT; +- type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); + if (instruction->flags & VKD3DSI_PRECISE_XYZW) + vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); +@@ -10022,7 +10032,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co + vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); + + spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + val_id = vkd3d_spirv_build_op_image_query_samples(builder, type_id, image.image_id); + } + +@@ -10049,13 +10059,13 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, + constituents[0] = val_id; + for (i = 1; i < VKD3D_VEC4_SIZE; ++i) + constituents[i] = spirv_compiler_get_constant_uint(compiler, 0); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); + + if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) + { + component_type = VKD3D_SHADER_COMPONENT_FLOAT; +- type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE); + val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); + if (instruction->flags & VKD3DSI_PRECISE_XYZW) + vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); +@@ -10121,13 +10131,13 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, + sample_count_id = spirv_compiler_emit_query_sample_count(compiler, &instruction->src[0]); + sample_index_id = spirv_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + index_id = vkd3d_spirv_build_op_iadd(builder, type_id, sample_count_id, sample_index_id); + index_id = vkd3d_spirv_build_op_isub(builder, + type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1)); + + /* Validate sample index. */ +- bool_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); ++ bool_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); + id = vkd3d_spirv_build_op_logical_and(builder, bool_id, + vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id), + vkd3d_spirv_build_op_uless_than_equal(builder, +@@ -10135,7 +10145,7 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, + index_id = vkd3d_spirv_build_op_select(builder, type_id, + id, index_id, spirv_compiler_get_constant_uint(compiler, 0)); + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); + if (!(id = compiler->sample_positions_id)) + { + length_id = spirv_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions)); +@@ -10199,7 +10209,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, + src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); + } + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, + vsir_write_mask_component_count(register_info.write_mask)); + + instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); +@@ -10334,9 +10344,8 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t type_id, direction_type_id, direction_id, val_id; + +- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, +- vsir_write_mask_component_count(dst->write_mask)); +- direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VSIR_DATA_U32, 1); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); ++ direction_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); + val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + direction_id = map_quad_read_across_direction(instruction->opcode); + direction_id = vkd3d_spirv_get_op_constant(builder, direction_type_id, direction_id); +@@ -10355,14 +10364,12 @@ static void spirv_compiler_emit_quad_read_lane_at(struct spirv_compiler *compile + + if (!register_is_constant_or_undef(&src[1].reg)) + { +- FIXME("Unsupported non-constant quad read lane index.\n"); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Non-constant quad read lane indices are not supported."); + return; + } + +- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, +- vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); + val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); + val_id = vkd3d_spirv_build_op_group_nonuniform_quad_broadcast(builder, type_id, val_id, lane_id); +@@ -10411,7 +10418,7 @@ static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compile + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + uint32_t type_id, val_id; + +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); + val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id); + +@@ -10470,8 +10477,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, + + op = map_wave_alu_op(instruction->opcode, data_type_is_floating_point(src->reg.data_type)); + +- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, +- vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); + val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + + vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformArithmetic); +@@ -10495,7 +10501,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, + : SpvGroupOperationReduce; + + val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); +- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ++ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + val_id = vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(builder, type_id, group_op, val_id); + + spirv_compiler_emit_store_dst(compiler, dst, val_id); +@@ -10520,8 +10526,7 @@ static void spirv_compiler_emit_wave_read_lane_at(struct spirv_compiler *compile + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t type_id, lane_id, val_id; + +- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, +- vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); + val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); + lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); + +@@ -10548,8 +10553,7 @@ static void spirv_compiler_emit_wave_read_lane_first(struct spirv_compiler *comp + const struct vkd3d_shader_src_param *src = instruction->src; + uint32_t type_id, val_id; + +- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, +- vsir_write_mask_component_count(dst->write_mask)); ++ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); + val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); + val_id = vkd3d_spirv_build_op_group_nonuniform_broadcast_first(builder, type_id, val_id); + +@@ -10608,12 +10612,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, + case VSIR_OP_DCL_VERTICES_OUT: + spirv_compiler_emit_output_vertex_count(compiler, instruction); + break; +- case VSIR_OP_DCL_INPUT_PRIMITIVE: +- spirv_compiler_emit_dcl_input_primitive(compiler, instruction); +- break; +- case VSIR_OP_DCL_OUTPUT_TOPOLOGY: +- spirv_compiler_emit_dcl_output_topology(compiler, instruction); +- break; + case VSIR_OP_DCL_GS_INSTANCES: + spirv_compiler_emit_dcl_gs_instances(compiler, instruction); + break; +@@ -11066,7 +11064,14 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + if (program->ssa_count) + spirv_compiler_allocate_ssa_register_ids(compiler, program->ssa_count); + if (compiler->shader_type == VKD3D_SHADER_TYPE_COMPUTE) ++ { + spirv_compiler_emit_thread_group_size(compiler, &program->thread_group_size); ++ } ++ else if (compiler->shader_type == VKD3D_SHADER_TYPE_GEOMETRY) ++ { ++ spirv_compiler_emit_input_primitive(compiler); ++ spirv_compiler_emit_output_topology(compiler); ++ } + spirv_compiler_emit_global_flags(compiler, program->global_flags); + + spirv_compiler_emit_descriptor_declarations(compiler); +@@ -11080,7 +11085,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, + { + uint32_t type_id, struct_id, ptr_type_id, var_id; + +- type_id = vkd3d_spirv_get_type_id(builder, ++ type_id = spirv_get_type_id_for_component_type(builder, + vkd3d_component_type_from_data_type(parameter_data_type_map[parameter->data_type].type), + parameter_data_type_map[parameter->data_type].component_count); + +diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c +index ea15c1a9ad5..ec1d8b91e09 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/tpf.c ++++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c +@@ -665,6 +665,8 @@ struct vkd3d_shader_sm4_parser + { + const uint32_t *start, *end, *ptr; + ++ struct vsir_program *program; ++ + enum vkd3d_shader_opcode phase; + bool has_control_point_phase; + unsigned int input_register_masks[MAX_REG_OUTPUT]; +@@ -764,7 +766,7 @@ static const enum vsir_data_type data_type_table[] = + + static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) + { +- const struct vkd3d_shader_version *version = &sm4->p.program->shader_version; ++ const struct vkd3d_shader_version *version = &sm4->program->shader_version; + + return version->major >= 5 && version->minor >= 1; + } +@@ -849,7 +851,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui + icb->element_count = icb_size / VKD3D_VEC4_SIZE; + icb->is_null = false; + memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); +- shader_instruction_array_add_icb(&priv->p.program->instructions, icb); ++ shader_instruction_array_add_icb(&priv->program->instructions, icb); + ins->declaration.icb = icb; + } + +@@ -971,7 +973,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) + { + struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range; +- struct vsir_program *program = priv->p.program; ++ struct vsir_program *program = priv->program; + unsigned int i, register_idx, register_count; + const struct shader_signature *signature; + enum vkd3d_shader_register_type type; +@@ -1094,14 +1096,14 @@ static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction + if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED) + FIXME("Unhandled output primitive type %#x.\n", primitive_type); + +- priv->p.program->output_topology = ins->declaration.primitive_type.type; ++ priv->program->output_topology = ins->declaration.primitive_type.type; + } + + static void shader_sm4_read_dcl_input_primitive(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 *sm4) + { + enum vkd3d_sm4_input_primitive_type primitive_type; +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + primitive_type = (opcode_token & VKD3D_SM4_PRIMITIVE_TYPE_MASK) >> VKD3D_SM4_PRIMITIVE_TYPE_SHIFT; + if (VKD3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= VKD3D_SM5_INPUT_PT_PATCH32) +@@ -1129,7 +1131,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction + static void shader_sm4_read_declaration_count(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 *sm4) + { +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + ins->declaration.count = *tokens; + if (opcode == VKD3D_SM4_OP_DCL_TEMPS) +@@ -1161,7 +1163,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u + if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) + { + struct signature_element *e = vsir_signature_find_element_for_reg( +- &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); ++ &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + + if (!e) + { +@@ -1187,7 +1189,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in + if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) + { + struct signature_element *e = vsir_signature_find_element_for_reg( +- &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); ++ &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + + if (!e) + { +@@ -1220,7 +1222,7 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in + uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) + { + ins->declaration.global_flags = (opcode_token & VKD3D_SM4_GLOBAL_FLAGS_MASK) >> VKD3D_SM4_GLOBAL_FLAGS_SHIFT; +- sm4->p.program->global_flags = ins->declaration.global_flags; ++ sm4->program->global_flags = ins->declaration.global_flags; + } + + static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, +@@ -1256,7 +1258,7 @@ static void shader_sm5_read_dcl_interface(struct vkd3d_shader_instruction *ins, + static void shader_sm5_read_control_point_count(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 *sm4) + { +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + ins->declaration.count = (opcode_token & VKD3D_SM5_CONTROL_POINT_COUNT_MASK) + >> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT; +@@ -1272,7 +1274,7 @@ static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instructi + { + ins->declaration.tessellator_domain = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) + >> VKD3D_SM5_TESSELLATOR_SHIFT; +- priv->p.program->tess_domain = ins->declaration.tessellator_domain; ++ priv->program->tess_domain = ins->declaration.tessellator_domain; + } + + static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_instruction *ins, uint32_t opcode, +@@ -1280,7 +1282,7 @@ static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_ins + { + ins->declaration.tessellator_partitioning = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) + >> VKD3D_SM5_TESSELLATOR_SHIFT; +- priv->p.program->tess_partitioning = ins->declaration.tessellator_partitioning; ++ priv->program->tess_partitioning = ins->declaration.tessellator_partitioning; + } + + static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, +@@ -1288,7 +1290,7 @@ static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader + { + ins->declaration.tessellator_output_primitive = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) + >> VKD3D_SM5_TESSELLATOR_SHIFT; +- priv->p.program->tess_output_primitive = ins->declaration.tessellator_output_primitive; ++ priv->program->tess_output_primitive = ins->declaration.tessellator_output_primitive; + } + + static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instruction *ins, uint32_t opcode, +@@ -1300,7 +1302,7 @@ static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instructio + static void shader_sm5_read_dcl_thread_group(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 *sm4) + { +- struct vsir_program *program = sm4->p.program; ++ struct vsir_program *program = sm4->program; + + ins->declaration.thread_group_size.x = *tokens++; + ins->declaration.thread_group_size.y = *tokens++; +@@ -2009,7 +2011,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const + { + if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) + { +- struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->p.program, 1); ++ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->program, 1); + + if (!(reg_idx->rel_addr = rel_addr)) + { +@@ -2284,7 +2286,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register * + { + return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT + || (reg->type == VKD3DSPR_INPUT && (priv->phase == VSIR_OP_HS_CONTROL_POINT_PHASE +- || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); ++ || priv->program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); + } + + static uint32_t mask_from_swizzle(uint32_t swizzle) +@@ -2608,8 +2610,8 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d + static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins) + { + const struct vkd3d_sm4_opcode_info *opcode_info; +- struct vsir_program *program = sm4->p.program; + uint32_t opcode_token, opcode, previous_token; ++ struct vsir_program *program = sm4->program; + struct vkd3d_shader_dst_param *dst_params; + struct vkd3d_shader_src_param *src_params; + const uint32_t **ptr = &sm4->ptr; +@@ -2814,8 +2816,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro + if (!vsir_program_init(program, compile_info, + &version, token_count / 7u + 20, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) + return false; +- vkd3d_shader_parser_init(&sm4->p, program, message_context, compile_info->source_name); ++ vkd3d_shader_parser_init(&sm4->p, message_context, compile_info->source_name); + sm4->ptr = sm4->start; ++ sm4->program = program; + + init_sm4_lookup_tables(&sm4->lookup); + +@@ -3692,7 +3695,7 @@ static void write_sm4_instruction(const struct tpf_compiler *tpf, const struct s + static void tpf_dcl_constant_buffer(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) + { + const struct vkd3d_shader_constant_buffer *cb = &ins->declaration.cb; +- size_t size = (cb->size + 3) / 4; ++ size_t size = cb->size / VKD3D_VEC4_SIZE / sizeof(float); + + struct sm4_instruction instr = + { +@@ -4222,6 +4225,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + + case VSIR_OP_DCL: + case VSIR_OP_DCL_RESOURCE_RAW: ++ case VSIR_OP_DCL_RESOURCE_STRUCTURED: + case VSIR_OP_DCL_UAV_RAW: + case VSIR_OP_DCL_UAV_STRUCTURED: + case VSIR_OP_DCL_UAV_TYPED: +@@ -4305,6 +4309,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ + case VSIR_OP_LD: + case VSIR_OP_LD2DMS: + case VSIR_OP_LD_RAW: ++ case VSIR_OP_LD_STRUCTURED: + case VSIR_OP_LD_UAV_TYPED: + case VSIR_OP_LOG: + case VSIR_OP_LOOP: +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +index 5fcc836aae1..6949c1cd38f 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +@@ -23,6 +23,8 @@ + #include + #include + ++/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */ ++ + static inline int char_to_int(char c) + { + if ('0' <= c && c <= '9') +@@ -722,14 +724,13 @@ uint64_t vkd3d_shader_init_config_flags(void) + return config_flags; + } + +-void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, ++void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, + struct vkd3d_shader_message_context *message_context, const char *source_name) + { + parser->message_context = message_context; + parser->location.source_name = source_name; + parser->location.line = 1; + parser->location.column = 0; +- parser->program = program; + } + + void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, +@@ -1683,6 +1684,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; + struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info; ++ struct vkd3d_shader_scan_thread_group_size_info *thread_group_size_info; + struct vkd3d_shader_scan_descriptor_info *descriptor_info; + struct vkd3d_shader_scan_signature_info *signature_info; + struct vkd3d_shader_scan_context context; +@@ -1704,6 +1706,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + } + + tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); ++ thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); + + vkd3d_shader_scan_context_init(&context, &program->shader_version, compile_info, + add_descriptor_info ? &program->descriptors : NULL, combined_sampler_info, message_context); +@@ -1756,6 +1759,13 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh + tessellation_info->partitioning = context.partitioning; + } + ++ if (!ret && thread_group_size_info) ++ { ++ thread_group_size_info->x = program->thread_group_size.x; ++ thread_group_size_info->y = program->thread_group_size.y; ++ thread_group_size_info->z = program->thread_group_size.z; ++ } ++ + if (ret < 0) + { + if (combined_sampler_info) +@@ -2182,6 +2192,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( + VKD3D_SHADER_TARGET_D3D_BYTECODE, + VKD3D_SHADER_TARGET_DXBC_TPF, + VKD3D_SHADER_TARGET_FX, ++#ifdef VKD3D_SHADER_UNSUPPORTED_MSL ++ VKD3D_SHADER_TARGET_MSL, ++#endif + }; + + static const enum vkd3d_shader_target_type d3dbc_types[] = +@@ -2253,6 +2266,7 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info + struct vkd3d_shader_code *out, char **messages) + { + struct vkd3d_shader_message_context message_context; ++ struct shader_dump_data dump_data; + int ret; + + TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages); +@@ -2265,7 +2279,11 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info + + vkd3d_shader_message_context_init(&message_context, compile_info->log_level); + +- ret = preproc_lexer_parse(compile_info, out, &message_context); ++ fill_shader_dump_data(compile_info, &dump_data); ++ vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); ++ ++ if ((ret = preproc_lexer_parse(compile_info, out, &message_context)) >= 0) ++ vkd3d_shader_dump_shader(&dump_data, out->code, out->size, SHADER_DUMP_TYPE_PREPROC); + + vkd3d_shader_message_context_trace_messages(&message_context); + if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) +@@ -2279,204 +2297,6 @@ void vkd3d_shader_set_log_callback(PFN_vkd3d_log callback) + vkd3d_dbg_set_log_callback(callback); + } + +-static struct vkd3d_shader_param_node *shader_param_allocator_node_create( +- struct vkd3d_shader_param_allocator *allocator) +-{ +- struct vkd3d_shader_param_node *node; +- +- if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride])))) +- return NULL; +- node->next = NULL; +- return node; +-} +- +-static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, +- size_t count, size_t stride) +-{ +- allocator->count = max(count, MAX_REG_OUTPUT); +- allocator->stride = stride; +- allocator->head = NULL; +- allocator->current = NULL; +- allocator->index = allocator->count; +-} +- +-static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator) +-{ +- struct vkd3d_shader_param_node *current = allocator->head; +- +- while (current) +- { +- struct vkd3d_shader_param_node *next = current->next; +- vkd3d_free(current); +- current = next; +- } +-} +- +-void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) +-{ +- void *params; +- +- if (!allocator->current || count > allocator->count - allocator->index) +- { +- struct vkd3d_shader_param_node *next; +- +- /* Monolithic switch has no definite parameter count limit. */ +- allocator->count = max(allocator->count, count); +- +- if (!(next = shader_param_allocator_node_create(allocator))) +- return NULL; +- if (allocator->current) +- allocator->current->next = next; +- else +- allocator->head = next; +- allocator->current = next; +- allocator->index = 0; +- } +- +- params = &allocator->current->param[allocator->index * allocator->stride]; +- allocator->index += count; +- return params; +-} +- +-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve) +-{ +- memset(instructions, 0, sizeof(*instructions)); +- /* Size the parameter initial allocations so they are large enough for most shaders. The +- * code path for chained allocations will be tested if a few shaders need to use it. */ +- shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u, +- sizeof(struct vkd3d_shader_dst_param)); +- shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); +- return shader_instruction_array_reserve(instructions, reserve); +-} +- +-bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve) +-{ +- if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve, +- sizeof(*instructions->elements))) +- { +- ERR("Failed to allocate instructions.\n"); +- return false; +- } +- return true; +-} +- +-bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, +- size_t idx, size_t count) +-{ +- VKD3D_ASSERT(idx <= instructions->count); +- +- if (!shader_instruction_array_reserve(instructions, instructions->count + count)) +- return false; +- +- memmove(&instructions->elements[idx + count], &instructions->elements[idx], +- (instructions->count - idx) * sizeof(*instructions->elements)); +- memset(&instructions->elements[idx], 0, count * sizeof(*instructions->elements)); +- +- instructions->count += count; +- +- return true; +-} +- +-bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, +- struct vkd3d_shader_immediate_constant_buffer *icb) +-{ +- if (!vkd3d_array_reserve((void **)&instructions->icbs, &instructions->icb_capacity, instructions->icb_count + 1, +- sizeof(*instructions->icbs))) +- return false; +- instructions->icbs[instructions->icb_count++] = icb; +- return true; +-} +- +-static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( +- struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, +- size_t count); +- +-static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, +- struct vkd3d_shader_instruction_array *instructions) +-{ +- unsigned int i; +- +- for (i = 0; i < reg->idx_count; ++i) +- { +- if (!reg->idx[i].rel_addr) +- continue; +- +- if (!(reg->idx[i].rel_addr = shader_instruction_array_clone_src_params(instructions, reg->idx[i].rel_addr, 1))) +- return false; +- } +- +- return true; +-} +- +-static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( +- struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_dst_param *params, +- size_t count) +-{ +- struct vkd3d_shader_dst_param *dst_params; +- size_t i; +- +- if (!(dst_params = shader_dst_param_allocator_get(&instructions->dst_params, count))) +- return NULL; +- +- memcpy(dst_params, params, count * sizeof(*params)); +- for (i = 0; i < count; ++i) +- { +- if (!shader_register_clone_relative_addresses(&dst_params[i].reg, instructions)) +- return NULL; +- } +- +- return dst_params; +-} +- +-static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( +- struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, +- size_t count) +-{ +- struct vkd3d_shader_src_param *src_params; +- size_t i; +- +- if (!(src_params = shader_src_param_allocator_get(&instructions->src_params, count))) +- return NULL; +- +- memcpy(src_params, params, count * sizeof(*params)); +- for (i = 0; i < count; ++i) +- { +- if (!shader_register_clone_relative_addresses(&src_params[i].reg, instructions)) +- return NULL; +- } +- +- return src_params; +-} +- +-/* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the +- * destination is in use. This seems like a reasonable requirement given how this is currently used. */ +-bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, +- size_t dst, size_t src) +-{ +- struct vkd3d_shader_instruction *ins = &instructions->elements[dst]; +- +- *ins = instructions->elements[src]; +- +- if (ins->dst_count && ins->dst && !(ins->dst = shader_instruction_array_clone_dst_params(instructions, +- ins->dst, ins->dst_count))) +- return false; +- +- return !ins->src_count || !!(ins->src = shader_instruction_array_clone_src_params(instructions, +- ins->src, ins->src_count)); +-} +- +-void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions) +-{ +- unsigned int i; +- +- vkd3d_free(instructions->elements); +- shader_param_allocator_destroy(&instructions->dst_params); +- shader_param_allocator_destroy(&instructions->src_params); +- for (i = 0; i < instructions->icb_count; ++i) +- vkd3d_free(instructions->icbs[i]); +- vkd3d_free(instructions->icbs); +-} +- + void vkd3d_shader_build_varying_map(const struct vkd3d_shader_signature *output_signature, + const struct vkd3d_shader_signature *input_signature, + unsigned int *ret_count, struct vkd3d_shader_varying_map *varyings) +diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +index e758c16b3d4..c00a7825610 100644 +--- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h ++++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +@@ -213,7 +213,7 @@ enum vkd3d_shader_error + VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT = 8005, + VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_TABLE = 8006, + VKD3D_SHADER_ERROR_DXIL_INVALID_VALUE_SYMTAB = 8007, +- VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED_BITCODE_FORMAT = 8008, ++ VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED = 8008, + VKD3D_SHADER_ERROR_DXIL_INVALID_FUNCTION_DCL = 8009, + VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID = 8010, + VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011, +@@ -716,7 +716,9 @@ enum vsir_data_type + VSIR_DATA_F32, + VSIR_DATA_F64, + ++ VSIR_DATA_I16, + VSIR_DATA_I32, ++ VSIR_DATA_I64, + + VSIR_DATA_U8, + VSIR_DATA_U16, +@@ -734,10 +736,13 @@ enum vsir_data_type + VSIR_DATA_TYPE_COUNT, + }; + ++const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error); ++ + static inline bool data_type_is_integer(enum vsir_data_type data_type) + { +- return data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 +- || data_type == VSIR_DATA_U32 || data_type == VSIR_DATA_U64; ++ return data_type == VSIR_DATA_I16 || data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_I64 ++ || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 || data_type == VSIR_DATA_U32 ++ || data_type == VSIR_DATA_U64; + } + + static inline bool data_type_is_bool(enum vsir_data_type data_type) +@@ -752,7 +757,7 @@ static inline bool data_type_is_floating_point(enum vsir_data_type data_type) + + static inline bool data_type_is_64_bit(enum vsir_data_type data_type) + { +- return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_U64; ++ return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_I64 || data_type == VSIR_DATA_U64; + } + + enum vsir_dimension +@@ -1439,15 +1444,11 @@ struct vkd3d_shader_instruction_array + struct vkd3d_shader_src_param *outpointid_param; + }; + +-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve); + bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve); + bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, + size_t idx, size_t count); + bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, + struct vkd3d_shader_immediate_constant_buffer *icb); +-bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, +- size_t dst, size_t src); +-void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); + + struct vsir_program_iterator + { +@@ -1510,6 +1511,38 @@ static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterat + return shader_instruction_array_insert_at(it->array, it->idx + 1, count); + } + ++/* When insertion takes place, argument `it' is updated to point to the same ++ * instruction as before the insertion, and the optional argument `ins_it' is ++ * initialized to point to the first inserted instruction. ++ * A pointer to the first inserted instruction is returned. */ ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before( ++ struct vsir_program_iterator *it, struct vsir_program_iterator *ins_it, size_t count) ++{ ++ VKD3D_ASSERT(it != ins_it); ++ VKD3D_ASSERT(it->idx != SIZE_MAX); ++ ++ if (!shader_instruction_array_insert_at(it->array, it->idx, count)) ++ return NULL; ++ ++ *ins_it = *it; ++ it->idx += count; ++ ++ return vsir_program_iterator_current(ins_it); ++} ++ ++/* When insertion takes place, argument `it' is updated to point to the first ++ * inserted instruction. A pointer to this first inserted instruction is ++ * returned. */ ++static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before_and_move( ++ struct vsir_program_iterator *it, size_t count) ++{ ++ VKD3D_ASSERT(it->idx != SIZE_MAX); ++ ++ if (!shader_instruction_array_insert_at(it->array, it->idx, count)) ++ return NULL; ++ return vsir_program_iterator_current(it); ++} ++ + enum vkd3d_shader_config_flags + { + VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, +@@ -1651,13 +1684,12 @@ struct vkd3d_shader_parser + { + struct vkd3d_shader_message_context *message_context; + struct vkd3d_shader_location location; +- struct vsir_program *program; + bool failed; + }; + + void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); +-void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, ++void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, + struct vkd3d_shader_message_context *message_context, const char *source_name); + void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); +@@ -1852,20 +1884,28 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty + { + case VSIR_DATA_BOOL: + return VKD3D_SHADER_COMPONENT_BOOL; +- case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ ++ case VSIR_DATA_F16: ++ return VKD3D_SHADER_COMPONENT_FLOAT16; + case VSIR_DATA_F32: + case VSIR_DATA_SNORM: + case VSIR_DATA_UNORM: + return VKD3D_SHADER_COMPONENT_FLOAT; + case VSIR_DATA_F64: + return VKD3D_SHADER_COMPONENT_DOUBLE; ++ case VSIR_DATA_I16: ++ return VKD3D_SHADER_COMPONENT_INT16; + case VSIR_DATA_I32: + return VKD3D_SHADER_COMPONENT_INT; +- case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */ ++ case VSIR_DATA_I64: ++ return VKD3D_SHADER_COMPONENT_INT64; ++ case VSIR_DATA_U16: ++ return VKD3D_SHADER_COMPONENT_UINT16; + case VSIR_DATA_U32: + return VKD3D_SHADER_COMPONENT_UINT; + case VSIR_DATA_U64: + return VKD3D_SHADER_COMPONENT_UINT64; ++ case VSIR_DATA_UNUSED: ++ return VKD3D_SHADER_COMPONENT_VOID; + default: + FIXME("Unhandled data type %#x.\n", data_type); + /* fall-through */ +@@ -1878,23 +1918,41 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_ + { + switch (component_type) + { +- case VKD3D_SHADER_COMPONENT_FLOAT: +- return VSIR_DATA_F32; ++ case VKD3D_SHADER_COMPONENT_VOID: ++ return VSIR_DATA_UNUSED; + case VKD3D_SHADER_COMPONENT_UINT: + return VSIR_DATA_U32; + case VKD3D_SHADER_COMPONENT_INT: + return VSIR_DATA_I32; ++ case VKD3D_SHADER_COMPONENT_FLOAT: ++ return VSIR_DATA_F32; ++ case VKD3D_SHADER_COMPONENT_BOOL: ++ return VSIR_DATA_BOOL; + case VKD3D_SHADER_COMPONENT_DOUBLE: + return VSIR_DATA_F64; +- default: +- FIXME("Unhandled component type %#x.\n", component_type); +- return VSIR_DATA_F32; ++ case VKD3D_SHADER_COMPONENT_UINT64: ++ return VSIR_DATA_U64; ++ case VKD3D_SHADER_COMPONENT_INT64: ++ return VSIR_DATA_I64; ++ case VKD3D_SHADER_COMPONENT_FLOAT16: ++ return VSIR_DATA_F16; ++ case VKD3D_SHADER_COMPONENT_UINT16: ++ return VSIR_DATA_U16; ++ case VKD3D_SHADER_COMPONENT_INT16: ++ return VSIR_DATA_I16; ++ case VKD3D_SHADER_COMPONENT_TYPE_FORCE_32BIT: ++ break; + } ++ ++ FIXME("Unhandled component type %#x.\n", component_type); ++ ++ return VSIR_DATA_UNUSED; + } + + static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) + { +- return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; ++ return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_INT64 ++ || component_type == VKD3D_SHADER_COMPONENT_UINT64; + } + + static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) +diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +index f2967835b62..fea8c2440d1 100644 +--- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c ++++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +@@ -19,6 +19,8 @@ + #include "vkd3d_utils_private.h" + #undef D3D12CreateDevice + ++/* VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG"); */ ++ + static const char *debug_d3d_blob_part(D3D_BLOB_PART part) + { + switch (part) +@@ -269,7 +271,7 @@ HRESULT WINAPI D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char * + + option = &options[0]; + option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; +- option->value = VKD3D_SHADER_API_VERSION_1_17; ++ option->value = VKD3D_SHADER_API_VERSION_CURRENT; + + compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; + compile_info.next = &preprocess_info; +@@ -433,7 +435,7 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, + }; + + TRACE("data %p, size %"PRIuPTR", filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", +@@ -482,7 +484,10 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename + + if (!ret) + { +- if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, preprocessed_code.size, preprocessed_blob))) ++ /* vkd3d-shader output is null-terminated, but the null terminator isn't ++ * included in the size. Increase the size to account for that. */ ++ if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, ++ preprocessed_code.size + 1, preprocessed_blob))) + { + vkd3d_shader_free_shader_code(&preprocessed_code); + return hr; +@@ -979,7 +984,7 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, + }; + + TRACE("data %p, data_size %"PRIuPTR", flags %#x, comments %p, blob %p.\n", +@@ -1032,7 +1037,9 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, + return hresult_from_vkd3d_result(ret); + } + +- if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size, blob))) ++ /* vkd3d-shader output is null-terminated, but the null terminator isn't ++ * included in the size. Increase the size to account for that. */ ++ if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size + 1, blob))) + vkd3d_shader_free_shader_code(&output); + + return hr; +diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c +index 074d8430585..d933e7ec463 100644 +--- a/libs/vkd3d/libs/vkd3d/command.c ++++ b/libs/vkd3d/libs/vkd3d/command.c +@@ -3049,7 +3049,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list + + if (descriptor_count > range->vk_binding_count) + { +- ERR("Heap descriptor count %u exceeds maximum Vulkan count %u. Reducing to the Vulkan maximum.\n", ++ MESSAGE("Heap descriptor count %u exceeds maximum Vulkan count %u. Reducing to the Vulkan maximum.\n", + descriptor_count, range->vk_binding_count); + descriptor_count = range->vk_binding_count; + } +diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c +index 6bbd6533b74..b6055a50a99 100644 +--- a/libs/vkd3d/libs/vkd3d/state.c ++++ b/libs/vkd3d/libs/vkd3d/state.c +@@ -2391,7 +2391,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device, + + const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, + {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, + {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0}, + {VKD3D_SHADER_COMPILE_OPTION_FEATURE, feature_flags_compile_option(device)}, +@@ -2456,7 +2456,7 @@ static int vkd3d_scan_dxbc(const struct d3d12_device *device, const D3D12_SHADER + + const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, + {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, + }; + +@@ -4135,7 +4135,7 @@ static int compile_hlsl_cs(const struct vkd3d_shader_code *hlsl, struct vkd3d_sh + + static const struct vkd3d_shader_compile_option options[] = + { +- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, ++ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, + }; + + info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; +diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c +index c2832a61f67..2d0510e5456 100644 +--- a/libs/vkd3d/libs/vkd3d/utils.c ++++ b/libs/vkd3d/libs/vkd3d/utils.c +@@ -703,7 +703,7 @@ const char *debug_vk_extent_3d(VkExtent3D extent) + + const char *debug_vk_queue_flags(VkQueueFlags flags) + { +- char buffer[191]; ++ char buffer[222]; + + buffer[0] = '\0'; + #define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; } +@@ -716,6 +716,7 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) + #define FLAG_TO_STR(f, n) if (flags & f) { strcat(buffer, " | "#n); flags &= ~f; } + FLAG_TO_STR(0x20, VK_QUEUE_VIDEO_DECODE_BIT_KHR) + FLAG_TO_STR(0x40, VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ++ FLAG_TO_STR(0x100, VK_QUEUE_OPTICAL_FLOW_BIT_NV) + #undef FLAG_TO_STR + if (flags) + FIXME("Unrecognized flag(s) %#x.\n", flags); +-- +2.51.0 + diff --git a/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch b/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch deleted file mode 100644 index f544d84f..00000000 --- a/patches/vkd3d-latest/0002-Updated-vkd3d-to-3b41d99fa9e80dda5844738a226f70f14f7.patch +++ /dev/null @@ -1,1929 +0,0 @@ -From a299300b535557f8c54b066d082b1bb47ffce104 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 22 Aug 2025 07:26:18 +1000 -Subject: [PATCH] Updated vkd3d to 3b41d99fa9e80dda5844738a226f70f14f778c8b. - ---- - libs/vkd3d/include/vkd3d_shader.h | 23 ++ - libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 34 ++- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 73 ++--- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 1 + - libs/vkd3d/libs/vkd3d-shader/hlsl.c | 70 +++++ - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 9 + - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 48 +++ - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 281 +++++++++++++++++- - .../libs/vkd3d-shader/hlsl_constant_ops.c | 83 +----- - libs/vkd3d/libs/vkd3d-shader/ir.c | 208 ++++++------- - libs/vkd3d/libs/vkd3d-shader/msl.c | 1 + - libs/vkd3d/libs/vkd3d-shader/tpf.c | 39 +-- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 15 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 3 +- - 14 files changed, 630 insertions(+), 258 deletions(-) - -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index d82869e79ea..a1f85dbbd05 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -120,6 +120,11 @@ enum vkd3d_shader_structure_type - * \since 1.15 - */ - VKD3D_SHADER_STRUCTURE_TYPE_SCAN_HULL_SHADER_TESSELLATION_INFO, -+ /** -+ * The structure is a vkd3d_shader_scan_thread_group_size_info structure. -+ * \since 1.18 -+ */ -+ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, - - VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), - }; -@@ -2282,6 +2287,24 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info - enum vkd3d_shader_tessellator_partitioning partitioning; - }; - -+/** -+ * A chained structure describing the thread group size in a compute shader. -+ * -+ * This structure extends vkd3d_shader_compile_info. -+ * -+ * \since 1.18 -+ */ -+struct vkd3d_shader_scan_thread_group_size_info -+{ -+ /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO. */ -+ enum vkd3d_shader_structure_type type; -+ /** Optional pointer to a structure containing further parameters. */ -+ const void *next; -+ -+ /** The thread group size in the x/y/z direction. */ -+ unsigned int x, y, z; -+}; -+ - /** - * Data type of a shader varying, returned as part of struct - * vkd3d_shader_signature_element. -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -index 751e5578276..0272271b782 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c -@@ -246,6 +246,7 @@ struct vkd3d_shader_sm1_parser - bool abort; - - struct vkd3d_shader_parser p; -+ struct vsir_program *program; - - struct - { -@@ -468,7 +469,7 @@ static bool has_relative_address(uint32_t param) - static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( - const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode) - { -- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; -+ const struct vkd3d_shader_version *version = &sm1->program->shader_version; - const struct vkd3d_sm1_opcode_info *info; - unsigned int i = 0; - -@@ -542,9 +543,9 @@ static enum vkd3d_shader_register_type parse_register_type( - } - - if (d3dbc_type == VKD3D_SM1_REG_ADDR) -- return sm1->p.program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; -+ return sm1->program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; - if (d3dbc_type == VKD3D_SM1_REG_TEXCRDOUT) -- return vkd3d_shader_ver_ge(&sm1->p.program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; -+ return vkd3d_shader_ver_ge(&sm1->program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; - - for (unsigned int i = 0; i < ARRAY_SIZE(register_types); ++i) - { -@@ -660,7 +661,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp - const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval, - unsigned int register_index, bool is_dcl, unsigned int mask) - { -- struct vsir_program *program = sm1->p.program; -+ struct vsir_program *program = sm1->program; - struct shader_signature *signature; - struct signature_element *element; - -@@ -702,7 +703,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp - static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, - unsigned int register_index, unsigned int mask) - { -- struct vsir_program *program = sm1->p.program; -+ struct vsir_program *program = sm1->program; - struct shader_signature *signature; - struct signature_element *element; - -@@ -749,7 +750,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, - static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, - const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) - { -- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; -+ const struct vkd3d_shader_version *version = &sm1->program->shader_version; - unsigned int register_index = reg->idx_count > 0 ? reg->idx[0].offset : 0; - - switch (reg->type) -@@ -844,7 +845,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * - static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1, - const struct vkd3d_shader_semantic *semantic) - { -- const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; -+ const struct vkd3d_shader_version *version = &sm1->program->shader_version; - const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg; - enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; - unsigned int mask = semantic->resource.reg.write_mask; -@@ -906,7 +907,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, - static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, - const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def) - { -- struct vsir_program *program = sm1->p.program; -+ struct vsir_program *program = sm1->program; - uint32_t register_index = reg->idx[0].offset; - - switch (reg->type) -@@ -955,7 +956,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, - * VS >= 2.0 have relative addressing (with token) - * VS >= 1.0 < 2.0 have relative addressing (without token) - * The version check below should work in general. */ -- if (sm1->p.program->shader_version.major < 2) -+ if (sm1->program->shader_version.major < 2) - { - *addr_token = (1u << 31) - | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2) -@@ -984,7 +985,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co - /* Version 2.0+ shaders may contain address tokens, but fortunately they - * have a useful length mask - use it here. Version 1.x shaders contain no - * such tokens. */ -- if (sm1->p.program->shader_version.major >= 2) -+ if (sm1->program->shader_version.major >= 2) - { - length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; - *ptr += length; -@@ -1019,7 +1020,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const - shader_sm1_read_param(sm1, ptr, &token, &addr_token); - if (has_relative_address(token)) - { -- if (!(src_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) -+ if (!(src_rel_addr = vsir_program_get_src_params(sm1->program, 1))) - { - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, - "Out of memory."); -@@ -1040,7 +1041,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const - shader_sm1_read_param(sm1, ptr, &token, &addr_token); - if (has_relative_address(token)) - { -- if (!(dst_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) -+ if (!(dst_rel_addr = vsir_program_get_src_params(sm1->program, 1))) - { - vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, - "Out of memory."); -@@ -1052,9 +1053,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const - shader_sm1_parse_dst_param(sm1, token, dst_rel_addr, dst_param); - - if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE) -- sm1->p.program->has_point_size = true; -+ sm1->program->has_point_size = true; - if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_FOG) -- sm1->p.program->has_fog = true; -+ sm1->program->has_fog = true; - } - - static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, -@@ -1214,7 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str - { - struct vkd3d_shader_src_param *src_params, *predicate; - const struct vkd3d_sm1_opcode_info *opcode_info; -- struct vsir_program *program = sm1->p.program; -+ struct vsir_program *program = sm1->program; - unsigned int vsir_dst_count, vsir_src_count; - struct vkd3d_shader_dst_param *dst_param; - const uint32_t **ptr = &sm1->ptr; -@@ -1446,7 +1447,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st - code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED, normalisation_level)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name); -+ vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name); -+ sm1->program = program; - sm1->ptr = sm1->start; - - return VKD3D_OK; -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index c448e000cf9..6a12dec14bf 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -892,6 +892,8 @@ struct sm6_parser - const uint32_t *ptr, *start, *end; - unsigned int bitpos; - -+ struct vsir_program *program; -+ - struct dxil_block root_block; - struct dxil_block *current_block; - -@@ -2437,7 +2439,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ - { - struct vkd3d_shader_src_param *params; - -- if (!(params = vsir_program_get_src_params(sm6->p.program, count))) -+ if (!(params = vsir_program_get_src_params(sm6->program, count))) - { - ERR("Failed to allocate src params.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -2454,7 +2456,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ - { - struct vkd3d_shader_dst_param *params; - -- if (!(params = vsir_program_get_dst_params(sm6->p.program, count))) -+ if (!(params = vsir_program_get_dst_params(sm6->program, count))) - { - ERR("Failed to allocate dst params.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -2756,7 +2758,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, - } - else - { -- struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1); -+ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->program, 1); - if (rel_addr) - src_param_init_from_value(rel_addr, address, sm6); - idx->offset = 0; -@@ -3224,7 +3226,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - "Out of memory allocating an immediate constant buffer of count %u.", count); - return VKD3D_ERROR_OUT_OF_MEMORY; - } -- if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb)) -+ if (!shader_instruction_array_add_icb(&sm6->program->instructions, icb)) - { - ERR("Failed to store icb object.\n"); - vkd3d_free(icb); -@@ -3653,7 +3655,7 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al - - static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra) - { -- struct vkd3d_shader_instruction_array *instructions = &sm6->p.program->instructions; -+ struct vkd3d_shader_instruction_array *instructions = &sm6->program->instructions; - - if (!shader_instruction_array_reserve(instructions, instructions->count + extra)) - { -@@ -3670,7 +3672,7 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa - struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); - VKD3D_ASSERT(ins); - vsir_instruction_init(ins, &sm6->p.location, handler_idx); -- ++sm6->p.program->instructions.count; -+ ++sm6->program->instructions.count; - return ins; - } - -@@ -3969,7 +3971,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm - - static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) - { -- struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions); -+ struct vsir_program_iterator it = vsir_program_iterator(&sm6->program->instructions); - size_t i, count, base_value_idx = sm6->value_count; - const struct dxil_block *block = &sm6->root_block; - struct vkd3d_shader_instruction *ins; -@@ -4125,7 +4127,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( - static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, - bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) - { -- enum vkd3d_shader_type shader_type = sm6->p.program->shader_version.type; -+ enum vkd3d_shader_type shader_type = sm6->program->shader_version.type; - enum vkd3d_shader_register_type io_reg_type; - bool is_patch_constant, is_control_point; - struct vkd3d_shader_dst_param *param; -@@ -4175,7 +4177,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade - if (is_control_point) - { - if (reg_type == VKD3DSPR_OUTPUT) -- param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->p.program); -+ param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->program); - param->reg.idx[count++].offset = 0; - } - -@@ -4190,7 +4192,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade - - static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) - { -- if (!(sm6->output_params = vsir_program_get_dst_params(sm6->p.program, output_signature->element_count))) -+ if (!(sm6->output_params = vsir_program_get_dst_params(sm6->program, output_signature->element_count))) - { - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, - "Failed to allocate output parameters."); -@@ -4204,7 +4206,7 @@ static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct - - static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) - { -- if (!(sm6->input_params = vsir_program_get_dst_params(sm6->p.program, input_signature->element_count))) -+ if (!(sm6->input_params = vsir_program_get_dst_params(sm6->program, input_signature->element_count))) - { - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, - "Failed to allocate input parameters."); -@@ -4219,9 +4221,9 @@ static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct - static int sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, - const struct shader_signature *patch_constant_signature) - { -- bool is_input = sm6->p.program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; -+ bool is_input = sm6->program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; - -- if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->p.program, -+ if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->program, - patch_constant_signature->element_count))) - { - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -@@ -5407,7 +5409,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri - row_index = sm6_value_get_constant_uint(operands[0], sm6); - column_index = sm6_value_get_constant_uint(operands[2], sm6); - -- signature = &sm6->p.program->input_signature; -+ signature = &sm6->program->input_signature; - if (row_index >= signature->element_count) - { - WARN("Invalid row index %u.\n", row_index); -@@ -5638,7 +5640,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin - bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT; - bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT; - struct vkd3d_shader_instruction *ins = state->ins; -- struct vsir_program *program = sm6->p.program; -+ struct vsir_program *program = sm6->program; - unsigned int count, row_index, column_index; - const struct vkd3d_shader_dst_param *params; - struct vkd3d_shader_src_param *src_param; -@@ -6148,7 +6150,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ - static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) - { -- const struct shader_signature *signature = &sm6->p.program->input_signature; -+ const struct shader_signature *signature = &sm6->program->input_signature; - struct vkd3d_shader_instruction *ins = state->ins; - struct vkd3d_shader_src_param *src_param; - unsigned int element_idx; -@@ -6207,7 +6209,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr - { - bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT; - struct vkd3d_shader_instruction *ins = state->ins; -- struct vsir_program *program = sm6->p.program; -+ struct vsir_program *program = sm6->program; - struct vkd3d_shader_src_param *src_param; - struct vkd3d_shader_dst_param *dst_param; - const struct shader_signature *signature; -@@ -8206,7 +8208,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun - static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, - struct sm6_function *function) - { -- struct vsir_program *program = sm6->p.program; -+ struct vsir_program *program = sm6->program; - struct vkd3d_shader_instruction *ins; - size_t i, block_idx, block_count; - const struct dxil_record *record; -@@ -8586,7 +8588,7 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) - - static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6) - { -- struct vsir_program *program = sm6->p.program; -+ struct vsir_program *program = sm6->program; - unsigned int i; - - program->block_count = function->block_count; -@@ -9592,7 +9594,7 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, - } - - ++sm6->descriptor_count; -- ++sm6->p.program->instructions.count; -+ ++sm6->program->instructions.count; - } - - return VKD3D_OK; -@@ -9711,7 +9713,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const - { - unsigned int i, j, column_count, operand_count, index; - const struct sm6_metadata_node *node, *element_node; -- struct vsir_program *program = sm6->p.program; -+ struct vsir_program *program = sm6->program; - struct signature_element *elements, *e; - unsigned int values[10]; - bool native_16bit; -@@ -9930,7 +9932,7 @@ invalid: - static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m, - enum vkd3d_tessellator_domain tessellator_domain) - { -- struct vsir_program *program = sm6->p.program; -+ struct vsir_program *program = sm6->program; - enum vkd3d_result ret; - - if (!sm6_metadata_value_is_node(m)) -@@ -9985,12 +9987,12 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm - - ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_GLOBAL_FLAGS); - ins->declaration.global_flags = global_flags; -- sm6->p.program->global_flags = global_flags; -+ sm6->program->global_flags = global_flags; - } - - static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m) - { -- struct vkd3d_shader_version *version = &sm6->p.program->shader_version; -+ struct vkd3d_shader_version *version = &sm6->program->shader_version; - const struct sm6_metadata_node *node; - struct vkd3d_shader_instruction *ins; - unsigned int group_sizes[3]; -@@ -10044,7 +10046,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co - ins->declaration.thread_group_size.x = group_sizes[0]; - ins->declaration.thread_group_size.y = group_sizes[1]; - ins->declaration.thread_group_size.z = group_sizes[2]; -- sm6->p.program->thread_group_size = ins->declaration.thread_group_size; -+ sm6->program->thread_group_size = ins->declaration.thread_group_size; - - return VKD3D_OK; - } -@@ -10082,7 +10084,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, - - ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_DOMAIN); - ins->declaration.tessellator_domain = tessellator_domain; -- sm6->p.program->tess_domain = tessellator_domain; -+ sm6->program->tess_domain = tessellator_domain; - } - - static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, -@@ -10111,7 +10113,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, - ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_PARTITIONING); - ins->declaration.tessellator_partitioning = tessellator_partitioning; - -- sm6->p.program->tess_partitioning = tessellator_partitioning; -+ sm6->program->tess_partitioning = tessellator_partitioning; - } - - static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, -@@ -10129,7 +10131,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * - ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); - ins->declaration.tessellator_output_primitive = primitive; - -- sm6->p.program->tess_output_primitive = primitive; -+ sm6->program->tess_output_primitive = primitive; - } - - static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m) -@@ -10241,8 +10243,8 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s - } - - sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); -- sm6->p.program->input_primitive = input_primitive; -- sm6->p.program->input_control_point_count = input_control_point_count; -+ sm6->program->input_primitive = input_primitive; -+ sm6->program->input_control_point_count = input_control_point_count; - - i = operands[1]; - /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */ -@@ -10253,7 +10255,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s - "Geometry shader output vertex count %u is invalid.", i); - } - sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i); -- sm6->p.program->vertices_out_count = i; -+ sm6->program->vertices_out_count = i; - - if (operands[2] > 1) - { -@@ -10271,7 +10273,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s - output_primitive = VKD3D_PT_TRIANGLELIST; - } - sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); -- sm6->p.program->output_topology = output_primitive; -+ sm6->program->output_topology = output_primitive; - - i = operands[4]; - if (!i || i > MAX_GS_INSTANCE_COUNT) -@@ -10326,7 +10328,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa - - sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); - sm6_parser_validate_control_point_count(sm6, operands[1], true, "Domain shader input"); -- sm6->p.program->input_control_point_count = operands[1]; -+ sm6->program->input_control_point_count = operands[1]; - - return operands[0]; - } -@@ -10334,7 +10336,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa - static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, - const struct sm6_metadata_value *m) - { -- struct vsir_program *program = sm6->p.program; -+ struct vsir_program *program = sm6->program; - const struct sm6_metadata_node *node; - unsigned int operands[6] = {0}; - unsigned int i; -@@ -10727,9 +10729,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro - if (!vsir_program_init(program, compile_info, &version, - (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS, VSIR_NORMALISED_SM6)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name); -+ vkd3d_shader_parser_init(&sm6->p, message_context, compile_info->source_name); - sm6->ptr = &sm6->start[1]; - sm6->bitpos = 2; -+ sm6->program = program; - - switch (program->shader_version.type) - { -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index dfe0a40ddf0..5988e7b3a30 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -1531,6 +1531,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - break; - case VSIR_OP_GEO: - case VSIR_OP_IGE: -+ case VSIR_OP_UGE: - shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); - break; - case VSIR_OP_IF: -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -index 62335086e20..d8eb18e39c7 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c -@@ -1809,6 +1809,76 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v - return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); - } - -+bool hlsl_constant_is_zero(struct hlsl_ir_constant *c) -+{ -+ struct hlsl_type *data_type = c->node.data_type; -+ unsigned int k; -+ -+ for (k = 0; k < data_type->e.numeric.dimx; ++k) -+ { -+ switch (data_type->e.numeric.type) -+ { -+ case HLSL_TYPE_FLOAT: -+ case HLSL_TYPE_HALF: -+ if (c->value.u[k].f != 0.0f) -+ return false; -+ break; -+ -+ case HLSL_TYPE_DOUBLE: -+ if (c->value.u[k].d != 0.0) -+ return false; -+ break; -+ -+ case HLSL_TYPE_UINT: -+ case HLSL_TYPE_INT: -+ case HLSL_TYPE_BOOL: -+ case HLSL_TYPE_MIN16UINT: -+ if (c->value.u[k].u != 0) -+ return false; -+ break; -+ } -+ } -+ -+ return true; -+} -+ -+bool hlsl_constant_is_one(struct hlsl_ir_constant *c) -+{ -+ struct hlsl_type *data_type = c->node.data_type; -+ unsigned int k; -+ -+ for (k = 0; k < data_type->e.numeric.dimx; ++k) -+ { -+ switch (data_type->e.numeric.type) -+ { -+ case HLSL_TYPE_FLOAT: -+ case HLSL_TYPE_HALF: -+ if (c->value.u[k].f != 1.0f) -+ return false; -+ break; -+ -+ case HLSL_TYPE_DOUBLE: -+ if (c->value.u[k].d != 1.0) -+ return false; -+ break; -+ -+ case HLSL_TYPE_UINT: -+ case HLSL_TYPE_INT: -+ case HLSL_TYPE_MIN16UINT: -+ if (c->value.u[k].u != 1) -+ return false; -+ break; -+ -+ case HLSL_TYPE_BOOL: -+ if (c->value.u[k].u != ~0) -+ return false; -+ break; -+ } -+ } -+ -+ return true; -+} -+ - static struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], - struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index d67f820fe8b..b6e5f4f2cf3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -1541,6 +1541,12 @@ static inline bool hlsl_var_has_buffer_offset_register_reservation(struct hlsl_c - return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; - } - -+static inline bool hlsl_is_comparison_op(enum hlsl_ir_expr_op op) -+{ -+ return op == HLSL_OP2_EQUAL || op == HLSL_OP2_GEQUAL -+ || op == HLSL_OP2_LESS || op == HLSL_OP2_NEQUAL; -+} -+ - 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); -@@ -1693,6 +1699,9 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, - struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, - struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct hlsl_ir_node *arg3); - -+bool hlsl_constant_is_zero(struct hlsl_ir_constant *c); -+bool hlsl_constant_is_one(struct hlsl_ir_constant *c); -+ - void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); - - struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 024d96c5663..e20a12bb42d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -3983,6 +3983,53 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, - return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); - } - -+static bool intrinsic_frexp(struct hlsl_ctx *ctx, -+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_type *type, *uint_dim_type, *int_dim_type, *bool_dim_type; -+ struct hlsl_ir_function_decl *func; -+ char *body; -+ -+ static const char template[] = -+ "%s frexp(%s x, out %s exp)\n" -+ "{\n" -+ /* If x is zero, always return zero for exp and mantissa. */ -+ " %s is_nonzero_mask = x != 0.0;\n" -+ " %s bits = asuint(x);\n" -+ /* Subtract 126, not 127, to increase the exponent */ -+ " %s exp_int = asint((bits & 0x7f800000u) >> 23) - 126;\n" -+ /* Clear the given exponent and replace it with the bit pattern -+ * for 2^-1 */ -+ " %s mantissa = asfloat((bits & 0x007fffffu) | 0x3f000000);\n" -+ " exp = is_nonzero_mask * %s(exp_int);\n" -+ " return is_nonzero_mask * mantissa;\n" -+ "}\n"; -+ -+ if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) -+ return false; -+ type = params->args[0]->data_type; -+ -+ if (type->e.numeric.type == HLSL_TYPE_DOUBLE) -+ { -+ hlsl_fixme(ctx, loc, "frexp() on doubles."); -+ return false; -+ } -+ type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy); -+ uint_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); -+ int_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_INT, type->e.numeric.dimx, type->e.numeric.dimy); -+ bool_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); -+ -+ if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name, -+ bool_dim_type->name, uint_dim_type->name, int_dim_type->name, type->name, type->name))) -+ return false; -+ func = hlsl_compile_internal_function(ctx, "frexp", body); -+ vkd3d_free(body); -+ if (!func) -+ return false; -+ -+ return !!add_user_call(ctx, func, params, false, loc); -+} -+ - static bool intrinsic_fwidth(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -5283,6 +5330,7 @@ intrinsic_functions[] = - {"floor", 1, true, intrinsic_floor}, - {"fmod", 2, true, intrinsic_fmod}, - {"frac", 1, true, intrinsic_frac}, -+ {"frexp", 2, true, intrinsic_frexp}, - {"fwidth", 1, true, intrinsic_fwidth}, - {"isinf", 1, true, intrinsic_isinf}, - {"ldexp", 2, true, intrinsic_ldexp}, -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 0b3dee4d2ce..8e3ed0a1b8d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -5029,8 +5029,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node - if (instr->type != HLSL_IR_EXPR) - return false; - expr = hlsl_ir_expr(instr); -- if (expr->op != HLSL_OP2_EQUAL && expr->op != HLSL_OP2_NEQUAL && expr->op != HLSL_OP2_LESS -- && expr->op != HLSL_OP2_GEQUAL) -+ if (!hlsl_is_comparison_op(expr->op)) - return false; - - arg1 = expr->operands[0].node; -@@ -8266,6 +8265,282 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) - lower_ir(ctx, lower_index_loads, body); - } - -+static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op) -+{ -+ switch (op) -+ { -+ case HLSL_OP2_EQUAL: -+ return HLSL_OP2_NEQUAL; -+ -+ case HLSL_OP2_GEQUAL: -+ return HLSL_OP2_LESS; -+ -+ case HLSL_OP2_LESS: -+ return HLSL_OP2_GEQUAL; -+ -+ case HLSL_OP2_NEQUAL: -+ return HLSL_OP2_EQUAL; -+ -+ default: -+ vkd3d_unreachable(); -+ } -+} -+ -+static bool fold_unary_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ struct hlsl_ir_node *res = NULL; -+ struct hlsl_ir_expr *expr, *x; -+ -+ if (instr->type != HLSL_IR_EXPR) -+ return false; -+ -+ if (instr->data_type->class > HLSL_CLASS_VECTOR) -+ return false; -+ -+ expr = hlsl_ir_expr(instr); -+ if (!expr->operands[0].node) -+ return false; -+ -+ if (expr->operands[0].node->type != HLSL_IR_EXPR) -+ return false; -+ x = hlsl_ir_expr(expr->operands[0].node); -+ -+ switch (expr->op) -+ { -+ case HLSL_OP1_ABS: -+ if (x->op == HLSL_OP1_ABS) -+ { -+ /* ||x|| -> |x| */ -+ hlsl_replace_node(instr, &x->node); -+ return true; -+ } -+ -+ if (x->op == HLSL_OP1_NEG) -+ { -+ /* |-x| -> |x| */ -+ hlsl_src_remove(&expr->operands[0]); -+ hlsl_src_from_node(&expr->operands[0], x->operands[0].node); -+ return true; -+ } -+ break; -+ -+ case HLSL_OP1_BIT_NOT: -+ if (x->op == HLSL_OP1_BIT_NOT) -+ { -+ /* ~(~x) -> x */ -+ hlsl_replace_node(instr, x->operands[0].node); -+ return true; -+ } -+ break; -+ -+ case HLSL_OP1_CEIL: -+ case HLSL_OP1_FLOOR: -+ if (x->op == HLSL_OP1_CEIL || x->op == HLSL_OP1_FLOOR) -+ { -+ /* f(g(x)) -> g(x), where f(), g() are floor() or ceil() functions. */ -+ hlsl_replace_node(instr, &x->node); -+ return true; -+ } -+ break; -+ -+ case HLSL_OP1_NEG: -+ if (x->op == HLSL_OP1_NEG) -+ { -+ /* -(-x) -> x */ -+ hlsl_replace_node(instr, x->operands[0].node); -+ return true; -+ } -+ break; -+ -+ case HLSL_OP1_LOGIC_NOT: -+ if (x->op == HLSL_OP1_LOGIC_NOT) -+ { -+ /* !!x -> x */ -+ hlsl_replace_node(instr, x->operands[0].node); -+ return true; -+ } -+ -+ if (hlsl_is_comparison_op(x->op) -+ && hlsl_base_type_is_integer(x->operands[0].node->data_type->e.numeric.type) -+ && hlsl_base_type_is_integer(x->operands[1].node->data_type->e.numeric.type)) -+ { -+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {x->operands[0].node, x->operands[1].node}; -+ struct hlsl_block block; -+ -+ hlsl_block_init(&block); -+ -+ /* !(x == y) -> x != y, !(x < y) -> x >= y, etc. */ -+ res = hlsl_block_add_expr(ctx, &block, invert_comparison_op(x->op), -+ operands, instr->data_type, &instr->loc); -+ -+ list_move_before(&instr->entry, &block.instrs); -+ hlsl_replace_node(instr, res); -+ return true; -+ } -+ -+ break; -+ -+ default: -+ break; -+ } -+ -+ return false; -+} -+ -+static bool nodes_are_equivalent(const struct hlsl_ir_node *c1, const struct hlsl_ir_node *c2) -+{ -+ if (c1 == c2) -+ return true; -+ -+ if (c1->type == HLSL_IR_SWIZZLE && c2->type == HLSL_IR_SWIZZLE -+ && hlsl_types_are_equal(c1->data_type, c2->data_type)) -+ { -+ const struct hlsl_ir_swizzle *s1 = hlsl_ir_swizzle(c1), *s2 = hlsl_ir_swizzle(c2); -+ -+ VKD3D_ASSERT(c1->data_type->class <= HLSL_CLASS_VECTOR); -+ -+ if (s1->val.node == s2->val.node && s1->u.vector == s2->u.vector) -+ return true; -+ } -+ -+ return false; -+} -+ -+/* Replaces all conditionals in an expression chain of the form (cond ? x : y) -+ * with x or y, assuming cond = cond_value. */ -+static struct hlsl_ir_node *evaluate_conditionals_recurse(struct hlsl_ctx *ctx, -+ struct hlsl_block *block, const struct hlsl_ir_node *cond, bool cond_value, -+ struct hlsl_ir_node *instr, const struct vkd3d_shader_location *loc) -+{ -+ struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; -+ struct hlsl_ir_expr *expr; -+ struct hlsl_ir_node *res; -+ bool progress = false; -+ unsigned int i; -+ -+ if (instr->type != HLSL_IR_EXPR) -+ return NULL; -+ expr = hlsl_ir_expr(instr); -+ -+ if (expr->op == HLSL_OP3_TERNARY && nodes_are_equivalent(cond, expr->operands[0].node)) -+ { -+ struct hlsl_ir_node *x = cond_value ? expr->operands[1].node : expr->operands[2].node; -+ -+ res = evaluate_conditionals_recurse(ctx, block, cond, cond_value, x, loc); -+ return res ? res : x; -+ } -+ -+ for (i = 0; i < HLSL_MAX_OPERANDS; ++i) -+ { -+ if (!expr->operands[i].node) -+ break; -+ -+ operands[i] = evaluate_conditionals_recurse(ctx, block, cond, cond_value, expr->operands[i].node, loc); -+ -+ if (operands[i]) -+ progress = true; -+ else -+ operands[i] = expr->operands[i].node; -+ } -+ -+ if (progress) -+ return hlsl_block_add_expr(ctx, block, expr->op, operands, expr->node.data_type, loc); -+ -+ return NULL; -+} -+ -+static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) -+{ -+ struct hlsl_ir_node *c, *x, *y, *res_x, *res_y; -+ struct hlsl_ir_node *res = NULL; -+ struct hlsl_ir_expr *expr, *ec; -+ struct hlsl_block block; -+ -+ if (instr->type != HLSL_IR_EXPR) -+ return false; -+ -+ if (instr->data_type->class > HLSL_CLASS_VECTOR) -+ return false; -+ -+ expr = hlsl_ir_expr(instr); -+ if (expr->op != HLSL_OP3_TERNARY) -+ return false; -+ -+ c = expr->operands[0].node; -+ x = expr->operands[1].node; -+ y = expr->operands[2].node; -+ -+ VKD3D_ASSERT(c->data_type->e.numeric.type == HLSL_TYPE_BOOL); -+ -+ if (nodes_are_equivalent(x, y)) -+ { -+ /* c ? x : x -> x */ -+ hlsl_replace_node(instr, x); -+ return true; -+ } -+ -+ if (c->type == HLSL_IR_CONSTANT) -+ { -+ if (hlsl_constant_is_zero(hlsl_ir_constant(c))) -+ { -+ /* false ? x : y -> y */ -+ hlsl_replace_node(instr, y); -+ return true; -+ } -+ -+ if (hlsl_constant_is_one(hlsl_ir_constant(c))) -+ { -+ /* true ? x : y -> x */ -+ hlsl_replace_node(instr, x); -+ return true; -+ } -+ } -+ -+ hlsl_block_init(&block); -+ -+ if (x->type == HLSL_IR_CONSTANT && y->type == HLSL_IR_CONSTANT -+ && hlsl_types_are_equal(c->data_type, x->data_type) -+ && hlsl_types_are_equal(c->data_type, y->data_type)) -+ { -+ if (hlsl_constant_is_one(hlsl_ir_constant(x)) && hlsl_constant_is_zero(hlsl_ir_constant(y))) -+ { -+ /* c ? true : false -> c */ -+ res = c; -+ goto done; -+ } -+ -+ if (hlsl_constant_is_zero(hlsl_ir_constant(x)) && hlsl_constant_is_one(hlsl_ir_constant(y))) -+ { -+ /* c ? false : true -> !c */ -+ res = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); -+ goto done; -+ } -+ } -+ -+ ec = c->type == HLSL_IR_EXPR ? hlsl_ir_expr(c) : NULL; -+ if (ec && ec->op == HLSL_OP1_LOGIC_NOT) -+ { -+ /* !c ? x : y -> c ? y : x */ -+ res = hlsl_add_conditional(ctx, &block, ec->operands[0].node, y, x); -+ goto done; -+ } -+ -+ res_x = evaluate_conditionals_recurse(ctx, &block, c, true, x, &instr->loc); -+ res_y = evaluate_conditionals_recurse(ctx, &block, c, false, y, &instr->loc); -+ if (res_x || res_y) -+ res = hlsl_add_conditional(ctx, &block, c, res_x ? res_x : x, res_y ? res_y : y); -+ -+done: -+ if (res) -+ { -+ list_move_before(&instr->entry, &block.instrs); -+ hlsl_replace_node(instr, res); -+ return true; -+ } -+ -+ hlsl_block_cleanup(&block); -+ return false; -+} - - static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) - { -@@ -8275,6 +8550,8 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) - { - progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); -+ progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); -+ progress |= hlsl_transform_ir(ctx, fold_conditional_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -index d339a06e6c7..4cd47a0632e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -@@ -1393,74 +1393,6 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - return success; - } - --static bool constant_is_zero(struct hlsl_ir_constant *const_arg) --{ -- struct hlsl_type *data_type = const_arg->node.data_type; -- unsigned int k; -- -- for (k = 0; k < data_type->e.numeric.dimx; ++k) -- { -- switch (data_type->e.numeric.type) -- { -- case HLSL_TYPE_FLOAT: -- case HLSL_TYPE_HALF: -- if (const_arg->value.u[k].f != 0.0f) -- return false; -- break; -- -- case HLSL_TYPE_DOUBLE: -- if (const_arg->value.u[k].d != 0.0) -- return false; -- break; -- -- case HLSL_TYPE_UINT: -- case HLSL_TYPE_INT: -- case HLSL_TYPE_BOOL: -- case HLSL_TYPE_MIN16UINT: -- if (const_arg->value.u[k].u != 0) -- return false; -- break; -- } -- } -- return true; --} -- --static bool constant_is_one(struct hlsl_ir_constant *const_arg) --{ -- struct hlsl_type *data_type = const_arg->node.data_type; -- unsigned int k; -- -- for (k = 0; k < data_type->e.numeric.dimx; ++k) -- { -- switch (data_type->e.numeric.type) -- { -- case HLSL_TYPE_FLOAT: -- case HLSL_TYPE_HALF: -- if (const_arg->value.u[k].f != 1.0f) -- return false; -- break; -- -- case HLSL_TYPE_DOUBLE: -- if (const_arg->value.u[k].d != 1.0) -- return false; -- break; -- -- case HLSL_TYPE_UINT: -- case HLSL_TYPE_INT: -- case HLSL_TYPE_MIN16UINT: -- if (const_arg->value.u[k].u != 1) -- return false; -- break; -- -- case HLSL_TYPE_BOOL: -- if (const_arg->value.u[k].u != ~0) -- return false; -- break; -- } -- } -- return true; --} -- - bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) - { - struct hlsl_ir_constant *const_arg = NULL; -@@ -1502,26 +1434,26 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in - switch (expr->op) - { - case HLSL_OP2_ADD: -- if (constant_is_zero(const_arg)) -+ if (hlsl_constant_is_zero(const_arg)) - res_node = mut_arg; - break; - - case HLSL_OP2_MUL: -- if (constant_is_one(const_arg)) -+ if (hlsl_constant_is_one(const_arg)) - res_node = mut_arg; - break; - - case HLSL_OP2_LOGIC_AND: -- if (constant_is_zero(const_arg)) -+ if (hlsl_constant_is_zero(const_arg)) - res_node = &const_arg->node; -- else if (constant_is_one(const_arg)) -+ else if (hlsl_constant_is_one(const_arg)) - res_node = mut_arg; - break; - - case HLSL_OP2_LOGIC_OR: -- if (constant_is_zero(const_arg)) -+ if (hlsl_constant_is_zero(const_arg)) - res_node = mut_arg; -- else if (constant_is_one(const_arg)) -+ else if (hlsl_constant_is_one(const_arg)) - res_node = &const_arg->node; - break; - -@@ -1649,6 +1581,9 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst - if (instr->data_type->class > HLSL_CLASS_VECTOR) - return false; - -+ if (expr->operands[2].node) -+ return false; -+ - hlsl_block_init(&block); - - arg1 = expr->operands[0].node; -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 23e059a3490..fef186ac34b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -1669,10 +1669,22 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - - switch (ins->opcode) - { -+ case VSIR_OP_IFC: -+ ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); -+ break; -+ -+ case VSIR_OP_SINCOS: -+ ret = vsir_program_lower_sm1_sincos(program, &it); -+ break; -+ - case VSIR_OP_TEXCRD: - ret = vsir_program_lower_texcrd(program, ins, message_context); - break; - -+ case VSIR_OP_TEXKILL: -+ ret = vsir_program_lower_texkill(program, &it, &tmp_idx); -+ break; -+ - case VSIR_OP_TEXLD: - if (program->shader_version.major == 1) - ret = vsir_program_lower_texld_sm1(program, ins, message_context); -@@ -1682,6 +1694,14 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr - ret = vsir_program_lower_texld(program, ins, message_context); - break; - -+ case VSIR_OP_TEXLDD: -+ ret = vsir_program_lower_texldd(program, ins); -+ break; -+ -+ case VSIR_OP_TEXLDL: -+ ret = vsir_program_lower_texldl(program, ins); -+ break; -+ - default: - ret = VKD3D_OK; - break; -@@ -1698,7 +1718,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - struct vsir_transformation_context *ctx) - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -- struct vkd3d_shader_message_context *message_context = ctx->message_context; - struct vkd3d_shader_instruction *ins; - unsigned int tmp_idx = ~0u; - enum vkd3d_result ret; -@@ -1707,16 +1726,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - { - switch (ins->opcode) - { -- case VSIR_OP_IFC: -- if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0) -- return ret; -- break; -- -- case VSIR_OP_TEXKILL: -- if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) -- return ret; -- break; -- - case VSIR_OP_MAD: - if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) - return ret; -@@ -1765,25 +1774,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - break; - - case VSIR_OP_SINCOS: -- if (ins->dst_count == 1) -- { -- if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) -- return ret; -- } -- else -- { -- if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) -- return ret; -- } -- break; -- -- case VSIR_OP_TEXLDD: -- if ((ret = vsir_program_lower_texldd(program, ins)) < 0) -- return ret; -- break; -- -- case VSIR_OP_TEXLDL: -- if ((ret = vsir_program_lower_texldl(program, ins)) < 0) -+ if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) - return ret; - break; - -@@ -7668,15 +7659,12 @@ static enum vkd3d_result vsir_program_add_fog_input(struct vsir_program *program - } - - static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *program, -- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_fragment_mode mode, -- uint32_t fog_signature_idx, uint32_t colour_signature_idx, uint32_t colour_temp, -- size_t *ret_pos, struct vkd3d_shader_message_context *message_context) -+ struct vsir_program_iterator *it, enum vkd3d_shader_fog_fragment_mode mode, uint32_t fog_signature_idx, -+ uint32_t colour_signature_idx, uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) - { -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -- struct vkd3d_shader_location loc = ret->location; -+ struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); -+ struct vkd3d_shader_location loc = ins->location; - uint32_t ssa_factor = program->ssa_count++; -- size_t pos = ret - instructions->elements; -- struct vkd3d_shader_instruction *ins; - uint32_t ssa_temp, ssa_temp2; - - switch (mode) -@@ -7687,16 +7675,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * add sr0, FOG_END, -vFOG.x - * mul_sat srFACTOR, sr0, FOG_SCALE - */ -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, 4)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- -- *ret_pos = pos + 4; -+ ins = vsir_program_iterator_next(it); - - ssa_temp = program->ssa_count++; - -- ins = &program->instructions.elements[pos]; -- - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); -@@ -7705,12 +7690,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - ins->src[1].modifiers = VKD3DSPSM_NEG; -+ ins = vsir_program_iterator_next(it); - -- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); -+ ins = vsir_program_iterator_next(it); -+ - break; - - case VKD3D_SHADER_FOG_FRAGMENT_EXP: -@@ -7719,16 +7707,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * mul sr0, FOG_SCALE, vFOG.x - * exp_sat srFACTOR, -sr0 - */ -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, 4)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- -- *ret_pos = pos + 4; -+ ins = vsir_program_iterator_next(it); - - ssa_temp = program->ssa_count++; - -- ins = &program->instructions.elements[pos]; -- - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); -@@ -7736,12 +7721,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - ins->src[1].reg.idx[0].offset = fog_signature_idx; - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ ins = vsir_program_iterator_next(it); - -- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp); - ins->src[0].modifiers = VKD3DSPSM_NEG; -+ ins = vsir_program_iterator_next(it); - break; - - case VKD3D_SHADER_FOG_FRAGMENT_EXP2: -@@ -7751,17 +7738,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * mul sr1, sr0, sr0 - * exp_sat srFACTOR, -sr1 - */ -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 5)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, 5)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- -- *ret_pos = pos + 5; -+ ins = vsir_program_iterator_next(it); - - ssa_temp = program->ssa_count++; - ssa_temp2 = program->ssa_count++; - -- ins = &program->instructions.elements[pos]; -- - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); -@@ -7769,17 +7753,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - ins->src[1].reg.idx[0].offset = fog_signature_idx; - ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; - ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); -+ ins = vsir_program_iterator_next(it); - -- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); - dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); - src_param_init_ssa_float(&ins->src[0], ssa_temp); - src_param_init_ssa_float(&ins->src[1], ssa_temp); -+ ins = vsir_program_iterator_next(it); - -- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); - dst_param_init_ssa_float(&ins->dst[0], ssa_factor); - ins->dst[0].modifiers = VKD3DSPDM_SATURATE; - src_param_init_ssa_float(&ins->src[0], ssa_temp2); - ins->src[0].modifiers = VKD3DSPSM_NEG; -+ ins = vsir_program_iterator_next(it); - break; - - default: -@@ -7792,18 +7779,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * mad oC0, sr0, srFACTOR, FOG_COLOUR - */ - -- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); - dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); - src_param_init_temp_float4(&ins->src[0], colour_temp); - src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); - ins->src[1].modifiers = VKD3DSPSM_NEG; -+ ins = vsir_program_iterator_next(it); - -- vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3); - dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, - program->output_signature.elements[colour_signature_idx].mask); - src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); - src_param_init_ssa_float(&ins->src[1], ssa_factor); - src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); -+ ins = vsir_program_iterator_next(it); - - return VKD3D_OK; - } -@@ -7811,6 +7800,7 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; - uint32_t colour_signature_idx, fog_signature_idx, colour_temp; - const struct vkd3d_shader_parameter1 *mode_parameter = NULL; -@@ -7818,7 +7808,6 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p - const struct signature_element *fog_element; - enum vkd3d_shader_fog_fragment_mode mode; - struct vkd3d_shader_instruction *ins; -- size_t new_pos; - int ret; - - if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) -@@ -7859,19 +7848,16 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p - * through the whole shader and convert it to a temp. */ - colour_temp = program->temp_count++; - -- for (size_t i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- ins = &program->instructions.elements[i]; -- - if (vsir_instruction_is_dcl(ins)) - continue; - - if (ins->opcode == VSIR_OP_RET) - { -- if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, -- colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) -+ if ((ret = insert_fragment_fog_before_ret(program, &it, mode, fog_signature_idx, -+ colour_signature_idx, colour_temp, message_context)) < 0) - return ret; -- i = new_pos; - continue; - } - -@@ -7927,21 +7913,18 @@ static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *progra - return VKD3D_OK; - } - --static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, -- const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp, -- uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos) -+static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, struct vsir_program_iterator *it, -+ enum vkd3d_shader_fog_source source, uint32_t temp, uint32_t fog_signature_idx, uint32_t source_signature_idx) - { - const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; -- struct vkd3d_shader_instruction_array *instructions = &program->instructions; -+ struct vkd3d_shader_instruction *ret = vsir_program_iterator_current(it); - const struct vkd3d_shader_location loc = ret->location; -- size_t pos = ret - instructions->elements; - struct vkd3d_shader_instruction *ins; - -- if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) -+ vsir_program_iterator_prev(it); -+ if (!vsir_program_iterator_insert_after(it, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ret = NULL; -- -- ins = &program->instructions.elements[pos]; -+ ins = vsir_program_iterator_next(it); - - /* Write the fog output. */ - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -@@ -7951,26 +7934,27 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr - ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); - else /* Position or specular W. */ - ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); -- ++ins; -+ ins = vsir_program_iterator_next(it); - - /* Write the position or specular output. */ - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - dst_param_init_output(&ins->dst[0], vsir_data_type_from_component_type(e->component_type), - source_signature_idx, e->mask); - src_param_init_temp_float4(&ins->src[0], temp); -- ++ins; -+ ins = vsir_program_iterator_next(it); - -- *ret_pos = pos + 2; - return VKD3D_OK; - } - - static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; - const struct vkd3d_shader_parameter1 *source_parameter = NULL; - uint32_t fog_signature_idx, source_signature_idx, temp; - static const struct vkd3d_shader_location no_loc; -+ struct vkd3d_shader_instruction *ins; - enum vkd3d_shader_fog_source source; - const struct signature_element *e; - -@@ -8027,22 +8011,18 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro - - /* Insert a fog write before each ret, and convert either specular or - * position output to a temp. */ -- for (size_t i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - if (vsir_instruction_is_dcl(ins)) - continue; - - if (ins->opcode == VSIR_OP_RET) - { -- size_t new_pos; - int ret; - -- if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp, -- fog_signature_idx, source_signature_idx, &new_pos)) < 0) -+ if ((ret = insert_vertex_fog_before_ret(program, &it, source, temp, -+ fog_signature_idx, source_signature_idx)) < 0) - return ret; -- i = new_pos; - continue; - } - -@@ -8565,9 +8545,12 @@ static void liveness_tracker_cleanup(struct liveness_tracker *tracker) - - static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_instruction *ins; - struct liveness_tracker_reg *regs; - unsigned int loop_depth = 0; - unsigned int loop_start = 0; -+ unsigned int i; - - memset(tracker, 0, sizeof(*tracker)); - -@@ -8575,10 +8558,8 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv - return VKD3D_ERROR_OUT_OF_MEMORY; - tracker->ssa_regs = regs; - -- for (unsigned int i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) - { -- const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - if (ins->opcode == VSIR_OP_LOOP || ins->opcode == VSIR_OP_REP) - { - if (!loop_depth++) -@@ -8838,8 +8819,10 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, - enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - const unsigned int prev_temp_count = program->temp_count; - struct temp_allocator allocator = {0}; -+ struct vkd3d_shader_instruction *ins; - struct temp_allocator_reg *regs; - struct liveness_tracker tracker; - enum vkd3d_result ret; -@@ -8873,10 +8856,8 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - ++allocator.allocated_ssa_count; - } - -- for (unsigned int i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - /* Make sure we do the srcs first; setting the dst writemask may need - * to remap their swizzles. */ - for (unsigned int j = 0; j < ins->src_count; ++j) -@@ -8902,11 +8883,14 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_location location; -+ struct vkd3d_shader_instruction *ins; - unsigned int temp_count = 0; - -- for (int i = program->instructions.count - 1; i >= 0; --i) -+ for (ins = vsir_program_iterator_tail(&it); ins; ins = vsir_program_iterator_prev(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -+ location = ins->location; - - if (ins->opcode == VSIR_OP_DCL_TEMPS) - { -@@ -8922,11 +8906,11 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, - { - /* The phase didn't have a dcl_temps instruction, but we added - * temps here, so we need to insert one. */ -- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) -+ if (!vsir_program_iterator_insert_after(&it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- ins = &program->instructions.elements[i + 1]; -- vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS); -+ ins = vsir_program_iterator_next(&it); -+ vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); - ins->declaration.count = temp_count; - temp_count = 0; - continue; -@@ -8947,13 +8931,15 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, - - if (temp_count && program->shader_version.major >= 4) - { -- struct vkd3d_shader_instruction *ins; -+ ins = vsir_program_iterator_head(&it); -+ location = ins->location; - -- if (!shader_instruction_array_insert_at(&program->instructions, 0, 1)) -+ vsir_program_iterator_prev(&it); -+ if (!vsir_program_iterator_insert_after(&it, 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- ins = &program->instructions.elements[0]; -- vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS); -+ ins = vsir_program_iterator_next(&it); -+ vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); - ins->declaration.count = temp_count; - } - -@@ -11842,14 +11828,12 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ - [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, - }; - --static void vsir_validate_instruction(struct validation_context *ctx) -+static void vsir_validate_instruction(struct validation_context *ctx, -+ const struct vkd3d_shader_instruction *instruction) - { - const struct vkd3d_shader_version *version = &ctx->program->shader_version; -- const struct vkd3d_shader_instruction *instruction; - size_t i; - -- instruction = &ctx->program->instructions.elements[ctx->instruction_idx]; -- - for (i = 0; i < instruction->dst_count; ++i) - vsir_validate_dst_param(ctx, &instruction->dst[i]); - -@@ -11938,6 +11922,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c - .inner_tess_idxs[0] = ~0u, - .inner_tess_idxs[1] = ~0u, - }; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ struct vkd3d_shader_instruction *ins; - unsigned int i; - - if (!(config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) -@@ -12046,9 +12032,13 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c - - ctx.invalid_instruction_idx = false; - -- for (ctx.instruction_idx = 0; ctx.instruction_idx < program->instructions.count -- && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ctx.instruction_idx) -- vsir_validate_instruction(&ctx); -+ ctx.instruction_idx = 0; -+ for (ins = vsir_program_iterator_head(&it); ins && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; -+ ins = vsir_program_iterator_next(&it)) -+ { -+ vsir_validate_instruction(&ctx, ins); -+ ++ctx.instruction_idx; -+ } - - ctx.invalid_instruction_idx = true; - -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index c6e048adb20..88d1160d4e8 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -1516,6 +1516,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d - break; - case VSIR_OP_GEO: - case VSIR_OP_IGE: -+ case VSIR_OP_UGE: - msl_relop(gen, ins, ">="); - break; - case VSIR_OP_IF: -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index ea15c1a9ad5..e2123656557 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -665,6 +665,8 @@ struct vkd3d_shader_sm4_parser - { - const uint32_t *start, *end, *ptr; - -+ struct vsir_program *program; -+ - enum vkd3d_shader_opcode phase; - bool has_control_point_phase; - unsigned int input_register_masks[MAX_REG_OUTPUT]; -@@ -764,7 +766,7 @@ static const enum vsir_data_type data_type_table[] = - - static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) - { -- const struct vkd3d_shader_version *version = &sm4->p.program->shader_version; -+ const struct vkd3d_shader_version *version = &sm4->program->shader_version; - - return version->major >= 5 && version->minor >= 1; - } -@@ -849,7 +851,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui - icb->element_count = icb_size / VKD3D_VEC4_SIZE; - icb->is_null = false; - memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); -- shader_instruction_array_add_icb(&priv->p.program->instructions, icb); -+ shader_instruction_array_add_icb(&priv->program->instructions, icb); - ins->declaration.icb = icb; - } - -@@ -971,7 +973,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) - { - struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range; -- struct vsir_program *program = priv->p.program; -+ struct vsir_program *program = priv->program; - unsigned int i, register_idx, register_count; - const struct shader_signature *signature; - enum vkd3d_shader_register_type type; -@@ -1094,14 +1096,14 @@ static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction - if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED) - FIXME("Unhandled output primitive type %#x.\n", primitive_type); - -- priv->p.program->output_topology = ins->declaration.primitive_type.type; -+ priv->program->output_topology = ins->declaration.primitive_type.type; - } - - static void shader_sm4_read_dcl_input_primitive(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 *sm4) - { - enum vkd3d_sm4_input_primitive_type primitive_type; -- struct vsir_program *program = sm4->p.program; -+ struct vsir_program *program = sm4->program; - - primitive_type = (opcode_token & VKD3D_SM4_PRIMITIVE_TYPE_MASK) >> VKD3D_SM4_PRIMITIVE_TYPE_SHIFT; - if (VKD3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= VKD3D_SM5_INPUT_PT_PATCH32) -@@ -1129,7 +1131,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction - static void shader_sm4_read_declaration_count(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 *sm4) - { -- struct vsir_program *program = sm4->p.program; -+ struct vsir_program *program = sm4->program; - - ins->declaration.count = *tokens; - if (opcode == VKD3D_SM4_OP_DCL_TEMPS) -@@ -1161,7 +1163,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u - if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) - { - struct signature_element *e = vsir_signature_find_element_for_reg( -- &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); -+ &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); - - if (!e) - { -@@ -1187,7 +1189,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in - if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) - { - struct signature_element *e = vsir_signature_find_element_for_reg( -- &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); -+ &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); - - if (!e) - { -@@ -1220,7 +1222,7 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in - uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) - { - ins->declaration.global_flags = (opcode_token & VKD3D_SM4_GLOBAL_FLAGS_MASK) >> VKD3D_SM4_GLOBAL_FLAGS_SHIFT; -- sm4->p.program->global_flags = ins->declaration.global_flags; -+ sm4->program->global_flags = ins->declaration.global_flags; - } - - static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, -@@ -1256,7 +1258,7 @@ static void shader_sm5_read_dcl_interface(struct vkd3d_shader_instruction *ins, - static void shader_sm5_read_control_point_count(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 *sm4) - { -- struct vsir_program *program = sm4->p.program; -+ struct vsir_program *program = sm4->program; - - ins->declaration.count = (opcode_token & VKD3D_SM5_CONTROL_POINT_COUNT_MASK) - >> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT; -@@ -1272,7 +1274,7 @@ static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instructi - { - ins->declaration.tessellator_domain = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) - >> VKD3D_SM5_TESSELLATOR_SHIFT; -- priv->p.program->tess_domain = ins->declaration.tessellator_domain; -+ priv->program->tess_domain = ins->declaration.tessellator_domain; - } - - static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_instruction *ins, uint32_t opcode, -@@ -1280,7 +1282,7 @@ static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_ins - { - ins->declaration.tessellator_partitioning = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) - >> VKD3D_SM5_TESSELLATOR_SHIFT; -- priv->p.program->tess_partitioning = ins->declaration.tessellator_partitioning; -+ priv->program->tess_partitioning = ins->declaration.tessellator_partitioning; - } - - static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, -@@ -1288,7 +1290,7 @@ static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader - { - ins->declaration.tessellator_output_primitive = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) - >> VKD3D_SM5_TESSELLATOR_SHIFT; -- priv->p.program->tess_output_primitive = ins->declaration.tessellator_output_primitive; -+ priv->program->tess_output_primitive = ins->declaration.tessellator_output_primitive; - } - - static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instruction *ins, uint32_t opcode, -@@ -1300,7 +1302,7 @@ static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instructio - static void shader_sm5_read_dcl_thread_group(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 *sm4) - { -- struct vsir_program *program = sm4->p.program; -+ struct vsir_program *program = sm4->program; - - ins->declaration.thread_group_size.x = *tokens++; - ins->declaration.thread_group_size.y = *tokens++; -@@ -2009,7 +2011,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const - { - if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) - { -- struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->p.program, 1); -+ struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->program, 1); - - if (!(reg_idx->rel_addr = rel_addr)) - { -@@ -2284,7 +2286,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register * - { - return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT - || (reg->type == VKD3DSPR_INPUT && (priv->phase == VSIR_OP_HS_CONTROL_POINT_PHASE -- || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); -+ || priv->program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); - } - - static uint32_t mask_from_swizzle(uint32_t swizzle) -@@ -2608,8 +2610,8 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d - static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins) - { - const struct vkd3d_sm4_opcode_info *opcode_info; -- struct vsir_program *program = sm4->p.program; - uint32_t opcode_token, opcode, previous_token; -+ struct vsir_program *program = sm4->program; - struct vkd3d_shader_dst_param *dst_params; - struct vkd3d_shader_src_param *src_params; - const uint32_t **ptr = &sm4->ptr; -@@ -2814,8 +2816,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro - if (!vsir_program_init(program, compile_info, - &version, token_count / 7u + 20, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) - return false; -- vkd3d_shader_parser_init(&sm4->p, program, message_context, compile_info->source_name); -+ vkd3d_shader_parser_init(&sm4->p, message_context, compile_info->source_name); - sm4->ptr = sm4->start; -+ sm4->program = program; - - init_sm4_lookup_tables(&sm4->lookup); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index d1992c9d446..75b7f9aa769 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -724,14 +724,13 @@ uint64_t vkd3d_shader_init_config_flags(void) - return config_flags; - } - --void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, -+void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, - struct vkd3d_shader_message_context *message_context, const char *source_name) - { - parser->message_context = message_context; - parser->location.source_name = source_name; - parser->location.line = 1; - parser->location.column = 0; -- parser->program = program; - } - - void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, -@@ -1685,6 +1684,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; - struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info; -+ struct vkd3d_shader_scan_thread_group_size_info *thread_group_size_info; - struct vkd3d_shader_scan_descriptor_info *descriptor_info; - struct vkd3d_shader_scan_signature_info *signature_info; - struct vkd3d_shader_scan_context context; -@@ -1706,6 +1706,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - } - - tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); -+ thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); - - vkd3d_shader_scan_context_init(&context, &program->shader_version, compile_info, - add_descriptor_info ? &program->descriptors : NULL, combined_sampler_info, message_context); -@@ -1758,6 +1759,13 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh - tessellation_info->partitioning = context.partitioning; - } - -+ if (!ret && thread_group_size_info) -+ { -+ thread_group_size_info->x = program->thread_group_size.x; -+ thread_group_size_info->y = program->thread_group_size.y; -+ thread_group_size_info->z = program->thread_group_size.z; -+ } -+ - if (ret < 0) - { - if (combined_sampler_info) -@@ -2184,6 +2192,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( - VKD3D_SHADER_TARGET_D3D_BYTECODE, - VKD3D_SHADER_TARGET_DXBC_TPF, - VKD3D_SHADER_TARGET_FX, -+#ifdef VKD3D_SHADER_UNSUPPORTED_MSL -+ VKD3D_SHADER_TARGET_MSL, -+#endif - }; - - static const enum vkd3d_shader_target_type d3dbc_types[] = -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index e758c16b3d4..b63c5785770 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1651,13 +1651,12 @@ struct vkd3d_shader_parser - { - struct vkd3d_shader_message_context *message_context; - struct vkd3d_shader_location location; -- struct vsir_program *program; - bool failed; - }; - - void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, - enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); --void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, -+void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, - struct vkd3d_shader_message_context *message_context, const char *source_name); - void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, - enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); --- -2.51.0 - diff --git a/patches/vkd3d-latest/0003-Updated-vkd3d-to-d0098b0d5968d1969ec622b91fd360fd0ae.patch b/patches/vkd3d-latest/0003-Updated-vkd3d-to-d0098b0d5968d1969ec622b91fd360fd0ae.patch deleted file mode 100644 index 722b9306..00000000 --- a/patches/vkd3d-latest/0003-Updated-vkd3d-to-d0098b0d5968d1969ec622b91fd360fd0ae.patch +++ /dev/null @@ -1,133 +0,0 @@ -From 38b9415c7e850a1774d508232dd0e5e97e505eab Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Sat, 23 Aug 2025 07:27:59 +1000 -Subject: [PATCH] Updated vkd3d to d0098b0d5968d1969ec622b91fd360fd0aec2328. - ---- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 9 +-------- - libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 +- - libs/vkd3d/libs/vkd3d-shader/preproc.l | 12 ++---------- - libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c | 7 ++++++- - libs/vkd3d/libs/vkd3d/utils.c | 3 ++- - 5 files changed, 12 insertions(+), 21 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index 5988e7b3a30..acc30b998f6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -2329,7 +2329,6 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc - struct vkd3d_string_buffer *buffer = gen->buffer; - struct vkd3d_shader_instruction *ins; - struct vsir_program_iterator it; -- void *code; - - MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); - -@@ -2358,13 +2357,7 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc - if (gen->failed) - return VKD3D_ERROR_INVALID_SHADER; - -- if ((code = vkd3d_malloc(buffer->buffer_size))) -- { -- memcpy(code, buffer->buffer, buffer->content_size); -- out->size = buffer->content_size; -- out->code = code; -- } -- else return VKD3D_ERROR_OUT_OF_MEMORY; -+ vkd3d_shader_code_from_string_buffer(out, buffer); - - return VKD3D_OK; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -index 0cdebb8a657..da9f0d39136 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l -@@ -346,7 +346,7 @@ while {return KW_WHILE; } - {ANY} {} - - {ANY} { -- return yytext[0]; -+ return (unsigned char)yytext[0]; - } - - %% -diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l -index 5c56fba0229..f9b1d67ac36 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/preproc.l -+++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l -@@ -824,7 +824,6 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, - static const struct vkd3d_shader_preprocess_info default_preprocess_info = {0}; - struct preproc_ctx ctx = {0}; - char *source_name = NULL; -- void *output_code; - unsigned int i; - - vkd3d_string_buffer_init(&ctx.buffer); -@@ -901,16 +900,9 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, - return VKD3D_ERROR_INVALID_SHADER; - } - -- if (!(output_code = vkd3d_malloc(ctx.buffer.content_size))) -- { -- vkd3d_string_buffer_cleanup(&ctx.buffer); -- return VKD3D_ERROR_OUT_OF_MEMORY; -- } -- memcpy(output_code, ctx.buffer.buffer, ctx.buffer.content_size); -- out->size = ctx.buffer.content_size; -- out->code = output_code; - vkd3d_string_buffer_trace(&ctx.buffer); -- vkd3d_string_buffer_cleanup(&ctx.buffer); -+ -+ vkd3d_shader_code_from_string_buffer(out, &ctx.buffer); - return VKD3D_OK; - - fail: -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 75b7f9aa769..08450b4cf85 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -2266,6 +2266,7 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info - struct vkd3d_shader_code *out, char **messages) - { - struct vkd3d_shader_message_context message_context; -+ struct shader_dump_data dump_data; - int ret; - - TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages); -@@ -2278,7 +2279,11 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info - - vkd3d_shader_message_context_init(&message_context, compile_info->log_level); - -- ret = preproc_lexer_parse(compile_info, out, &message_context); -+ fill_shader_dump_data(compile_info, &dump_data); -+ vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); -+ -+ if ((ret = preproc_lexer_parse(compile_info, out, &message_context)) >= 0) -+ vkd3d_shader_dump_shader(&dump_data, out->code, out->size, SHADER_DUMP_TYPE_PREPROC); - - vkd3d_shader_message_context_trace_messages(&message_context); - if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) -diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c -index c2832a61f67..2d0510e5456 100644 ---- a/libs/vkd3d/libs/vkd3d/utils.c -+++ b/libs/vkd3d/libs/vkd3d/utils.c -@@ -703,7 +703,7 @@ const char *debug_vk_extent_3d(VkExtent3D extent) - - const char *debug_vk_queue_flags(VkQueueFlags flags) - { -- char buffer[191]; -+ char buffer[222]; - - buffer[0] = '\0'; - #define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; } -@@ -716,6 +716,7 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) - #define FLAG_TO_STR(f, n) if (flags & f) { strcat(buffer, " | "#n); flags &= ~f; } - FLAG_TO_STR(0x20, VK_QUEUE_VIDEO_DECODE_BIT_KHR) - FLAG_TO_STR(0x40, VK_QUEUE_VIDEO_ENCODE_BIT_KHR) -+ FLAG_TO_STR(0x100, VK_QUEUE_OPTICAL_FLOW_BIT_NV) - #undef FLAG_TO_STR - if (flags) - FIXME("Unrecognized flag(s) %#x.\n", flags); --- -2.51.0 - diff --git a/patches/vkd3d-latest/0004-Updated-vkd3d-to-158f8b3cf6ff528eb6897baf04db80f0db2.patch b/patches/vkd3d-latest/0004-Updated-vkd3d-to-158f8b3cf6ff528eb6897baf04db80f0db2.patch deleted file mode 100644 index 7f0ff0e4..00000000 --- a/patches/vkd3d-latest/0004-Updated-vkd3d-to-158f8b3cf6ff528eb6897baf04db80f0db2.patch +++ /dev/null @@ -1,1759 +0,0 @@ -From b62327e3e6fae6a2df820e0160b04c1c54dfb68a Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Sat, 30 Aug 2025 07:08:53 +1000 -Subject: [PATCH] Updated vkd3d to 158f8b3cf6ff528eb6897baf04db80f0db2b53f8. - ---- - libs/vkd3d/include/private/spirv_grammar.h | 561 ++---------------- - libs/vkd3d/include/private/vkd3d_common.h | 2 + - libs/vkd3d/libs/vkd3d-shader/dxil.c | 52 +- - libs/vkd3d/libs/vkd3d-shader/fx.c | 2 +- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 38 +- - libs/vkd3d/libs/vkd3d-shader/ir.c | 133 ++--- - libs/vkd3d/libs/vkd3d-shader/msl.c | 15 +- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 10 + - .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 6 +- - libs/vkd3d/libs/vkd3d/command.c | 2 +- - libs/vkd3d/libs/vkd3d/state.c | 6 +- - 11 files changed, 184 insertions(+), 643 deletions(-) - -diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h -index 34cadd9bd58..2aac5a6558c 100644 ---- a/libs/vkd3d/include/private/spirv_grammar.h -+++ b/libs/vkd3d/include/private/spirv_grammar.h -@@ -43,12 +43,10 @@ enum spirv_parser_operand_type - SPIRV_PARSER_OPERAND_TYPE_ADDRESSING_MODEL, - SPIRV_PARSER_OPERAND_TYPE_BUILT_IN, - SPIRV_PARSER_OPERAND_TYPE_CAPABILITY, -- SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE, - SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, - SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, - SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE, - SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, -- SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT, - SPIRV_PARSER_OPERAND_TYPE_DECORATION, - SPIRV_PARSER_OPERAND_TYPE_DIM, - SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE, -@@ -84,7 +82,6 @@ enum spirv_parser_operand_type - SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, - SPIRV_PARSER_OPERAND_TYPE_LOAD_CACHE_CONTROL, - SPIRV_PARSER_OPERAND_TYPE_LOOP_CONTROL, -- SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, - SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, - SPIRV_PARSER_OPERAND_TYPE_MEMORY_MODEL, - SPIRV_PARSER_OPERAND_TYPE_MEMORY_SEMANTICS, -@@ -149,7 +146,7 @@ spirv_parser_operand_type_info[] = - }, - [SPIRV_PARSER_OPERAND_TYPE_BUILT_IN] = - { -- "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 126, -+ "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 116, - (struct spirv_parser_enumerant[]) - { - {0, "Position"}, -@@ -210,9 +207,6 @@ spirv_parser_operand_type_info[] = - {0x1156, "DeviceIndex"}, - {0x1158, "ViewIndex"}, - {0x115c, "ShadingRateKHR"}, -- {0x118c, "TileOffsetQCOM"}, -- {0x118d, "TileDimensionQCOM"}, -- {0x118e, "TileApronSizeQCOM"}, - {0x1380, "BaryCoordNoPerspAMD"}, - {0x1381, "BaryCoordNoPerspCentroidAMD"}, - {0x1382, "BaryCoordNoPerspSampleAMD"}, -@@ -264,25 +258,18 @@ spirv_parser_operand_type_info[] = - {0x14e0, "HitMicroTriangleVertexBarycentricsNV"}, - {0x14e7, "IncomingRayFlagsKHR"}, - {0x14e8, "RayGeometryIndexKHR"}, -- {0x14ef, "HitIsSphereNV"}, -- {0x14f0, "HitIsLSSNV"}, -- {0x14f1, "HitSpherePositionNV"}, - {0x14fe, "WarpsPerSMNV"}, - {0x14ff, "SMCountNV"}, - {0x1500, "WarpIDNV"}, - {0x1501, "SMIDNV"}, -- {0x1514, "HitLSSPositionsNV"}, - {0x151d, "HitKindFrontFacingMicroTriangleNV"}, - {0x151e, "HitKindBackFacingMicroTriangleNV"}, -- {0x152c, "HitSphereRadiusNV"}, -- {0x152d, "HitLSSRadiiNV"}, -- {0x153c, "ClusterIDNV"}, - {0x1785, "CullMaskKHR"}, - } - }, - [SPIRV_PARSER_OPERAND_TYPE_CAPABILITY] = - { -- "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 261, -+ "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 245, - (struct spirv_parser_enumerant[]) - { - {0, "Matrix"}, -@@ -393,7 +380,6 @@ spirv_parser_operand_type_info[] = - {0x1184, "TextureSampleWeightedQCOM"}, - {0x1185, "TextureBoxFilterQCOM"}, - {0x1186, "TextureBlockMatchQCOM"}, -- {0x118f, "TileShadingQCOM"}, - {0x1192, "TextureBlockMatch2QCOM"}, - {0x1390, "Float16ImageAMD"}, - {0x1391, "ImageGatherBiasLodAMD"}, -@@ -404,9 +390,6 @@ spirv_parser_operand_type_info[] = - {0x13bf, "ShaderClockKHR"}, - {0x13cb, "ShaderEnqueueAMDX"}, - {0x13df, "QuadControlKHR"}, -- {0x13fc, "BFloat16TypeKHR"}, -- {0x13fd, "BFloat16DotProductKHR"}, -- {0x13fe, "BFloat16CooperativeMatrixKHR"}, - {0x1481, "SampleMaskOverrideCoverageNV"}, - {0x1483, "GeometryShaderPassthroughNV"}, - {0x1486, "ShaderViewportIndexLayerEXT"}, -@@ -452,19 +435,14 @@ spirv_parser_operand_type_info[] = - {0x1507, "ShaderInvocationReorderNV"}, - {0x150e, "BindlessTextureNV"}, - {0x150f, "RayQueryPositionFetchKHR"}, -- {0x1512, "CooperativeVectorNV"}, - {0x151c, "AtomicFloat16VectorNV"}, - {0x1521, "RayTracingDisplacementMicromapNV"}, - {0x1526, "RawAccessChainsNV"}, -- {0x152a, "RayTracingSpheresGeometryNV"}, -- {0x152b, "RayTracingLinearSweptSpheresGeometryNV"}, - {0x1536, "CooperativeMatrixReductionsNV"}, - {0x1537, "CooperativeMatrixConversionsNV"}, - {0x1538, "CooperativeMatrixPerElementOperationsNV"}, - {0x1539, "CooperativeMatrixTensorAddressingNV"}, - {0x153a, "CooperativeMatrixBlockLoadsNV"}, -- {0x153b, "CooperativeVectorTrainingNV"}, -- {0x153d, "RayTracingClusterAccelerationStructureNV"}, - {0x153f, "TensorAddressingNV"}, - {0x15c0, "SubgroupShuffleINTEL"}, - {0x15c1, "SubgroupBufferBlockIOINTEL"}, -@@ -529,47 +507,18 @@ spirv_parser_operand_type_info[] = - {0x1800, "ArithmeticFenceEXT"}, - {0x1806, "FPGAClusterAttributesV2INTEL"}, - {0x1811, "FPGAKernelAttributesv2INTEL"}, -- {0x1812, "TaskSequenceINTEL"}, - {0x1819, "FPMaxErrorINTEL"}, - {0x181b, "FPGALatencyControlINTEL"}, - {0x181e, "FPGAArgumentInterfacesINTEL"}, - {0x182b, "GlobalVariableHostAccessINTEL"}, - {0x182d, "GlobalVariableFPGADecorationsINTEL"}, - {0x184c, "SubgroupBufferPrefetchINTEL"}, -- {0x1854, "Subgroup2DBlockIOINTEL"}, -- {0x1855, "Subgroup2DBlockTransformINTEL"}, -- {0x1856, "Subgroup2DBlockTransposeINTEL"}, -- {0x185c, "SubgroupMatrixMultiplyAccumulateINTEL"}, -- {0x1861, "TernaryBitwiseFunctionINTEL"}, - {0x1900, "GroupUniformArithmeticKHR"}, -- {0x1919, "TensorFloat32RoundingINTEL"}, - {0x191b, "MaskedGatherScatterINTEL"}, - {0x1929, "CacheControlsINTEL"}, - {0x193c, "RegisterLimitsINTEL"}, - } - }, -- [SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE] = -- { -- "ComponentType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 15, -- (struct spirv_parser_enumerant[]) -- { -- {0, "Float16NV"}, -- {0x1, "Float32NV"}, -- {0x2, "Float64NV"}, -- {0x3, "SignedInt8NV"}, -- {0x4, "SignedInt16NV"}, -- {0x5, "SignedInt32NV"}, -- {0x6, "SignedInt64NV"}, -- {0x7, "UnsignedInt8NV"}, -- {0x8, "UnsignedInt16NV"}, -- {0x9, "UnsignedInt32NV"}, -- {0xa, "UnsignedInt64NV"}, -- {0x3ba247f8, "SignedInt8PackedNV"}, -- {0x3ba247f9, "UnsignedInt8PackedNV"}, -- {0x3ba247fa, "FloatE4M3NV"}, -- {0x3ba247fb, "FloatE5M2NV"}, -- } -- }, - [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT] = - { - "CooperativeMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, -@@ -614,17 +563,6 @@ spirv_parser_operand_type_info[] = - {0x2, "MatrixAccumulatorKHR"}, - } - }, -- [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT] = -- { -- "CooperativeVectorMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, -- (struct spirv_parser_enumerant[]) -- { -- {0, "RowMajorNV"}, -- {0x1, "ColumnMajorNV"}, -- {0x2, "InferencingOptimalNV"}, -- {0x3, "TrainingOptimalNV"}, -- } -- }, - [SPIRV_PARSER_OPERAND_TYPE_DECORATION] = - { - "Decoration", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 142, -@@ -1240,7 +1178,7 @@ spirv_parser_operand_type_info[] = - }, - [SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE] = - { -- "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 96, -+ "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 94, - (struct spirv_parser_enumerant[]) - { - { -@@ -1389,16 +1327,6 @@ spirv_parser_operand_type_info[] = - SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, - } - }, -- {0x1189, "NonCoherentTileAttachmentReadQCOM"}, -- { -- 0x118a, "TileShadingRateQCOM", 3, -- (enum spirv_parser_operand_type[]) -- { -- SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, -- SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, -- SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, -- } -- }, - {0x1399, "EarlyAndLateFragmentTestsAMD"}, - {0x13a3, "StencilRefReplacingEXT"}, - {0x13cd, "CoalescingAMDX"}, -@@ -1628,11 +1556,7 @@ spirv_parser_operand_type_info[] = - }, - [SPIRV_PARSER_OPERAND_TYPE_FPENCODING] = - { -- "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 1, -- (struct spirv_parser_enumerant[]) -- { -- {0, "BFloat16KHR"}, -- } -+ "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM - }, - [SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE] = - { -@@ -1757,7 +1681,7 @@ spirv_parser_operand_type_info[] = - }, - [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE] = - { -- "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 26, -+ "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 20, - (struct spirv_parser_enumerant[]) - { - {0, "SnormInt8"}, -@@ -1777,15 +1701,9 @@ spirv_parser_operand_type_info[] = - {0xe, "Float"}, - {0xf, "UnormInt24"}, - {0x10, "UnormInt101010_2"}, -- {0x11, "UnormInt10X6EXT"}, - {0x13, "UnsignedIntRaw10EXT"}, - {0x14, "UnsignedIntRaw12EXT"}, - {0x15, "UnormInt2_101010EXT"}, -- {0x16, "UnsignedInt10X6EXT"}, -- {0x17, "UnsignedInt12X4EXT"}, -- {0x18, "UnsignedInt14X2EXT"}, -- {0x19, "UnormInt12X4EXT"}, -- {0x1a, "UnormInt14X2EXT"}, - } - }, - [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_ORDER] = -@@ -2146,28 +2064,6 @@ spirv_parser_operand_type_info[] = - }, - } - }, -- [SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS] = -- { -- "MatrixMultiplyAccumulateOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 15, -- (struct spirv_parser_enumerant[]) -- { -- {0, "None"}, -- {0x1, "MatrixASignedComponentsINTEL"}, -- {0x2, "MatrixBSignedComponentsINTEL"}, -- {0x4, "MatrixCBFloat16INTEL"}, -- {0x8, "MatrixResultBFloat16INTEL"}, -- {0x10, "MatrixAPackedInt8INTEL"}, -- {0x20, "MatrixBPackedInt8INTEL"}, -- {0x40, "MatrixAPackedInt4INTEL"}, -- {0x80, "MatrixBPackedInt4INTEL"}, -- {0x100, "MatrixATF32INTEL"}, -- {0x200, "MatrixBTF32INTEL"}, -- {0x400, "MatrixAPackedFloat16INTEL"}, -- {0x800, "MatrixBPackedFloat16INTEL"}, -- {0x1000, "MatrixAPackedBFloat16INTEL"}, -- {0x2000, "MatrixBPackedBFloat16INTEL"}, -- } -- }, - [SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS] = - { - "MemoryAccess", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 9, -@@ -2405,7 +2301,7 @@ spirv_parser_operand_type_info[] = - }, - [SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE] = - { -- "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 14, -+ "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 13, - (struct spirv_parser_enumerant[]) - { - {0, "Unknown"}, -@@ -2421,12 +2317,11 @@ spirv_parser_operand_type_info[] = - {0xa, "WGSL"}, - {0xb, "Slang"}, - {0xc, "Zig"}, -- {0xd, "Rust"}, - } - }, - [SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS] = - { -- "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 28, -+ "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 27, - (struct spirv_parser_enumerant[]) - { - {0, "UniformConstant"}, -@@ -2443,7 +2338,6 @@ spirv_parser_operand_type_info[] = - {0xb, "Image"}, - {0xc, "StorageBuffer"}, - {0x104c, "TileImageEXT"}, -- {0x118b, "TileAttachmentQCOM"}, - {0x13cc, "NodePayloadAMDX"}, - {0x14d0, "CallableDataKHR"}, - {0x14d1, "IncomingCallableDataKHR"}, -@@ -6996,78 +6890,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_IMAGE_OPERANDS, '?'}, - } - }, -- { -- 0x14a8, "OpTypeCooperativeVectorNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x14a9, "OpCooperativeVectorMatrixMulNV", 13, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, -- {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, -- } -- }, -- { -- 0x14aa, "OpCooperativeVectorOuterProductAccumulateNV", 7, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, -- } -- }, -- { -- 0x14ab, "OpCooperativeVectorReduceSumAccumulateNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x14ac, "OpCooperativeVectorMatrixMulAddNV", 16, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, -- {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, -- } -- }, - { - 0x14ad, "OpCooperativeMatrixConvertNV", 3, - (struct spirv_parser_instruction_operand[]) -@@ -7138,27 +6960,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, -- { -- 0x14b6, "OpCooperativeVectorLoadNV", 5, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, -- } -- }, -- { -- 0x14b7, "OpCooperativeVectorStoreNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, -- } -- }, - { - 0x14d6, "OpReportIntersectionKHR", 4, - (struct spirv_parser_instruction_operand[]) -@@ -7249,25 +7050,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, -- { -- 0x14e1, "OpRayQueryGetClusterIdNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x14e2, "OpHitObjectGetClusterIdNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, - { - 0x14ee, "OpTypeCooperativeMatrixNV", 5, - (struct spirv_parser_instruction_operand[]) -@@ -7580,130 +7362,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, '?'}, - } - }, -- { -- 0x1533, "OpRayQueryGetIntersectionSpherePositionNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1534, "OpRayQueryGetIntersectionSphereRadiusNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1535, "OpRayQueryGetIntersectionLSSPositionsNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1536, "OpRayQueryGetIntersectionLSSRadiiNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1537, "OpRayQueryGetIntersectionLSSHitValueNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1538, "OpHitObjectGetSpherePositionNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1539, "OpHitObjectGetSphereRadiusNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x153a, "OpHitObjectGetLSSPositionsNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x153b, "OpHitObjectGetLSSRadiiNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x153c, "OpHitObjectIsSphereHitNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x153d, "OpHitObjectIsLSSHitNV", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x153e, "OpRayQueryIsSphereHitNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x153f, "OpRayQueryIsLSSHitNV", 4, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, - { - 0x15c3, "OpSubgroupShuffleINTEL", 4, - (struct spirv_parser_instruction_operand[]) -@@ -7962,9 +7620,10 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x15e9, "OpAsmTargetINTEL", 2, -+ 0x15e9, "OpAsmTargetINTEL", 3, - (struct spirv_parser_instruction_operand[]) - { -+ {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, - } -@@ -9237,7 +8896,7 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 8, -+ 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -@@ -9248,6 +8907,7 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -+ {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - } - }, - { -@@ -9279,7 +8939,7 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x16d3, "OpArbitraryFloatCastToIntINTEL", 8, -+ 0x16d3, "OpArbitraryFloatCastToIntINTEL", 7, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -@@ -9289,7 +8949,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - } - }, - { -@@ -9803,7 +9462,7 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x16fa, "OpArbitraryFloatPowNINTEL", 10, -+ 0x16fa, "OpArbitraryFloatPowNINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -@@ -9815,7 +9474,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - } - }, - { -@@ -9851,12 +9509,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x1723, "OpFixedSqrtINTEL", 8, -+ 0x1723, "OpFixedSqrtINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9865,12 +9524,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x1724, "OpFixedRecipINTEL", 8, -+ 0x1724, "OpFixedRecipINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9879,12 +9539,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x1725, "OpFixedRsqrtINTEL", 8, -+ 0x1725, "OpFixedRsqrtINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9893,12 +9554,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x1726, "OpFixedSinINTEL", 8, -+ 0x1726, "OpFixedSinINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9907,12 +9569,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x1727, "OpFixedCosINTEL", 8, -+ 0x1727, "OpFixedCosINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9921,12 +9584,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x1728, "OpFixedSinCosINTEL", 8, -+ 0x1728, "OpFixedSinCosINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9935,12 +9599,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x1729, "OpFixedSinPiINTEL", 8, -+ 0x1729, "OpFixedSinPiINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9949,12 +9614,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x172a, "OpFixedCosPiINTEL", 8, -+ 0x172a, "OpFixedCosPiINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9963,12 +9629,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x172b, "OpFixedSinCosPiINTEL", 8, -+ 0x172b, "OpFixedSinCosPiINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9977,12 +9644,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x172c, "OpFixedLogINTEL", 8, -+ 0x172c, "OpFixedLogINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -9991,12 +9659,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x172d, "OpFixedExpINTEL", 8, -+ 0x172d, "OpFixedExpINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -@@ -10043,12 +9712,13 @@ spirv_parser_opcode_info[] = - } - }, - { -- 0x173d, "OpFPGARegINTEL", 3, -+ 0x173d, "OpFPGARegINTEL", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -+ {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { -@@ -10311,50 +9981,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, -- { -- 0x1813, "OpTaskSequenceCreateINTEL", 7, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -- {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, -- } -- }, -- { -- 0x1814, "OpTaskSequenceAsyncINTEL", 2, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, -- } -- }, -- { -- 0x1815, "OpTaskSequenceGetINTEL", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1816, "OpTaskSequenceReleaseINTEL", 1, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1837, "OpTypeTaskSequenceINTEL", 1, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- } -- }, - { - 0x184d, "OpSubgroupBlockPrefetchINTEL", 3, - (struct spirv_parser_instruction_operand[]) -@@ -10364,110 +9990,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, - } - }, -- { -- 0x1857, "OpSubgroup2DBlockLoadINTEL", 10, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1858, "OpSubgroup2DBlockLoadTransformINTEL", 10, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x1859, "OpSubgroup2DBlockLoadTransposeINTEL", 10, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x185a, "OpSubgroup2DBlockPrefetchINTEL", 9, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x185b, "OpSubgroup2DBlockStoreINTEL", 10, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, -- { -- 0x185d, "OpSubgroupMatrixMultiplyAccumulateINTEL", 7, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, '?'}, -- } -- }, -- { -- 0x1862, "OpBitwiseFunctionINTEL", 6, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, - { - 0x1901, "OpGroupIMulKHR", 5, - (struct spirv_parser_instruction_operand[]) -@@ -10556,15 +10078,6 @@ spirv_parser_opcode_info[] = - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, -- { -- 0x191a, "OpRoundFToTF32INTEL", 3, -- (struct spirv_parser_instruction_operand[]) -- { -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, -- {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, -- } -- }, - { - 0x191c, "OpMaskedGatherINTEL", 6, - (struct spirv_parser_instruction_operand[]) -diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h -index 0501e6a06c2..8b63acf68e1 100644 ---- a/libs/vkd3d/include/private/vkd3d_common.h -+++ b/libs/vkd3d/include/private/vkd3d_common.h -@@ -38,6 +38,8 @@ - #include - #endif - -+#define VKD3D_SHADER_API_VERSION_CURRENT VKD3D_SHADER_API_VERSION_1_17 -+ - #ifndef ARRAY_SIZE - # define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) - #endif -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 6a12dec14bf..172204f2226 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -3665,14 +3665,15 @@ static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_pars - return &instructions->elements[instructions->count]; - } - --/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */ - static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_parser *sm6, -- enum vkd3d_shader_opcode handler_idx) -+ enum vkd3d_shader_opcode op) - { -- struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); -- VKD3D_ASSERT(ins); -- vsir_instruction_init(ins, &sm6->p.location, handler_idx); -- ++sm6->program->instructions.count; -+ struct vkd3d_shader_instruction *ins; -+ -+ if (!(ins = vsir_program_append(sm6->program))) -+ return NULL; -+ vsir_instruction_init(ins, &sm6->p.location, op); -+ - return ins; - } - -@@ -8589,7 +8590,8 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) - static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6) - { - struct vsir_program *program = sm6->program; -- unsigned int i; -+ struct vkd3d_shader_instruction *ins; -+ unsigned int i, j; - - program->block_count = function->block_count; - -@@ -8607,10 +8609,11 @@ static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *fun - sm6_parser_emit_label(sm6, block->id); - sm6_block_emit_phi(block, sm6); - -- memcpy(&program->instructions.elements[program->instructions.count], block->instructions, -- block->instruction_count * sizeof(*block->instructions)); -- program->instructions.count += block->instruction_count; -- -+ for (j = 0; j < block->instruction_count; ++j) -+ { -+ ins = vsir_program_append(program); -+ *ins = block->instructions[j]; -+ } - sm6_block_emit_terminator(block, sm6); - } - -@@ -9512,8 +9515,8 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, - struct vkd3d_shader_instruction *ins; - const struct sm6_metadata_node *node; - const struct sm6_metadata_value *m; -+ enum vkd3d_result ret = VKD3D_OK; - struct sm6_descriptor_info *d; -- enum vkd3d_result ret; - unsigned int i; - - for (i = 0; i < descriptor_node->operand_count; ++i) -@@ -9562,9 +9565,10 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, - return VKD3D_ERROR_INVALID_SHADER; - } - -- if (!(ins = sm6_parser_require_space(sm6, 1))) -+ if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_NOP))) - { -- ERR("Failed to allocate instruction.\n"); -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, -+ "Out of memory emitting shader instructions."); - return VKD3D_ERROR_OUT_OF_MEMORY; - } - -@@ -9572,32 +9576,34 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, - { - case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: - if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0) -- return ret; -+ goto done; - break; - case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: - if ((ret = sm6_parser_resources_load_srv(sm6, node, d, ins)) < 0) -- return ret; -+ goto done; - break; - case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: - if ((ret = sm6_parser_resources_load_uav(sm6, node, d, ins)) < 0) -- return ret; -+ goto done; - break; - case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: - if ((ret = sm6_parser_resources_load_sampler(sm6, node, d, ins)) < 0) -- return ret; -+ goto done; - break; - default: -- FIXME("Unsupported descriptor type %u.\n", type); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, -- "Resource descriptor type %u is unsupported.", type); -- return VKD3D_ERROR_INVALID_SHADER; -+ "Resource descriptor type %#x is unsupported.", type); -+ ret = VKD3D_ERROR_INVALID_SHADER; -+ goto done; - } - - ++sm6->descriptor_count; -- ++sm6->program->instructions.count; - } - -- return VKD3D_OK; -+done: -+ if (ret < 0) -+ vsir_instruction_init(ins, &ins->location, VSIR_OP_NOP); -+ return ret; - } - - static enum vkd3d_result sm6_parser_resources_init(struct sm6_parser *sm6) -diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c -index 676c501bb08..a14346a45d2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/fx.c -+++ b/libs/vkd3d/libs/vkd3d-shader/fx.c -@@ -4205,7 +4205,7 @@ static void fx_parse_shader_blob(struct fx_parser *parser, enum vkd3d_shader_sou - - static const struct vkd3d_shader_compile_option options[] = - { -- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, -+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, - }; - - info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index acc30b998f6..7325661ea7b 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -792,7 +792,7 @@ static void shader_glsl_print_texel_offset(struct vkd3d_string_buffer *buffer, s - - static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) - { -- unsigned int resource_id, resource_idx, resource_space, sample_count; -+ unsigned int coord_size, resource_id, resource_idx, resource_space, sample_count; - const struct glsl_resource_type_info *resource_type_info; - const struct vkd3d_shader_descriptor_info1 *d; - enum vkd3d_shader_resource_type resource_type; -@@ -800,11 +800,9 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ - enum vsir_data_type data_type; - struct glsl_src coord; - struct glsl_dst dst; -- uint32_t coord_mask; -+ bool array, offset; - -- if (vkd3d_shader_instruction_has_texel_offset(ins)) -- vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -- "Internal compiler error: Unhandled texel fetch offset."); -+ offset = vkd3d_shader_instruction_has_texel_offset(ins); - - if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, -@@ -831,20 +829,22 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ - - if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) - { -- coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); -+ coord_size = resource_type_info->coord_size; -+ array = resource_type_info->array; - } - else - { - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled resource type %#x.", resource_type); -- coord_mask = vkd3d_write_mask_from_component_count(2); -+ coord_size = 2; -+ array = false; - } - - glsl_dst_init(&dst, gen, ins, &ins->dst[0]); -- glsl_src_init(&coord, gen, &ins->src[0], coord_mask); -+ glsl_src_init(&coord, gen, &ins->src[0], vkd3d_write_mask_from_component_count(coord_size)); - fetch = vkd3d_string_buffer_get(&gen->string_buffers); - -- vkd3d_string_buffer_printf(fetch, "texelFetch("); -+ vkd3d_string_buffer_printf(fetch, "texelFetch%s(", offset ? "Offset" : ""); - shader_glsl_print_combined_sampler_name(fetch, gen, resource_idx, - resource_space, VKD3D_SHADER_DUMMY_SAMPLER_INDEX, 0); - vkd3d_string_buffer_printf(fetch, ", %s", coord.str->buffer); -@@ -860,6 +860,11 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ - else - shader_glsl_print_src(fetch, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, ins->src[2].reg.data_type); - } -+ if (offset) -+ { -+ vkd3d_string_buffer_printf(fetch, ", "); -+ shader_glsl_print_texel_offset(fetch, gen, coord_size - array, &ins->texel_offset); -+ } - vkd3d_string_buffer_printf(fetch, ")"); - shader_glsl_print_swizzle(fetch, ins->src[1].swizzle, ins->dst[0].write_mask); - -@@ -1475,6 +1480,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - case VSIR_OP_CONTINUE: - shader_glsl_continue(gen); - break; -+ case VSIR_OP_COS: -+ shader_glsl_intrinsic(gen, ins, "cos"); -+ break; - case VSIR_OP_DCL_INDEXABLE_TEMP: - shader_glsl_dcl_indexable_temp(gen, ins); - break; -@@ -1495,6 +1503,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - case VSIR_OP_DP4: - shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); - break; -+ case VSIR_OP_DSX: -+ shader_glsl_intrinsic(gen, ins, "dFdx"); -+ break; -+ case VSIR_OP_DSY: -+ shader_glsl_intrinsic(gen, ins, "dFdy"); -+ break; - case VSIR_OP_ELSE: - shader_glsl_else(gen, ins); - break; -@@ -1621,6 +1635,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - case VSIR_OP_RSQ: - shader_glsl_intrinsic(gen, ins, "inversesqrt"); - break; -+ case VSIR_OP_SIN: -+ shader_glsl_intrinsic(gen, ins, "sin"); -+ break; - case VSIR_OP_SQRT: - shader_glsl_intrinsic(gen, ins, "sqrt"); - break; -@@ -1630,6 +1647,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - case VSIR_OP_SWITCH: - shader_glsl_switch(gen, ins); - break; -+ case VSIR_OP_UDIV_SIMPLE: -+ shader_glsl_binop(gen, ins, "/"); -+ break; - case VSIR_OP_XOR: - shader_glsl_binop(gen, ins, "^"); - break; -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index fef186ac34b..396562e65e4 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -27,6 +27,22 @@ struct vsir_transformation_context - uint64_t config_flags; - const struct vkd3d_shader_compile_info *compile_info; - struct vkd3d_shader_message_context *message_context; -+ struct vkd3d_shader_location null_location; -+}; -+ -+static void vsir_transformation_context_init(struct vsir_transformation_context *ctx, -+ struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, -+ struct vkd3d_shader_message_context *message_context) -+{ -+ *ctx = (struct vsir_transformation_context) -+ { -+ .result = VKD3D_OK, -+ .program = program, -+ .config_flags = config_flags, -+ .compile_info = compile_info, -+ .message_context = message_context, -+ .null_location = {.source_name = compile_info->source_name}, -+ }; - }; - - const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) -@@ -1814,16 +1830,19 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -- static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; -+ struct vkd3d_shader_location loc; - -- ins = vsir_program_iterator_tail(&it); -- if (ins && ins->opcode == VSIR_OP_RET) -+ if (!(ins = vsir_program_iterator_tail(&it))) -+ loc = ctx->null_location; -+ else if (ins->opcode == VSIR_OP_RET) - return VKD3D_OK; -+ else -+ loc = ins->location; - - if (!(ins = vsir_program_append(program))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); -+ vsir_instruction_init(ins, &loc, VSIR_OP_RET); - - return VKD3D_OK; - } -@@ -1914,7 +1933,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra - struct vsir_transformation_context *ctx) - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -- static const struct vkd3d_shader_location no_loc; -+ struct vkd3d_shader_location loc = ctx->null_location; - struct vkd3d_shader_instruction *ins; - unsigned int i; - -@@ -1928,15 +1947,16 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra - for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { - if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) -+ { -+ loc = ins->location; - break; -+ } - } - -- vsir_program_iterator_prev(&it); -- if (!vsir_program_iterator_insert_after(&it, 1)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(&it); - -- vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); - ins->dst[0].reg.idx[0].offset = 0; - ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; -@@ -2153,10 +2173,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program - continue; - - loc = ins->location; -- vsir_program_iterator_prev(&it); -- if (!vsir_program_iterator_insert_after(&it, uninit_varying_count)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, uninit_varying_count))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(&it); - - for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) - { -@@ -4224,9 +4242,11 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs - struct vsir_transformation_context *ctx) - { - unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label; -- size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0; -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -+ size_t ins_capacity = 0, ins_count = 0, map_capacity = 0, map_count = 0; - struct vkd3d_shader_instruction *instructions = NULL; - struct lower_switch_to_if_ladder_block_mapping *block_map = NULL; -+ struct vkd3d_shader_instruction *ins; - - VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); - -@@ -4236,9 +4256,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs - /* First subpass: convert SWITCH_MONOLITHIC instructions to - * selection ladders, keeping a map between blocks before and - * after the subpass. */ -- for (i = 0; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - unsigned int case_count, j, default_label; - - switch (ins->opcode) -@@ -6872,7 +6891,6 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru - static bool use_flat_interpolation(const struct vsir_program *program, - struct vkd3d_shader_message_context *message_context, bool *flat) - { -- static const struct vkd3d_shader_location no_loc; - const struct vkd3d_shader_parameter1 *parameter; - - *flat = false; -@@ -6882,13 +6900,13 @@ static bool use_flat_interpolation(const struct vsir_program *program, - - if (parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Unsupported flat interpolation parameter type %#x.", parameter->type); - return false; - } - if (parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid flat interpolation parameter data type %#x.", parameter->data_type); - return false; - } -@@ -6929,7 +6947,6 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) - { - struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; -- static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; - - static const struct -@@ -6950,10 +6967,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - - if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) - { -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, 1)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); - ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; -@@ -6963,10 +6978,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - return VKD3D_OK; - } - -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, 3)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 3))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - switch (ref->data_type) - { -@@ -6985,7 +6998,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr - break; - - case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4: -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, - "Alpha test reference data type must be a single component."); - return VKD3D_ERROR_INVALID_ARGUMENT; - -@@ -7027,7 +7040,6 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro - struct vkd3d_shader_message_context *message_context = ctx->message_context; - const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL; - uint32_t colour_signature_idx, colour_temp = ~0u; -- static const struct vkd3d_shader_location no_loc; - enum vkd3d_shader_comparison_func compare_func; - struct vkd3d_shader_instruction *ins; - int ret; -@@ -7045,13 +7057,13 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro - - if (func->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Unsupported alpha test function parameter type %#x.", func->type); - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - if (func->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid alpha test function parameter data type %#x.", func->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7108,10 +7120,8 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog - struct vkd3d_shader_instruction *ins; - unsigned int output_idx = 0; - -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, vkd3d_popcount(mask) + 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - for (unsigned int i = 0; i < 8; ++i) - { -@@ -7279,10 +7289,8 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr - const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; - struct vkd3d_shader_instruction *ins; - -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, 1)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); -@@ -7604,10 +7612,8 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - - if (used_texcoord) - { -- vsir_program_iterator_prev(&it); -- if (!vsir_program_iterator_insert_after(&it, 2)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(&it); - - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); - dst_param_init_temp_float4(&ins->dst[0], coord_temp); -@@ -7675,10 +7681,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * add sr0, FOG_END, -vFOG.x - * mul_sat srFACTOR, sr0, FOG_SCALE - */ -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, 4)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - ssa_temp = program->ssa_count++; - -@@ -7707,10 +7711,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * mul sr0, FOG_SCALE, vFOG.x - * exp_sat srFACTOR, -sr0 - */ -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, 4)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - ssa_temp = program->ssa_count++; - -@@ -7738,10 +7740,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro - * mul sr1, sr0, sr0 - * exp_sat srFACTOR, -sr1 - */ -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, 5)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 5))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - ssa_temp = program->ssa_count++; - ssa_temp2 = program->ssa_count++; -@@ -7921,10 +7921,8 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr - const struct vkd3d_shader_location loc = ret->location; - struct vkd3d_shader_instruction *ins; - -- vsir_program_iterator_prev(it); -- if (!vsir_program_iterator_insert_after(it, 2)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(it, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- ins = vsir_program_iterator_next(it); - - /* Write the fog output. */ - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); -@@ -8934,11 +8932,9 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, - ins = vsir_program_iterator_head(&it); - location = ins->location; - -- vsir_program_iterator_prev(&it); -- if (!vsir_program_iterator_insert_after(&it, 1)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 1))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- ins = vsir_program_iterator_next(&it); - vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); - ins->declaration.count = temp_count; - } -@@ -12103,14 +12099,9 @@ static void vsir_transform_( - enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) - { -- struct vsir_transformation_context ctx = -- { -- .result = VKD3D_OK, -- .program = program, -- .config_flags = config_flags, -- .compile_info = compile_info, -- .message_context = message_context, -- }; -+ struct vsir_transformation_context ctx; -+ -+ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); - - /* For vsir_program_ensure_diffuse(). */ - if (program->shader_version.major <= 2) -@@ -12128,15 +12119,9 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin - enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) - { -- struct vsir_transformation_context ctx = -- { -- .result = VKD3D_OK, -- .program = program, -- .config_flags = config_flags, -- .compile_info = compile_info, -- .message_context = message_context, -- }; -+ struct vsir_transformation_context ctx; - -+ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); - vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); - if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) - vsir_transform(&ctx, vsir_program_normalise_ps1_output); -@@ -12150,15 +12135,9 @@ enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_ - enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) - { -- struct vsir_transformation_context ctx = -- { -- .result = VKD3D_OK, -- .program = program, -- .config_flags = config_flags, -- .compile_info = compile_info, -- .message_context = message_context, -- }; -+ struct vsir_transformation_context ctx; - -+ vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); - vsir_transform(&ctx, vsir_program_lower_instructions); - - if (program->shader_version.major >= 6) -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index 88d1160d4e8..fc8d482e08a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -1996,6 +1996,7 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) - static void msl_generate_entrypoint(struct msl_generator *gen) - { - enum vkd3d_shader_type type = gen->program->shader_version.type; -+ bool output = true; - - switch (type) - { -@@ -2007,13 +2008,21 @@ static void msl_generate_entrypoint(struct msl_generator *gen) - vkd3d_string_buffer_printf(gen->buffer, "[[early_fragment_tests]]\n"); - vkd3d_string_buffer_printf(gen->buffer, "fragment "); - break; -+ case VKD3D_SHADER_TYPE_COMPUTE: -+ vkd3d_string_buffer_printf(gen->buffer, "kernel "); -+ output = false; -+ break; - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled shader type %#x.", type); - return; - } - -- vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix); -+ if (output) -+ vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out ", gen->prefix); -+ else -+ vkd3d_string_buffer_printf(gen->buffer, "void "); -+ vkd3d_string_buffer_printf(gen->buffer, "shader_entry(\n"); - - if (gen->program->descriptors.descriptor_count) - { -@@ -2055,7 +2064,9 @@ static void msl_generate_entrypoint(struct msl_generator *gen) - - msl_generate_entrypoint_epilogue(gen); - -- vkd3d_string_buffer_printf(gen->buffer, " return output;\n}\n"); -+ if (output) -+ vkd3d_string_buffer_printf(gen->buffer, " return output;\n"); -+ vkd3d_string_buffer_printf(gen->buffer, "}\n"); - } - - static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out) -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index b63c5785770..4102fe53e67 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1510,6 +1510,16 @@ static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterat - return shader_instruction_array_insert_at(it->array, it->idx + 1, count); - } - -+static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before_and_move( -+ struct vsir_program_iterator *it, size_t count) -+{ -+ VKD3D_ASSERT(it->idx != SIZE_MAX); -+ -+ if (!shader_instruction_array_insert_at(it->array, it->idx, count)) -+ return NULL; -+ return vsir_program_iterator_current(it); -+} -+ - enum vkd3d_shader_config_flags - { - VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, -diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -index f804c1f0c24..15c5b77c8df 100644 ---- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -+++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -@@ -271,7 +271,7 @@ HRESULT WINAPI D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char * - - option = &options[0]; - option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; -- option->value = VKD3D_SHADER_API_VERSION_1_17; -+ option->value = VKD3D_SHADER_API_VERSION_CURRENT; - - compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; - compile_info.next = &preprocess_info; -@@ -435,7 +435,7 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename - - static const struct vkd3d_shader_compile_option options[] = - { -- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, -+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, - }; - - TRACE("data %p, size %"PRIuPTR", filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", -@@ -981,7 +981,7 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, - - static const struct vkd3d_shader_compile_option options[] = - { -- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, -+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, - }; - - TRACE("data %p, data_size %"PRIuPTR", flags %#x, comments %p, blob %p.\n", -diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c -index 074d8430585..d933e7ec463 100644 ---- a/libs/vkd3d/libs/vkd3d/command.c -+++ b/libs/vkd3d/libs/vkd3d/command.c -@@ -3049,7 +3049,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list - - if (descriptor_count > range->vk_binding_count) - { -- ERR("Heap descriptor count %u exceeds maximum Vulkan count %u. Reducing to the Vulkan maximum.\n", -+ MESSAGE("Heap descriptor count %u exceeds maximum Vulkan count %u. Reducing to the Vulkan maximum.\n", - descriptor_count, range->vk_binding_count); - descriptor_count = range->vk_binding_count; - } -diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c -index 6bbd6533b74..b6055a50a99 100644 ---- a/libs/vkd3d/libs/vkd3d/state.c -+++ b/libs/vkd3d/libs/vkd3d/state.c -@@ -2391,7 +2391,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device, - - const struct vkd3d_shader_compile_option options[] = - { -- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, -+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, - {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, - {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0}, - {VKD3D_SHADER_COMPILE_OPTION_FEATURE, feature_flags_compile_option(device)}, -@@ -2456,7 +2456,7 @@ static int vkd3d_scan_dxbc(const struct d3d12_device *device, const D3D12_SHADER - - const struct vkd3d_shader_compile_option options[] = - { -- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, -+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, - {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, - }; - -@@ -4135,7 +4135,7 @@ static int compile_hlsl_cs(const struct vkd3d_shader_code *hlsl, struct vkd3d_sh - - static const struct vkd3d_shader_compile_option options[] = - { -- {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, -+ {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, - }; - - info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; --- -2.51.0 - diff --git a/patches/vkd3d-latest/0005-Updated-vkd3d-to-979d7e4b85f2fb8db60219f4a2673fc8071.patch b/patches/vkd3d-latest/0005-Updated-vkd3d-to-979d7e4b85f2fb8db60219f4a2673fc8071.patch deleted file mode 100644 index 20034037..00000000 --- a/patches/vkd3d-latest/0005-Updated-vkd3d-to-979d7e4b85f2fb8db60219f4a2673fc8071.patch +++ /dev/null @@ -1,365 +0,0 @@ -From f6510f66601eba7d3dbe69168831429c930aa494 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 2 Sep 2025 07:37:13 +1000 -Subject: [PATCH] Updated vkd3d to 979d7e4b85f2fb8db60219f4a2673fc807142ebd. - ---- - libs/vkd3d/libs/vkd3d-shader/glsl.c | 26 ++++++++++++++++ - libs/vkd3d/libs/vkd3d-shader/ir.c | 44 ++++++++++++++-------------- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 29 +++++++++--------- - 3 files changed, 63 insertions(+), 36 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c -index 7325661ea7b..b2679beff9f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/glsl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c -@@ -288,6 +288,14 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, - shader_glsl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); - break; - -+ case VKD3DSPR_SAMPLEMASK: -+ if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) -+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -+ "Internal compiler error: Unhandled sample coverage mask in shader type #%x.", -+ gen->program->shader_version.type); -+ vkd3d_string_buffer_printf(buffer, "o_mask"); -+ break; -+ - default: - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled register type %#x.", reg->type); -@@ -1286,6 +1294,13 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st - vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_VertexID, 0, 0, 0))"); - break; - -+ case VKD3D_SHADER_SV_INSTANCE_ID: -+ if (version->type != VKD3D_SHADER_TYPE_VERTEX) -+ vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -+ "Internal compiler error: Unhandled SV_INSTANCE_ID in shader type #%x.", version->type); -+ vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_InstanceID, 0, 0, 0))"); -+ break; -+ - case VKD3D_SHADER_SV_IS_FRONT_FACE: - if (version->type != VKD3D_SHADER_TYPE_PIXEL) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, -@@ -1434,6 +1449,12 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen) - shader_glsl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, ";\n"); - } -+ -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) -+ { -+ shader_glsl_print_indent(buffer, gen->indent); -+ vkd3d_string_buffer_printf(gen->buffer, "gl_SampleMask[0] = floatBitsToInt(o_mask);\n"); -+ } - } - - static void shader_glsl_ret(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) -@@ -1650,6 +1671,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, - case VSIR_OP_UDIV_SIMPLE: - shader_glsl_binop(gen, ins, "/"); - break; -+ case VSIR_OP_UREM: -+ shader_glsl_binop(gen, ins, "%"); -+ break; - case VSIR_OP_XOR: - shader_glsl_binop(gen, ins, "^"); - break; -@@ -2339,6 +2363,8 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) - vkd3d_string_buffer_printf(buffer, "vec4 %s_in[%u];\n", gen->prefix, gen->limits.input_count); - if (gen->limits.output_count) - vkd3d_string_buffer_printf(buffer, "vec4 %s_out[%u];\n", gen->prefix, gen->limits.output_count); -+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) -+ vkd3d_string_buffer_printf(gen->buffer, "float o_mask;\n"); - if (program->temp_count) - vkd3d_string_buffer_printf(buffer, "vec4 r[%u];\n", program->temp_count); - vkd3d_string_buffer_printf(buffer, "\n"); -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 396562e65e4..1ab406a9d84 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -1750,6 +1750,8 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr - case VSIR_OP_DCL: - case VSIR_OP_DCL_CONSTANT_BUFFER: - case VSIR_OP_DCL_GLOBAL_FLAGS: -+ case VSIR_OP_DCL_INPUT_PRIMITIVE: -+ case VSIR_OP_DCL_OUTPUT_TOPOLOGY: - case VSIR_OP_DCL_SAMPLER: - case VSIR_OP_DCL_TEMPS: - case VSIR_OP_DCL_TESSELLATOR_DOMAIN: -@@ -7167,7 +7169,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr - unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; - const struct vkd3d_shader_parameter1 *mask_parameter = NULL; - uint32_t position_signature_idx, position_temp, mask; -- static const struct vkd3d_shader_location no_loc; - struct signature_element *clip_element; - struct vkd3d_shader_instruction *ins; - unsigned int plane_count; -@@ -7189,13 +7190,13 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr - - if (mask_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Unsupported clip plane mask parameter type %#x.", mask_parameter->type); - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - if (mask_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid clip plane mask parameter data type %#x.", mask_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7208,7 +7209,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr - { - if (signature->elements[i].sysval_semantic == VKD3D_SHADER_SV_CLIP_DISTANCE) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, -+ vkd3d_shader_error(ctx->message_context, &ctx->null_location, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, - "Clip planes cannot be used if the shader writes clip distance."); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7216,7 +7217,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr - - if (!vsir_signature_find_sysval(signature, VKD3D_SHADER_SV_POSITION, 0, &position_signature_idx)) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, -+ vkd3d_shader_error(ctx->message_context, &ctx->null_location, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, - "Shader does not write position."); - return VKD3D_ERROR_INVALID_SHADER; - } -@@ -7306,7 +7307,6 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - const struct vkd3d_shader_parameter1 *size_parameter = NULL; -- static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; - - if (program->has_point_size) -@@ -7328,7 +7328,7 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro - - if (size_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid point size parameter data type %#x.", size_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7355,7 +7355,6 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - { - const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL; - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -- static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; - - if (!program->has_point_size) -@@ -7379,14 +7378,14 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra - - if (min_parameter && min_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid minimum point size parameter data type %#x.", min_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } - - if (max_parameter && max_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid maximum point size parameter data type %#x.", max_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7529,7 +7528,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2; - const struct vkd3d_shader_parameter1 *sprite_parameter = NULL; -- static const struct vkd3d_shader_location no_loc; -+ struct vkd3d_shader_location loc = ctx->null_location; - struct vkd3d_shader_instruction *ins; - bool used_texcoord = false; - unsigned int coord_temp; -@@ -7551,13 +7550,13 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - - if (sprite_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Unsupported point sprite parameter type %#x.", sprite_parameter->type); - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - if (sprite_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid point sprite parameter data type %#x.", sprite_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7577,7 +7576,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { - if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) -+ { -+ loc = ins->location; - break; -+ } - } - - it2 = it; -@@ -7615,7 +7617,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 2))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - dst_param_init_temp_float4(&ins->dst[0], coord_temp); - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; - vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); -@@ -7623,7 +7625,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr - ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ins = vsir_program_iterator_next(&it); - -- vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); -+ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); - dst_param_init_temp_float4(&ins->dst[0], coord_temp); - ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; - vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); -@@ -7804,7 +7806,6 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p - struct vkd3d_shader_message_context *message_context = ctx->message_context; - uint32_t colour_signature_idx, fog_signature_idx, colour_temp; - const struct vkd3d_shader_parameter1 *mode_parameter = NULL; -- static const struct vkd3d_shader_location no_loc; - const struct signature_element *fog_element; - enum vkd3d_shader_fog_fragment_mode mode; - struct vkd3d_shader_instruction *ins; -@@ -7821,13 +7822,13 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p - - if (mode_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Unsupported fog fragment mode parameter type %#x.", mode_parameter->type); - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - if (mode_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid fog fragment mode parameter data type %#x.", mode_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7951,7 +7952,6 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro - struct vkd3d_shader_message_context *message_context = ctx->message_context; - const struct vkd3d_shader_parameter1 *source_parameter = NULL; - uint32_t fog_signature_idx, source_signature_idx, temp; -- static const struct vkd3d_shader_location no_loc; - struct vkd3d_shader_instruction *ins; - enum vkd3d_shader_fog_source source; - const struct signature_element *e; -@@ -7964,13 +7964,13 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro - - if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Unsupported fog source parameter type %#x.", source_parameter->type); - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) - { -- vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -+ vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid fog source parameter data type %#x.", source_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } -@@ -7992,7 +7992,7 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro - if (!vsir_signature_find_sysval(&program->output_signature, - VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx)) - { -- vkd3d_shader_error(ctx->message_context, &no_loc, -+ vkd3d_shader_error(ctx->message_context, &ctx->null_location, - VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); - return VKD3D_ERROR_INVALID_SHADER; - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 97c0d0e73a8..a57c42b167d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -7209,10 +7209,9 @@ static void spirv_compiler_emit_output_vertex_count(struct spirv_compiler *compi - SpvExecutionModeOutputVertices, instruction->declaration.count); - } - --static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) -+static void spirv_compiler_emit_input_primitive(struct spirv_compiler *compiler) - { -- enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; -+ enum vkd3d_primitive_type primitive_type = compiler->program->input_primitive; - SpvExecutionMode mode; - - switch (primitive_type) -@@ -7233,7 +7232,8 @@ static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compi - mode = SpvExecutionModeInputTrianglesAdjacency; - break; - default: -- FIXME("Unhandled primitive type %#x.\n", primitive_type); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled input primitive type %#x.", primitive_type); - return; - } - -@@ -7263,10 +7263,9 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) - } - } - --static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compiler, -- const struct vkd3d_shader_instruction *instruction) -+static void spirv_compiler_emit_output_topology(struct spirv_compiler *compiler) - { -- enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; -+ enum vkd3d_primitive_type primitive_type = compiler->program->output_topology; - SpvExecutionMode mode; - - switch (primitive_type) -@@ -7282,7 +7281,8 @@ static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compi - mode = SpvExecutionModeOutputTriangleStrip; - break; - default: -- ERR("Unexpected primitive type %#x.\n", primitive_type); -+ spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, -+ "Unhandled output topology %#x.", primitive_type); - return; - } - -@@ -10608,12 +10608,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, - case VSIR_OP_DCL_VERTICES_OUT: - spirv_compiler_emit_output_vertex_count(compiler, instruction); - break; -- case VSIR_OP_DCL_INPUT_PRIMITIVE: -- spirv_compiler_emit_dcl_input_primitive(compiler, instruction); -- break; -- case VSIR_OP_DCL_OUTPUT_TOPOLOGY: -- spirv_compiler_emit_dcl_output_topology(compiler, instruction); -- break; - case VSIR_OP_DCL_GS_INSTANCES: - spirv_compiler_emit_dcl_gs_instances(compiler, instruction); - break; -@@ -11066,7 +11060,14 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - if (program->ssa_count) - spirv_compiler_allocate_ssa_register_ids(compiler, program->ssa_count); - if (compiler->shader_type == VKD3D_SHADER_TYPE_COMPUTE) -+ { - spirv_compiler_emit_thread_group_size(compiler, &program->thread_group_size); -+ } -+ else if (compiler->shader_type == VKD3D_SHADER_TYPE_GEOMETRY) -+ { -+ spirv_compiler_emit_input_primitive(compiler); -+ spirv_compiler_emit_output_topology(compiler); -+ } - spirv_compiler_emit_global_flags(compiler, program->global_flags); - - spirv_compiler_emit_descriptor_declarations(compiler); --- -2.51.0 - diff --git a/patches/vkd3d-latest/0006-Updated-vkd3d-to-d6bed4be377432e4c54e23abcd7863fefbe.patch b/patches/vkd3d-latest/0006-Updated-vkd3d-to-d6bed4be377432e4c54e23abcd7863fefbe.patch deleted file mode 100644 index 41c5edb1..00000000 --- a/patches/vkd3d-latest/0006-Updated-vkd3d-to-d6bed4be377432e4c54e23abcd7863fefbe.patch +++ /dev/null @@ -1,1757 +0,0 @@ -From d6553ac0d36434c95def8553efc28663fb5f77a1 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Wed, 3 Sep 2025 08:08:18 +1000 -Subject: [PATCH] Updated vkd3d to d6bed4be377432e4c54e23abcd7863fefbef94aa. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 23 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 4 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 102 ++++--- - libs/vkd3d/libs/vkd3d-shader/ir.c | 167 ++++++++++-- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 249 +++++++++--------- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 2 + - 6 files changed, 331 insertions(+), 216 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 6425a8f62d2..58135e71f30 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -390,27 +390,10 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, - - static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type) - { -- static const char *const data_type_names[] = -- { -- [VSIR_DATA_BOOL ] = "bool", -- [VSIR_DATA_F16 ] = "half", -- [VSIR_DATA_F32 ] = "float", -- [VSIR_DATA_F64 ] = "double", -- [VSIR_DATA_I32 ] = "int", -- [VSIR_DATA_U8 ] = "uint8", -- [VSIR_DATA_U16 ] = "uint16", -- [VSIR_DATA_U32 ] = "uint", -- [VSIR_DATA_U64 ] = "uint64", -- [VSIR_DATA_SNORM ] = "snorm", -- [VSIR_DATA_UNORM ] = "unorm", -- [VSIR_DATA_OPAQUE ] = "opaque", -- [VSIR_DATA_MIXED ] = "mixed", -- [VSIR_DATA_CONTINUED] = "", -- [VSIR_DATA_UNUSED ] = "", -- }; -+ const char *name; - -- if (type < ARRAY_SIZE(data_type_names)) -- vkd3d_string_buffer_printf(&compiler->buffer, "%s", data_type_names[type]); -+ if ((name = vsir_data_type_get_name(type, NULL))) -+ vkd3d_string_buffer_printf(&compiler->buffer, "%s", name); - else - vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", - compiler->colours.error, type, compiler->colours.reset); -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index b6e5f4f2cf3..df1333f55a6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -1184,8 +1184,8 @@ struct hlsl_ctx - } constant_defs; - /* 'c' registers where the constants expected by SM2 sincos are stored. */ - struct hlsl_reg d3dsincosconst1, d3dsincosconst2; -- /* Number of allocated SSA IDs, used in translation to vsir. */ -- unsigned int ssa_count; -+ /* Number of allocated SSA and temp IDs, used in translation to vsir. */ -+ unsigned int ssa_count, temp_count; - - /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in - * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 8e3ed0a1b8d..5d413c43374 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -5905,6 +5905,9 @@ static void mark_vars_usage(struct hlsl_ctx *ctx) - - struct register_allocator - { -+ /* Type of registers we are allocating (not counting indexable temps). */ -+ enum vkd3d_shader_register_type type; -+ - struct allocation - { - uint32_t reg; -@@ -6019,7 +6022,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a - unsigned int writemask = hlsl_combine_writemasks(available_writemask, - vkd3d_write_mask_from_component_count(reg_size)); - -- ret.type = VKD3DSPR_TEMP; -+ ret.type = allocator->type; - ret.id = reg_idx; - ret.writemask = hlsl_combine_writemasks(writemask, - vkd3d_write_mask_from_component_count(component_count)); -@@ -6030,7 +6033,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a - } - } - -- ret.type = VKD3DSPR_TEMP; -+ ret.type = allocator->type; - ret.id = allocator->reg_count; - ret.writemask = vkd3d_write_mask_from_component_count(component_count); - record_allocation(ctx, allocator, allocator->reg_count, -@@ -6103,7 +6106,7 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo - record_allocation(ctx, allocator, reg_idx + (reg_size / 4), - (1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip); - -- ret.type = VKD3DSPR_TEMP; -+ ret.type = allocator->type; - ret.id = reg_idx; - ret.allocation_size = align(reg_size, 4) / 4; - ret.allocated = true; -@@ -6114,14 +6117,18 @@ static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, - unsigned int first_write, unsigned int last_read, const struct hlsl_type *type) - { - unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; -+ struct hlsl_reg ret; - - /* FIXME: We could potentially pack structs or arrays more efficiently... */ - - if (type->class <= HLSL_CLASS_VECTOR) -- return allocate_register(ctx, allocator, first_write, last_read, -+ ret = allocate_register(ctx, allocator, first_write, last_read, - type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); - else -- return allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); -+ ret = allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); -+ if (allocator->type == VKD3DSPR_TEMP) -+ ctx->temp_count = max(ctx->temp_count, ret.id + ret.allocation_size); -+ return ret; - } - - static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) -@@ -6329,11 +6336,21 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); - - if (reg_writemask) -+ { - instr->reg = allocate_register_with_masks(ctx, allocator, - instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false); -+ ctx->temp_count = max(ctx->temp_count, instr->reg.id + 1); -+ } - else if (is_per_component) -- instr->reg = allocate_numeric_registers_for_type(ctx, allocator, -- instr->index, instr->last_read, instr->data_type); -+ { -+ instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); -+ instr->reg.allocation_size = 1; -+ instr->reg.allocated = true; -+ instr->reg.type = VKD3DSPR_TEMP; -+ instr->reg.id = ctx->temp_count++; -+ -+ record_allocation(ctx, allocator, ctx->temp_count - 1, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); -+ } - else - { - instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); -@@ -6350,24 +6367,35 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - static void allocate_variable_temp_register(struct hlsl_ctx *ctx, - struct hlsl_ir_var *var, struct register_allocator *allocator) - { -+ struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; -+ - if (var->is_input_semantic || var->is_output_semantic || var->is_uniform) - return; - -- if (!var->regs[HLSL_REGSET_NUMERIC].allocated && var->last_read) -+ if (!reg->allocated && var->last_read) - { - if (var->indexable) - { -- var->regs[HLSL_REGSET_NUMERIC].id = allocator->indexable_count++; -- var->regs[HLSL_REGSET_NUMERIC].allocation_size = 1; -- var->regs[HLSL_REGSET_NUMERIC].writemask = 0; -- var->regs[HLSL_REGSET_NUMERIC].allocated = true; -+ reg->id = allocator->indexable_count++; -+ reg->allocation_size = 1; -+ reg->writemask = 0; -+ reg->allocated = true; - -- TRACE("Allocated %s to x%u[].\n", var->name, var->regs[HLSL_REGSET_NUMERIC].id); -+ TRACE("Allocated %s to x%u[].\n", var->name, reg->id); - } - else - { -- var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator, -- var->first_write, var->last_read, var->data_type); -+ reg->type = VKD3DSPR_TEMP; -+ reg->id = ctx->temp_count; -+ reg->allocation_size = align(var->data_type->reg_size[HLSL_REGSET_NUMERIC], 4) / 4; -+ if (var->data_type->class <= HLSL_CLASS_VECTOR) -+ reg->writemask = vkd3d_write_mask_from_component_count(var->data_type->e.numeric.dimx); -+ reg->allocated = true; -+ -+ for (unsigned int i = 0; i < reg->allocation_size; ++i) -+ record_allocation(ctx, allocator, ctx->temp_count + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); -+ -+ ctx->temp_count += reg->allocation_size; - - TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, - debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); -@@ -6553,7 +6581,6 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, - } - - constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -- constant->reg.type = VKD3DSPR_CONST; - TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type)); - - for (unsigned int x = 0, i = 0; x < 4; ++x) -@@ -6651,7 +6678,6 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl - type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); - - ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -- ctx->d3dsincosconst1.type = VKD3DSPR_CONST; - TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type)); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc); -@@ -6659,7 +6685,6 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 3, 2.60416680e-04f, &instr->loc); - - ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -- ctx->d3dsincosconst2.type = VKD3DSPR_CONST; - TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type)); - record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc); -@@ -6673,8 +6698,7 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl - - static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *body) - { -- struct register_allocator allocator_used = {0}; -- struct register_allocator allocator = {0}; -+ struct register_allocator allocator = {.type = VKD3DSPR_CONST}, allocator_used = {.type = VKD3DSPR_CONST}; - struct hlsl_ir_var *var; - - sort_uniforms_by_bind_count(ctx, HLSL_REGSET_NUMERIC); -@@ -6730,7 +6754,6 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo - if (!var->regs[HLSL_REGSET_NUMERIC].allocated) - { - var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false); -- var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; - TRACE("Allocated %s to %s.\n", var->name, - debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); - } -@@ -6747,9 +6770,9 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo - * index to all (simultaneously live) variables or intermediate values. Agnostic - * as to how many registers are actually available for the current backend, and - * does not handle constants. */ --static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) -+static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) - { -- struct register_allocator allocator = {0}; -+ struct register_allocator allocator = {.type = VKD3DSPR_TEMP}; - struct hlsl_scope *scope; - struct hlsl_ir_var *var; - -@@ -6772,6 +6795,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block - { - record_allocation(ctx, &allocator, 0, VKD3DSP_WRITEMASK_ALL, - var->first_write, UINT_MAX, 0, false); -+ ctx->temp_count = 1; - break; - } - } -@@ -6779,16 +6803,6 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block - - allocate_temp_registers_recurse(ctx, body, &allocator); - vkd3d_free(allocator.allocations); -- -- if (allocator.indexable_count) -- TRACE("Declaration of %s function required %u temp registers, and %u indexable temps.\n", -- ctx->is_patch_constant_func ? "patch constant" : "main", -- allocator.reg_count, allocator.indexable_count); -- else -- TRACE("Declaration of %s function required %u temp registers.\n", -- ctx->is_patch_constant_func ? "patch constant" : "main", allocator.reg_count); -- -- return allocator.reg_count; - } - - static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, -@@ -6929,7 +6943,6 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var - - var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, - reg_size, component_count, mode, var->force_align, vip_allocation); -- var->regs[HLSL_REGSET_NUMERIC].type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; - - TRACE("Allocated %s to %s (mode %d).\n", var->name, - debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); -@@ -6944,11 +6957,17 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *seman - bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; - struct hlsl_ir_var *var; - -+ in_prim_allocator.type = VKD3DSPR_INPUT; - in_prim_allocator.prioritize_smaller_writemasks = true; -+ patch_constant_out_patch_allocator.type = VKD3DSPR_INPUT; - patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; -+ input_allocator.type = VKD3DSPR_INPUT; - input_allocator.prioritize_smaller_writemasks = true; - for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) -+ { -+ output_allocators[i].type = VKD3DSPR_OUTPUT; - output_allocators[i].prioritize_smaller_writemasks = true; -+ } - - LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) - { -@@ -10210,7 +10229,8 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - struct hlsl_block block; - - program->ssa_count = 0; -- program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); -+ program->temp_count = 0; -+ allocate_temp_registers(ctx, body, semantic_vars); - if (ctx->result) - return; - -@@ -10222,6 +10242,7 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co - sm1_generate_vsir_block(ctx, body, program); - - program->ssa_count = ctx->ssa_count; -+ program->temp_count = ctx->temp_count; - - if (ctx->result) - return; -@@ -12370,16 +12391,15 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se - struct hlsl_block block = {0}; - struct hlsl_scope *scope; - struct hlsl_ir_var *var; -- uint32_t temp_count; - - ctx->is_patch_constant_func = func == ctx->patch_constant_func; - - compute_liveness(ctx, body); - mark_indexable_vars(ctx, body); -- temp_count = allocate_temp_registers(ctx, body, semantic_vars); -+ allocate_temp_registers(ctx, body, semantic_vars); - if (ctx->result) - return; -- program->temp_count = max(program->temp_count, temp_count); -+ program->temp_count = max(program->temp_count, ctx->temp_count); - - hlsl_block_init(&block); - -@@ -12390,8 +12410,8 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se - sm4_generate_vsir_instr_dcl_semantic(ctx, program, var, &block, &var->loc); - } - -- if (temp_count) -- sm4_generate_vsir_instr_dcl_temps(ctx, program, temp_count, &block, &func->loc); -+ if (ctx->temp_count) -+ sm4_generate_vsir_instr_dcl_temps(ctx, program, ctx->temp_count, &block, &func->loc); - - LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) - { -@@ -13061,6 +13081,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - } - - program->ssa_count = 0; -+ program->temp_count = 0; - - if (version->type == VKD3D_SHADER_TYPE_HULL) - generate_vsir_add_program_instruction(ctx, program, -@@ -13078,6 +13099,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, - generate_vsir_scan_global_flags(ctx, program, semantic_vars, func); - - program->ssa_count = ctx->ssa_count; -+ program->temp_count = ctx->temp_count; - } - - /* For some reason, for matrices, values from default value initializers end -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 1ab406a9d84..b120801d5f9 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -45,6 +45,33 @@ static void vsir_transformation_context_init(struct vsir_transformation_context - }; - }; - -+const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error) -+{ -+ static const char * const names[] = -+ { -+ [VSIR_DATA_BOOL ] = "bool", -+ [VSIR_DATA_F16 ] = "half", -+ [VSIR_DATA_F32 ] = "float", -+ [VSIR_DATA_F64 ] = "double", -+ [VSIR_DATA_I32 ] = "int", -+ [VSIR_DATA_U8 ] = "uint8", -+ [VSIR_DATA_U16 ] = "uint16", -+ [VSIR_DATA_U32 ] = "uint", -+ [VSIR_DATA_U64 ] = "uint64", -+ [VSIR_DATA_SNORM ] = "snorm", -+ [VSIR_DATA_UNORM ] = "unorm", -+ [VSIR_DATA_OPAQUE ] = "opaque", -+ [VSIR_DATA_MIXED ] = "mixed", -+ [VSIR_DATA_CONTINUED] = "", -+ [VSIR_DATA_UNUSED ] = "", -+ }; -+ -+ if ((size_t)t < ARRAY_SIZE(names)) -+ return names[t] ? names[t] : error; -+ -+ return error; -+} -+ - const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) - { - static const char * const names[] = -@@ -8428,7 +8455,7 @@ struct liveness_tracker - bool fixed_mask; - uint8_t mask; - unsigned int first_write, last_access; -- } *ssa_regs; -+ } *ssa_regs, *temp_regs; - }; - - static void liveness_track_src(struct liveness_tracker *tracker, -@@ -8442,6 +8469,8 @@ static void liveness_track_src(struct liveness_tracker *tracker, - - if (src->reg.type == VKD3DSPR_SSA) - tracker->ssa_regs[src->reg.idx[0].offset].last_access = index; -+ else if (src->reg.type == VKD3DSPR_TEMP) -+ tracker->temp_regs[src->reg.idx[0].offset].last_access = index; - } - - static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst, -@@ -8457,6 +8486,8 @@ static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_sh - - if (dst->reg.type == VKD3DSPR_SSA) - reg = &tracker->ssa_regs[dst->reg.idx[0].offset]; -+ else if (dst->reg.type == VKD3DSPR_TEMP) -+ reg = &tracker->temp_regs[dst->reg.idx[0].offset]; - else - return; - -@@ -8552,9 +8583,10 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv - - memset(tracker, 0, sizeof(*tracker)); - -- if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) -+ if (!(regs = vkd3d_calloc(program->ssa_count + program->temp_count, sizeof(*regs)))) - return VKD3D_ERROR_OUT_OF_MEMORY; - tracker->ssa_regs = regs; -+ tracker->temp_regs = ®s[program->ssa_count]; - - for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) - { -@@ -8583,8 +8615,7 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv - * should be illegal for an SSA value to be read in a block - * containing L.) - * We don't try to perform this optimization yet, in the name of -- * maximal simplicity, and also because this code is intended to -- * be extended to non-SSA values. */ -+ * maximal simplicity. */ - for (unsigned int j = 0; j < program->ssa_count; ++j) - { - struct liveness_tracker_reg *reg = &tracker->ssa_regs[j]; -@@ -8594,6 +8625,16 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv - if (reg->last_access < i) - reg->last_access = i; - } -+ -+ for (unsigned int j = 0; j < program->temp_count; ++j) -+ { -+ struct liveness_tracker_reg *reg = &tracker->temp_regs[j]; -+ -+ if (reg->first_write > loop_start) -+ reg->first_write = loop_start; -+ if (reg->last_access < i) -+ reg->last_access = i; -+ } - } - } - -@@ -8613,8 +8654,8 @@ struct temp_allocator - { - uint8_t allocated_mask; - uint32_t temp_id; -- } *ssa_regs; -- size_t allocated_ssa_count; -+ } *ssa_regs, *temp_regs; -+ size_t allocated_ssa_count, allocated_temp_count; - enum vkd3d_result result; - }; - -@@ -8641,16 +8682,30 @@ static uint8_t get_available_writemask(const struct temp_allocator *allocator, - return writemask; - } - -+ for (size_t i = 0; i < allocator->allocated_temp_count; ++i) -+ { -+ const struct temp_allocator_reg *reg = &allocator->temp_regs[i]; -+ const struct liveness_tracker_reg *liveness_reg = &tracker->temp_regs[i]; -+ -+ if (reg->temp_id == temp_id -+ && first_write < liveness_reg->last_access -+ && last_access > liveness_reg->first_write) -+ writemask &= ~reg->allocated_mask; -+ -+ if (!writemask) -+ return writemask; -+ } -+ - return writemask; - } - - static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker, -- struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg, uint32_t base_id) -+ struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg) - { - if (!liveness_reg->written) - return false; - -- for (uint32_t id = base_id;; ++id) -+ for (uint32_t id = 0;; ++id) - { - uint8_t available_mask = get_available_writemask(allocator, tracker, - liveness_reg->first_write, liveness_reg->last_access, id); -@@ -8667,13 +8722,21 @@ static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liv - else - { - /* For SSA values the mask is always zero-based and contiguous. -- * We don't correctly handle cases where it's not, currently. */ -- VKD3D_ASSERT((liveness_reg->mask | (liveness_reg->mask - 1)) == liveness_reg->mask); -- -- if (vkd3d_popcount(available_mask) >= vkd3d_popcount(liveness_reg->mask)) -+ * For TEMP values we assume the register was allocated that way, -+ * but it may only be partially used. -+ * We currently only handle cases where the mask is zero-based and -+ * contiguous, so we need to fill in the missing components to -+ * ensure this. */ -+ uint8_t mask = (1u << (vkd3d_log2i(liveness_reg->mask) + 1)) - 1; -+ -+ if (vkd3d_popcount(available_mask) >= vkd3d_popcount(mask)) - { -+ if (mask != liveness_reg->mask) -+ WARN("Allocating a mask %#x with used components %#x; this is not optimized.\n", -+ mask, liveness_reg->mask); -+ - reg->temp_id = id; -- reg->allocated_mask = vsir_combine_write_masks(available_mask, liveness_reg->mask); -+ reg->allocated_mask = vsir_combine_write_masks(available_mask, mask); - return true; - } - } -@@ -8692,6 +8755,8 @@ static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3 - - if (src->reg.type == VKD3DSPR_SSA) - reg = &allocator->ssa_regs[src->reg.idx[0].offset]; -+ else if (src->reg.type == VKD3DSPR_TEMP) -+ reg = &allocator->temp_regs[src->reg.idx[0].offset]; - else - return; - -@@ -8771,6 +8836,7 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, - struct vkd3d_shader_dst_param *dst, const struct vkd3d_shader_instruction *ins) - { - struct temp_allocator_reg *reg; -+ uint32_t remapped_mask; - - for (unsigned int k = 0; k < dst->reg.idx_count; ++k) - { -@@ -8780,15 +8846,18 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, - - if (dst->reg.type == VKD3DSPR_SSA) - reg = &allocator->ssa_regs[dst->reg.idx[0].offset]; -+ else if (dst->reg.type == VKD3DSPR_TEMP) -+ reg = &allocator->temp_regs[dst->reg.idx[0].offset]; - else - return; - - dst->reg.type = VKD3DSPR_TEMP; - dst->reg.dimension = VSIR_DIMENSION_VEC4; - dst->reg.idx[0].offset = reg->temp_id; -- if (reg->allocated_mask != dst->write_mask) -+ remapped_mask = vsir_combine_write_masks(reg->allocated_mask, dst->write_mask); -+ if (dst->write_mask != remapped_mask) - { -- dst->write_mask = reg->allocated_mask; -+ dst->write_mask = remapped_mask; - - if (vsir_opcode_is_double(ins->opcode)) - { -@@ -8804,16 +8873,32 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, - if (vsir_src_is_masked(ins->opcode, i)) - { - if (src->reg.type == VKD3DSPR_IMMCONST) -- vsir_remap_immconst(src, dst->write_mask); -+ vsir_remap_immconst(src, reg->allocated_mask); - else if (src->reg.type == VKD3DSPR_IMMCONST64) -- vsir_remap_immconst64(src, dst->write_mask); -+ vsir_remap_immconst64(src, reg->allocated_mask); - else -- src->swizzle = vsir_map_swizzle(src->swizzle, dst->write_mask); -+ src->swizzle = vsir_map_swizzle(src->swizzle, reg->allocated_mask); - } - } - } - } - -+/* This pass does two things: -+ * -+ * - converts SSA registers (sr#) into temp registers (r#); -+ * -+ * - contracts temp registers with non-overlapping ranges by reallocating them -+ * into the same register. -+ * -+ * These are done at the same time so that SSA and temp registers with -+ * non-overlapping liveness can share the same register. -+ * -+ * The temp contraction is not particularly sophisticated. In particular, it -+ * does not detect cases where a single temp register has multiple disjoint -+ * ranges of liveness, and it also assumes that the components used by a single -+ * registers is zero-based and contiguous. -+ * The intent for temp contraction is that HLSL will output each distinct -+ * variable to a unique temp ID. */ - enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context) - { -@@ -8825,28 +8910,53 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, - struct liveness_tracker tracker; - enum vkd3d_result ret; - -- if (!program->ssa_count) -+ if (!program->ssa_count && !prev_temp_count) - return VKD3D_OK; - - if ((ret = track_liveness(program, &tracker))) - return ret; - -- if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) -+ if (!(regs = vkd3d_calloc(program->ssa_count + prev_temp_count, sizeof(*regs)))) - { - liveness_tracker_cleanup(&tracker); - return VKD3D_ERROR_OUT_OF_MEMORY; - } - allocator.message_context = message_context; - allocator.ssa_regs = regs; -+ allocator.temp_regs = regs + program->ssa_count; -+ -+ program->temp_count = 0; -+ -+ /* Reallocate temps first. We do this specifically to make sure that r0 is -+ * the first register to be allocated, and thus will be reallocated in -+ * place, and left alone. -+ * This is necessary because, in pixel shader model 1.x, r0 doubles as the -+ * output register, and needs to remain at r0. (Note that we need to already -+ * have the output in r0, rather than e.g. putting it in o0 and converting -+ * it to r0 after this pass, so that we know when r0 is live.) */ -+ for (unsigned int i = 0; i < prev_temp_count; ++i) -+ { -+ const struct liveness_tracker_reg *liveness_reg = &tracker.temp_regs[i]; -+ struct temp_allocator_reg *reg = &allocator.temp_regs[i]; -+ -+ if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg)) -+ { -+ TRACE("Reallocated r%u%s for r%u (liveness %u-%u).\n", -+ reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, -+ liveness_reg->first_write, liveness_reg->last_access); -+ program->temp_count = max(program->temp_count, reg->temp_id + 1); -+ } -+ ++allocator.allocated_temp_count; -+ } - - for (unsigned int i = 0; i < program->ssa_count; ++i) - { - const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i]; - struct temp_allocator_reg *reg = &allocator.ssa_regs[i]; - -- if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count)) -+ if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg)) - { -- TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n", -+ TRACE("Allocated r%u%s for sr%u (liveness %u-%u).\n", - reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, - liveness_reg->first_write, liveness_reg->last_access); - program->temp_count = max(program->temp_count, reg->temp_id + 1); -@@ -9441,7 +9551,8 @@ static void vsir_validate_label_register(struct validation_context *ctx, - - if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for a LABEL register.", reg->data_type); -+ "Invalid data type \"%s\" (%#x) for a LABEL register.", -+ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); - - if (reg->dimension != VSIR_DIMENSION_NONE) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, -@@ -9520,7 +9631,8 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, - - if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for a SAMPLER register.", reg->data_type); -+ "Invalid data type \"%s\" (%#x) for a SAMPLER register.", -+ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); - - /* VEC4 is allowed in gather operations. */ - if (reg->dimension == VSIR_DIMENSION_SCALAR) -@@ -9546,7 +9658,8 @@ static void vsir_validate_resource_register(struct validation_context *ctx, - - if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for a RESOURCE register.", reg->data_type); -+ "Invalid data type \"%s\" (%#x) for a RESOURCE register.", -+ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); - - if (reg->dimension != VSIR_DIMENSION_VEC4) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, -@@ -9572,8 +9685,8 @@ static void vsir_validate_uav_register(struct validation_context *ctx, - - if (reg->data_type != VSIR_DATA_UNUSED) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for a UAV register.", -- reg->data_type); -+ "Invalid data type \"%s\" (%#x) for a UAV register.", -+ vsir_data_type_get_name(reg->data_type, ""), reg->data_type); - - /* NONE is allowed in counter operations. */ - if (reg->dimension == VSIR_DIMENSION_SCALAR) -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index a57c42b167d..058a631f25e 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -2518,7 +2518,7 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build - GLSLstd450NClamp, operands, ARRAY_SIZE(operands)); - } - --static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, -+static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder *builder, - enum vkd3d_shader_component_type component_type, unsigned int component_count) - { - uint32_t scalar_id, type_id; -@@ -2564,7 +2564,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, - else - { - VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); -- scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ scalar_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); - } - -@@ -2573,13 +2573,13 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, - return type_id; - } - --static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, -+static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, - enum vsir_data_type data_type, unsigned int component_count) - { - enum vkd3d_shader_component_type component_type; - - component_type = vkd3d_component_type_from_data_type(data_type); -- return vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ return spirv_get_type_id_for_component_type(builder, component_type, component_count); - } - - static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, -@@ -3656,7 +3656,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, - unsigned int i; - - VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_VEC4_SIZE); -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - - switch (component_type) - { -@@ -3683,7 +3683,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, - } - else - { -- scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ scalar_type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - for (i = 0; i < component_count; ++i) - component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, values[i]); - return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count); -@@ -3698,7 +3698,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, - unsigned int i; - - VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - - if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64) - { -@@ -3712,7 +3712,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, - } - else - { -- scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ scalar_type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - for (i = 0; i < component_count; ++i) - component_ids[i] = vkd3d_spirv_get_op_constant64(builder, scalar_type_id, values[i]); - return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count); -@@ -3772,9 +3772,7 @@ static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compil - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - -- return vkd3d_spirv_get_type_id(builder, -- vkd3d_component_type_from_data_type(reg->data_type), -- vsir_write_mask_component_count(write_mask)); -+ return spirv_get_type_id(builder, reg->data_type, vsir_write_mask_component_count(write_mask)); - } - - static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler, -@@ -3901,7 +3899,7 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil - uint32_t type_id, length_id, ptr_type_id; - unsigned int i; - -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - for (i = 0; i < length_count; ++i) - { - if (!array_lengths[i]) -@@ -4000,8 +3998,8 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile - info = get_spec_constant_info(name); - default_value = info ? info->default_value.u : 0; - -- scalar_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1); -- vector_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); -+ scalar_type_id = spirv_get_type_id(builder, type, 1); -+ vector_type_id = spirv_get_type_id(builder, type, component_count); - - for (unsigned int i = 0; i < component_count; ++i) - { -@@ -4050,7 +4048,7 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi - unsigned int index = parameter - compiler->program->parameters; - uint32_t type_id, ptr_id, ptr_type_id; - -- type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); -+ type_id = spirv_get_type_id(builder, type, component_count); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, - compiler->spirv_parameter_info[index].buffer_id, -@@ -4114,7 +4112,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp - - VKD3D_ASSERT(val_component_idx < val_component_count); - -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - if (val_component_count == 1) - { - for (i = 0; i < component_count; ++i) -@@ -4147,7 +4145,7 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c - addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); - if (reg_index->offset) - { -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, - addr_id, spirv_compiler_get_constant_uint(compiler, reg_index->offset)); - } -@@ -4296,7 +4294,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2]; - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) - { - index_ids[0] = compiler->descriptor_offsets_member_id; -@@ -4369,7 +4367,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp - if (index_count) - { - component_count = vsir_write_mask_component_count(register_info->write_mask); -- type_id = vkd3d_spirv_get_type_id(builder, register_info->component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, register_info->component_type, component_count); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id); - register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, - register_info->id, indexes, index_count); -@@ -4428,7 +4426,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, - && (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask))) - return val_id; - -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - - if (component_count == 1) - { -@@ -4479,7 +4477,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil - components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i); - } - -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - return vkd3d_spirv_build_op_vector_shuffle(builder, - type_id, vector1_id, vector2_id, components, component_count); - } -@@ -4494,7 +4492,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - - VKD3D_ASSERT(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); - op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; - return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, - data_type == VSIR_DATA_U64 -@@ -4510,7 +4508,7 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, - - true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); - false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -@@ -4523,7 +4521,7 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile - true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, - component_count); - false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -@@ -4535,7 +4533,7 @@ static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compile - - true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); - false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -@@ -4547,7 +4545,7 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil - - true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); - false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -@@ -4614,7 +4612,8 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, - - VKD3D_ASSERT(reg->type == VKD3DSPR_UNDEF); - -- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count); -+ type_id = spirv_get_type_id(builder, reg->data_type, component_count); -+ - return vkd3d_spirv_get_op_undef(builder, type_id); - } - -@@ -4646,7 +4645,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, - component_idx, reg->type, reg->idx[0].offset, reg_info->write_mask); - } - -- type_id = vkd3d_spirv_get_type_id(builder, reg_info->component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, reg_info->component_type, 1); - reg_id = reg_info->id; - if (reg_component_count != 1) - { -@@ -4663,7 +4662,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, - { - if (reg_info->component_type != VKD3D_SHADER_COMPONENT_UINT) - { -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - val_id = spirv_compiler_emit_int_to_bool(compiler, -@@ -4671,7 +4670,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, - } - else - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - } -@@ -4691,7 +4690,7 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil - - component_type = vkd3d_component_type_from_data_type(icb->data_type); - component_count = icb->component_count; -- elem_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, icb->data_type, component_count); -+ elem_type_id = spirv_get_type_id(builder, icb->data_type, component_count); - length_id = spirv_compiler_get_constant_uint(compiler, element_count); - type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id); - -@@ -4777,7 +4776,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - - if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - return vkd3d_spirv_get_op_undef(builder, type_id); - } - spirv_compiler_emit_dereference_register(compiler, reg, ®_info); -@@ -4796,7 +4795,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - } - else - { -- type_id = vkd3d_spirv_get_type_id(builder, -+ type_id = spirv_get_type_id_for_component_type(builder, - reg_info.component_type, vsir_write_mask_component_count(reg_info.write_mask)); - val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); - swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; -@@ -4811,7 +4810,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - { - if (reg_info.component_type != VKD3D_SHADER_COMPONENT_UINT) - { -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - val_id = spirv_compiler_emit_int_to_bool(compiler, -@@ -4819,7 +4818,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, - } - else - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - } -@@ -4923,7 +4922,7 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, - - if (vsir_write_mask_component_count(dst_write_mask) > 1) - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); - component_idx = vsir_write_mask_get_component_idx(write_mask); - component_idx -= vsir_write_mask_get_component_idx(dst_write_mask); -@@ -4951,7 +4950,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, - - if (dst_component_count == 1 && component_count != 1) - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, - vsir_write_mask_get_component_idx(dst_write_mask)); - write_mask &= dst_write_mask; -@@ -4966,7 +4965,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, - - if (dst_component_count != component_count) - { -- type_id = vkd3d_spirv_get_type_id(builder, component_type, dst_component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, dst_component_count); - dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); - - VKD3D_ASSERT(component_count <= ARRAY_SIZE(components)); -@@ -5018,7 +5017,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, - if (component_type == VKD3D_SHADER_COMPONENT_BOOL) - val_id = spirv_compiler_emit_bool_to_int(compiler, - vsir_write_mask_component_count(src_write_mask), val_id, false); -- type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, -+ type_id = spirv_get_type_id_for_component_type(builder, reg_info.component_type, - vsir_write_mask_component_count(src_write_mask)); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - component_type = reg_info.component_type; -@@ -5101,7 +5100,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, dst_type_id, val_id; - -- type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - if (component_count > 1) - { - val_id = vkd3d_spirv_build_op_composite_construct(builder, -@@ -5112,7 +5111,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp - val_id = *component_ids; - } - -- dst_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); -+ dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); - if (dst_type_id != type_id) - val_id = vkd3d_spirv_build_op_bitcast(builder, dst_type_id, val_id); - -@@ -5281,7 +5280,7 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * - vkd3d_spirv_add_iface_variable(builder, base_var_id); - spirv_compiler_decorate_builtin(compiler, base_var_id, base); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_INT, 1); - base_id = vkd3d_spirv_build_op_load(builder, - type_id, base_var_id, SpvMemoryAccessMaskNone); - -@@ -5317,11 +5316,11 @@ static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, w_id; - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); - w_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, frag_coord_id, 3); - w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, - spirv_compiler_get_constant_float(compiler, 1.0f), w_id); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - return vkd3d_spirv_build_op_composite_insert1(builder, type_id, w_id, frag_coord_id, 3); - } - -@@ -5527,7 +5526,7 @@ static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *co - uint32_t type_id, id; - - id = spirv_compiler_get_invocation_id(compiler); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_INT, 1); - return vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); - } - -@@ -5867,7 +5866,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - vsir_register_init(&dst_reg, reg_type, VSIR_DATA_F32, 1); - dst_reg.idx[0].offset = element_idx; - -- type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, input_component_count); - - val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone); - -@@ -5876,7 +5875,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, - - if (component_type != VKD3D_SHADER_COMPONENT_FLOAT) - { -- float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, input_component_count); -+ float_type_id = spirv_get_type_id_for_component_type(builder, -+ VKD3D_SHADER_COMPONENT_FLOAT, input_component_count); - val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id); - } - -@@ -6225,7 +6225,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - - if (output_info->component_type != VKD3D_SHADER_COMPONENT_FLOAT) - { -- type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - -@@ -6250,7 +6250,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - output_id = output_info->id; - if (output_index_id) - { -- type_id = vkd3d_spirv_get_type_id(builder, -+ type_id = spirv_get_type_id_for_component_type(builder, - output_info->component_type, vsir_write_mask_component_count(dst_write_mask)); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); - output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id); -@@ -6263,7 +6263,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi - return; - } - -- type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); - mask = output_info->array_element_mask; - array_idx = spirv_compiler_get_output_array_index(compiler, output); -@@ -6305,7 +6305,7 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler * - function_id = compiler->epilogue_function_id; - - void_id = vkd3d_spirv_get_op_type_void(builder); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); - for (i = 0, count = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i) - { -@@ -6536,7 +6536,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil - vkd3d_spirv_begin_function_stream_insertion(builder, function_location); - - component_type = vkd3d_component_type_from_data_type(temp->data_type); -- type_id = vkd3d_spirv_get_type_id(builder, component_type, temp->component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, temp->component_count); - length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size); - type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); -@@ -6577,7 +6577,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com - if (!(member_ids = vkd3d_calloc(count, sizeof(*member_ids)))) - return; - -- vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ vec4_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - - for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) - { -@@ -6594,7 +6594,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com - - if (compiler->offset_info.descriptor_table_count) - { -- uint32_t type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ uint32_t type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - length_id = spirv_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count); - member_ids[j] = vkd3d_spirv_build_op_type_array(builder, type_id, length_id); - vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4); -@@ -6788,7 +6788,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, - return; - } - -- vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ vec4_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - length_id = spirv_compiler_get_constant_uint(compiler, size); - array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); - vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16); -@@ -6927,7 +6927,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler - vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); - } - -- sampled_type_id = vkd3d_spirv_get_type_id(builder, data_type, 1); -+ sampled_type_id = spirv_get_type_id_for_component_type(builder, data_type, 1); - return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, - 2, resource_type_info->arrayed, resource_type_info->ms, - reg->type == VKD3DSPR_UAV ? 2 : 1, format); -@@ -7053,7 +7053,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - { - uint32_t array_type_id, struct_id; - -- type_id = vkd3d_spirv_get_type_id(builder, sampled_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, sampled_type, 1); - - array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); - vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); -@@ -7094,7 +7094,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp - { - VKD3D_ASSERT(structure_stride); /* counters are valid only for structured buffers */ - -- counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ counter_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - if (spirv_compiler_is_opengl_target(compiler)) - { - vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage); -@@ -7158,7 +7158,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler - if (alignment) - TRACE("Ignoring alignment %u.\n", alignment); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - length_id = spirv_compiler_get_constant_uint(compiler, size); - array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); - -@@ -7878,7 +7878,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp - component_count = vsir_write_mask_component_count(dst->write_mask); - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT32_MAX, component_count); - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpIEqual, -- vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), val_id, uint_max_id); -+ spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), -+ val_id, uint_max_id); - rev_val_id = vkd3d_spirv_build_op_isub(builder, type_id, - spirv_compiler_get_constant_uint_vector(compiler, 31, component_count), val_id); - val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, rev_val_id); -@@ -7928,7 +7929,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, - dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); - src_id = spirv_compiler_get_register_id(compiler, &src->reg); - -- type_id = vkd3d_spirv_get_type_id(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone); - dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); - -@@ -7957,7 +7958,7 @@ general_implementation: - val_id = spirv_compiler_emit_load_src(compiler, src, write_mask); - if (dst->reg.data_type != src->reg.data_type) - { -- val_id = vkd3d_spirv_build_op_bitcast(builder, vkd3d_spirv_get_type_id_for_data_type(builder, -+ val_id = vkd3d_spirv_build_op_bitcast(builder, spirv_get_type_id(builder, - dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)), val_id); - } - spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -7983,8 +7984,8 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, - { - if (instruction->opcode == VSIR_OP_CMP) - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, -- vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), condition_id, -- spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); -+ spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), -+ condition_id, spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); - else - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); -@@ -8010,7 +8011,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, - src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); - - component_count = vsir_write_mask_component_count(dst->write_mask); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); - - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); -@@ -8046,7 +8047,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, - for (i = 0; i < ARRAY_SIZE(src_ids); ++i) - src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); - -- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - - val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpDot, type_id, src_ids[0], src_ids[1]); -@@ -8092,7 +8093,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, - unsigned int i, component_count; - - component_count = vsir_write_mask_component_count(dst->write_mask); -- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); - - for (i = 0; i < ARRAY_SIZE(src_ids); ++i) - src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); -@@ -8146,7 +8147,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, - component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); - - int_max_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, INT_MAX); -- condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); - -@@ -8199,7 +8200,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, - val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); - - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); -- condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); - condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); - -@@ -8224,7 +8225,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, - - src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); - val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id); - if (instruction->flags & VKD3DSI_PRECISE_XYZW) - vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); -@@ -8248,7 +8249,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); - - component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); -- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20; - mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); - size_id = spirv_compiler_get_constant_uint(compiler, size); -@@ -8305,8 +8306,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, - unsigned int i, j; - - instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -- scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -+ scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); - - /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ - VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); -@@ -8338,8 +8339,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, - unsigned int i, j; - - instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -- scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -+ scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - zero_id = spirv_compiler_get_constant_float(compiler, 0.0f); - - /* FIXME: Consider a single PackHalf2x16 instruction per 2 components. */ -@@ -8418,7 +8419,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], write_mask); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); - result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, - op, type_id, src0_id, src1_id); - -@@ -8470,7 +8471,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); - result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); - - result_id = spirv_compiler_emit_bool_to_float(compiler, component_count, result_id, false); -@@ -8999,7 +9000,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, - - spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -- type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); - if (image.resource_type_info->resource_type != VKD3D_SHADER_RESOURCE_BUFFER && !multisample) -@@ -9045,7 +9046,7 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, - spirv_compiler_prepare_image(compiler, &image, - &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); - val_id = vkd3d_spirv_build_op_image_query_lod(builder, - type_id, image.sampled_image_id, coordinate_id); -@@ -9115,7 +9116,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, - instruction, image.resource_type_info); - } - -- sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); - VKD3D_ASSERT(image_operand_count <= ARRAY_SIZE(image_operands)); - val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, -@@ -9160,7 +9161,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, - instruction, image.resource_type_info); - } - -- sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); -+ sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, 1); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); - dref_id = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_image_sample_dref(builder, op, sampled_type_id, -@@ -9219,7 +9220,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, - instruction, image.resource_type_info); - } - -- sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, addr, coordinate_mask); - if (image_flags & VKD3D_IMAGE_FLAG_DEPTH) -@@ -9301,10 +9302,10 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler - - if (storage_buffer_uav) - { -- texel_type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ texel_type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, resource_symbol->info.resource.structure_stride, - &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9336,11 +9337,11 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler - - spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - -- texel_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ texel_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); - VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); - for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) - { -@@ -9379,7 +9380,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, - if (!spirv_compiler_get_register_info(compiler, &resource->reg, ®_info)) - return; - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9438,10 +9439,10 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { -- type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, resource_symbol->info.resource.structure_stride, - &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9469,7 +9470,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * - } - else - { -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9512,7 +9513,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, - if (!spirv_compiler_get_register_info(compiler, &dst->reg, ®_info)) - return; - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); - base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, - type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); -@@ -9570,7 +9571,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, - - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { -- type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - indices[0] = spirv_compiler_get_constant_uint(compiler, 0); -@@ -9585,7 +9586,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, - else - { - spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); -- type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); - coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); - -@@ -9613,7 +9614,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, - - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { -- type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - indices[0] = spirv_compiler_get_constant_uint(compiler, 0); -@@ -9658,7 +9659,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c - counter_id = resource_symbol->info.resource.uav_counter_id; - VKD3D_ASSERT(counter_id); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - - if (resource_symbol->info.resource.uav_counter_array) - { -@@ -9820,7 +9821,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - } - } - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - if (structure_stride || raw) - { - VKD3D_ASSERT(!raw != !structure_stride); -@@ -9845,7 +9846,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) - { - component_type = resource_symbol->info.resource.sampled_type; -- type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - operands[0] = spirv_compiler_get_constant_uint(compiler, 0); - operands[1] = coordinate_id; -@@ -9854,7 +9855,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil - else - { - component_type = image.sampled_type; -- type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, 1); - ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id); - sample_id = spirv_compiler_get_constant_uint(compiler, 0); - pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, -@@ -9907,7 +9908,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - { - resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0); - write_mask = VKD3DSP_WRITEMASK_0; - } -@@ -9917,7 +9918,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - - spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); - write_mask = VKD3DSP_WRITEMASK_0; - } -@@ -9927,7 +9928,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, - stride_id = spirv_compiler_get_constant_uint(compiler, image.structure_stride); - constituents[0] = vkd3d_spirv_build_op_udiv(builder, type_id, val_id, stride_id); - constituents[1] = stride_id; -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); - val_id = vkd3d_spirv_build_op_composite_construct(builder, - type_id, constituents, ARRAY_SIZE(constituents)); - write_mask |= VKD3DSP_WRITEMASK_1; -@@ -9966,14 +9967,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - size_component_count = image.resource_type_info->coordinate_component_count; - if (image.resource_type_info->dim == SpvDimCube) - --size_component_count; -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count); - - supports_mipmaps = src[1].reg.type != VKD3DSPR_UAV && !image.resource_type_info->ms; - if (supports_mipmaps) - { - lod_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_image_query_size_lod(builder, type_id, image.image_id, lod_id); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - miplevel_count_id = vkd3d_spirv_build_op_image_query_levels(builder, type_id, image.image_id); - } - else -@@ -9987,14 +9988,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, - for (i = 0; i < 3 - size_component_count; ++i) - constituents[i + 1] = spirv_compiler_get_constant_uint(compiler, 0); - constituents[i + 1] = miplevel_count_id; -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_composite_construct(builder, - type_id, constituents, i + 2); - - if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) - { - component_type = VKD3D_SHADER_COMPONENT_FLOAT; -- type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); - if (instruction->flags & VKD3DSI_PRECISE_XYZW) - vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); -@@ -10022,7 +10023,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co - vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); - - spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - val_id = vkd3d_spirv_build_op_image_query_samples(builder, type_id, image.image_id); - } - -@@ -10049,13 +10050,13 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, - constituents[0] = val_id; - for (i = 1; i < VKD3D_VEC4_SIZE; ++i) - constituents[i] = spirv_compiler_get_constant_uint(compiler, 0); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); - - if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) - { - component_type = VKD3D_SHADER_COMPONENT_FLOAT; -- type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE); - val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); - if (instruction->flags & VKD3DSI_PRECISE_XYZW) - vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); -@@ -10121,13 +10122,13 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, - sample_count_id = spirv_compiler_emit_query_sample_count(compiler, &instruction->src[0]); - sample_index_id = spirv_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - index_id = vkd3d_spirv_build_op_iadd(builder, type_id, sample_count_id, sample_index_id); - index_id = vkd3d_spirv_build_op_isub(builder, - type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1)); - - /* Validate sample index. */ -- bool_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); -+ bool_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); - id = vkd3d_spirv_build_op_logical_and(builder, bool_id, - vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id), - vkd3d_spirv_build_op_uless_than_equal(builder, -@@ -10135,7 +10136,7 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, - index_id = vkd3d_spirv_build_op_select(builder, type_id, - id, index_id, spirv_compiler_get_constant_uint(compiler, 0)); - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); - if (!(id = compiler->sample_positions_id)) - { - length_id = spirv_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions)); -@@ -10199,7 +10200,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, - src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); - } - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, - vsir_write_mask_component_count(register_info.write_mask)); - - instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); -@@ -10334,9 +10335,8 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, direction_type_id, direction_id, val_id; - -- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, -- vsir_write_mask_component_count(dst->write_mask)); -- direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VSIR_DATA_U32, 1); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); -+ direction_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); - val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - direction_id = map_quad_read_across_direction(instruction->opcode); - direction_id = vkd3d_spirv_get_op_constant(builder, direction_type_id, direction_id); -@@ -10355,14 +10355,12 @@ static void spirv_compiler_emit_quad_read_lane_at(struct spirv_compiler *compile - - if (!register_is_constant_or_undef(&src[1].reg)) - { -- FIXME("Unsupported non-constant quad read lane index.\n"); - spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, - "Non-constant quad read lane indices are not supported."); - return; - } - -- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, -- vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_group_nonuniform_quad_broadcast(builder, type_id, val_id, lane_id); -@@ -10411,7 +10409,7 @@ static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compile - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, val_id; - -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); - val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); - val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id); - -@@ -10470,8 +10468,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, - - op = map_wave_alu_op(instruction->opcode, data_type_is_floating_point(src->reg.data_type)); - -- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, -- vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - - vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformArithmetic); -@@ -10495,7 +10492,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, - : SpvGroupOperationReduce; - - val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); -- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - val_id = vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(builder, type_id, group_op, val_id); - - spirv_compiler_emit_store_dst(compiler, dst, val_id); -@@ -10520,8 +10517,7 @@ static void spirv_compiler_emit_wave_read_lane_at(struct spirv_compiler *compile - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, lane_id, val_id; - -- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, -- vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); - lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); - -@@ -10548,8 +10544,7 @@ static void spirv_compiler_emit_wave_read_lane_first(struct spirv_compiler *comp - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, val_id; - -- type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, -- vsir_write_mask_component_count(dst->write_mask)); -+ type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); - val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - val_id = vkd3d_spirv_build_op_group_nonuniform_broadcast_first(builder, type_id, val_id); - -@@ -11081,7 +11076,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, - { - uint32_t type_id, struct_id, ptr_type_id, var_id; - -- type_id = vkd3d_spirv_get_type_id(builder, -+ type_id = spirv_get_type_id_for_component_type(builder, - vkd3d_component_type_from_data_type(parameter_data_type_map[parameter->data_type].type), - parameter_data_type_map[parameter->data_type].component_count); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 4102fe53e67..698ad541359 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -734,6 +734,8 @@ enum vsir_data_type - VSIR_DATA_TYPE_COUNT, - }; - -+const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error); -+ - static inline bool data_type_is_integer(enum vsir_data_type data_type) - { - return data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 --- -2.51.0 - diff --git a/patches/vkd3d-latest/0007-Updated-vkd3d-to-2aefcf5d99cfb4836c3c6178be74061277b.patch b/patches/vkd3d-latest/0007-Updated-vkd3d-to-2aefcf5d99cfb4836c3c6178be74061277b.patch deleted file mode 100644 index 192a0ce4..00000000 --- a/patches/vkd3d-latest/0007-Updated-vkd3d-to-2aefcf5d99cfb4836c3c6178be74061277b.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 154bd7a2207e5046788c9b5bf9419147fb01b6bb Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 4 Sep 2025 07:55:34 +1000 -Subject: [PATCH] Updated vkd3d to 2aefcf5d99cfb4836c3c6178be74061277b9d15c. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 6 ++--- - libs/vkd3d/libs/vkd3d-shader/dxil.c | 22 ++++++++++--------- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 10 ++++++++- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 2 +- - 4 files changed, 25 insertions(+), 15 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 58135e71f30..897803ecb56 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -834,7 +834,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - && reg->type != VKD3DSPR_NULL - && reg->type != VKD3DSPR_DEPTHOUT) - { -- if (offset != ~0u) -+ if (reg->idx_count) - { - bool is_sm_5_1 = vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1); - -@@ -862,10 +862,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const - /* For descriptors in sm < 5.1 we move the reg->idx values up one slot - * to normalise with 5.1. - * Here we should ignore it if it's a descriptor in sm < 5.1. */ -- if (reg->idx[1].offset != ~0u && (!is_descriptor || is_sm_5_1)) -+ if (reg->idx_count > 1 && (!is_descriptor || is_sm_5_1)) - shader_print_subscript(compiler, reg->idx[1].offset, reg->idx[1].rel_addr); - -- if (reg->idx[2].offset != ~0u) -+ if (reg->idx_count > 2) - shader_print_subscript(compiler, reg->idx[2].offset, reg->idx[2].rel_addr); - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 172204f2226..1678128da83 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -2475,7 +2475,7 @@ static void register_init_with_id(struct vkd3d_shader_register *reg, - reg->idx[0].offset = id; - } - --static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) -+static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type, struct sm6_parser *dxil) - { - if (type->class == TYPE_CLASS_INTEGER) - { -@@ -2492,7 +2492,8 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) - case 64: - return VSIR_DATA_U64; - default: -- FIXME("Unhandled width %u.\n", type->u.width); -+ vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, -+ "Unhandled integer width %u.", type->u.width); - return VSIR_DATA_U32; - } - } -@@ -2507,12 +2508,14 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) - case 64: - return VSIR_DATA_F64; - default: -- FIXME("Unhandled width %u.\n", type->u.width); -+ vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, -+ "Unhandled floating-point width %u.", type->u.width); - return VSIR_DATA_F32; - } - } - -- FIXME("Unhandled type %u.\n", type->class); -+ vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, -+ "Unhandled type %#x.", type->class); - return VSIR_DATA_U32; - } - -@@ -2599,7 +2602,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str - enum vsir_data_type data_type; - - scalar_type = sm6_type_get_scalar_type(value->type, 0); -- data_type = vsir_data_type_from_dxil(scalar_type); -+ data_type = vsir_data_type_from_dxil(scalar_type, sm6); - - switch (value->value_type) - { -@@ -3239,7 +3242,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co - dst->u.data = icb; - - icb->register_idx = sm6->icb_count++; -- icb->data_type = vsir_data_type_from_dxil(elem_type); -+ icb->data_type = vsir_data_type_from_dxil(elem_type, sm6); - icb->element_count = type->u.array.count; - icb->component_count = 1; - icb->is_null = !operands; -@@ -3693,7 +3696,7 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru - unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init, - struct vkd3d_shader_instruction *ins, struct sm6_value *dst) - { -- enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type); -+ enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type, sm6); - - if (ins) - vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP); -@@ -4012,8 +4015,7 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) - return VKD3D_ERROR_INVALID_SHADER; - if ((version = record->operands[0]) != 1) - { -- FIXME("Unsupported format version %#"PRIx64".\n", version); -- vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED_BITCODE_FORMAT, -+ vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, - "Bitcode format version %#"PRIx64" is unsupported.", version); - return VKD3D_ERROR_INVALID_SHADER; - } -@@ -5183,7 +5185,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr - - type = sm6_type_get_scalar_type(dst->type, 0); - VKD3D_ASSERT(type); -- src_param->reg.data_type = vsir_data_type_from_dxil(type); -+ src_param->reg.data_type = vsir_data_type_from_dxil(type, sm6); - if (data_type_is_64_bit(src_param->reg.data_type)) - src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); - else -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index e20a12bb42d..41aeb7f22f6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -4748,7 +4748,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * - } - - if (!strcmp(name, "tex2Dbias") -- || !strcmp(name, "tex2Dlod")) -+ || !strcmp(name, "tex2Dlod") -+ || !strcmp(name, "texCUBEbias")) - { - struct hlsl_ir_node *lod, *c; - -@@ -4900,6 +4901,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, - return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE); - } - -+static bool intrinsic_texCUBEbias(struct hlsl_ctx *ctx, -+ const struct parse_initializer *params, const struct vkd3d_shader_location *loc) -+{ -+ return intrinsic_tex(ctx, params, loc, "texCUBEbias", HLSL_SAMPLER_DIM_CUBE); -+} -+ - static bool intrinsic_texCUBEgrad(struct hlsl_ctx *ctx, - const struct parse_initializer *params, const struct vkd3d_shader_location *loc) - { -@@ -5375,6 +5382,7 @@ intrinsic_functions[] = - {"tex3Dgrad", 4, false, intrinsic_tex3Dgrad}, - {"tex3Dproj", 2, false, intrinsic_tex3Dproj}, - {"texCUBE", -1, false, intrinsic_texCUBE}, -+ {"texCUBEbias", 2, false, intrinsic_texCUBEbias}, - {"texCUBEgrad", 4, false, intrinsic_texCUBEgrad}, - {"texCUBEproj", 2, false, intrinsic_texCUBEproj}, - {"transpose", 1, true, intrinsic_transpose}, -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 698ad541359..9bf196b1fe2 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -213,7 +213,7 @@ enum vkd3d_shader_error - VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT = 8005, - VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_TABLE = 8006, - VKD3D_SHADER_ERROR_DXIL_INVALID_VALUE_SYMTAB = 8007, -- VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED_BITCODE_FORMAT = 8008, -+ VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED = 8008, - VKD3D_SHADER_ERROR_DXIL_INVALID_FUNCTION_DCL = 8009, - VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID = 8010, - VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011, --- -2.51.0 - diff --git a/patches/vkd3d-latest/0008-Updated-vkd3d-to-0096ae43e114e5bab8a6ff1093b509588a4.patch b/patches/vkd3d-latest/0008-Updated-vkd3d-to-0096ae43e114e5bab8a6ff1093b509588a4.patch deleted file mode 100644 index b0b766a2..00000000 --- a/patches/vkd3d-latest/0008-Updated-vkd3d-to-0096ae43e114e5bab8a6ff1093b509588a4.patch +++ /dev/null @@ -1,1133 +0,0 @@ -From 20e183247b7cd2ba19048f6a1b712c94b88dd548 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Fri, 5 Sep 2025 09:30:19 +1000 -Subject: [PATCH] Updated vkd3d to 0096ae43e114e5bab8a6ff1093b509588a49e38a. - ---- - libs/vkd3d/libs/vkd3d-shader/hlsl.h | 7 +- - libs/vkd3d/libs/vkd3d-shader/hlsl.y | 2 +- - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 375 ++++++++++++-------- - libs/vkd3d/libs/vkd3d-shader/ir.c | 51 +-- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 18 +- - libs/vkd3d/libs/vkd3d-shader/tpf.c | 2 + - 6 files changed, 268 insertions(+), 187 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -index df1333f55a6..a3e8ccc1e2a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h -@@ -233,6 +233,9 @@ struct hlsl_type - /* Offset where the type's description starts in the output bytecode, in bytes. */ - size_t bytecode_offset; - -+ /* Offset where the type's packed description starts in the output bytecode, in bytes. */ -+ size_t packed_bytecode_offset; -+ - bool is_typedef; - - uint32_t is_minimum_precision : 1; -@@ -1184,8 +1187,8 @@ struct hlsl_ctx - } constant_defs; - /* 'c' registers where the constants expected by SM2 sincos are stored. */ - struct hlsl_reg d3dsincosconst1, d3dsincosconst2; -- /* Number of allocated SSA and temp IDs, used in translation to vsir. */ -- unsigned int ssa_count, temp_count; -+ /* Number of allocated registers, used in translation to vsir. */ -+ unsigned int ssa_count, temp_count, indexable_temp_count; - - /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in - * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -index 41aeb7f22f6..d83ad9fe7d8 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y -@@ -8115,7 +8115,7 @@ resource_format: - { - uint32_t modifiers = $1; - -- if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, false, &@1))) -+ if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) - YYABORT; - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 5d413c43374..9a682a7550d 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -175,12 +175,29 @@ static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) - } - } - -+static unsigned int struct_field_get_packed_offset(const struct hlsl_type *record, unsigned int field_idx) -+{ -+ unsigned int offset = 0; -+ -+ VKD3D_ASSERT(record->class == HLSL_CLASS_STRUCT); -+ VKD3D_ASSERT(field_idx < record->e.record.field_count); -+ -+ for (unsigned int i = 0; i < field_idx; ++i) -+ { -+ struct hlsl_struct_field *field = &record->e.record.fields[i]; -+ offset = align(offset, hlsl_type_get_packed_alignment(field->type)) + hlsl_type_get_packed_size(field->type); -+ } -+ -+ return align(offset, hlsl_type_get_packed_alignment(record->e.record.fields[field_idx].type)); -+} -+ -+ - static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx, - struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx, - struct hlsl_type *type, const struct vkd3d_shader_location *loc) - { - struct hlsl_ir_node *idx_offset = NULL, *c; -- unsigned int field_idx, offset, size, i; -+ unsigned int field_idx, offset, size; - - switch (type->class) - { -@@ -203,15 +220,7 @@ static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hls - - case HLSL_CLASS_STRUCT: - field_idx = hlsl_ir_constant(idx)->value.u[0].u; -- for (i = 0, offset = 0; i < field_idx; ++i) -- { -- struct hlsl_struct_field *field = &type->e.record.fields[i]; -- -- offset = align(offset, hlsl_type_get_packed_alignment(field->type)) -- + hlsl_type_get_packed_size(field->type); -- } -- -- offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type)); -+ offset = struct_field_get_packed_offset(type, field_idx); - idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); - break; - -@@ -5912,7 +5921,6 @@ struct register_allocator - { - uint32_t reg; - unsigned int writemask; -- unsigned int first_write, last_read; - - /* Two allocations with different mode can't share the same register. */ - int mode; -@@ -5922,11 +5930,7 @@ struct register_allocator - } *allocations; - size_t count, capacity; - -- /* Indexable temps are allocated separately and always keep their index regardless of their -- * lifetime. */ -- uint32_t indexable_count; -- -- /* Total number of registers allocated so far. Used to declare sm4 temp count. */ -+ /* Total number of registers allocated so far. */ - uint32_t reg_count; - - /* Special flag so allocations that can share registers prioritize those -@@ -5938,7 +5942,7 @@ struct register_allocator - }; - - static unsigned int get_available_writemask(const struct register_allocator *allocator, -- unsigned int first_write, unsigned int last_read, uint32_t reg_idx, int mode, bool vip) -+ uint32_t reg_idx, int mode, bool vip) - { - unsigned int writemask = VKD3DSP_WRITEMASK_ALL; - size_t i; -@@ -5947,12 +5951,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all - { - const struct allocation *allocation = &allocator->allocations[i]; - -- /* We do not overlap if first write == last read: -- * this is the case where we are allocating the result of that -- * expression, e.g. "add r0, r0, r1". */ -- -- if (allocation->reg == reg_idx -- && first_write < allocation->last_read && last_read > allocation->first_write) -+ if (allocation->reg == reg_idx) - { - writemask &= ~allocation->writemask; - if (allocation->mode != mode) -@@ -5969,7 +5968,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all - } - - static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *allocator, uint32_t reg_idx, -- unsigned int writemask, unsigned int first_write, unsigned int last_read, int mode, bool vip) -+ unsigned int writemask, int mode, bool vip) - { - struct allocation *allocation; - -@@ -5980,8 +5979,6 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a - allocation = &allocator->allocations[allocator->count++]; - allocation->reg = reg_idx; - allocation->writemask = writemask; -- allocation->first_write = first_write; -- allocation->last_read = last_read; - allocation->mode = mode; - allocation->vip = vip; - -@@ -6000,8 +5997,7 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a - * 'vip' can be used so that no new allocations can be made in the given register - * unless they are 'vip' as well. */ - static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_allocator *allocator, -- unsigned int first_write, unsigned int last_read, unsigned int reg_size, -- unsigned int component_count, int mode, bool force_align, bool vip) -+ unsigned int reg_size, unsigned int component_count, int mode, bool force_align, bool vip) - { - struct hlsl_reg ret = {.allocation_size = 1, .allocated = true}; - unsigned int required_size = force_align ? 4 : reg_size; -@@ -6014,8 +6010,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a - { - for (uint32_t reg_idx = 0; reg_idx < allocator->reg_count; ++reg_idx) - { -- unsigned int available_writemask = get_available_writemask(allocator, -- first_write, last_read, reg_idx, mode, vip); -+ unsigned int available_writemask = get_available_writemask(allocator, reg_idx, mode, vip); - - if (vkd3d_popcount(available_writemask) >= pref) - { -@@ -6027,7 +6022,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a - ret.writemask = hlsl_combine_writemasks(writemask, - vkd3d_write_mask_from_component_count(component_count)); - -- record_allocation(ctx, allocator, reg_idx, writemask, first_write, last_read, mode, vip); -+ record_allocation(ctx, allocator, reg_idx, writemask, mode, vip); - return ret; - } - } -@@ -6037,39 +6032,12 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a - ret.id = allocator->reg_count; - ret.writemask = vkd3d_write_mask_from_component_count(component_count); - record_allocation(ctx, allocator, allocator->reg_count, -- vkd3d_write_mask_from_component_count(reg_size), first_write, last_read, mode, vip); -- return ret; --} -- --/* Allocate a register with writemask, while reserving reg_writemask. */ --static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx, -- struct register_allocator *allocator, unsigned int first_write, unsigned int last_read, -- uint32_t reg_writemask, uint32_t writemask, int mode, bool vip) --{ -- struct hlsl_reg ret = {0}; -- uint32_t reg_idx; -- -- VKD3D_ASSERT((reg_writemask & writemask) == writemask); -- -- for (reg_idx = 0;; ++reg_idx) -- { -- if ((get_available_writemask(allocator, first_write, last_read, -- reg_idx, mode, vip) & reg_writemask) == reg_writemask) -- break; -- } -- -- record_allocation(ctx, allocator, reg_idx, reg_writemask, first_write, last_read, mode, vip); -- -- ret.type = VKD3DSPR_TEMP; -- ret.id = reg_idx; -- ret.allocation_size = 1; -- ret.writemask = writemask; -- ret.allocated = true; -+ vkd3d_write_mask_from_component_count(reg_size), mode, vip); - return ret; - } - --static bool is_range_available(const struct register_allocator *allocator, unsigned int first_write, -- unsigned int last_read, uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) -+static bool is_range_available(const struct register_allocator *allocator, -+ uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) - { - unsigned int last_reg_mask = (1u << (reg_size % 4)) - 1; - unsigned int writemask; -@@ -6077,18 +6045,18 @@ static bool is_range_available(const struct register_allocator *allocator, unsig - - for (i = 0; i < (reg_size / 4); ++i) - { -- writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + i, mode, vip); -+ writemask = get_available_writemask(allocator, reg_idx + i, mode, vip); - if (writemask != VKD3DSP_WRITEMASK_ALL) - return false; - } -- writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + (reg_size / 4), mode, vip); -+ writemask = get_available_writemask(allocator, reg_idx + (reg_size / 4), mode, vip); - if ((writemask & last_reg_mask) != last_reg_mask) - return false; - return true; - } - --static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allocator *allocator, -- unsigned int first_write, unsigned int last_read, unsigned int reg_size, int mode, bool vip) -+static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, -+ struct register_allocator *allocator, unsigned int reg_size, int mode, bool vip) - { - struct hlsl_reg ret = {0}; - uint32_t reg_idx; -@@ -6096,15 +6064,14 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo - - for (reg_idx = 0;; ++reg_idx) - { -- if (is_range_available(allocator, first_write, last_read, reg_idx, reg_size, mode, vip)) -+ if (is_range_available(allocator, reg_idx, reg_size, mode, vip)) - break; - } - - for (i = 0; i < reg_size / 4; ++i) -- record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, first_write, last_read, mode, vip); -+ record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, mode, vip); - if (reg_size % 4) -- record_allocation(ctx, allocator, reg_idx + (reg_size / 4), -- (1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip); -+ record_allocation(ctx, allocator, reg_idx + (reg_size / 4), (1u << (reg_size % 4)) - 1, mode, vip); - - ret.type = allocator->type; - ret.id = reg_idx; -@@ -6113,22 +6080,17 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo - return ret; - } - --static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, struct register_allocator *allocator, -- unsigned int first_write, unsigned int last_read, const struct hlsl_type *type) -+static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, -+ struct register_allocator *allocator, const struct hlsl_type *type) - { - unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; -- struct hlsl_reg ret; - - /* FIXME: We could potentially pack structs or arrays more efficiently... */ - - if (type->class <= HLSL_CLASS_VECTOR) -- ret = allocate_register(ctx, allocator, first_write, last_read, -- type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); -+ return allocate_register(ctx, allocator, type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); - else -- ret = allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); -- if (allocator->type == VKD3DSPR_TEMP) -- ctx->temp_count = max(ctx->temp_count, ret.id + ret.allocation_size); -- return ret; -+ return allocate_range(ctx, allocator, reg_size, 0, false); - } - - static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) -@@ -6293,10 +6255,9 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) - } - } - --static void allocate_instr_temp_register(struct hlsl_ctx *ctx, -- struct hlsl_ir_node *instr, struct register_allocator *allocator) -+static void allocate_instr_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr) - { -- unsigned int reg_writemask = 0, dst_writemask = 0; -+ unsigned int dst_writemask = 0; - bool is_per_component = false; - - if (instr->reg.allocated || !instr->last_read) -@@ -6308,12 +6269,10 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - { - case HLSL_OP1_COS_REDUCED: - dst_writemask = VKD3DSP_WRITEMASK_0; -- reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_0; - break; - - case HLSL_OP1_SIN_REDUCED: - dst_writemask = VKD3DSP_WRITEMASK_1; -- reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_1; - break; - - case HLSL_OP1_EXP2: -@@ -6335,11 +6294,13 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - - VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); - -- if (reg_writemask) -+ if (dst_writemask) - { -- instr->reg = allocate_register_with_masks(ctx, allocator, -- instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false); -- ctx->temp_count = max(ctx->temp_count, instr->reg.id + 1); -+ instr->reg.writemask = dst_writemask; -+ instr->reg.allocation_size = 1; -+ instr->reg.allocated = true; -+ instr->reg.type = VKD3DSPR_TEMP; -+ instr->reg.id = ctx->temp_count++; - } - else if (is_per_component) - { -@@ -6348,8 +6309,6 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - instr->reg.allocated = true; - instr->reg.type = VKD3DSPR_TEMP; - instr->reg.id = ctx->temp_count++; -- -- record_allocation(ctx, allocator, ctx->temp_count - 1, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); - } - else - { -@@ -6360,12 +6319,11 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - instr->reg.id = ctx->ssa_count++; - } - -- TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, -- debug_register(instr->reg, instr->data_type), instr->index, instr->last_read); -+ TRACE("Allocated anonymous expression @%u to %s.\n", instr->index, -+ debug_register(instr->reg, instr->data_type)); - } - --static void allocate_variable_temp_register(struct hlsl_ctx *ctx, -- struct hlsl_ir_var *var, struct register_allocator *allocator) -+static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) - { - struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; - -@@ -6376,7 +6334,7 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, - { - if (var->indexable) - { -- reg->id = allocator->indexable_count++; -+ reg->id = ctx->indexable_temp_count++; - reg->allocation_size = 1; - reg->writemask = 0; - reg->allocated = true; -@@ -6392,19 +6350,15 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, - reg->writemask = vkd3d_write_mask_from_component_count(var->data_type->e.numeric.dimx); - reg->allocated = true; - -- for (unsigned int i = 0; i < reg->allocation_size; ++i) -- record_allocation(ctx, allocator, ctx->temp_count + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); -- - ctx->temp_count += reg->allocation_size; - -- TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, -- debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); -+ TRACE("Allocated %s to %s.\n", var->name, -+ debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); - } - } - } - --static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, -- struct hlsl_block *block, struct register_allocator *allocator) -+static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block) - { - struct hlsl_ir_node *instr; - -@@ -6414,15 +6368,15 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, - if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) - continue; - -- allocate_instr_temp_register(ctx, instr, allocator); -+ allocate_instr_temp_register(ctx, instr); - - switch (instr->type) - { - case HLSL_IR_IF: - { - struct hlsl_ir_if *iff = hlsl_ir_if(instr); -- allocate_temp_registers_recurse(ctx, &iff->then_block, allocator); -- allocate_temp_registers_recurse(ctx, &iff->else_block, allocator); -+ allocate_temp_registers_recurse(ctx, &iff->then_block); -+ allocate_temp_registers_recurse(ctx, &iff->else_block); - break; - } - -@@ -6431,21 +6385,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, - struct hlsl_ir_load *load = hlsl_ir_load(instr); - /* We need to at least allocate a variable for undefs. - * FIXME: We should probably find a way to remove them instead. */ -- allocate_variable_temp_register(ctx, load->src.var, allocator); -+ allocate_variable_temp_register(ctx, load->src.var); - break; - } - - case HLSL_IR_LOOP: - { - struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); -- allocate_temp_registers_recurse(ctx, &loop->body, allocator); -+ allocate_temp_registers_recurse(ctx, &loop->body); - break; - } - - case HLSL_IR_STORE: - { - struct hlsl_ir_store *store = hlsl_ir_store(instr); -- allocate_variable_temp_register(ctx, store->lhs.var, allocator); -+ allocate_variable_temp_register(ctx, store->lhs.var); - break; - } - -@@ -6456,7 +6410,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, - - LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) - { -- allocate_temp_registers_recurse(ctx, &c->body, allocator); -+ allocate_temp_registers_recurse(ctx, &c->body); - } - break; - } -@@ -6580,7 +6534,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, - break; - } - -- constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -+ constant->reg = allocate_numeric_registers_for_type(ctx, allocator, type); - TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type)); - - for (unsigned int x = 0, i = 0; x < 4; ++x) -@@ -6677,14 +6631,14 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl - { - type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); - -- ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -+ ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, type); - TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type)); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 2, 2.60416674e-03f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 3, 2.60416680e-04f, &instr->loc); - -- ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); -+ ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, type); - TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type)); - record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc); - record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc); -@@ -6721,15 +6675,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo - { - if (i < bind_count) - { -- if (get_available_writemask(&allocator_used, 1, UINT_MAX, -- reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) -+ if (get_available_writemask(&allocator_used, reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) - { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, - "Overlapping register() reservations on 'c%u'.", reg_idx + i); - } -- record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); -+ record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); - } -- record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); -+ record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); - } - - var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; -@@ -6753,7 +6706,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo - - if (!var->regs[HLSL_REGSET_NUMERIC].allocated) - { -- var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false); -+ var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, alloc_size, 0, false); - TRACE("Allocated %s to %s.\n", var->name, - debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); - } -@@ -6772,10 +6725,11 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo - * does not handle constants. */ - static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) - { -- struct register_allocator allocator = {.type = VKD3DSPR_TEMP}; - struct hlsl_scope *scope; - struct hlsl_ir_var *var; - -+ ctx->indexable_temp_count = 0; -+ - /* Reset variable temp register allocations. */ - LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) - { -@@ -6793,16 +6747,13 @@ static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *bod - { - if (var->is_output_semantic) - { -- record_allocation(ctx, &allocator, 0, VKD3DSP_WRITEMASK_ALL, -- var->first_write, UINT_MAX, 0, false); - ctx->temp_count = 1; - break; - } - } - } - -- allocate_temp_registers_recurse(ctx, body, &allocator); -- vkd3d_free(allocator.allocations); -+ allocate_temp_registers_recurse(ctx, body); - } - - static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, -@@ -6941,7 +6892,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var - if (special_interpolation) - mode = VKD3DSIM_NONE; - -- var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, -+ var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, - reg_size, component_count, mode, var->force_align, vip_allocation); - - TRACE("Allocated %s to %s (mode %d).\n", var->name, -@@ -9763,8 +9714,6 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr - break; - - case HLSL_OP3_CMP: -- if (!hlsl_type_is_floating_point(type)) -- goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true); - break; - -@@ -11735,6 +11684,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - const struct vkd3d_shader_version *version = &program->shader_version; - const struct hlsl_ir_node *sample_index = load->sample_index.node; - const struct hlsl_ir_node *texel_offset = load->texel_offset.node; -+ const struct hlsl_ir_node *byte_offset = load->byte_offset.node; - const struct hlsl_ir_node *coords = load->coords.node; - unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; - const struct hlsl_deref *resource = &load->resource; -@@ -11742,20 +11692,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - enum hlsl_sampler_dim dim = load->sampling_dim; - bool tgsm = load->resource.var->is_tgsm; - struct vkd3d_shader_instruction *ins; -+ bool multisampled, raw, structured; - enum vkd3d_shader_opcode opcode; -- bool multisampled, raw; - - VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD); - -- if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -- { -- hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads."); -- return false; -- } -- - multisampled = resource_type->class == HLSL_CLASS_TEXTURE - && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS - || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); -+ structured = resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; - - if (!tgsm) - { -@@ -11766,15 +11711,19 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); - return false; - } -+ VKD3D_ASSERT(!(structured && multisampled)); - -- if (uav) -+ if (structured) -+ opcode = VSIR_OP_LD_STRUCTURED; -+ else if (uav) - opcode = VSIR_OP_LD_UAV_TYPED; - else if (raw) - opcode = VSIR_OP_LD_RAW; - else - opcode = multisampled ? VSIR_OP_LD2DMS : VSIR_OP_LD; - -- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled))) -+ if (!(ins = generate_vsir_add_program_instruction(ctx, program, -+ &instr->loc, opcode, 1, 2 + multisampled + structured))) - return false; - - if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset)) -@@ -11802,10 +11751,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, - vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, coords_writemask); - - if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, -- &ins->src[1], resource, ins->dst[0].write_mask, &instr->loc)) -+ &ins->src[structured ? 2 : 1], resource, ins->dst[0].write_mask, &instr->loc)) - return false; - -- if (multisampled) -+ if (structured) -+ { -+ VKD3D_ASSERT(byte_offset); -+ vsir_src_from_hlsl_node(&ins->src[1], ctx, byte_offset, VKD3DSP_WRITEMASK_ALL); -+ } -+ else if (multisampled) - { - if (sample_index->type == HLSL_IR_CONSTANT) - vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, -@@ -12889,6 +12843,9 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - { - switch (component_type->sampler_dim) - { -+ case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: -+ opcode = VSIR_OP_DCL_RESOURCE_STRUCTURED; -+ break; - case HLSL_SAMPLER_DIM_RAW_BUFFER: - opcode = VSIR_OP_DCL_RESOURCE_RAW; - break; -@@ -12944,7 +12901,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, - else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) - { - ins->structured = true; -- ins->resource_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; -+ ins->resource_stride = hlsl_type_get_packed_size(component_type->e.resource.format); - ins->declaration.structured_resource.byte_stride = ins->resource_stride; - } - else -@@ -13214,14 +13171,16 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) - - static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) - { -+ bool structured = type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; -+ - switch (type->class) - { - case HLSL_CLASS_SAMPLER: - return D3D_SIT_SAMPLER; - case HLSL_CLASS_TEXTURE: -- return D3D_SIT_TEXTURE; -+ return structured ? D3D_SIT_STRUCTURED : D3D_SIT_TEXTURE; - case HLSL_CLASS_UAV: -- return D3D_SIT_UAV_RWTYPED; -+ return structured ? D3D_SIT_UAV_RWSTRUCTURED : D3D_SIT_UAV_RWTYPED; - default: - break; - } -@@ -13297,7 +13256,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) - vkd3d_unreachable(); - } - --static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type) -+static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, -+ struct hlsl_type *type, bool structured) - { - const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type); - const char *name = array_type->name ? array_type->name : ""; -@@ -13306,7 +13266,10 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b - size_t name_offset = 0; - size_t i; - -- if (type->bytecode_offset) -+ if (!structured && type->bytecode_offset) -+ return; -+ -+ if (structured && type->packed_bytecode_offset) - return; - - if (profile->major_version >= 5) -@@ -13328,7 +13291,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b - continue; - - field->name_bytecode_offset = put_string(buffer, field->name); -- write_sm4_type(ctx, buffer, field->type); -+ write_sm4_type(ctx, buffer, field->type, structured); - ++field_count; - } - -@@ -13337,15 +13300,29 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b - for (i = 0; i < array_type->e.record.field_count; ++i) - { - struct hlsl_struct_field *field = &array_type->e.record.fields[i]; -+ unsigned int field_type_offset, offset; - - if (!field->type->reg_size[HLSL_REGSET_NUMERIC]) - continue; - - put_u32(buffer, field->name_bytecode_offset); -- put_u32(buffer, field->type->bytecode_offset); -- put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float)); -+ -+ if (!structured) -+ field_type_offset = field->type->bytecode_offset; -+ else -+ field_type_offset = field->type->packed_bytecode_offset; -+ put_u32(buffer, field_type_offset); -+ -+ if (!structured) -+ offset = field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float); -+ else -+ offset = struct_field_get_packed_offset(array_type, i); -+ put_u32(buffer, offset); - } -- type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); -+ if (!structured) -+ type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); -+ else -+ type->packed_bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); - put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type))); - put_u32(buffer, vkd3d_make_u32(array_size, field_count)); - put_u32(buffer, fields_offset); -@@ -13353,7 +13330,11 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b - else - { - VKD3D_ASSERT(array_type->class <= HLSL_CLASS_LAST_NUMERIC); -- type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); -+ if (!structured) -+ type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); -+ else -+ type->packed_bytecode_offset = put_u32(buffer, -+ vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); - put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx)); - put_u32(buffer, vkd3d_make_u32(array_size, 0)); - put_u32(buffer, 1); -@@ -13372,9 +13353,9 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b - static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef) - { - uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t); -- size_t cbuffers_offset, resources_offset, creator_offset, string_offset; -- unsigned int cbuffer_count = 0, extern_resources_count, i, j; -+ size_t buffers_offset, resources_offset, creator_offset, string_offset; - size_t cbuffer_position, resource_position, creator_position; -+ unsigned int buffer_count = 0, extern_resources_count, i, j; - const struct hlsl_profile_info *profile = ctx->profile; - struct vkd3d_bytecode_buffer buffer = {0}; - struct extern_resource *extern_resources; -@@ -13396,10 +13377,20 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) - { - if (cbuffer->reg.allocated) -- ++cbuffer_count; -+ ++buffer_count; -+ } -+ -+ for (i = 0; i < extern_resources_count; ++i) -+ { -+ const struct extern_resource *resource = &extern_resources[i]; -+ -+ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ continue; -+ -+ ++buffer_count; - } - -- put_u32(&buffer, cbuffer_count); -+ put_u32(&buffer, buffer_count); - cbuffer_position = put_u32(&buffer, 0); - put_u32(&buffer, extern_resources_count); - resource_position = put_u32(&buffer, 0); -@@ -13440,12 +13431,19 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - put_u32(&buffer, sm4_resource_type(resource->component_type)); - if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) - { -+ bool structured = resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; - unsigned int dimx = resource->component_type->e.resource.format->e.numeric.dimx; - - put_u32(&buffer, sm4_data_type(resource->component_type)); - put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type)); -- put_u32(&buffer, ~0u); /* FIXME: multisample count */ -- flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; -+ -+ if (structured) -+ put_u32(&buffer, hlsl_type_get_packed_size(resource->component_type->e.resource.format)); -+ else -+ put_u32(&buffer, ~0u); /* FIXME: multisample count */ -+ -+ if (!structured) -+ flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; - } - else - { -@@ -13474,8 +13472,8 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - - /* Buffers. */ - -- cbuffers_offset = bytecode_align(&buffer); -- set_u32(&buffer, cbuffer_position, cbuffers_offset); -+ buffers_offset = bytecode_align(&buffer); -+ set_u32(&buffer, cbuffer_position, buffers_offset); - LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) - { - unsigned int var_count = 0; -@@ -13497,6 +13495,24 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER); - } - -+ for (i = 0; i < extern_resources_count; ++i) -+ { -+ const struct extern_resource *resource = &extern_resources[i]; -+ struct hlsl_type *resource_type; -+ -+ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ continue; -+ -+ resource_type = resource->component_type->e.resource.format; -+ -+ put_u32(&buffer, 0); /* name */ -+ put_u32(&buffer, 1); /* var count */ -+ put_u32(&buffer, 0); /* variable offset */ -+ put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); /* size */ -+ put_u32(&buffer, 0); /* FIXME: flags */ -+ put_u32(&buffer, D3D_CT_RESOURCE_BIND_INFO); -+ } -+ - i = 0; - LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) - { -@@ -13504,7 +13520,18 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - continue; - - string_offset = put_string(&buffer, cbuffer->name); -- set_u32(&buffer, cbuffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); -+ set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); -+ } -+ -+ for (j = 0; j < extern_resources_count; ++j) -+ { -+ const struct extern_resource *resource = &extern_resources[j]; -+ -+ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ continue; -+ -+ string_offset = put_string(&buffer, resource->name); -+ set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); - } - - i = 0; -@@ -13515,7 +13542,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - if (!cbuffer->reg.allocated) - continue; - -- set_u32(&buffer, cbuffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); -+ set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); - - LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - { -@@ -13554,7 +13581,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - - string_offset = put_string(&buffer, var->name); - set_u32(&buffer, var_offset, string_offset); -- write_sm4_type(ctx, &buffer, var->data_type); -+ write_sm4_type(ctx, &buffer, var->data_type, false); - set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset); - - if (var->default_values) -@@ -13597,6 +13624,42 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd - } - } - -+ for (j = 0; j < extern_resources_count; ++j) -+ { -+ const struct extern_resource *resource = &extern_resources[j]; -+ struct hlsl_type *resource_type; -+ size_t vars_start; -+ -+ if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) -+ continue; -+ -+ resource_type = resource->component_type->e.resource.format; -+ -+ vars_start = bytecode_align(&buffer); -+ -+ set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); -+ -+ put_u32(&buffer, 0); /* name */ -+ put_u32(&buffer, 0); /* offset */ -+ put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); -+ put_u32(&buffer, D3D_SVF_USED); -+ put_u32(&buffer, 0); /* type */ -+ put_u32(&buffer, 0); /* default value */ -+ -+ if (profile->major_version >= 5) -+ { -+ put_u32(&buffer, ~0u); /* texture start */ -+ put_u32(&buffer, 0); /* texture count */ -+ put_u32(&buffer, ~0u); /* sampler start */ -+ put_u32(&buffer, 0); /* sampler count */ -+ } -+ -+ string_offset = put_string(&buffer, "$Element"); -+ set_u32(&buffer, vars_start, string_offset); -+ write_sm4_type(ctx, &buffer, resource_type, true); -+ set_u32(&buffer, vars_start + 4 * sizeof(uint32_t), resource_type->packed_bytecode_offset); -+ } -+ - creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL)); - set_u32(&buffer, creator_position, creator_offset); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index b120801d5f9..3e06e887096 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -9758,9 +9758,10 @@ static void vsir_validate_ssa_register(struct validation_context *ctx, - - if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for a SSA register: " -- "it has already been seen with data type %#x at instruction %zu.", -- reg->data_type, data->data_type, data->first_seen); -+ "Invalid data type \"%s\" (%#x) for SSA register %u: " -+ "it has already been seen with data type \"%s\" (%#x) at instruction %zu.", -+ vsir_data_type_get_name(reg->data_type, ""), reg->data_type, reg->idx[0].offset, -+ vsir_data_type_get_name(data->data_type, ""), data->data_type, data->first_seen); - } - } - -@@ -10008,7 +10009,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, - - default: - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for destination with saturate modifier.", dst->reg.data_type); -+ "Invalid data type \"%s\" (%#x) for destination with saturate modifier.", -+ vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); - break; - - } -@@ -10027,7 +10029,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, - case 15: - if (dst->reg.data_type != VSIR_DATA_F32) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for destination with shift.", dst->reg.data_type); -+ "Invalid data type \"%s\" (%#x) for destination with shift.", -+ vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); - break; - - default: -@@ -10165,7 +10168,8 @@ static void vsir_validate_src_param(struct validation_context *ctx, - { - if (!(src_modifier_data[src->modifiers].data_type_mask & (1u << src->reg.data_type))) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, -- "Source has invalid modifier %#x for data type %u.", src->modifiers, src->reg.data_type); -+ "Source has invalid modifier %#x for data type \"%s\" (%#x).", -+ src->modifiers, vsir_data_type_get_name(src->reg.data_type, ""), src->reg.data_type); - } - - switch (src->reg.type) -@@ -10817,7 +10821,7 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, - static void vsir_validate_elementwise_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) - { -- enum vsir_data_type dst_data_type; -+ enum vsir_data_type dst_data_type, src_data_type; - unsigned int i; - - if (instruction->dst_count < 1) -@@ -10830,16 +10834,18 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, - - if (!types[dst_data_type]) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for elementwise operation \"%s\" (%#x).", -- dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ "Invalid data type \"%s\" (%#x) for elementwise operation \"%s\" (%#x).", -+ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - - for (i = 0; i < instruction->src_count; ++i) - { -- if (instruction->src[i].reg.data_type != dst_data_type) -+ if ((src_data_type = instruction->src[i].reg.data_type) != dst_data_type) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Data type %#x for operand %u doesn't match the destination data type %#x " -+ "Data type \"%s\" (%#x) for operand %u doesn't match the destination data type \"%s\" (%#x) " - "for elementwise operation \"%s\" (%#x).", -- instruction->src[i].reg.data_type, i, dst_data_type, -+ vsir_data_type_get_name(src_data_type, ""), src_data_type, i, -+ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, - vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - } - } -@@ -10896,7 +10902,7 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context - static void vsir_validate_comparison_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) - { -- enum vsir_data_type dst_data_type, src_data_type; -+ enum vsir_data_type dst_data_type, src_data_type, data_type; - unsigned int i; - - if (instruction->dst_count < 1) -@@ -10906,8 +10912,9 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, - - if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for result of comparison operation \"%s\" (%#x).", -- dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ "Invalid data type \"%s\" (%#x) for result of comparison operation \"%s\" (%#x).", -+ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - - if (instruction->src_count == 0) - return; -@@ -10919,16 +10926,18 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, - - if (!types[src_data_type]) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid data type %#x for comparison operation \"%s\" (%#x).", -- src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ "Invalid data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", -+ vsir_data_type_get_name(src_data_type, ""), src_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - - for (i = 1; i < instruction->src_count; ++i) - { -- if (instruction->src[i].reg.data_type != src_data_type) -+ if ((data_type = instruction->src[i].reg.data_type) != src_data_type) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Data type %#x for operand %u doesn't match the first operands data type %#x " -- "for comparison operation \"%s\" (%#x).", -- instruction->src[i].reg.data_type, i, src_data_type, -+ "Data type \"%s\" (%#x) for operand %u doesn't match the first " -+ "operands data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", -+ vsir_data_type_get_name(data_type, ""), data_type, i, -+ vsir_data_type_get_name(src_data_type, ""), src_data_type, - vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - } - } -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 058a631f25e..9cd9aafb587 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -4145,10 +4145,11 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c - addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); - if (reg_index->offset) - { -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -- addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, -- addr_id, spirv_compiler_get_constant_uint(compiler, reg_index->offset)); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); -+ addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, addr_id, -+ spirv_compiler_get_constant_uint(compiler, reg_index->offset)); - } -+ - return addr_id; - } - -@@ -4294,7 +4295,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2]; - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); - if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) - { - index_ids[0] = compiler->descriptor_offsets_member_id; -@@ -4492,8 +4493,9 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - - VKD3D_ASSERT(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); - op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; -+ - return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, - data_type == VSIR_DATA_U64 - ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) -@@ -4508,7 +4510,8 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, - - true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); - false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); -+ - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -@@ -4521,7 +4524,8 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile - true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, - component_count); - false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_U64, component_count); -+ - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c -index e2123656557..24a28886b00 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/tpf.c -+++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c -@@ -4225,6 +4225,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ - - case VSIR_OP_DCL: - case VSIR_OP_DCL_RESOURCE_RAW: -+ case VSIR_OP_DCL_RESOURCE_STRUCTURED: - case VSIR_OP_DCL_UAV_RAW: - case VSIR_OP_DCL_UAV_STRUCTURED: - case VSIR_OP_DCL_UAV_TYPED: -@@ -4308,6 +4309,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ - case VSIR_OP_LD: - case VSIR_OP_LD2DMS: - case VSIR_OP_LD_RAW: -+ case VSIR_OP_LD_STRUCTURED: - case VSIR_OP_LD_UAV_TYPED: - case VSIR_OP_LOG: - case VSIR_OP_LOOP: --- -2.51.0 - diff --git a/patches/vkd3d-latest/0009-Updated-vkd3d-to-6607b94ad7ce77907a912923f39e6371d23.patch b/patches/vkd3d-latest/0009-Updated-vkd3d-to-6607b94ad7ce77907a912923f39e6371d23.patch deleted file mode 100644 index 6c234200..00000000 --- a/patches/vkd3d-latest/0009-Updated-vkd3d-to-6607b94ad7ce77907a912923f39e6371d23.patch +++ /dev/null @@ -1,126 +0,0 @@ -From 847e0c6da106b68aa30bf48575ad204f547b913a Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Tue, 9 Sep 2025 12:15:35 +1000 -Subject: [PATCH] Updated vkd3d to 6607b94ad7ce77907a912923f39e6371d23e339b. - ---- - libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 17 +++++++++++++++++ - libs/vkd3d/libs/vkd3d-shader/dxil.c | 8 ++++++++ - libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 3 +-- - libs/vkd3d/libs/vkd3d-shader/msl.c | 6 ++++++ - .../libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++++-- - 5 files changed, 36 insertions(+), 4 deletions(-) - -diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -index 897803ecb56..e2fb8b12998 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -+++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c -@@ -957,6 +957,22 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, - vkd3d_string_buffer_printf(buffer, ">%s", suffix); - } - -+static void shader_print_indexable_temp_data_type(struct vkd3d_d3d_asm_compiler *compiler, -+ const struct vkd3d_shader_indexable_temp *t) -+{ -+ struct vkd3d_string_buffer *buffer = &compiler->buffer; -+ -+ if (!(compiler->flags & VSIR_ASM_FLAG_DUMP_TYPES)) -+ return; -+ -+ if (t->component_count > 1) -+ vkd3d_string_buffer_printf(buffer, " component_count); -+ else -+ vkd3d_string_buffer_printf(buffer, " data_type); -+ vkd3d_string_buffer_printf(buffer, ">"); -+} -+ - static void shader_print_write_mask(struct vkd3d_d3d_asm_compiler *compiler, - const char *prefix, uint32_t mask, const char *suffix) - { -@@ -1511,6 +1527,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, - vkd3d_string_buffer_printf(buffer, " %sx%u%s", compiler->colours.reg, - ins->declaration.indexable_temp.register_idx, compiler->colours.reset); - shader_print_subscript(compiler, ins->declaration.indexable_temp.register_size, NULL); -+ shader_print_indexable_temp_data_type(compiler, &ins->declaration.indexable_temp); - shader_print_uint_literal(compiler, ", ", ins->declaration.indexable_temp.component_count, ""); - if (ins->declaration.indexable_temp.alignment) - shader_print_uint_literal(compiler, ", align ", ins->declaration.indexable_temp.alignment, ""); -diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c -index 1678128da83..fb2cde4501a 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/dxil.c -+++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c -@@ -3698,6 +3698,14 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru - { - enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type, sm6); - -+ if (!(sm6->program->global_flags & VKD3DSGF_FORCE_NATIVE_LOW_PRECISION)) -+ { -+ if (data_type == VSIR_DATA_F16) -+ data_type = VSIR_DATA_F32; -+ else if (data_type == VSIR_DATA_U16) -+ data_type = VSIR_DATA_U32; -+ } -+ - if (ins) - vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP); - else -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -index 9a682a7550d..ee21207a855 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c -@@ -8817,9 +8817,8 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c - case HLSL_TYPE_DOUBLE: - return VSIR_DATA_F64; - case HLSL_TYPE_FLOAT: -- return VSIR_DATA_F32; - case HLSL_TYPE_HALF: -- return VSIR_DATA_F16; -+ return VSIR_DATA_F32; - case HLSL_TYPE_INT: - return VSIR_DATA_I32; - case HLSL_TYPE_UINT: -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index fc8d482e08a..d9e22abdfc3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -1414,6 +1414,12 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc - static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) - { - const char *type = ins->declaration.indexable_temp.component_count == 4 ? "vkd3d_vec4" : "vkd3d_scalar"; -+ -+ if (ins->declaration.indexable_temp.initialiser) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -+ "Internal compiler error: Unhandled initialiser for indexable temporary %u.", -+ ins->declaration.indexable_temp.register_idx); -+ - msl_print_indent(gen->buffer, gen->indent); - vkd3d_string_buffer_printf(gen->buffer, "%s x%u[%u];\n", type, - ins->declaration.indexable_temp.register_idx, -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index 9bf196b1fe2..ae88d97f461 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -1863,7 +1863,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty - { - case VSIR_DATA_BOOL: - return VKD3D_SHADER_COMPONENT_BOOL; -- case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ -+ case VSIR_DATA_F16: -+ return VKD3D_SHADER_COMPONENT_FLOAT16; - case VSIR_DATA_F32: - case VSIR_DATA_SNORM: - case VSIR_DATA_UNORM: -@@ -1872,7 +1873,8 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty - return VKD3D_SHADER_COMPONENT_DOUBLE; - case VSIR_DATA_I32: - return VKD3D_SHADER_COMPONENT_INT; -- case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */ -+ case VSIR_DATA_U16: -+ return VKD3D_SHADER_COMPONENT_UINT16; - case VSIR_DATA_U32: - return VKD3D_SHADER_COMPONENT_UINT; - case VSIR_DATA_U64: --- -2.51.0 - diff --git a/patches/vkd3d-latest/0010-Updated-vkd3d-to-de2095fda435c5ed47e946cf4e18c68b148.patch b/patches/vkd3d-latest/0010-Updated-vkd3d-to-de2095fda435c5ed47e946cf4e18c68b148.patch deleted file mode 100644 index 6dd37287..00000000 --- a/patches/vkd3d-latest/0010-Updated-vkd3d-to-de2095fda435c5ed47e946cf4e18c68b148.patch +++ /dev/null @@ -1,1793 +0,0 @@ -From 4b9fa54600c3aaa1f06e6d226f79cc19627072b1 Mon Sep 17 00:00:00 2001 -From: Alistair Leslie-Hughes -Date: Thu, 11 Sep 2025 06:55:40 +1000 -Subject: [PATCH] Updated vkd3d to de2095fda435c5ed47e946cf4e18c68b14856081. - ---- - libs/vkd3d/include/vkd3d_shader.h | 15 +- - .../libs/vkd3d-shader/hlsl_constant_ops.c | 160 +++++ - libs/vkd3d/libs/vkd3d-shader/ir.c | 559 ++++++++++++------ - libs/vkd3d/libs/vkd3d-shader/msl.c | 23 +- - libs/vkd3d/libs/vkd3d-shader/spirv.c | 45 +- - .../libs/vkd3d-shader/vkd3d_shader_main.c | 198 ------- - .../libs/vkd3d-shader/vkd3d_shader_private.h | 71 ++- - .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 9 +- - 8 files changed, 651 insertions(+), 429 deletions(-) - -diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h -index a1f85dbbd05..3a2f54c8f22 100644 ---- a/libs/vkd3d/include/vkd3d_shader.h -+++ b/libs/vkd3d/include/vkd3d_shader.h -@@ -422,10 +422,17 @@ struct vkd3d_shader_code - { - /** - * Pointer to the code. Note that textual formats are not null-terminated. -- * Therefore \a size should not include a null terminator, when this -- * structure is passed as input to a vkd3d-shader function, and the -- * allocated string will not include a null terminator when this structure -- * is used as output. -+ * Therefore \a size should not include a null terminator when this -+ * structure is passed as input to a vkd3d-shader function, and \a size -+ * will not include a null terminator when this structure is used as -+ * output. -+ * -+ * For convenience, vkd3d_shader_preprocess() and vkd3d_shader_compile() -+ * will append a null terminator past the end of their output when -+ * outputting textual formats like VKD3D_SHADER_TARGET_D3D_ASM. This makes -+ * it safe to call functions like strlen() on \a code for such output, -+ * although doing so will obviously not account for any embedded null -+ * characters that may be present. - */ - const void *code; - /** Size of \a code, in bytes. */ -diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -index 4cd47a0632e..252ed51a4e4 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -+++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c -@@ -250,6 +250,36 @@ static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, - return true; - } - -+static bool fold_cos(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, -+ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) -+{ -+ enum hlsl_base_type type = dst_type->e.numeric.type; -+ unsigned int k; -+ -+ VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); -+ -+ for (k = 0; k < dst_type->e.numeric.dimx; ++k) -+ { -+ switch (type) -+ { -+ case HLSL_TYPE_FLOAT: -+ case HLSL_TYPE_HALF: -+ dst->u[k].f = cosf(src->value.u[k].f); -+ break; -+ -+ case HLSL_TYPE_DOUBLE: -+ dst->u[k].d = cos(src->value.u[k].d); -+ break; -+ -+ default: -+ FIXME("Fold 'cos' for type %s.\n", debug_hlsl_type(ctx, dst_type)); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ - static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, - const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) - { -@@ -478,6 +508,48 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons - return true; - } - -+static bool fold_reinterpret(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, -+ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) -+{ -+ unsigned int k; -+ -+ for (k = 0; k < dst_type->e.numeric.dimx; ++k) -+ { -+ dst->u[k] = src->value.u[k]; -+ } -+ -+ return true; -+} -+ -+static bool fold_round(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, -+ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) -+{ -+ enum hlsl_base_type type = dst_type->e.numeric.type; -+ unsigned int k; -+ -+ VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); -+ -+ for (k = 0; k < dst_type->e.numeric.dimx; ++k) -+ { -+ switch (type) -+ { -+ case HLSL_TYPE_FLOAT: -+ case HLSL_TYPE_HALF: -+ /* Somewhat unfortunately, constant folded round() rounds -+ * halfway cases towards positive infinity, as opposed to -+ * nearest even like vsir/TPF round_ne. */ -+ dst->u[k].f = floorf(src->value.u[k].f + 0.5f); -+ break; -+ -+ default: -+ FIXME("Fold 'round' for type %s.\n", debug_hlsl_type(ctx, dst_type)); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ - static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, - const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) - { -@@ -544,6 +616,36 @@ static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons - return true; - } - -+static bool fold_sin(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, -+ const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) -+{ -+ enum hlsl_base_type type = dst_type->e.numeric.type; -+ unsigned int k; -+ -+ VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); -+ -+ for (k = 0; k < dst_type->e.numeric.dimx; ++k) -+ { -+ switch (type) -+ { -+ case HLSL_TYPE_FLOAT: -+ case HLSL_TYPE_HALF: -+ dst->u[k].f = sinf(src->value.u[k].f); -+ break; -+ -+ case HLSL_TYPE_DOUBLE: -+ dst->u[k].d = sin(src->value.u[k].d); -+ break; -+ -+ default: -+ FIXME("Fold 'sin' for type %s.\n", debug_hlsl_type(ctx, dst_type)); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ - static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, - const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) - { -@@ -974,6 +1076,44 @@ static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c - return true; - } - -+static bool fold_mad(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, -+ const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3) -+{ -+ enum hlsl_base_type type = dst_type->e.numeric.type; -+ unsigned int k; -+ -+ VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type); -+ VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type); -+ VKD3D_ASSERT(type == src3->node.data_type->e.numeric.type); -+ -+ for (k = 0; k < dst_type->e.numeric.dimx; ++k) -+ { -+ switch (type) -+ { -+ case HLSL_TYPE_FLOAT: -+ case HLSL_TYPE_HALF: -+ dst->u[k].f = fmaf(src1->value.u[k].f, src2->value.u[k].f, src3->value.u[k].f); -+ break; -+ -+ case HLSL_TYPE_DOUBLE: -+ dst->u[k].d = fma(src1->value.u[k].d, src2->value.u[k].d, src3->value.u[k].d); -+ break; -+ -+ case HLSL_TYPE_INT: -+ case HLSL_TYPE_MIN16UINT: -+ case HLSL_TYPE_UINT: -+ dst->u[k].u = src1->value.u[k].u * src2->value.u[k].u + src3->value.u[k].u; -+ break; -+ -+ default: -+ FIXME("Fold 'mad' for type %s.\n", debug_hlsl_type(ctx, dst_type)); -+ return false; -+ } -+ } -+ -+ return true; -+} -+ - static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, - const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) - { -@@ -1263,6 +1403,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - success = fold_ceil(ctx, &res, instr->data_type, arg1); - break; - -+ case HLSL_OP1_COS: -+ success = fold_cos(ctx, &res, instr->data_type, arg1); -+ break; -+ - case HLSL_OP1_EXP2: - success = fold_exp2(ctx, &res, instr->data_type, arg1); - break; -@@ -1291,6 +1435,14 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc); - break; - -+ case HLSL_OP1_REINTERPRET: -+ success = fold_reinterpret(ctx, &res, instr->data_type, arg1); -+ break; -+ -+ case HLSL_OP1_ROUND: -+ success = fold_round(ctx, &res, instr->data_type, arg1); -+ break; -+ - case HLSL_OP1_RSQ: - success = fold_rsq(ctx, &res, instr->data_type, arg1, &instr->loc); - break; -@@ -1299,6 +1451,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - success = fold_sat(ctx, &res, instr->data_type, arg1); - break; - -+ case HLSL_OP1_SIN: -+ success = fold_sin(ctx, &res, instr->data_type, arg1); -+ break; -+ - case HLSL_OP1_SQRT: - success = fold_sqrt(ctx, &res, instr->data_type, arg1, &instr->loc); - break; -@@ -1373,6 +1529,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, - success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3); - break; - -+ case HLSL_OP3_MAD: -+ success = fold_mad(ctx, &res, instr->data_type, arg1, arg2, arg3); -+ break; -+ - case HLSL_OP3_TERNARY: - success = fold_ternary(ctx, &res, instr->data_type, arg1, arg2, arg3); - break; -diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c -index 3e06e887096..29bf62709eb 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/ir.c -+++ b/libs/vkd3d/libs/vkd3d-shader/ir.c -@@ -53,7 +53,9 @@ const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error) - [VSIR_DATA_F16 ] = "half", - [VSIR_DATA_F32 ] = "float", - [VSIR_DATA_F64 ] = "double", -+ [VSIR_DATA_I16 ] = "i16", - [VSIR_DATA_I32 ] = "int", -+ [VSIR_DATA_I64 ] = "i64", - [VSIR_DATA_U8 ] = "uint8", - [VSIR_DATA_U16 ] = "uint16", - [VSIR_DATA_U32 ] = "uint", -@@ -416,6 +418,183 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) - return error; - } - -+static struct vkd3d_shader_param_node *shader_param_allocator_node_create( -+ struct vkd3d_shader_param_allocator *allocator) -+{ -+ struct vkd3d_shader_param_node *node; -+ -+ if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride])))) -+ return NULL; -+ node->next = NULL; -+ -+ return node; -+} -+ -+static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, size_t count, size_t stride) -+{ -+ allocator->count = max(count, MAX_REG_OUTPUT); -+ allocator->stride = stride; -+ allocator->head = NULL; -+ allocator->current = NULL; -+ allocator->index = allocator->count; -+} -+ -+static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator) -+{ -+ struct vkd3d_shader_param_node *current = allocator->head; -+ -+ while (current) -+ { -+ struct vkd3d_shader_param_node *next = current->next; -+ vkd3d_free(current); -+ current = next; -+ } -+} -+ -+void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) -+{ -+ void *params; -+ -+ if (!allocator->current || count > allocator->count - allocator->index) -+ { -+ struct vkd3d_shader_param_node *next; -+ -+ allocator->count = max(allocator->count, count); -+ if (!(next = shader_param_allocator_node_create(allocator))) -+ return NULL; -+ if (allocator->current) -+ allocator->current->next = next; -+ else -+ allocator->head = next; -+ allocator->current = next; -+ allocator->index = 0; -+ } -+ -+ params = &allocator->current->param[allocator->index * allocator->stride]; -+ allocator->index += count; -+ -+ return params; -+} -+ -+bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *array, size_t reserve) -+{ -+ if (!vkd3d_array_reserve((void **)&array->elements, &array->capacity, reserve, sizeof(*array->elements))) -+ { -+ ERR("Failed to allocate instructions.\n"); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *array, size_t idx, size_t count) -+{ -+ VKD3D_ASSERT(idx <= array->count); -+ -+ if (!shader_instruction_array_reserve(array, array->count + count)) -+ return false; -+ -+ memmove(&array->elements[idx + count], &array->elements[idx], (array->count - idx) * sizeof(*array->elements)); -+ memset(&array->elements[idx], 0, count * sizeof(*array->elements)); -+ array->count += count; -+ -+ return true; -+} -+ -+bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *array, -+ struct vkd3d_shader_immediate_constant_buffer *icb) -+{ -+ if (!vkd3d_array_reserve((void **)&array->icbs, &array->icb_capacity, array->icb_count + 1, sizeof(*array->icbs))) -+ return false; -+ -+ array->icbs[array->icb_count++] = icb; -+ -+ return true; -+} -+ -+static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( -+ struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count); -+ -+static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, -+ struct vkd3d_shader_instruction_array *array) -+{ -+ size_t i; -+ -+ for (i = 0; i < reg->idx_count; ++i) -+ { -+ if (!reg->idx[i].rel_addr) -+ continue; -+ -+ if (!(reg->idx[i].rel_addr = shader_instruction_array_clone_src_params(array, reg->idx[i].rel_addr, 1))) -+ return false; -+ } -+ -+ return true; -+} -+ -+static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( -+ struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_dst_param *params, size_t count) -+{ -+ struct vkd3d_shader_dst_param *dst_params; -+ size_t i; -+ -+ if (!(dst_params = shader_dst_param_allocator_get(&array->dst_params, count))) -+ return NULL; -+ -+ memcpy(dst_params, params, count * sizeof(*params)); -+ for (i = 0; i < count; ++i) -+ { -+ if (!shader_register_clone_relative_addresses(&dst_params[i].reg, array)) -+ return NULL; -+ } -+ -+ return dst_params; -+} -+ -+static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( -+ struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count) -+{ -+ struct vkd3d_shader_src_param *src_params; -+ size_t i; -+ -+ if (!(src_params = shader_src_param_allocator_get(&array->src_params, count))) -+ return NULL; -+ -+ memcpy(src_params, params, count * sizeof(*params)); -+ for (i = 0; i < count; ++i) -+ { -+ if (!shader_register_clone_relative_addresses(&src_params[i].reg, array)) -+ return NULL; -+ } -+ -+ return src_params; -+} -+ -+static void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *array) -+{ -+ unsigned int i; -+ -+ vkd3d_free(array->elements); -+ shader_param_allocator_destroy(&array->dst_params); -+ shader_param_allocator_destroy(&array->src_params); -+ for (i = 0; i < array->icb_count; ++i) -+ { -+ vkd3d_free(array->icbs[i]); -+ } -+ vkd3d_free(array->icbs); -+} -+ -+static bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *array, size_t reserve) -+{ -+ memset(array, 0, sizeof(*array)); -+ /* Size the parameter initial allocations so they are large enough for most shaders. The -+ * code path for chained allocations will be tested if a few shaders need to use it. */ -+ shader_param_allocator_init(&array->dst_params, reserve - reserve / 8u, sizeof(struct vkd3d_shader_dst_param)); -+ shader_param_allocator_init(&array->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); -+ -+ return shader_instruction_array_reserve(array, reserve); -+} -+ - static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, - unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) - { -@@ -907,6 +1086,23 @@ static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *i - vsir_instruction_init(ins, &location, VSIR_OP_NOP); - } - -+/* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the -+ * destination is in use. This seems like a reasonable requirement given how this is currently used. */ -+static bool vsir_program_iterator_clone_instruction(struct vsir_program_iterator *dst_it, -+ const struct vkd3d_shader_instruction *src) -+{ -+ struct vkd3d_shader_instruction *dst = vsir_program_iterator_current(dst_it); -+ -+ *dst = *src; -+ -+ if (dst->dst_count && !(dst->dst = shader_instruction_array_clone_dst_params(dst_it->array, -+ dst->dst, dst->dst_count))) -+ return false; -+ -+ return !dst->src_count || !!(dst->src = shader_instruction_array_clone_src_params(dst_it->array, -+ dst->src, dst->src_count)); -+} -+ - static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, - enum vsir_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap) - { -@@ -2238,8 +2434,6 @@ struct hull_flattener - { - struct vsir_program *program; - -- unsigned int instance_count; -- unsigned int phase_body_idx; - enum vkd3d_shader_opcode phase; - struct vkd3d_shader_location last_ret_location; - unsigned int *ssa_map; -@@ -2251,68 +2445,6 @@ static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flat - return flattener->phase == VSIR_OP_HS_FORK_PHASE || flattener->phase == VSIR_OP_HS_JOIN_PHASE; - } - --struct shader_phase_location --{ -- unsigned int index; -- unsigned int instance_count; -- unsigned int instruction_count; --}; -- --struct shader_phase_location_array --{ -- /* Unlikely worst case: one phase for each component of each output register. */ -- struct shader_phase_location locations[MAX_REG_OUTPUT * VKD3D_VEC4_SIZE]; -- unsigned int count; --}; -- --static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index, -- struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations) --{ -- struct shader_phase_location *loc; -- bool b; -- -- if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) -- { -- b = flattener_is_in_fork_or_join_phase(normaliser); -- /* Reset the phase info. */ -- normaliser->phase_body_idx = ~0u; -- normaliser->phase = ins->opcode; -- normaliser->instance_count = 1; -- /* Leave the first occurrence and delete the rest. */ -- if (b) -- vkd3d_shader_instruction_make_nop(ins); -- return; -- } -- else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT -- || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) -- { -- normaliser->instance_count = ins->declaration.count + !ins->declaration.count; -- vkd3d_shader_instruction_make_nop(ins); -- return; -- } -- -- if (normaliser->phase == VSIR_OP_INVALID || vsir_instruction_is_dcl(ins)) -- return; -- -- if (normaliser->phase_body_idx == ~0u) -- normaliser->phase_body_idx = index; -- -- if (ins->opcode == VSIR_OP_RET) -- { -- normaliser->last_ret_location = ins->location; -- vkd3d_shader_instruction_make_nop(ins); -- if (locations->count >= ARRAY_SIZE(locations->locations)) -- { -- FIXME("Insufficient space for phase location.\n"); -- return; -- } -- loc = &locations->locations[locations->count++]; -- loc->index = normaliser->phase_body_idx; -- loc->instance_count = normaliser->instance_count; -- loc->instruction_count = index - normaliser->phase_body_idx; -- } --} -- - static void flattener_fixup_ssa_register(struct hull_flattener *normaliser, - struct vkd3d_shader_register *reg, unsigned int instance_id) - { -@@ -2375,54 +2507,109 @@ static void flattener_fixup_registers(struct hull_flattener *normaliser, - flattener_fixup_register_indices(normaliser, &ins->dst[i].reg, instance_id); - } - --static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser, -- struct shader_phase_location_array *locations) -+static enum vkd3d_result flattener_replicate_location(struct hull_flattener *normaliser, -+ struct vsir_program_iterator *it, size_t instance_count, size_t instruction_count) - { -- struct vkd3d_shader_instruction_array *instructions = &normaliser->program->instructions; -- struct shader_phase_location *loc; -- unsigned int i, j, k, end, count; -- -- for (i = 0, count = 0; i < locations->count; ++i) -- count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count; -+ struct vsir_program_iterator dst_it, src_it, first_it; -+ struct vkd3d_shader_instruction *ins; -+ unsigned int i, j; -+ size_t count; - -- if (!shader_instruction_array_reserve(instructions, instructions->count + count)) -+ VKD3D_ASSERT(instance_count); -+ count = (instance_count - 1) * instruction_count; -+ if (!vsir_program_iterator_insert_before(it, &first_it, count)) - return VKD3D_ERROR_OUT_OF_MEMORY; -- end = instructions->count; -- instructions->count += count; - -- for (i = locations->count; i > 0; --i) -+ /* Make a copy of the non-dcl instructions for each instance. */ -+ dst_it = first_it; -+ for (i = 1; i < instance_count; ++i) -+ { -+ src_it = *it; -+ for (j = 0; j < instruction_count; ++j) -+ { -+ if (!vsir_program_iterator_clone_instruction(&dst_it, vsir_program_iterator_current(&src_it))) -+ return VKD3D_ERROR_OUT_OF_MEMORY; -+ -+ vsir_program_iterator_next(&dst_it); -+ vsir_program_iterator_next(&src_it); -+ } -+ } -+ /* Replace each reference to the instance id with a constant instance id. */ -+ *it = first_it; -+ for (i = 0; i < instance_count; ++i) - { -- loc = &locations->locations[i - 1]; -- j = loc->index + loc->instruction_count; -- memmove(&instructions->elements[j + count], &instructions->elements[j], -- (end - j) * sizeof(*instructions->elements)); -- end = j; -- count -= (loc->instance_count - 1) * loc->instruction_count; -- loc->index += count; -+ if (i) -+ memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); -+ -+ for (j = 0; j < instruction_count; ++j) -+ { -+ ins = vsir_program_iterator_current(it); -+ flattener_fixup_registers(normaliser, ins, i); -+ vsir_program_iterator_next(it); -+ } - } - -- for (i = 0, count = 0; i < locations->count; ++i) -+ return VKD3D_OK; -+} -+ -+static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser) -+{ -+ struct vsir_program_iterator it = vsir_program_iterator(&normaliser->program->instructions); -+ struct vsir_program_iterator phase_body_it; -+ struct vkd3d_shader_instruction *ins; -+ bool b, phase_body_it_valid = false; -+ unsigned int instruction_count = 0; -+ unsigned int instance_count = 0; -+ enum vkd3d_result res; -+ -+ normaliser->phase = VSIR_OP_INVALID; -+ for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) - { -- loc = &locations->locations[i]; -- /* Make a copy of the non-dcl instructions for each instance. */ -- for (j = 1; j < loc->instance_count; ++j) -+ if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) - { -- for (k = 0; k < loc->instruction_count; ++k) -- { -- if (!shader_instruction_array_clone_instruction(instructions, -- loc->index + loc->instruction_count * j + k, loc->index + k)) -- return VKD3D_ERROR_OUT_OF_MEMORY; -- } -+ b = flattener_is_in_fork_or_join_phase(normaliser); -+ /* Reset the phase info. */ -+ phase_body_it_valid = false; -+ normaliser->phase = ins->opcode; -+ instance_count = 1; -+ instruction_count = 0; -+ /* Leave the first occurrence and delete the rest. */ -+ if (b) -+ vkd3d_shader_instruction_make_nop(ins); -+ continue; - } -- /* Replace each reference to the instance id with a constant instance id. */ -- for (j = 0; j < loc->instance_count; ++j) -+ else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT -+ || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) - { -- if (j != 0) -- memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); -+ instance_count = ins->declaration.count + !ins->declaration.count; -+ vkd3d_shader_instruction_make_nop(ins); -+ ++instruction_count; -+ continue; -+ } - -- for (k = 0; k < loc->instruction_count; ++k) -- flattener_fixup_registers(normaliser, -- &instructions->elements[loc->index + loc->instruction_count * j + k], j); -+ if (normaliser->phase == VSIR_OP_INVALID) -+ continue; -+ -+ if (!phase_body_it_valid && !vsir_instruction_is_dcl(ins)) -+ { -+ phase_body_it_valid = true; -+ phase_body_it = it; -+ instruction_count = 0; -+ } -+ -+ if (ins->opcode == VSIR_OP_RET) -+ { -+ normaliser->last_ret_location = ins->location; -+ vkd3d_shader_instruction_make_nop(ins); -+ it = phase_body_it; -+ if ((res = flattener_replicate_location(normaliser, &it, -+ instance_count, instruction_count)) < 0) -+ return res; -+ phase_body_it_valid = false; -+ } -+ else -+ { -+ ++instruction_count; - } - } - -@@ -2432,19 +2619,10 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali - static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -- struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); -- struct shader_phase_location_array locations; - struct hull_flattener flattener = {program}; - struct vkd3d_shader_instruction *ins; - enum vkd3d_result result = VKD3D_OK; -- unsigned int i; - -- flattener.phase = VSIR_OP_INVALID; -- locations.count = 0; -- for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) -- { -- flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations); -- } - bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); - bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); - -@@ -2452,8 +2630,7 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro - if (!(flattener.ssa_map = vkd3d_calloc(flattener.orig_ssa_count, sizeof(*flattener.ssa_map)))) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- result = flattener_flatten_phases(&flattener, &locations); -- -+ result = flattener_flatten_phases(&flattener); - vkd3d_free(flattener.ssa_map); - flattener.ssa_map = NULL; - -@@ -2519,8 +2696,8 @@ static void shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param - } - - static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser, -- const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst, -- const struct vkd3d_shader_location *location) -+ const struct shader_signature *s, unsigned int input_control_point_count, -+ struct vsir_program_iterator *dst_it, const struct vkd3d_shader_location *location) - { - struct vkd3d_shader_instruction *ins; - const struct signature_element *e; -@@ -2529,17 +2706,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p - for (i = 0; i < s->element_count; ++i) - count += !!s->elements[i].used_mask; - -- if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count)) -+ if (!(ins = vsir_program_iterator_insert_before_and_move(dst_it, count))) - return VKD3D_ERROR_OUT_OF_MEMORY; -- -- memmove(&normaliser->instructions.elements[dst + count], &normaliser->instructions.elements[dst], -- (normaliser->instructions.count - dst) * sizeof(*normaliser->instructions.elements)); -- normaliser->instructions.count += count; -- -- ins = &normaliser->instructions.elements[dst]; - vsir_instruction_init(ins, location, VSIR_OP_HS_CONTROL_POINT_PHASE); - -- ++ins; -+ ins = vsir_program_iterator_next(dst_it); - - for (i = 0; i < s->element_count; ++i) - { -@@ -2571,7 +2742,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p - ins->src[0].reg.idx[0].rel_addr = normaliser->outpointid_param; - ins->src[0].reg.idx[1].offset = e->register_index; - -- ++ins; -+ ins = vsir_program_iterator_next(dst_it); - } - - vsir_instruction_init(ins, location, VSIR_OP_RET); -@@ -2643,8 +2814,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i - case VSIR_OP_HS_JOIN_PHASE: - /* ins may be relocated if the instruction array expands. */ - location = ins->location; -- ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature, -- input_control_point_count, i, &location); -+ ret = control_point_normaliser_emit_hs_input(&normaliser, -+ &program->input_signature, input_control_point_count, &it, &location); - program->instructions = normaliser.instructions; - program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; - return ret; -@@ -4839,8 +5010,8 @@ struct vsir_cfg - { - struct vkd3d_shader_message_context *message_context; - struct vsir_program *program; -- size_t function_begin; -- size_t function_end; -+ struct vsir_program_iterator function_begin; -+ struct vsir_program_iterator function_end; - struct vsir_block *blocks; - struct vsir_block *entry; - size_t block_count; -@@ -5085,10 +5256,11 @@ static void vsir_cfg_dump_structured_program(struct vsir_cfg *cfg) - } - - static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program *program, -- struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, -- size_t *pos) -+ struct vkd3d_shader_message_context *message_context, -+ struct vsir_cfg_emit_target *target, struct vsir_program_iterator *it) - { - struct vsir_block *current_block = NULL; -+ struct vkd3d_shader_instruction *ins; - enum vkd3d_result ret; - size_t i; - -@@ -5097,7 +5269,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - cfg->program = program; - cfg->block_count = program->block_count; - cfg->target = target; -- cfg->function_begin = *pos; -+ cfg->function_begin = *it; - - vsir_block_list_init(&cfg->order); - -@@ -5107,12 +5279,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - if (TRACE_ON()) - vkd3d_string_buffer_init(&cfg->debug_buffer); - -- for (i = *pos; i < program->instructions.count; ++i) -+ for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) - { -- struct vkd3d_shader_instruction *instruction = &program->instructions.elements[i]; - bool finish = false; - -- switch (instruction->opcode) -+ switch (ins->opcode) - { - case VSIR_OP_PHI: - case VSIR_OP_SWITCH_MONOLITHIC: -@@ -5120,7 +5291,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - - case VSIR_OP_LABEL: - { -- unsigned int label = label_from_src_param(&instruction->src[0]); -+ unsigned int label = label_from_src_param(&ins->src[0]); - - VKD3D_ASSERT(!current_block); - VKD3D_ASSERT(label > 0); -@@ -5129,7 +5300,8 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - VKD3D_ASSERT(current_block->label == 0); - if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0) - goto fail; -- current_block->begin = &program->instructions.elements[i + 1]; -+ current_block->begin = vsir_program_iterator_next(it); -+ vsir_program_iterator_prev(it); - if (!cfg->entry) - cfg->entry = current_block; - break; -@@ -5138,7 +5310,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - case VSIR_OP_BRANCH: - case VSIR_OP_RET: - VKD3D_ASSERT(current_block); -- current_block->end = instruction; -+ current_block->end = ins; - current_block = NULL; - break; - -@@ -5157,8 +5329,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program - break; - } - -- *pos = i; -- cfg->function_end = *pos; -+ cfg->function_end = *it; - - for (i = 0; i < cfg->block_count; ++i) - { -@@ -6655,13 +6826,13 @@ static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg) - } - - static enum vkd3d_result vsir_program_structurize_function(struct vsir_program *program, -- struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, -- size_t *pos) -+ struct vkd3d_shader_message_context *message_context, -+ struct vsir_cfg_emit_target *target, struct vsir_program_iterator *it) - { - enum vkd3d_result ret; - struct vsir_cfg cfg; - -- if ((ret = vsir_cfg_init(&cfg, program, message_context, target, pos)) < 0) -+ if ((ret = vsir_cfg_init(&cfg, program, message_context, target, it)) < 0) - return ret; - - vsir_cfg_compute_dominators(&cfg); -@@ -6692,10 +6863,11 @@ out: - static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; - struct vsir_cfg_emit_target target = {0}; -+ struct vkd3d_shader_instruction *ins; - enum vkd3d_result ret; -- size_t i; - - VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); - -@@ -6705,19 +6877,17 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, - if (!reserve_instructions(&target.instructions, &target.ins_capacity, program->instructions.count)) - return VKD3D_ERROR_OUT_OF_MEMORY; - -- for (i = 0; i < program->instructions.count;) -+ for (ins = vsir_program_iterator_head(&it); ins;) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - switch (ins->opcode) - { - case VSIR_OP_LABEL: - VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); - TRACE("Structurizing a non-hull shader.\n"); -- if ((ret = vsir_program_structurize_function(program, message_context, -- &target, &i)) < 0) -+ if ((ret = vsir_program_structurize_function(program, message_context, &target, &it)) < 0) - goto fail; -- VKD3D_ASSERT(i == program->instructions.count); -+ ins = vsir_program_iterator_current(&it); -+ VKD3D_ASSERT(!ins); - break; - - case VSIR_OP_HS_CONTROL_POINT_PHASE: -@@ -6726,17 +6896,17 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, - VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); - TRACE("Structurizing phase %u of a hull shader.\n", ins->opcode); - target.instructions[target.ins_count++] = *ins; -- ++i; -- if ((ret = vsir_program_structurize_function(program, message_context, -- &target, &i)) < 0) -+ vsir_program_iterator_next(&it); -+ if ((ret = vsir_program_structurize_function(program, message_context, &target, &it)) < 0) - goto fail; -+ ins = vsir_program_iterator_current(&it); - break; - - default: - if (!reserve_instructions(&target.instructions, &target.ins_capacity, target.ins_count + 1)) - return VKD3D_ERROR_OUT_OF_MEMORY; - target.instructions[target.ins_count++] = *ins; -- ++i; -+ ins = vsir_program_iterator_next(&it); - break; - } - } -@@ -6781,8 +6951,10 @@ static void register_map_undominated_use(struct vkd3d_shader_register *reg, stru - static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct vsir_cfg *cfg) - { - struct vsir_program *program = cfg->program; -+ struct vkd3d_shader_instruction *ins, *end; - struct ssas_to_temps_alloc alloc = {0}; - struct vsir_block **origin_blocks; -+ struct vsir_program_iterator it; - unsigned int j; - size_t i; - -@@ -6800,7 +6972,6 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v - for (i = 0; i < cfg->block_count; ++i) - { - struct vsir_block *block = &cfg->blocks[i]; -- struct vkd3d_shader_instruction *ins; - - if (block->label == 0) - continue; -@@ -6818,7 +6989,6 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v - for (i = 0; i < cfg->block_count; ++i) - { - struct vsir_block *block = &cfg->blocks[i]; -- struct vkd3d_shader_instruction *ins; - - if (block->label == 0) - continue; -@@ -6835,10 +7005,10 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v - - TRACE("Emitting temps for %u values with undominated usage.\n", alloc.next_temp_idx - program->temp_count); - -- for (i = cfg->function_begin; i < cfg->function_end; ++i) -+ it = cfg->function_begin; -+ end = vsir_program_iterator_current(&cfg->function_end); -+ for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - for (j = 0; j < ins->dst_count; ++j) - materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst[j].reg); - -@@ -6854,14 +7024,13 @@ done: - return VKD3D_OK; - } - --static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function( -- struct vsir_program *program, struct vkd3d_shader_message_context *message_context, -- size_t *pos) -+static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function(struct vsir_program *program, -+ struct vkd3d_shader_message_context *message_context, struct vsir_program_iterator *it) - { - enum vkd3d_result ret; - struct vsir_cfg cfg; - -- if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, pos)) < 0) -+ if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, it)) < 0) - return ret; - - vsir_cfg_compute_dominators(&cfg); -@@ -6876,25 +7045,25 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_f - static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program, - struct vsir_transformation_context *ctx) - { -+ struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; -+ struct vkd3d_shader_instruction *ins; - enum vkd3d_result ret; -- size_t i; - - VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); - -- for (i = 0; i < program->instructions.count;) -+ for (ins = vsir_program_iterator_head(&it); ins;) - { -- struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; -- - switch (ins->opcode) - { - case VSIR_OP_LABEL: - VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); - TRACE("Materializing undominated SSAs in a non-hull shader.\n"); - if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( -- program, message_context, &i)) < 0) -+ program, message_context, &it)) < 0) - return ret; -- VKD3D_ASSERT(i == program->instructions.count); -+ ins = vsir_program_iterator_current(&it); -+ VKD3D_ASSERT(!ins); - break; - - case VSIR_OP_HS_CONTROL_POINT_PHASE: -@@ -6902,14 +7071,15 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru - case VSIR_OP_HS_JOIN_PHASE: - VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); - TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->opcode); -- ++i; -+ vsir_program_iterator_next(&it); - if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( -- program, message_context, &i)) < 0) -+ program, message_context, &it)) < 0) - return ret; -+ ins = vsir_program_iterator_current(&it); - break; - - default: -- ++i; -+ ins = vsir_program_iterator_next(&it); - break; - } - } -@@ -9057,7 +9227,7 @@ struct validation_context - struct vkd3d_shader_message_context *message_context; - const struct vsir_program *program; - size_t instruction_idx; -- struct vkd3d_shader_location null_location; -+ struct vkd3d_shader_location location; - bool invalid_instruction_idx; - enum vkd3d_result status; - bool dcl_temps_found; -@@ -9116,13 +9286,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c - - if (ctx->invalid_instruction_idx) - { -- vkd3d_shader_error(ctx->message_context, &ctx->null_location, error, "%s", buf.buffer); -+ vkd3d_shader_error(ctx->message_context, &ctx->location, error, "%s", buf.buffer); - WARN("VSIR validation error: %s\n", buf.buffer); - } - else - { -- const struct vkd3d_shader_instruction *ins = &ctx->program->instructions.elements[ctx->instruction_idx]; -- vkd3d_shader_error(ctx->message_context, &ins->location, error, -+ vkd3d_shader_error(ctx->message_context, &ctx->location, error, - "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); - WARN("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); - } -@@ -10995,19 +11164,21 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, - - if (!src_types[src_data_type]) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid source data type %#x for cast operation \"%s\" (%#x).", -- src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ "Invalid source data type \"%s\" (%#x) for cast operation \"%s\" (%#x).", -+ vsir_data_type_get_name(src_data_type, ""), src_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - - if (!dst_types[dst_data_type]) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid destination data type %#x for cast operation \"%s\" (%#x).", -- dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ "Invalid destination data type \"%s\" (%#x) for cast operation \"%s\" (%#x).", -+ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - } - - static void vsir_validate_shift_operation(struct validation_context *ctx, - const struct vkd3d_shader_instruction *instruction) - { -- enum vsir_data_type data_type; -+ enum vsir_data_type dst_data_type, src_data_type; - - static const bool types[] = - { -@@ -11016,24 +11187,27 @@ static void vsir_validate_shift_operation(struct validation_context *ctx, - [VSIR_DATA_U64] = true, - }; - -- data_type = instruction->dst[0].reg.data_type; -- if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) -+ dst_data_type = instruction->dst[0].reg.data_type; -+ if ((size_t)dst_data_type >= ARRAY_SIZE(types) || !types[dst_data_type]) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid destination data type %#x for shift operation \"%s\" (%#x).", -- data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ "Invalid destination data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", -+ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - -- if (instruction->src[0].reg.data_type != data_type) -+ if ((src_data_type = instruction->src[0].reg.data_type) != dst_data_type) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Data type %#x for source operand 0 doesn't match destination data type %#x " -+ "Data type \"%s\" (%#x) for source operand 0 doesn't match destination data type \"%s\" (%#x) " - "for shift operation \"%s\" (%#x).", -- instruction->src[0].reg.data_type, data_type, -+ vsir_data_type_get_name(src_data_type, ""), src_data_type, -+ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, - vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - -- data_type = instruction->src[1].reg.data_type; -- if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) -+ src_data_type = instruction->src[1].reg.data_type; -+ if ((size_t)src_data_type >= ARRAY_SIZE(types) || !types[src_data_type]) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid source operand 1 data type %#x for shift operation \"%s\" (%#x).", -- data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); -+ "Invalid source operand 1 data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", -+ vsir_data_type_get_name(src_data_type, ""), src_data_type, -+ vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - } - - static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) -@@ -11728,7 +11902,8 @@ static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validat - enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; - - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, -- "Invalid destination data type %#x for operation \"%s\" (%#x) with flags %#x.", dst_data_type, -+ "Invalid destination data type \"%s\" (%#x) for operation \"%s\" (%#x) with flags %#x.", -+ vsir_data_type_get_name(dst_data_type, ""), dst_data_type, - vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode, instruction->flags); - } - -@@ -12029,7 +12204,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c - { - .message_context = message_context, - .program = program, -- .null_location = {.source_name = source_name}, -+ .location = {.source_name = source_name}, - .status = VKD3D_OK, - .phase = VSIR_OP_INVALID, - .invalid_instruction_idx = true, -@@ -12154,11 +12329,13 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c - for (ins = vsir_program_iterator_head(&it); ins && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(&it)) - { -+ ctx.location = ins->location; - vsir_validate_instruction(&ctx, ins); - ++ctx.instruction_idx; - } - - ctx.invalid_instruction_idx = true; -+ ctx.location = (struct vkd3d_shader_location){.source_name = source_name}; - - if (ctx.depth != 0) - validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "%zu nested blocks were not closed.", ctx.depth); -diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c -index d9e22abdfc3..9150e77e2c6 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/msl.c -+++ b/libs/vkd3d/libs/vkd3d-shader/msl.c -@@ -943,8 +943,8 @@ static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct ms - - static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) - { -+ unsigned int resource_id, resource_idx, resource_space, sample_count; - const struct msl_resource_type_info *resource_type_info; -- unsigned int resource_id, resource_idx, resource_space; - const struct vkd3d_shader_descriptor_info1 *descriptor; - const struct vkd3d_shader_descriptor_binding *binding; - enum vkd3d_shader_resource_type resource_type; -@@ -969,6 +969,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - { - resource_type = descriptor->resource_type; - resource_space = descriptor->register_space; -+ sample_count = descriptor->sample_count; - data_type = descriptor->resource_data_type; - } - else -@@ -977,6 +978,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - "Internal compiler error: Undeclared resource descriptor %u.", resource_id); - resource_space = 0; - resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ sample_count = 1; - data_type = VSIR_DATA_F32; - } - -@@ -988,6 +990,16 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, - "Texel fetches from resource type %#x are not supported.", resource_type); - -+ if (sample_count == 1) -+ { -+ /* Similar to the SPIR-V and GLSL targets, we map multi-sample -+ * textures with sample count 1 to their single-sample equivalents. */ -+ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS) -+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; -+ else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) -+ resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; -+ } -+ - if (!(resource_type_info = msl_get_resource_type_info(resource_type))) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -@@ -1030,6 +1042,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct - vkd3d_string_buffer_printf(read, ", "); - if (ins->opcode != VSIR_OP_LD2DMS) - msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32); -+ else if (sample_count == 1) -+ /* If the resource isn't a true multisample resource, this is the -+ * "lod" parameter instead of the "sample" parameter. */ -+ vkd3d_string_buffer_printf(read, "0"); - else - msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); - } -@@ -1294,6 +1310,11 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh - data_type = VSIR_DATA_F32; - } - -+ if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS -+ || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) -+ msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, -+ "Storing to resource type %#x is not supported.", resource_type); -+ - if (!(resource_type_info = msl_get_resource_type_info(resource_type))) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, -diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c -index 9cd9aafb587..756aab995a3 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/spirv.c -+++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c -@@ -2553,8 +2553,9 @@ static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder - case VKD3D_SHADER_COMPONENT_DOUBLE: - type_id = vkd3d_spirv_get_op_type_float(builder, 64); - break; -+ case VKD3D_SHADER_COMPONENT_INT64: - case VKD3D_SHADER_COMPONENT_UINT64: -- type_id = vkd3d_spirv_get_op_type_int(builder, 64, 0); -+ type_id = vkd3d_spirv_get_op_type_int(builder, 64, component_type == VKD3D_SHADER_COMPONENT_INT64); - break; - default: - FIXME("Unhandled component type %#x.\n", component_type); -@@ -3700,7 +3701,8 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, - VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); - type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - -- if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64) -+ if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_INT64 -+ && component_type != VKD3D_SHADER_COMPONENT_UINT64) - { - FIXME("Unhandled component_type %#x.\n", component_type); - return vkd3d_spirv_get_op_undef(builder, type_id); -@@ -4497,7 +4499,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; - - return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, -- data_type == VSIR_DATA_U64 -+ data_type_is_64_bit(data_type) - ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) - : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); - } -@@ -4537,7 +4539,8 @@ static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compile - - true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); - false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); -+ - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -@@ -4549,7 +4552,8 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil - - true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); - false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F64, component_count); -+ - return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); - } - -@@ -4725,6 +4729,7 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil - &icb->data[component_count * i]); - break; - case VSIR_DATA_F64: -+ case VSIR_DATA_I64: - case VSIR_DATA_U64: - { - uint64_t *data = (uint64_t *)icb->data; -@@ -5284,9 +5289,8 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * - vkd3d_spirv_add_iface_variable(builder, base_var_id); - spirv_compiler_decorate_builtin(compiler, base_var_id, base); - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_INT, 1); -- base_id = vkd3d_spirv_build_op_load(builder, -- type_id, base_var_id, SpvMemoryAccessMaskNone); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); -+ base_id = vkd3d_spirv_build_op_load(builder, type_id, base_var_id, SpvMemoryAccessMaskNone); - - return vkd3d_spirv_build_op_isub(builder, type_id, index_id, base_id); - } -@@ -5314,17 +5318,16 @@ static uint32_t sv_front_face_fixup(struct spirv_compiler *compiler, - } - - /* frag_coord.w = 1.0f / frag_coord.w */ --static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, -- uint32_t frag_coord_id) -+static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, uint32_t frag_coord_id) - { - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - uint32_t type_id, w_id; - -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); - w_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, frag_coord_id, 3); -- w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, -- spirv_compiler_get_constant_float(compiler, 1.0f), w_id); -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); -+ w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, spirv_compiler_get_constant_float(compiler, 1.0f), w_id); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); -+ - return vkd3d_spirv_build_op_composite_insert1(builder, type_id, w_id, frag_coord_id, 3); - } - -@@ -5530,7 +5533,8 @@ static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *co - uint32_t type_id, id; - - id = spirv_compiler_get_invocation_id(compiler); -- type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_INT, 1); -+ type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); -+ - return vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); - } - -@@ -7628,11 +7632,12 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, - /* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */ - val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); - } -- else if (dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) -+ else if (dst->reg.data_type == VSIR_DATA_I16 || dst->reg.data_type == VSIR_DATA_I32 -+ || dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) - { - val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); - } -- else if (dst->reg.data_type == VSIR_DATA_U64) -+ else if (dst->reg.data_type == VSIR_DATA_I64 || dst->reg.data_type == VSIR_DATA_U64) - { - val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); - } -@@ -7728,7 +7733,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]); - -- if (dst[0].reg.data_type == VSIR_DATA_U64) -+ if (data_type_is_64_bit(dst[0].reg.data_type)) - uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count); - else - uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); -@@ -7843,7 +7848,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp - unsigned int i, component_count; - enum GLSLstd450 glsl_inst; - -- if (src[0].reg.data_type == VSIR_DATA_U64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI -+ if (data_type_is_64_bit(src[0].reg.data_type) && (instruction->opcode == VSIR_OP_FIRSTBIT_HI - || instruction->opcode == VSIR_OP_FIRSTBIT_LO || instruction->opcode == VSIR_OP_FIRSTBIT_SHI)) - { - /* At least some drivers support this anyway, but if validation is enabled it will fail. */ -@@ -8254,7 +8259,7 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp - - component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); - type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); -- size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20; -+ size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; - mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); - size_id = spirv_compiler_get_constant_uint(compiler, size); - -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -index 08450b4cf85..6949c1cd38f 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c -@@ -2297,204 +2297,6 @@ void vkd3d_shader_set_log_callback(PFN_vkd3d_log callback) - vkd3d_dbg_set_log_callback(callback); - } - --static struct vkd3d_shader_param_node *shader_param_allocator_node_create( -- struct vkd3d_shader_param_allocator *allocator) --{ -- struct vkd3d_shader_param_node *node; -- -- if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride])))) -- return NULL; -- node->next = NULL; -- return node; --} -- --static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, -- size_t count, size_t stride) --{ -- allocator->count = max(count, MAX_REG_OUTPUT); -- allocator->stride = stride; -- allocator->head = NULL; -- allocator->current = NULL; -- allocator->index = allocator->count; --} -- --static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator) --{ -- struct vkd3d_shader_param_node *current = allocator->head; -- -- while (current) -- { -- struct vkd3d_shader_param_node *next = current->next; -- vkd3d_free(current); -- current = next; -- } --} -- --void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) --{ -- void *params; -- -- if (!allocator->current || count > allocator->count - allocator->index) -- { -- struct vkd3d_shader_param_node *next; -- -- /* Monolithic switch has no definite parameter count limit. */ -- allocator->count = max(allocator->count, count); -- -- if (!(next = shader_param_allocator_node_create(allocator))) -- return NULL; -- if (allocator->current) -- allocator->current->next = next; -- else -- allocator->head = next; -- allocator->current = next; -- allocator->index = 0; -- } -- -- params = &allocator->current->param[allocator->index * allocator->stride]; -- allocator->index += count; -- return params; --} -- --bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve) --{ -- memset(instructions, 0, sizeof(*instructions)); -- /* Size the parameter initial allocations so they are large enough for most shaders. The -- * code path for chained allocations will be tested if a few shaders need to use it. */ -- shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u, -- sizeof(struct vkd3d_shader_dst_param)); -- shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); -- return shader_instruction_array_reserve(instructions, reserve); --} -- --bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve) --{ -- if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve, -- sizeof(*instructions->elements))) -- { -- ERR("Failed to allocate instructions.\n"); -- return false; -- } -- return true; --} -- --bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, -- size_t idx, size_t count) --{ -- VKD3D_ASSERT(idx <= instructions->count); -- -- if (!shader_instruction_array_reserve(instructions, instructions->count + count)) -- return false; -- -- memmove(&instructions->elements[idx + count], &instructions->elements[idx], -- (instructions->count - idx) * sizeof(*instructions->elements)); -- memset(&instructions->elements[idx], 0, count * sizeof(*instructions->elements)); -- -- instructions->count += count; -- -- return true; --} -- --bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, -- struct vkd3d_shader_immediate_constant_buffer *icb) --{ -- if (!vkd3d_array_reserve((void **)&instructions->icbs, &instructions->icb_capacity, instructions->icb_count + 1, -- sizeof(*instructions->icbs))) -- return false; -- instructions->icbs[instructions->icb_count++] = icb; -- return true; --} -- --static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( -- struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, -- size_t count); -- --static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, -- struct vkd3d_shader_instruction_array *instructions) --{ -- unsigned int i; -- -- for (i = 0; i < reg->idx_count; ++i) -- { -- if (!reg->idx[i].rel_addr) -- continue; -- -- if (!(reg->idx[i].rel_addr = shader_instruction_array_clone_src_params(instructions, reg->idx[i].rel_addr, 1))) -- return false; -- } -- -- return true; --} -- --static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( -- struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_dst_param *params, -- size_t count) --{ -- struct vkd3d_shader_dst_param *dst_params; -- size_t i; -- -- if (!(dst_params = shader_dst_param_allocator_get(&instructions->dst_params, count))) -- return NULL; -- -- memcpy(dst_params, params, count * sizeof(*params)); -- for (i = 0; i < count; ++i) -- { -- if (!shader_register_clone_relative_addresses(&dst_params[i].reg, instructions)) -- return NULL; -- } -- -- return dst_params; --} -- --static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( -- struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, -- size_t count) --{ -- struct vkd3d_shader_src_param *src_params; -- size_t i; -- -- if (!(src_params = shader_src_param_allocator_get(&instructions->src_params, count))) -- return NULL; -- -- memcpy(src_params, params, count * sizeof(*params)); -- for (i = 0; i < count; ++i) -- { -- if (!shader_register_clone_relative_addresses(&src_params[i].reg, instructions)) -- return NULL; -- } -- -- return src_params; --} -- --/* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the -- * destination is in use. This seems like a reasonable requirement given how this is currently used. */ --bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, -- size_t dst, size_t src) --{ -- struct vkd3d_shader_instruction *ins = &instructions->elements[dst]; -- -- *ins = instructions->elements[src]; -- -- if (ins->dst_count && ins->dst && !(ins->dst = shader_instruction_array_clone_dst_params(instructions, -- ins->dst, ins->dst_count))) -- return false; -- -- return !ins->src_count || !!(ins->src = shader_instruction_array_clone_src_params(instructions, -- ins->src, ins->src_count)); --} -- --void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions) --{ -- unsigned int i; -- -- vkd3d_free(instructions->elements); -- shader_param_allocator_destroy(&instructions->dst_params); -- shader_param_allocator_destroy(&instructions->src_params); -- for (i = 0; i < instructions->icb_count; ++i) -- vkd3d_free(instructions->icbs[i]); -- vkd3d_free(instructions->icbs); --} -- - void vkd3d_shader_build_varying_map(const struct vkd3d_shader_signature *output_signature, - const struct vkd3d_shader_signature *input_signature, - unsigned int *ret_count, struct vkd3d_shader_varying_map *varyings) -diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -index ae88d97f461..c00a7825610 100644 ---- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -+++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h -@@ -716,7 +716,9 @@ enum vsir_data_type - VSIR_DATA_F32, - VSIR_DATA_F64, - -+ VSIR_DATA_I16, - VSIR_DATA_I32, -+ VSIR_DATA_I64, - - VSIR_DATA_U8, - VSIR_DATA_U16, -@@ -738,8 +740,9 @@ const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error); - - static inline bool data_type_is_integer(enum vsir_data_type data_type) - { -- return data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 -- || data_type == VSIR_DATA_U32 || data_type == VSIR_DATA_U64; -+ return data_type == VSIR_DATA_I16 || data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_I64 -+ || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 || data_type == VSIR_DATA_U32 -+ || data_type == VSIR_DATA_U64; - } - - static inline bool data_type_is_bool(enum vsir_data_type data_type) -@@ -754,7 +757,7 @@ static inline bool data_type_is_floating_point(enum vsir_data_type data_type) - - static inline bool data_type_is_64_bit(enum vsir_data_type data_type) - { -- return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_U64; -+ return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_I64 || data_type == VSIR_DATA_U64; - } - - enum vsir_dimension -@@ -1441,15 +1444,11 @@ struct vkd3d_shader_instruction_array - struct vkd3d_shader_src_param *outpointid_param; - }; - --bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve); - bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve); - bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, - size_t idx, size_t count); - bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, - struct vkd3d_shader_immediate_constant_buffer *icb); --bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, -- size_t dst, size_t src); --void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); - - struct vsir_program_iterator - { -@@ -1512,6 +1511,28 @@ static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterat - return shader_instruction_array_insert_at(it->array, it->idx + 1, count); - } - -+/* When insertion takes place, argument `it' is updated to point to the same -+ * instruction as before the insertion, and the optional argument `ins_it' is -+ * initialized to point to the first inserted instruction. -+ * A pointer to the first inserted instruction is returned. */ -+static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before( -+ struct vsir_program_iterator *it, struct vsir_program_iterator *ins_it, size_t count) -+{ -+ VKD3D_ASSERT(it != ins_it); -+ VKD3D_ASSERT(it->idx != SIZE_MAX); -+ -+ if (!shader_instruction_array_insert_at(it->array, it->idx, count)) -+ return NULL; -+ -+ *ins_it = *it; -+ it->idx += count; -+ -+ return vsir_program_iterator_current(ins_it); -+} -+ -+/* When insertion takes place, argument `it' is updated to point to the first -+ * inserted instruction. A pointer to this first inserted instruction is -+ * returned. */ - static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before_and_move( - struct vsir_program_iterator *it, size_t count) - { -@@ -1871,14 +1892,20 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty - return VKD3D_SHADER_COMPONENT_FLOAT; - case VSIR_DATA_F64: - return VKD3D_SHADER_COMPONENT_DOUBLE; -+ case VSIR_DATA_I16: -+ return VKD3D_SHADER_COMPONENT_INT16; - case VSIR_DATA_I32: - return VKD3D_SHADER_COMPONENT_INT; -+ case VSIR_DATA_I64: -+ return VKD3D_SHADER_COMPONENT_INT64; - case VSIR_DATA_U16: - return VKD3D_SHADER_COMPONENT_UINT16; - case VSIR_DATA_U32: - return VKD3D_SHADER_COMPONENT_UINT; - case VSIR_DATA_U64: - return VKD3D_SHADER_COMPONENT_UINT64; -+ case VSIR_DATA_UNUSED: -+ return VKD3D_SHADER_COMPONENT_VOID; - default: - FIXME("Unhandled data type %#x.\n", data_type); - /* fall-through */ -@@ -1891,23 +1918,41 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_ - { - switch (component_type) - { -- case VKD3D_SHADER_COMPONENT_FLOAT: -- return VSIR_DATA_F32; -+ case VKD3D_SHADER_COMPONENT_VOID: -+ return VSIR_DATA_UNUSED; - case VKD3D_SHADER_COMPONENT_UINT: - return VSIR_DATA_U32; - case VKD3D_SHADER_COMPONENT_INT: - return VSIR_DATA_I32; -+ case VKD3D_SHADER_COMPONENT_FLOAT: -+ return VSIR_DATA_F32; -+ case VKD3D_SHADER_COMPONENT_BOOL: -+ return VSIR_DATA_BOOL; - case VKD3D_SHADER_COMPONENT_DOUBLE: - return VSIR_DATA_F64; -- default: -- FIXME("Unhandled component type %#x.\n", component_type); -- return VSIR_DATA_F32; -+ case VKD3D_SHADER_COMPONENT_UINT64: -+ return VSIR_DATA_U64; -+ case VKD3D_SHADER_COMPONENT_INT64: -+ return VSIR_DATA_I64; -+ case VKD3D_SHADER_COMPONENT_FLOAT16: -+ return VSIR_DATA_F16; -+ case VKD3D_SHADER_COMPONENT_UINT16: -+ return VSIR_DATA_U16; -+ case VKD3D_SHADER_COMPONENT_INT16: -+ return VSIR_DATA_I16; -+ case VKD3D_SHADER_COMPONENT_TYPE_FORCE_32BIT: -+ break; - } -+ -+ FIXME("Unhandled component type %#x.\n", component_type); -+ -+ return VSIR_DATA_UNUSED; - } - - static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) - { -- return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; -+ return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_INT64 -+ || component_type == VKD3D_SHADER_COMPONENT_UINT64; - } - - static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) -diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -index 15c5b77c8df..fea8c2440d1 100644 ---- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -+++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c -@@ -484,7 +484,10 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename - - if (!ret) - { -- if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, preprocessed_code.size, preprocessed_blob))) -+ /* vkd3d-shader output is null-terminated, but the null terminator isn't -+ * included in the size. Increase the size to account for that. */ -+ if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, -+ preprocessed_code.size + 1, preprocessed_blob))) - { - vkd3d_shader_free_shader_code(&preprocessed_code); - return hr; -@@ -1034,7 +1037,9 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, - return hresult_from_vkd3d_result(ret); - } - -- if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size, blob))) -+ /* vkd3d-shader output is null-terminated, but the null terminator isn't -+ * included in the size. Increase the size to account for that. */ -+ if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size + 1, blob))) - vkd3d_shader_free_shader_code(&output); - - return hr; --- -2.51.0 -