From: Alexandre Julliard julliard@winehq.org
--- dlls/d3dcompiler_43/tests/hlsl_d3d11.c | 8 +- libs/vkd3d/config.h | 4 +- libs/vkd3d/include/private/spirv_grammar.h | 10103 ++++++++++++++++ libs/vkd3d/include/private/vkd3d_common.h | 3 + .../include/private/vkd3d_shader_utils.h | 4 - libs/vkd3d/include/vkd3d.h | 1 + libs/vkd3d/include/vkd3d_shader.h | 26 +- libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 229 +- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 163 +- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 34 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 624 +- libs/vkd3d/libs/vkd3d-shader/fx.c | 1920 ++- libs/vkd3d/libs/vkd3d-shader/glsl.c | 95 +- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 534 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 141 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 5 + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 1573 +-- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 3766 +++--- .../libs/vkd3d-shader/hlsl_constant_ops.c | 90 +- libs/vkd3d/libs/vkd3d-shader/ir.c | 512 +- libs/vkd3d/libs/vkd3d-shader/msl.c | 625 +- libs/vkd3d/libs/vkd3d-shader/preproc.y | 10 + libs/vkd3d/libs/vkd3d-shader/spirv.c | 484 +- libs/vkd3d/libs/vkd3d-shader/tpf.c | 187 +- .../libs/vkd3d-shader/vkd3d_shader_main.c | 321 +- .../libs/vkd3d-shader/vkd3d_shader_private.h | 107 +- .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 6 +- libs/vkd3d/libs/vkd3d/command.c | 181 +- libs/vkd3d/libs/vkd3d/device.c | 158 +- libs/vkd3d/libs/vkd3d/resource.c | 14 +- libs/vkd3d/libs/vkd3d/state.c | 124 +- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 22 +- 32 files changed, 18283 insertions(+), 3791 deletions(-) create mode 100644 libs/vkd3d/include/private/spirv_grammar.h
diff --git a/dlls/d3dcompiler_43/tests/hlsl_d3d11.c b/dlls/d3dcompiler_43/tests/hlsl_d3d11.c index 67f61c30a44..5f58e6f3d1c 100644 --- a/dlls/d3dcompiler_43/tests/hlsl_d3d11.c +++ b/dlls/d3dcompiler_43/tests/hlsl_d3d11.c @@ -1125,14 +1125,8 @@ static void test_semantic_reflection(void) { winetest_push_context("Test %u", i);
- todo_wine_if (i > 6) code = compile_shader_flags(tests[i].source, tests[i].target, + code = compile_shader_flags(tests[i].source, tests[i].target, tests[i].legacy ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0); - if (!code) - { - winetest_pop_context(); - continue; - } - hr = D3DReflect(ID3D10Blob_GetBufferPointer(code), ID3D10Blob_GetBufferSize(code), &IID_ID3D11ShaderReflection, (void **)&reflection); ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr); diff --git a/libs/vkd3d/config.h b/libs/vkd3d/config.h index f282667877c..85d63e5fddd 100644 --- a/libs/vkd3d/config.h +++ b/libs/vkd3d/config.h @@ -1,5 +1,5 @@ #define PACKAGE_NAME "vkd3d" -#define PACKAGE_STRING "vkd3d 1.15" -#define PACKAGE_VERSION "1.15" +#define PACKAGE_STRING "vkd3d 1.16" +#define PACKAGE_VERSION "1.16" #define PATH_MAX 1024 #define SONAME_LIBVULKAN "vulkan-1.dll" diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h new file mode 100644 index 00000000000..2aac5a6558c --- /dev/null +++ b/libs/vkd3d/include/private/spirv_grammar.h @@ -0,0 +1,10103 @@ +/* This file is automatically generated from version 1.6.4 of the + * machine-readable SPIR-V grammar. + * + * The original source is covered by the following license: + * + * Copyright (c) 2014-2024 The Khronos Group Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and/or associated documentation files (the "Materials"), + * to deal in the Materials without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Materials, and to permit persons to whom the + * Materials are furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Materials. + * + * MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS + * STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND + * HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ + * + * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS + * IN THE MATERIALS. + */ + +enum spirv_parser_operand_category +{ + SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, + SPIRV_PARSER_OPERAND_CATEGORY_COMPOSITE, + SPIRV_PARSER_OPERAND_CATEGORY_ID, + SPIRV_PARSER_OPERAND_CATEGORY_LITERAL, + SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, +}; + +enum spirv_parser_operand_type +{ + SPIRV_PARSER_OPERAND_TYPE_ACCESS_QUALIFIER, + SPIRV_PARSER_OPERAND_TYPE_ADDRESSING_MODEL, + SPIRV_PARSER_OPERAND_TYPE_BUILT_IN, + SPIRV_PARSER_OPERAND_TYPE_CAPABILITY, + 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_DECORATION, + SPIRV_PARSER_OPERAND_TYPE_DIM, + SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE, + SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODEL, + SPIRV_PARSER_OPERAND_TYPE_FPDENORM_MODE, + SPIRV_PARSER_OPERAND_TYPE_FPENCODING, + SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE, + SPIRV_PARSER_OPERAND_TYPE_FPOPERATION_MODE, + SPIRV_PARSER_OPERAND_TYPE_FPROUNDING_MODE, + SPIRV_PARSER_OPERAND_TYPE_FRAGMENT_SHADING_RATE, + SPIRV_PARSER_OPERAND_TYPE_FUNCTION_CONTROL, + SPIRV_PARSER_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, + SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION, + SPIRV_PARSER_OPERAND_TYPE_HOST_ACCESS_QUALIFIER, + SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_RESULT, + SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE, + SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE, + SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE, + SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_ORDER, + SPIRV_PARSER_OPERAND_TYPE_IMAGE_FORMAT, + SPIRV_PARSER_OPERAND_TYPE_IMAGE_OPERANDS, + SPIRV_PARSER_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER, + SPIRV_PARSER_OPERAND_TYPE_KERNEL_ENQUEUE_FLAGS, + SPIRV_PARSER_OPERAND_TYPE_KERNEL_PROFILING_INFO, + SPIRV_PARSER_OPERAND_TYPE_LINKAGE_TYPE, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_CONTEXT_DEPENDENT_NUMBER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_EXT_INST_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_FLOAT, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_SPEC_CONSTANT_OP_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + SPIRV_PARSER_OPERAND_TYPE_LOAD_CACHE_CONTROL, + SPIRV_PARSER_OPERAND_TYPE_LOOP_CONTROL, + SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, + SPIRV_PARSER_OPERAND_TYPE_MEMORY_MODEL, + SPIRV_PARSER_OPERAND_TYPE_MEMORY_SEMANTICS, + SPIRV_PARSER_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS, + SPIRV_PARSER_OPERAND_TYPE_OVERFLOW_MODES, + SPIRV_PARSER_OPERAND_TYPE_PACKED_VECTOR_FORMAT, + SPIRV_PARSER_OPERAND_TYPE_PAIR_ID_REF_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_PAIR_ID_REF_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_PAIR_LITERAL_INTEGER_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_QUANTIZATION_MODES, + SPIRV_PARSER_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, + SPIRV_PARSER_OPERAND_TYPE_RAY_FLAGS, + SPIRV_PARSER_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE, + SPIRV_PARSER_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE, + SPIRV_PARSER_OPERAND_TYPE_RAY_QUERY_INTERSECTION, + SPIRV_PARSER_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE, + SPIRV_PARSER_OPERAND_TYPE_SAMPLER_FILTER_MODE, + SPIRV_PARSER_OPERAND_TYPE_SCOPE, + SPIRV_PARSER_OPERAND_TYPE_SELECTION_CONTROL, + SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE, + SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS, + SPIRV_PARSER_OPERAND_TYPE_STORE_CACHE_CONTROL, + SPIRV_PARSER_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS, + SPIRV_PARSER_OPERAND_TYPE_TENSOR_CLAMP_MODE, +}; + +static const struct spirv_parser_operand_type_info +{ + const char *name; + enum spirv_parser_operand_category category; + size_t enumerant_count; + const struct spirv_parser_enumerant + { + uint32_t value; + const char *name; + size_t parameter_count; + enum spirv_parser_operand_type *parameters; + } *enumerants; +} +spirv_parser_operand_type_info[] = +{ + [SPIRV_PARSER_OPERAND_TYPE_ACCESS_QUALIFIER] = + { + "AccessQualifier", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "ReadOnly"}, + {0x1, "WriteOnly"}, + {0x2, "ReadWrite"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_ADDRESSING_MODEL] = + { + "AddressingModel", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0, "Logical"}, + {0x1, "Physical32"}, + {0x2, "Physical64"}, + {0x14e4, "PhysicalStorageBuffer64"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_BUILT_IN] = + { + "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 116, + (struct spirv_parser_enumerant[]) + { + {0, "Position"}, + {0x1, "PointSize"}, + {0x3, "ClipDistance"}, + {0x4, "CullDistance"}, + {0x5, "VertexId"}, + {0x6, "InstanceId"}, + {0x7, "PrimitiveId"}, + {0x8, "InvocationId"}, + {0x9, "Layer"}, + {0xa, "ViewportIndex"}, + {0xb, "TessLevelOuter"}, + {0xc, "TessLevelInner"}, + {0xd, "TessCoord"}, + {0xe, "PatchVertices"}, + {0xf, "FragCoord"}, + {0x10, "PointCoord"}, + {0x11, "FrontFacing"}, + {0x12, "SampleId"}, + {0x13, "SamplePosition"}, + {0x14, "SampleMask"}, + {0x16, "FragDepth"}, + {0x17, "HelperInvocation"}, + {0x18, "NumWorkgroups"}, + {0x19, "WorkgroupSize"}, + {0x1a, "WorkgroupId"}, + {0x1b, "LocalInvocationId"}, + {0x1c, "GlobalInvocationId"}, + {0x1d, "LocalInvocationIndex"}, + {0x1e, "WorkDim"}, + {0x1f, "GlobalSize"}, + {0x20, "EnqueuedWorkgroupSize"}, + {0x21, "GlobalOffset"}, + {0x22, "GlobalLinearId"}, + {0x24, "SubgroupSize"}, + {0x25, "SubgroupMaxSize"}, + {0x26, "NumSubgroups"}, + {0x27, "NumEnqueuedSubgroups"}, + {0x28, "SubgroupId"}, + {0x29, "SubgroupLocalInvocationId"}, + {0x2a, "VertexIndex"}, + {0x2b, "InstanceIndex"}, + {0x1040, "CoreIDARM"}, + {0x1041, "CoreCountARM"}, + {0x1042, "CoreMaxIDARM"}, + {0x1043, "WarpIDARM"}, + {0x1044, "WarpMaxIDARM"}, + {0x1140, "SubgroupEqMask"}, + {0x1141, "SubgroupGeMask"}, + {0x1142, "SubgroupGtMask"}, + {0x1143, "SubgroupLeMask"}, + {0x1144, "SubgroupLtMask"}, + {0x1148, "BaseVertex"}, + {0x1149, "BaseInstance"}, + {0x114a, "DrawIndex"}, + {0x1150, "PrimitiveShadingRateKHR"}, + {0x1156, "DeviceIndex"}, + {0x1158, "ViewIndex"}, + {0x115c, "ShadingRateKHR"}, + {0x1380, "BaryCoordNoPerspAMD"}, + {0x1381, "BaryCoordNoPerspCentroidAMD"}, + {0x1382, "BaryCoordNoPerspSampleAMD"}, + {0x1383, "BaryCoordSmoothAMD"}, + {0x1384, "BaryCoordSmoothCentroidAMD"}, + {0x1385, "BaryCoordSmoothSampleAMD"}, + {0x1386, "BaryCoordPullModelAMD"}, + {0x1396, "FragStencilRefEXT"}, + {0x139d, "RemainingRecursionLevelsAMDX"}, + {0x13d1, "ShaderIndexAMDX"}, + {0x1485, "ViewportMaskNV"}, + {0x1489, "SecondaryPositionNV"}, + {0x148a, "SecondaryViewportMaskNV"}, + {0x148d, "PositionPerViewNV"}, + {0x148e, "ViewportMaskPerViewNV"}, + {0x1490, "FullyCoveredEXT"}, + {0x149a, "TaskCountNV"}, + {0x149b, "PrimitiveCountNV"}, + {0x149c, "PrimitiveIndicesNV"}, + {0x149d, "ClipDistancePerViewNV"}, + {0x149e, "CullDistancePerViewNV"}, + {0x149f, "LayerPerViewNV"}, + {0x14a0, "MeshViewCountNV"}, + {0x14a1, "MeshViewIndicesNV"}, + {0x14a6, "BaryCoordKHR"}, + {0x14a7, "BaryCoordNoPerspKHR"}, + {0x14ac, "FragSizeEXT"}, + {0x14ad, "FragInvocationCountEXT"}, + {0x14ae, "PrimitivePointIndicesEXT"}, + {0x14af, "PrimitiveLineIndicesEXT"}, + {0x14b0, "PrimitiveTriangleIndicesEXT"}, + {0x14b3, "CullPrimitiveEXT"}, + {0x14c7, "LaunchIdKHR"}, + {0x14c8, "LaunchSizeKHR"}, + {0x14c9, "WorldRayOriginKHR"}, + {0x14ca, "WorldRayDirectionKHR"}, + {0x14cb, "ObjectRayOriginKHR"}, + {0x14cc, "ObjectRayDirectionKHR"}, + {0x14cd, "RayTminKHR"}, + {0x14ce, "RayTmaxKHR"}, + {0x14cf, "InstanceCustomIndexKHR"}, + {0x14d2, "ObjectToWorldKHR"}, + {0x14d3, "WorldToObjectKHR"}, + {0x14d4, "HitTNV"}, + {0x14d5, "HitKindKHR"}, + {0x14d6, "CurrentRayTimeNV"}, + {0x14d7, "HitTriangleVertexPositionsKHR"}, + {0x14d9, "HitMicroTriangleVertexPositionsNV"}, + {0x14e0, "HitMicroTriangleVertexBarycentricsNV"}, + {0x14e7, "IncomingRayFlagsKHR"}, + {0x14e8, "RayGeometryIndexKHR"}, + {0x14fe, "WarpsPerSMNV"}, + {0x14ff, "SMCountNV"}, + {0x1500, "WarpIDNV"}, + {0x1501, "SMIDNV"}, + {0x151d, "HitKindFrontFacingMicroTriangleNV"}, + {0x151e, "HitKindBackFacingMicroTriangleNV"}, + {0x1785, "CullMaskKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_CAPABILITY] = + { + "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 245, + (struct spirv_parser_enumerant[]) + { + {0, "Matrix"}, + {0x1, "Shader"}, + {0x2, "Geometry"}, + {0x3, "Tessellation"}, + {0x4, "Addresses"}, + {0x5, "Linkage"}, + {0x6, "Kernel"}, + {0x7, "Vector16"}, + {0x8, "Float16Buffer"}, + {0x9, "Float16"}, + {0xa, "Float64"}, + {0xb, "Int64"}, + {0xc, "Int64Atomics"}, + {0xd, "ImageBasic"}, + {0xe, "ImageReadWrite"}, + {0xf, "ImageMipmap"}, + {0x11, "Pipes"}, + {0x12, "Groups"}, + {0x13, "DeviceEnqueue"}, + {0x14, "LiteralSampler"}, + {0x15, "AtomicStorage"}, + {0x16, "Int16"}, + {0x17, "TessellationPointSize"}, + {0x18, "GeometryPointSize"}, + {0x19, "ImageGatherExtended"}, + {0x1b, "StorageImageMultisample"}, + {0x1c, "UniformBufferArrayDynamicIndexing"}, + {0x1d, "SampledImageArrayDynamicIndexing"}, + {0x1e, "StorageBufferArrayDynamicIndexing"}, + {0x1f, "StorageImageArrayDynamicIndexing"}, + {0x20, "ClipDistance"}, + {0x21, "CullDistance"}, + {0x22, "ImageCubeArray"}, + {0x23, "SampleRateShading"}, + {0x24, "ImageRect"}, + {0x25, "SampledRect"}, + {0x26, "GenericPointer"}, + {0x27, "Int8"}, + {0x28, "InputAttachment"}, + {0x29, "SparseResidency"}, + {0x2a, "MinLod"}, + {0x2b, "Sampled1D"}, + {0x2c, "Image1D"}, + {0x2d, "SampledCubeArray"}, + {0x2e, "SampledBuffer"}, + {0x2f, "ImageBuffer"}, + {0x30, "ImageMSArray"}, + {0x31, "StorageImageExtendedFormats"}, + {0x32, "ImageQuery"}, + {0x33, "DerivativeControl"}, + {0x34, "InterpolationFunction"}, + {0x35, "TransformFeedback"}, + {0x36, "GeometryStreams"}, + {0x37, "StorageImageReadWithoutFormat"}, + {0x38, "StorageImageWriteWithoutFormat"}, + {0x39, "MultiViewport"}, + {0x3a, "SubgroupDispatch"}, + {0x3b, "NamedBarrier"}, + {0x3c, "PipeStorage"}, + {0x3d, "GroupNonUniform"}, + {0x3e, "GroupNonUniformVote"}, + {0x3f, "GroupNonUniformArithmetic"}, + {0x40, "GroupNonUniformBallot"}, + {0x41, "GroupNonUniformShuffle"}, + {0x42, "GroupNonUniformShuffleRelative"}, + {0x43, "GroupNonUniformClustered"}, + {0x44, "GroupNonUniformQuad"}, + {0x45, "ShaderLayer"}, + {0x46, "ShaderViewportIndex"}, + {0x47, "UniformDecoration"}, + {0x1045, "CoreBuiltinsARM"}, + {0x1046, "TileImageColorReadAccessEXT"}, + {0x1047, "TileImageDepthReadAccessEXT"}, + {0x1048, "TileImageStencilReadAccessEXT"}, + {0x1069, "CooperativeMatrixLayoutsARM"}, + {0x1146, "FragmentShadingRateKHR"}, + {0x1147, "SubgroupBallotKHR"}, + {0x114b, "DrawParameters"}, + {0x114c, "WorkgroupMemoryExplicitLayoutKHR"}, + {0x114d, "WorkgroupMemoryExplicitLayout8BitAccessKHR"}, + {0x114e, "WorkgroupMemoryExplicitLayout16BitAccessKHR"}, + {0x114f, "SubgroupVoteKHR"}, + {0x1151, "StorageBuffer16BitAccess"}, + {0x1152, "UniformAndStorageBuffer16BitAccess"}, + {0x1153, "StoragePushConstant16"}, + {0x1154, "StorageInputOutput16"}, + {0x1155, "DeviceGroup"}, + {0x1157, "MultiView"}, + {0x1159, "VariablePointersStorageBuffer"}, + {0x115a, "VariablePointers"}, + {0x115d, "AtomicStorageOps"}, + {0x115f, "SampleMaskPostDepthCoverage"}, + {0x1160, "StorageBuffer8BitAccess"}, + {0x1161, "UniformAndStorageBuffer8BitAccess"}, + {0x1162, "StoragePushConstant8"}, + {0x1170, "DenormPreserve"}, + {0x1171, "DenormFlushToZero"}, + {0x1172, "SignedZeroInfNanPreserve"}, + {0x1173, "RoundingModeRTE"}, + {0x1174, "RoundingModeRTZ"}, + {0x1177, "RayQueryProvisionalKHR"}, + {0x1178, "RayQueryKHR"}, + {0x1179, "UntypedPointersKHR"}, + {0x117e, "RayTraversalPrimitiveCullingKHR"}, + {0x117f, "RayTracingKHR"}, + {0x1184, "TextureSampleWeightedQCOM"}, + {0x1185, "TextureBoxFilterQCOM"}, + {0x1186, "TextureBlockMatchQCOM"}, + {0x1192, "TextureBlockMatch2QCOM"}, + {0x1390, "Float16ImageAMD"}, + {0x1391, "ImageGatherBiasLodAMD"}, + {0x1392, "FragmentMaskAMD"}, + {0x1395, "StencilExportEXT"}, + {0x1397, "ImageReadWriteLodAMD"}, + {0x1398, "Int64ImageEXT"}, + {0x13bf, "ShaderClockKHR"}, + {0x13cb, "ShaderEnqueueAMDX"}, + {0x13df, "QuadControlKHR"}, + {0x1481, "SampleMaskOverrideCoverageNV"}, + {0x1483, "GeometryShaderPassthroughNV"}, + {0x1486, "ShaderViewportIndexLayerEXT"}, + {0x1487, "ShaderViewportMaskNV"}, + {0x148b, "ShaderStereoViewNV"}, + {0x148c, "PerViewAttributesNV"}, + {0x1491, "FragmentFullyCoveredEXT"}, + {0x1492, "MeshShadingNV"}, + {0x14a2, "ImageFootprintNV"}, + {0x14a3, "MeshShadingEXT"}, + {0x14a4, "FragmentBarycentricKHR"}, + {0x14a8, "ComputeDerivativeGroupQuadsKHR"}, + {0x14ab, "FragmentDensityEXT"}, + {0x14b1, "GroupNonUniformPartitionedNV"}, + {0x14b5, "ShaderNonUniform"}, + {0x14b6, "RuntimeDescriptorArray"}, + {0x14b7, "InputAttachmentArrayDynamicIndexing"}, + {0x14b8, "UniformTexelBufferArrayDynamicIndexing"}, + {0x14b9, "StorageTexelBufferArrayDynamicIndexing"}, + {0x14ba, "UniformBufferArrayNonUniformIndexing"}, + {0x14bb, "SampledImageArrayNonUniformIndexing"}, + {0x14bc, "StorageBufferArrayNonUniformIndexing"}, + {0x14bd, "StorageImageArrayNonUniformIndexing"}, + {0x14be, "InputAttachmentArrayNonUniformIndexing"}, + {0x14bf, "UniformTexelBufferArrayNonUniformIndexing"}, + {0x14c0, "StorageTexelBufferArrayNonUniformIndexing"}, + {0x14d8, "RayTracingPositionFetchKHR"}, + {0x14dc, "RayTracingNV"}, + {0x14dd, "RayTracingMotionBlurNV"}, + {0x14e1, "VulkanMemoryModel"}, + {0x14e2, "VulkanMemoryModelDeviceScope"}, + {0x14e3, "PhysicalStorageBufferAddresses"}, + {0x14e6, "ComputeDerivativeGroupLinearKHR"}, + {0x14e9, "RayTracingProvisionalKHR"}, + {0x14ed, "CooperativeMatrixNV"}, + {0x14f3, "FragmentShaderSampleInterlockEXT"}, + {0x14fc, "FragmentShaderShadingRateInterlockEXT"}, + {0x14fd, "ShaderSMBuiltinsNV"}, + {0x1502, "FragmentShaderPixelInterlockEXT"}, + {0x1503, "DemoteToHelperInvocation"}, + {0x1504, "DisplacementMicromapNV"}, + {0x1505, "RayTracingOpacityMicromapEXT"}, + {0x1507, "ShaderInvocationReorderNV"}, + {0x150e, "BindlessTextureNV"}, + {0x150f, "RayQueryPositionFetchKHR"}, + {0x151c, "AtomicFloat16VectorNV"}, + {0x1521, "RayTracingDisplacementMicromapNV"}, + {0x1526, "RawAccessChainsNV"}, + {0x1536, "CooperativeMatrixReductionsNV"}, + {0x1537, "CooperativeMatrixConversionsNV"}, + {0x1538, "CooperativeMatrixPerElementOperationsNV"}, + {0x1539, "CooperativeMatrixTensorAddressingNV"}, + {0x153a, "CooperativeMatrixBlockLoadsNV"}, + {0x153f, "TensorAddressingNV"}, + {0x15c0, "SubgroupShuffleINTEL"}, + {0x15c1, "SubgroupBufferBlockIOINTEL"}, + {0x15c2, "SubgroupImageBlockIOINTEL"}, + {0x15cb, "SubgroupImageMediaBlockIOINTEL"}, + {0x15ce, "RoundToInfinityINTEL"}, + {0x15cf, "FloatingPointModeINTEL"}, + {0x15d0, "IntegerFunctions2INTEL"}, + {0x15e3, "FunctionPointersINTEL"}, + {0x15e4, "IndirectReferencesINTEL"}, + {0x15e6, "AsmINTEL"}, + {0x15ec, "AtomicFloat32MinMaxEXT"}, + {0x15ed, "AtomicFloat64MinMaxEXT"}, + {0x15f0, "AtomicFloat16MinMaxEXT"}, + {0x15f1, "VectorComputeINTEL"}, + {0x15f3, "VectorAnyINTEL"}, + {0x15fd, "ExpectAssumeKHR"}, + {0x1640, "SubgroupAvcMotionEstimationINTEL"}, + {0x1641, "SubgroupAvcMotionEstimationIntraINTEL"}, + {0x1642, "SubgroupAvcMotionEstimationChromaINTEL"}, + {0x16b9, "VariableLengthArrayINTEL"}, + {0x16bd, "FunctionFloatControlINTEL"}, + {0x16c0, "FPGAMemoryAttributesINTEL"}, + {0x16cd, "FPFastMathModeINTEL"}, + {0x16d4, "ArbitraryPrecisionIntegersINTEL"}, + {0x16d5, "ArbitraryPrecisionFloatingPointINTEL"}, + {0x16fe, "UnstructuredLoopControlsINTEL"}, + {0x1700, "FPGALoopControlsINTEL"}, + {0x1704, "KernelAttributesINTEL"}, + {0x1709, "FPGAKernelAttributesINTEL"}, + {0x170a, "FPGAMemoryAccessesINTEL"}, + {0x1710, "FPGAClusterAttributesINTEL"}, + {0x1712, "LoopFuseINTEL"}, + {0x1714, "FPGADSPControlINTEL"}, + {0x1716, "MemoryAccessAliasingINTEL"}, + {0x171c, "FPGAInvocationPipeliningAttributesINTEL"}, + {0x1720, "FPGABufferLocationINTEL"}, + {0x1722, "ArbitraryPrecisionFixedPointINTEL"}, + {0x172f, "USMStorageClassesINTEL"}, + {0x1733, "RuntimeAlignedAttributeINTEL"}, + {0x1737, "IOPipesINTEL"}, + {0x1739, "BlockingPipesINTEL"}, + {0x173c, "FPGARegINTEL"}, + {0x1780, "DotProductInputAll"}, + {0x1781, "DotProductInput4x8Bit"}, + {0x1782, "DotProductInput4x8BitPacked"}, + {0x1783, "DotProduct"}, + {0x1784, "RayCullMaskKHR"}, + {0x1786, "CooperativeMatrixKHR"}, + {0x1788, "ReplicatedCompositesEXT"}, + {0x1789, "BitInstructions"}, + {0x178a, "GroupNonUniformRotateKHR"}, + {0x178d, "FloatControls2"}, + {0x1791, "AtomicFloat32AddEXT"}, + {0x1792, "AtomicFloat64AddEXT"}, + {0x17c9, "LongCompositesINTEL"}, + {0x17ce, "OptNoneEXT"}, + {0x17cf, "AtomicFloat16AddEXT"}, + {0x17e2, "DebugInfoModuleINTEL"}, + {0x17e3, "BFloat16ConversionINTEL"}, + {0x17fd, "SplitBarrierINTEL"}, + {0x1800, "ArithmeticFenceEXT"}, + {0x1806, "FPGAClusterAttributesV2INTEL"}, + {0x1811, "FPGAKernelAttributesv2INTEL"}, + {0x1819, "FPMaxErrorINTEL"}, + {0x181b, "FPGALatencyControlINTEL"}, + {0x181e, "FPGAArgumentInterfacesINTEL"}, + {0x182b, "GlobalVariableHostAccessINTEL"}, + {0x182d, "GlobalVariableFPGADecorationsINTEL"}, + {0x184c, "SubgroupBufferPrefetchINTEL"}, + {0x1900, "GroupUniformArithmeticKHR"}, + {0x191b, "MaskedGatherScatterINTEL"}, + {0x1929, "CacheControlsINTEL"}, + {0x193c, "RegisterLimitsINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT] = + { + "CooperativeMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0, "RowMajorKHR"}, + {0x1, "ColumnMajorKHR"}, + {0x106a, "RowBlockedInterleavedARM"}, + {0x106b, "ColumnBlockedInterleavedARM"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS] = + { + "CooperativeMatrixOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 6, + (struct spirv_parser_enumerant[]) + { + {0, "NoneKHR"}, + {0x1, "MatrixASignedComponentsKHR"}, + {0x2, "MatrixBSignedComponentsKHR"}, + {0x4, "MatrixCSignedComponentsKHR"}, + {0x8, "MatrixResultSignedComponentsKHR"}, + {0x10, "SaturatingAccumulationKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE] = + { + "CooperativeMatrixReduce", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0x1, "Row"}, + {0x2, "Column"}, + {0x4, "2x2"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_USE] = + { + "CooperativeMatrixUse", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "MatrixAKHR"}, + {0x1, "MatrixBKHR"}, + {0x2, "MatrixAccumulatorKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_DECORATION] = + { + "Decoration", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 142, + (struct spirv_parser_enumerant[]) + { + {0, "RelaxedPrecision"}, + { + 0x1, "SpecId", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x2, "Block"}, + {0x3, "BufferBlock"}, + {0x4, "RowMajor"}, + {0x5, "ColMajor"}, + { + 0x6, "ArrayStride", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x7, "MatrixStride", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x8, "GLSLShared"}, + {0x9, "GLSLPacked"}, + {0xa, "CPacked"}, + { + 0xb, "BuiltIn", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_BUILT_IN, + } + }, + {0xd, "NoPerspective"}, + {0xe, "Flat"}, + {0xf, "Patch"}, + {0x10, "Centroid"}, + {0x11, "Sample"}, + {0x12, "Invariant"}, + {0x13, "Restrict"}, + {0x14, "Aliased"}, + {0x15, "Volatile"}, + {0x16, "Constant"}, + {0x17, "Coherent"}, + {0x18, "NonWritable"}, + {0x19, "NonReadable"}, + {0x1a, "Uniform"}, + { + 0x1b, "UniformId", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE, + } + }, + {0x1c, "SaturatedConversion"}, + { + 0x1d, "Stream", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1e, "Location", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1f, "Component", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x20, "Index", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x21, "Binding", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x22, "DescriptorSet", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x23, "Offset", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x24, "XfbBuffer", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x25, "XfbStride", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x26, "FuncParamAttr", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE, + } + }, + { + 0x27, "FPRoundingMode", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_FPROUNDING_MODE, + } + }, + { + 0x28, "FPFastMathMode", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE, + } + }, + { + 0x29, "LinkageAttributes", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + SPIRV_PARSER_OPERAND_TYPE_LINKAGE_TYPE, + } + }, + {0x2a, "NoContraction"}, + { + 0x2b, "InputAttachmentIndex", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x2c, "Alignment", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x2d, "MaxByteOffset", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x2e, "AlignmentId", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x2f, "MaxByteOffsetId", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + {0x1175, "NoSignedWrap"}, + {0x1176, "NoUnsignedWrap"}, + {0x1187, "WeightTextureQCOM"}, + {0x1188, "BlockMatchTextureQCOM"}, + {0x1193, "BlockMatchSamplerQCOM"}, + {0x1387, "ExplicitInterpAMD"}, + { + 0x139b, "NodeSharesPayloadLimitsWithAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x139c, "NodeMaxPayloadsAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + {0x13d6, "TrackFinishWritingAMDX"}, + { + 0x13e3, "PayloadNodeNameAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x13ea, "PayloadNodeBaseIndexAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + {0x13eb, "PayloadNodeSparseArrayAMDX"}, + { + 0x13ec, "PayloadNodeArraySizeAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + {0x13f1, "PayloadDispatchIndirectAMDX"}, + {0x1480, "OverrideCoverageNV"}, + {0x1482, "PassthroughNV"}, + {0x1484, "ViewportRelativeNV"}, + { + 0x1488, "SecondaryViewportRelativeNV", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1497, "PerPrimitiveEXT"}, + {0x1498, "PerViewNV"}, + {0x1499, "PerTaskNV"}, + {0x14a5, "PerVertexKHR"}, + {0x14b4, "NonUniform"}, + {0x14eb, "RestrictPointer"}, + {0x14ec, "AliasedPointer"}, + {0x150a, "HitObjectShaderRecordBufferNV"}, + {0x1516, "BindlessSamplerNV"}, + {0x1517, "BindlessImageNV"}, + {0x1518, "BoundSamplerNV"}, + {0x1519, "BoundImageNV"}, + { + 0x15df, "SIMTCallINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x15e2, "ReferencedIndirectlyINTEL"}, + { + 0x15e7, "ClobberINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + } + }, + {0x15e8, "SideEffectsINTEL"}, + {0x15f8, "VectorComputeVariableINTEL"}, + { + 0x15f9, "FuncParamIOKindINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x15fa, "VectorComputeFunctionINTEL"}, + {0x15fb, "StackCallINTEL"}, + { + 0x15fc, "GlobalVariableOffsetINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1602, "CounterBuffer", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x1603, "UserSemantic", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + } + }, + { + 0x1604, "UserTypeGOOGLE", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + } + }, + { + 0x16be, "FunctionRoundingModeINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_FPROUNDING_MODE, + } + }, + { + 0x16bf, "FunctionDenormModeINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_FPDENORM_MODE, + } + }, + {0x16c1, "RegisterINTEL"}, + { + 0x16c2, "MemoryINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + } + }, + { + 0x16c3, "NumbanksINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x16c4, "BankwidthINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x16c5, "MaxPrivateCopiesINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x16c6, "SinglepumpINTEL"}, + {0x16c7, "DoublepumpINTEL"}, + { + 0x16c8, "MaxReplicatesINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x16c9, "SimpleDualPortINTEL"}, + { + 0x16ca, "MergeINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + } + }, + { + 0x16cb, "BankBitsINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x16cc, "ForcePow2DepthINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x16fb, "StridesizeINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x16fc, "WordsizeINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x16fd, "TrueDualPortINTEL"}, + {0x170b, "BurstCoalesceINTEL"}, + { + 0x170c, "CacheSizeINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x170d, "DontStaticallyCoalesceINTEL"}, + { + 0x170e, "PrefetchINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1711, "StallEnableINTEL"}, + {0x1713, "FuseLoopsInFunctionINTEL"}, + { + 0x1715, "MathOpDSPModeINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x171a, "AliasScopeINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x171b, "NoAliasINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x171d, "InitiationIntervalINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x171e, "MaxConcurrencyINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x171f, "PipelineEnableINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1721, "BufferLocationINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1738, "IOPipeStorageINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x17c0, "FunctionFloatingPointModeINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_FPOPERATION_MODE, + } + }, + {0x17c5, "SingleElementVectorINTEL"}, + {0x17c7, "VectorComputeCallableFunctionINTEL"}, + {0x17fc, "MediaBlockIOINTEL"}, + {0x1807, "StallFreeINTEL"}, + { + 0x181a, "FPMaxErrorDecorationINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_FLOAT, + } + }, + { + 0x181c, "LatencyControlLabelINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x181d, "LatencyControlConstraintINTEL", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x181f, "ConduitKernelArgumentINTEL"}, + {0x1820, "RegisterMapKernelArgumentINTEL"}, + { + 0x1821, "MMHostInterfaceAddressWidthINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1822, "MMHostInterfaceDataWidthINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1823, "MMHostInterfaceLatencyINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1824, "MMHostInterfaceReadWriteModeINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ACCESS_QUALIFIER, + } + }, + { + 0x1825, "MMHostInterfaceMaxBurstINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1826, "MMHostInterfaceWaitRequestINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1827, "StableKernelArgumentINTEL"}, + { + 0x182c, "HostAccessINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_HOST_ACCESS_QUALIFIER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, + } + }, + { + 0x182e, "InitModeINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER, + } + }, + { + 0x182f, "ImplementInRegisterMapINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x192a, "CacheControlLoadINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LOAD_CACHE_CONTROL, + } + }, + { + 0x192b, "CacheControlStoreINTEL", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_STORE_CACHE_CONTROL, + } + }, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_DIM] = + { + "Dim", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 8, + (struct spirv_parser_enumerant[]) + { + {0, "1D"}, + {0x1, "2D"}, + {0x2, "3D"}, + {0x3, "Cube"}, + {0x4, "Rect"}, + {0x5, "Buffer"}, + {0x6, "SubpassData"}, + {0x104d, "TileImageDataEXT"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE] = + { + "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 94, + (struct spirv_parser_enumerant[]) + { + { + 0, "Invocations", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1, "SpacingEqual"}, + {0x2, "SpacingFractionalEven"}, + {0x3, "SpacingFractionalOdd"}, + {0x4, "VertexOrderCw"}, + {0x5, "VertexOrderCcw"}, + {0x6, "PixelCenterInteger"}, + {0x7, "OriginUpperLeft"}, + {0x8, "OriginLowerLeft"}, + {0x9, "EarlyFragmentTests"}, + {0xa, "PointMode"}, + {0xb, "Xfb"}, + {0xc, "DepthReplacing"}, + {0xe, "DepthGreater"}, + {0xf, "DepthLess"}, + {0x10, "DepthUnchanged"}, + { + 0x11, "LocalSize", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x12, "LocalSizeHint", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x13, "InputPoints"}, + {0x14, "InputLines"}, + {0x15, "InputLinesAdjacency"}, + {0x16, "Triangles"}, + {0x17, "InputTrianglesAdjacency"}, + {0x18, "Quads"}, + {0x19, "Isolines"}, + { + 0x1a, "OutputVertices", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1b, "OutputPoints"}, + {0x1c, "OutputLineStrip"}, + {0x1d, "OutputTriangleStrip"}, + { + 0x1e, "VecTypeHint", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1f, "ContractionOff"}, + {0x21, "Initializer"}, + {0x22, "Finalizer"}, + { + 0x23, "SubgroupSize", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x24, "SubgroupsPerWorkgroup", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x25, "SubgroupsPerWorkgroupId", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x26, "LocalSizeId", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x27, "LocalSizeHintId", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + {0x1049, "NonCoherentColorAttachmentReadEXT"}, + {0x104a, "NonCoherentDepthAttachmentReadEXT"}, + {0x104b, "NonCoherentStencilAttachmentReadEXT"}, + {0x1145, "SubgroupUniformControlFlowKHR"}, + {0x115e, "PostDepthCoverage"}, + { + 0x116b, "DenormPreserve", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x116c, "DenormFlushToZero", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x116d, "SignedZeroInfNanPreserve", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x116e, "RoundingModeRTE", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x116f, "RoundingModeRTZ", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1399, "EarlyAndLateFragmentTestsAMD"}, + {0x13a3, "StencilRefReplacingEXT"}, + {0x13cd, "CoalescingAMDX"}, + { + 0x13ce, "IsApiEntryAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x13cf, "MaxNodeRecursionAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x13d0, "StaticNumWorkgroupsAMDX", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x13d1, "ShaderIndexAMDX", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x13d5, "MaxNumWorkgroupsAMDX", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + {0x13d7, "StencilRefUnchangedFrontAMD"}, + {0x13d8, "StencilRefGreaterFrontAMD"}, + {0x13d9, "StencilRefLessFrontAMD"}, + {0x13da, "StencilRefUnchangedBackAMD"}, + {0x13db, "StencilRefGreaterBackAMD"}, + {0x13dc, "StencilRefLessBackAMD"}, + {0x13e0, "QuadDerivativesKHR"}, + {0x13e1, "RequireFullQuadsKHR"}, + { + 0x13ee, "SharesInputWithAMDX", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + {0x1495, "OutputLinesEXT"}, + { + 0x1496, "OutputPrimitivesEXT", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x14a9, "DerivativeGroupQuadsKHR"}, + {0x14aa, "DerivativeGroupLinearKHR"}, + {0x14b2, "OutputTrianglesEXT"}, + {0x14f6, "PixelInterlockOrderedEXT"}, + {0x14f7, "PixelInterlockUnorderedEXT"}, + {0x14f8, "SampleInterlockOrderedEXT"}, + {0x14f9, "SampleInterlockUnorderedEXT"}, + {0x14fa, "ShadingRateInterlockOrderedEXT"}, + {0x14fb, "ShadingRateInterlockUnorderedEXT"}, + { + 0x15f2, "SharedLocalMemorySizeINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x15f4, "RoundingModeRTPINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x15f5, "RoundingModeRTNINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x15f6, "FloatingPointModeALTINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x15f7, "FloatingPointModeIEEEINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1705, "MaxWorkgroupSizeINTEL", 3, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1706, "MaxWorkDimINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1707, "NoGlobalOffsetINTEL"}, + { + 0x1708, "NumSIMDWorkitemsINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x170f, "SchedulerTargetFmaxMhzINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x1787, "MaximallyReconvergesKHR"}, + { + 0x178c, "FPFastMathDefault", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x180a, "StreamingInterfaceINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1810, "RegisterMapInterfaceINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x1911, "NamedBarrierCountINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x193d, "MaximumRegistersINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x193e, "MaximumRegistersIdINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x193f, "NamedMaximumRegistersINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS, + } + }, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODEL] = + { + "ExecutionModel", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 17, + (struct spirv_parser_enumerant[]) + { + {0, "Vertex"}, + {0x1, "TessellationControl"}, + {0x2, "TessellationEvaluation"}, + {0x3, "Geometry"}, + {0x4, "Fragment"}, + {0x5, "GLCompute"}, + {0x6, "Kernel"}, + {0x1493, "TaskNV"}, + {0x1494, "MeshNV"}, + {0x14c1, "RayGenerationKHR"}, + {0x14c2, "IntersectionKHR"}, + {0x14c3, "AnyHitKHR"}, + {0x14c4, "ClosestHitKHR"}, + {0x14c5, "MissKHR"}, + {0x14c6, "CallableKHR"}, + {0x14f4, "TaskEXT"}, + {0x14f5, "MeshEXT"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_FPDENORM_MODE] = + { + "FPDenormMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 2, + (struct spirv_parser_enumerant[]) + { + {0, "Preserve"}, + {0x1, "FlushToZero"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_FPENCODING] = + { + "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM + }, + [SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE] = + { + "FPFastMathMode", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 9, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "NotNaN"}, + {0x2, "NotInf"}, + {0x4, "NSZ"}, + {0x8, "AllowRecip"}, + {0x10, "Fast"}, + {0x10000, "AllowContract"}, + {0x20000, "AllowReassoc"}, + {0x40000, "AllowTransform"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_FPOPERATION_MODE] = + { + "FPOperationMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 2, + (struct spirv_parser_enumerant[]) + { + {0, "IEEE"}, + {0x1, "ALT"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_FPROUNDING_MODE] = + { + "FPRoundingMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0, "RTE"}, + {0x1, "RTZ"}, + {0x2, "RTP"}, + {0x3, "RTN"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_FRAGMENT_SHADING_RATE] = + { + "FragmentShadingRate", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0x1, "Vertical2Pixels"}, + {0x2, "Vertical4Pixels"}, + {0x4, "Horizontal2Pixels"}, + {0x8, "Horizontal4Pixels"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_FUNCTION_CONTROL] = + { + "FunctionControl", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 6, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "Inline"}, + {0x2, "DontInline"}, + {0x4, "Pure"}, + {0x8, "Const"}, + {0x10000, "OptNoneEXT"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_FUNCTION_PARAMETER_ATTRIBUTE] = + { + "FunctionParameterAttribute", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 9, + (struct spirv_parser_enumerant[]) + { + {0, "Zext"}, + {0x1, "Sext"}, + {0x2, "ByVal"}, + {0x3, "Sret"}, + {0x4, "NoAlias"}, + {0x5, "NoCapture"}, + {0x6, "NoWrite"}, + {0x7, "NoReadWrite"}, + {0x1734, "RuntimeAlignedINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION] = + { + "GroupOperation", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 7, + (struct spirv_parser_enumerant[]) + { + {0, "Reduce"}, + {0x1, "InclusiveScan"}, + {0x2, "ExclusiveScan"}, + {0x3, "ClusteredReduce"}, + {0x6, "PartitionedReduceNV"}, + {0x7, "PartitionedInclusiveScanNV"}, + {0x8, "PartitionedExclusiveScanNV"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_HOST_ACCESS_QUALIFIER] = + { + "HostAccessQualifier", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0, "NoneINTEL"}, + {0x1, "ReadINTEL"}, + {0x2, "WriteINTEL"}, + {0x3, "ReadWriteINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS] = + { + "IdMemorySemantics", SPIRV_PARSER_OPERAND_CATEGORY_ID + }, + [SPIRV_PARSER_OPERAND_TYPE_ID_REF] = + { + "IdRef", SPIRV_PARSER_OPERAND_CATEGORY_ID + }, + [SPIRV_PARSER_OPERAND_TYPE_ID_RESULT] = + { + "IdResult", SPIRV_PARSER_OPERAND_CATEGORY_ID + }, + [SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE] = + { + "IdResultType", SPIRV_PARSER_OPERAND_CATEGORY_ID + }, + [SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE] = + { + "IdScope", SPIRV_PARSER_OPERAND_CATEGORY_ID + }, + [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE] = + { + "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 20, + (struct spirv_parser_enumerant[]) + { + {0, "SnormInt8"}, + {0x1, "SnormInt16"}, + {0x2, "UnormInt8"}, + {0x3, "UnormInt16"}, + {0x4, "UnormShort565"}, + {0x5, "UnormShort555"}, + {0x6, "UnormInt101010"}, + {0x7, "SignedInt8"}, + {0x8, "SignedInt16"}, + {0x9, "SignedInt32"}, + {0xa, "UnsignedInt8"}, + {0xb, "UnsignedInt16"}, + {0xc, "UnsignedInt32"}, + {0xd, "HalfFloat"}, + {0xe, "Float"}, + {0xf, "UnormInt24"}, + {0x10, "UnormInt101010_2"}, + {0x13, "UnsignedIntRaw10EXT"}, + {0x14, "UnsignedIntRaw12EXT"}, + {0x15, "UnormInt2_101010EXT"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_ORDER] = + { + "ImageChannelOrder", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 20, + (struct spirv_parser_enumerant[]) + { + {0, "R"}, + {0x1, "A"}, + {0x2, "RG"}, + {0x3, "RA"}, + {0x4, "RGB"}, + {0x5, "RGBA"}, + {0x6, "BGRA"}, + {0x7, "ARGB"}, + {0x8, "Intensity"}, + {0x9, "Luminance"}, + {0xa, "Rx"}, + {0xb, "RGx"}, + {0xc, "RGBx"}, + {0xd, "Depth"}, + {0xe, "DepthStencil"}, + {0xf, "sRGB"}, + {0x10, "sRGBx"}, + {0x11, "sRGBA"}, + {0x12, "sBGRA"}, + {0x13, "ABGR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_IMAGE_FORMAT] = + { + "ImageFormat", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 42, + (struct spirv_parser_enumerant[]) + { + {0, "Unknown"}, + {0x1, "Rgba32f"}, + {0x2, "Rgba16f"}, + {0x3, "R32f"}, + {0x4, "Rgba8"}, + {0x5, "Rgba8Snorm"}, + {0x6, "Rg32f"}, + {0x7, "Rg16f"}, + {0x8, "R11fG11fB10f"}, + {0x9, "R16f"}, + {0xa, "Rgba16"}, + {0xb, "Rgb10A2"}, + {0xc, "Rg16"}, + {0xd, "Rg8"}, + {0xe, "R16"}, + {0xf, "R8"}, + {0x10, "Rgba16Snorm"}, + {0x11, "Rg16Snorm"}, + {0x12, "Rg8Snorm"}, + {0x13, "R16Snorm"}, + {0x14, "R8Snorm"}, + {0x15, "Rgba32i"}, + {0x16, "Rgba16i"}, + {0x17, "Rgba8i"}, + {0x18, "R32i"}, + {0x19, "Rg32i"}, + {0x1a, "Rg16i"}, + {0x1b, "Rg8i"}, + {0x1c, "R16i"}, + {0x1d, "R8i"}, + {0x1e, "Rgba32ui"}, + {0x1f, "Rgba16ui"}, + {0x20, "Rgba8ui"}, + {0x21, "R32ui"}, + {0x22, "Rgb10a2ui"}, + {0x23, "Rg32ui"}, + {0x24, "Rg16ui"}, + {0x25, "Rg8ui"}, + {0x26, "R16ui"}, + {0x27, "R8ui"}, + {0x28, "R64ui"}, + {0x29, "R64i"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_IMAGE_OPERANDS] = + { + "ImageOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 17, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + { + 0x1, "Bias", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x2, "Lod", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x4, "Grad", 2, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x8, "ConstOffset", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x10, "Offset", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x20, "ConstOffsets", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x40, "Sample", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x80, "MinLod", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x100, "MakeTexelAvailable", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE, + } + }, + { + 0x200, "MakeTexelVisible", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE, + } + }, + {0x400, "NonPrivateTexel"}, + {0x800, "VolatileTexel"}, + {0x1000, "SignExtend"}, + {0x2000, "ZeroExtend"}, + {0x4000, "Nontemporal"}, + { + 0x10000, "Offsets", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_INITIALIZATION_MODE_QUALIFIER] = + { + "InitializationModeQualifier", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 2, + (struct spirv_parser_enumerant[]) + { + {0, "InitOnDeviceReprogramINTEL"}, + {0x1, "InitOnDeviceResetINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_KERNEL_ENQUEUE_FLAGS] = + { + "KernelEnqueueFlags", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "NoWait"}, + {0x1, "WaitKernel"}, + {0x2, "WaitWorkGroup"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_KERNEL_PROFILING_INFO] = + { + "KernelProfilingInfo", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 2, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "CmdExecTime"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_LINKAGE_TYPE] = + { + "LinkageType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "Export"}, + {0x1, "Import"}, + {0x2, "LinkOnceODR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_LITERAL_CONTEXT_DEPENDENT_NUMBER] = + { + "LiteralContextDependentNumber", SPIRV_PARSER_OPERAND_CATEGORY_LITERAL + }, + [SPIRV_PARSER_OPERAND_TYPE_LITERAL_EXT_INST_INTEGER] = + { + "LiteralExtInstInteger", SPIRV_PARSER_OPERAND_CATEGORY_LITERAL + }, + [SPIRV_PARSER_OPERAND_TYPE_LITERAL_FLOAT] = + { + "LiteralFloat", SPIRV_PARSER_OPERAND_CATEGORY_LITERAL + }, + [SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER] = + { + "LiteralInteger", SPIRV_PARSER_OPERAND_CATEGORY_LITERAL + }, + [SPIRV_PARSER_OPERAND_TYPE_LITERAL_SPEC_CONSTANT_OP_INTEGER] = + { + "LiteralSpecConstantOpInteger", SPIRV_PARSER_OPERAND_CATEGORY_LITERAL + }, + [SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING] = + { + "LiteralString", SPIRV_PARSER_OPERAND_CATEGORY_LITERAL + }, + [SPIRV_PARSER_OPERAND_TYPE_LOAD_CACHE_CONTROL] = + { + "LoadCacheControl", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 5, + (struct spirv_parser_enumerant[]) + { + {0, "UncachedINTEL"}, + {0x1, "CachedINTEL"}, + {0x2, "StreamingINTEL"}, + {0x3, "InvalidateAfterReadINTEL"}, + {0x4, "ConstCachedINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_LOOP_CONTROL] = + { + "LoopControl", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 20, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "Unroll"}, + {0x2, "DontUnroll"}, + {0x4, "DependencyInfinite"}, + { + 0x8, "DependencyLength", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x10, "MinIterations", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x20, "MaxIterations", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x40, "IterationMultiple", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x80, "PeelCount", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x100, "PartialCount", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x10000, "InitiationIntervalINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x20000, "MaxConcurrencyINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x40000, "DependencyArrayINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x80000, "PipelineEnableINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x100000, "LoopCoalesceINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x200000, "MaxInterleavingINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x400000, "SpeculatedIterationsINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x800000, "NoFusionINTEL"}, + { + 0x1000000, "LoopCountINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + { + 0x2000000, "MaxReinvocationDelayINTEL", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS] = + { + "MemoryAccess", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 9, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "Volatile"}, + { + 0x2, "Aligned", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, + } + }, + {0x4, "Nontemporal"}, + { + 0x8, "MakePointerAvailable", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE, + } + }, + { + 0x10, "MakePointerVisible", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE, + } + }, + {0x20, "NonPrivatePointer"}, + { + 0x10000, "AliasScopeINTELMask", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x20000, "NoAliasINTELMask", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_MEMORY_MODEL] = + { + "MemoryModel", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0, "Simple"}, + {0x1, "GLSL450"}, + {0x2, "OpenCL"}, + {0x3, "Vulkan"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_MEMORY_SEMANTICS] = + { + "MemorySemantics", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 15, + (struct spirv_parser_enumerant[]) + { + {0, "Relaxed"}, + {0x2, "Acquire"}, + {0x4, "Release"}, + {0x8, "AcquireRelease"}, + {0x10, "SequentiallyConsistent"}, + {0x40, "UniformMemory"}, + {0x80, "SubgroupMemory"}, + {0x100, "WorkgroupMemory"}, + {0x200, "CrossWorkgroupMemory"}, + {0x400, "AtomicCounterMemory"}, + {0x800, "ImageMemory"}, + {0x1000, "OutputMemory"}, + {0x2000, "MakeAvailable"}, + {0x4000, "MakeVisible"}, + {0x8000, "Volatile"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_NAMED_MAXIMUM_NUMBER_OF_REGISTERS] = + { + "NamedMaximumNumberOfRegisters", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 1, + (struct spirv_parser_enumerant[]) + { + {0, "AutoINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_OVERFLOW_MODES] = + { + "OverflowModes", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0, "WRAP"}, + {0x1, "SAT"}, + {0x2, "SAT_ZERO"}, + {0x3, "SAT_SYM"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_PACKED_VECTOR_FORMAT] = + { + "PackedVectorFormat", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 1, + (struct spirv_parser_enumerant[]) + { + {0, "PackedVectorFormat4x8Bit"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_PAIR_ID_REF_ID_REF] = + { + "PairIdRefIdRef", SPIRV_PARSER_OPERAND_CATEGORY_COMPOSITE + }, + [SPIRV_PARSER_OPERAND_TYPE_PAIR_ID_REF_LITERAL_INTEGER] = + { + "PairIdRefLiteralInteger", SPIRV_PARSER_OPERAND_CATEGORY_COMPOSITE + }, + [SPIRV_PARSER_OPERAND_TYPE_PAIR_LITERAL_INTEGER_ID_REF] = + { + "PairLiteralIntegerIdRef", SPIRV_PARSER_OPERAND_CATEGORY_COMPOSITE + }, + [SPIRV_PARSER_OPERAND_TYPE_QUANTIZATION_MODES] = + { + "QuantizationModes", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 8, + (struct spirv_parser_enumerant[]) + { + {0, "TRN"}, + {0x1, "TRN_ZERO"}, + {0x2, "RND"}, + {0x3, "RND_ZERO"}, + {0x4, "RND_INF"}, + {0x5, "RND_MIN_INF"}, + {0x6, "RND_CONV"}, + {0x7, "RND_CONV_ODD"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS] = + { + "RawAccessChainOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "RobustnessPerComponentNV"}, + {0x2, "RobustnessPerElementNV"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_RAY_FLAGS] = + { + "RayFlags", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 12, + (struct spirv_parser_enumerant[]) + { + {0, "NoneKHR"}, + {0x1, "OpaqueKHR"}, + {0x2, "NoOpaqueKHR"}, + {0x4, "TerminateOnFirstHitKHR"}, + {0x8, "SkipClosestHitShaderKHR"}, + {0x10, "CullBackFacingTrianglesKHR"}, + {0x20, "CullFrontFacingTrianglesKHR"}, + {0x40, "CullOpaqueKHR"}, + {0x80, "CullNoOpaqueKHR"}, + {0x100, "SkipTrianglesKHR"}, + {0x200, "SkipAABBsKHR"}, + {0x400, "ForceOpacityMicromap2StateEXT"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_RAY_QUERY_CANDIDATE_INTERSECTION_TYPE] = + { + "RayQueryCandidateIntersectionType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 2, + (struct spirv_parser_enumerant[]) + { + {0, "RayQueryCandidateIntersectionTriangleKHR"}, + {0x1, "RayQueryCandidateIntersectionAABBKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_RAY_QUERY_COMMITTED_INTERSECTION_TYPE] = + { + "RayQueryCommittedIntersectionType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "RayQueryCommittedIntersectionNoneKHR"}, + {0x1, "RayQueryCommittedIntersectionTriangleKHR"}, + {0x2, "RayQueryCommittedIntersectionGeneratedKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_RAY_QUERY_INTERSECTION] = + { + "RayQueryIntersection", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 2, + (struct spirv_parser_enumerant[]) + { + {0, "RayQueryCandidateIntersectionKHR"}, + {0x1, "RayQueryCommittedIntersectionKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE] = + { + "SamplerAddressingMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 5, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "ClampToEdge"}, + {0x2, "Clamp"}, + {0x3, "Repeat"}, + {0x4, "RepeatMirrored"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_SAMPLER_FILTER_MODE] = + { + "SamplerFilterMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 2, + (struct spirv_parser_enumerant[]) + { + {0, "Nearest"}, + {0x1, "Linear"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_SCOPE] = + { + "Scope", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 7, + (struct spirv_parser_enumerant[]) + { + {0, "CrossDevice"}, + {0x1, "Device"}, + {0x2, "Workgroup"}, + {0x3, "Subgroup"}, + {0x4, "Invocation"}, + {0x5, "QueueFamily"}, + {0x6, "ShaderCallKHR"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_SELECTION_CONTROL] = + { + "SelectionControl", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + {0x1, "Flatten"}, + {0x2, "DontFlatten"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE] = + { + "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 13, + (struct spirv_parser_enumerant[]) + { + {0, "Unknown"}, + {0x1, "ESSL"}, + {0x2, "GLSL"}, + {0x3, "OpenCL_C"}, + {0x4, "OpenCL_CPP"}, + {0x5, "HLSL"}, + {0x6, "CPP_for_OpenCL"}, + {0x7, "SYCL"}, + {0x8, "HERO_C"}, + {0x9, "NZSL"}, + {0xa, "WGSL"}, + {0xb, "Slang"}, + {0xc, "Zig"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS] = + { + "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 27, + (struct spirv_parser_enumerant[]) + { + {0, "UniformConstant"}, + {0x1, "Input"}, + {0x2, "Uniform"}, + {0x3, "Output"}, + {0x4, "Workgroup"}, + {0x5, "CrossWorkgroup"}, + {0x6, "Private"}, + {0x7, "Function"}, + {0x8, "Generic"}, + {0x9, "PushConstant"}, + {0xa, "AtomicCounter"}, + {0xb, "Image"}, + {0xc, "StorageBuffer"}, + {0x104c, "TileImageEXT"}, + {0x13cc, "NodePayloadAMDX"}, + {0x14d0, "CallableDataKHR"}, + {0x14d1, "IncomingCallableDataKHR"}, + {0x14da, "RayPayloadKHR"}, + {0x14db, "HitAttributeKHR"}, + {0x14de, "IncomingRayPayloadKHR"}, + {0x14df, "ShaderRecordBufferKHR"}, + {0x14e5, "PhysicalStorageBuffer"}, + {0x1509, "HitObjectAttributeNV"}, + {0x151a, "TaskPayloadWorkgroupEXT"}, + {0x15e5, "CodeSectionINTEL"}, + {0x1730, "DeviceOnlyINTEL"}, + {0x1731, "HostOnlyINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_STORE_CACHE_CONTROL] = + { + "StoreCacheControl", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, + (struct spirv_parser_enumerant[]) + { + {0, "UncachedINTEL"}, + {0x1, "WriteThroughINTEL"}, + {0x2, "WriteBackINTEL"}, + {0x3, "StreamingINTEL"}, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS] = + { + "TensorAddressingOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 3, + (struct spirv_parser_enumerant[]) + { + {0, "None"}, + { + 0x1, "TensorView", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + { + 0x2, "DecodeFunc", 1, + (enum spirv_parser_operand_type[]) + { + SPIRV_PARSER_OPERAND_TYPE_ID_REF, + } + }, + } + }, + [SPIRV_PARSER_OPERAND_TYPE_TENSOR_CLAMP_MODE] = + { + "TensorClampMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 5, + (struct spirv_parser_enumerant[]) + { + {0, "Undefined"}, + {0x1, "Constant"}, + {0x2, "ClampToEdge"}, + {0x3, "Repeat"}, + {0x4, "RepeatMirrored"}, + } + }, +}; + +static const struct spirv_parser_opcode_info +{ + uint16_t op; + const char *name; + size_t operand_count; + const struct spirv_parser_instruction_operand + { + enum spirv_parser_operand_type type; + char quantifier; + } *operands; +} +spirv_parser_opcode_info[] = +{ + {0x0000, "OpNop"}, + { + 0x0001, "OpUndef", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0002, "OpSourceContinued", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x0003, "OpSource", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, '?'}, + } + }, + { + 0x0004, "OpSourceExtension", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x0005, "OpName", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x0006, "OpMemberName", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x0007, "OpString", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x0008, "OpLine", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x000a, "OpExtension", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x000b, "OpExtInstImport", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x000c, "OpExtInst", 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_LITERAL_EXT_INST_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x000e, "OpMemoryModel", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ADDRESSING_MODEL}, + {SPIRV_PARSER_OPERAND_TYPE_MEMORY_MODEL}, + } + }, + { + 0x000f, "OpEntryPoint", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODEL}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x0010, "OpExecutionMode", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE}, + } + }, + { + 0x0011, "OpCapability", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_CAPABILITY}, + } + }, + { + 0x0013, "OpTypeVoid", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0014, "OpTypeBool", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0015, "OpTypeInt", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x0016, "OpTypeFloat", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_FPENCODING, '?'}, + } + }, + { + 0x0017, "OpTypeVector", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x0018, "OpTypeMatrix", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x0019, "OpTypeImage", 9, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_DIM}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_IMAGE_FORMAT}, + {SPIRV_PARSER_OPERAND_TYPE_ACCESS_QUALIFIER, '?'}, + } + }, + { + 0x001a, "OpTypeSampler", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x001b, "OpTypeSampledImage", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x001c, "OpTypeArray", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x001d, "OpTypeRuntimeArray", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x001e, "OpTypeStruct", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x001f, "OpTypeOpaque", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x0020, "OpTypePointer", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0021, "OpTypeFunction", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x0022, "OpTypeEvent", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0023, "OpTypeDeviceEvent", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0024, "OpTypeReserveId", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0025, "OpTypeQueue", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0026, "OpTypePipe", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ACCESS_QUALIFIER}, + } + }, + { + 0x0027, "OpTypeForwardPointer", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS}, + } + }, + { + 0x0029, "OpConstantTrue", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x002a, "OpConstantFalse", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x002b, "OpConstant", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_CONTEXT_DEPENDENT_NUMBER}, + } + }, + { + 0x002c, "OpConstantComposite", 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, '*'}, + } + }, + { + 0x002d, "OpConstantSampler", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_SAMPLER_ADDRESSING_MODE}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_SAMPLER_FILTER_MODE}, + } + }, + { + 0x002e, "OpConstantNull", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0030, "OpSpecConstantTrue", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0031, "OpSpecConstantFalse", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0032, "OpSpecConstant", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_CONTEXT_DEPENDENT_NUMBER}, + } + }, + { + 0x0033, "OpSpecConstantComposite", 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, '*'}, + } + }, + { + 0x0034, "OpSpecConstantOp", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_SPEC_CONSTANT_OP_INTEGER}, + } + }, + { + 0x0036, "OpFunction", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_FUNCTION_CONTROL}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0037, "OpFunctionParameter", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + {0x0038, "OpFunctionEnd"}, + { + 0x0039, "OpFunctionCall", 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, '*'}, + } + }, + { + 0x003b, "OpVariable", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x003c, "OpImageTexelPointer", 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_ID_REF}, + } + }, + { + 0x003d, "OpLoad", 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_MEMORY_ACCESS, '?'}, + } + }, + { + 0x003e, "OpStore", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, + } + }, + { + 0x003f, "OpCopyMemory", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, + {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, + } + }, + { + 0x0040, "OpCopyMemorySized", 5, + (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, '?'}, + {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, + } + }, + { + 0x0041, "OpAccessChain", 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, '*'}, + } + }, + { + 0x0042, "OpInBoundsAccessChain", 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, '*'}, + } + }, + { + 0x0043, "OpPtrAccessChain", 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_ID_REF, '*'}, + } + }, + { + 0x0044, "OpArrayLength", 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_LITERAL_INTEGER}, + } + }, + { + 0x0045, "OpGenericPtrMemSemantics", 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}, + } + }, + { + 0x0046, "OpInBoundsPtrAccessChain", 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_ID_REF, '*'}, + } + }, + { + 0x0047, "OpDecorate", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_DECORATION}, + } + }, + { + 0x0048, "OpMemberDecorate", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_DECORATION}, + } + }, + { + 0x0049, "OpDecorationGroup", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x004a, "OpGroupDecorate", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x004b, "OpGroupMemberDecorate", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_PAIR_ID_REF_LITERAL_INTEGER, '*'}, + } + }, + { + 0x004d, "OpVectorExtractDynamic", 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}, + } + }, + { + 0x004e, "OpVectorInsertDynamic", 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_ID_REF}, + } + }, + { + 0x004f, "OpVectorShuffle", 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_LITERAL_INTEGER, '*'}, + } + }, + { + 0x0050, "OpCompositeConstruct", 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, '*'}, + } + }, + { + 0x0051, "OpCompositeExtract", 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_LITERAL_INTEGER, '*'}, + } + }, + { + 0x0052, "OpCompositeInsert", 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_LITERAL_INTEGER, '*'}, + } + }, + { + 0x0053, "OpCopyObject", 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}, + } + }, + { + 0x0054, "OpTranspose", 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}, + } + }, + { + 0x0056, "OpSampledImage", 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}, + } + }, + { + 0x0057, "OpImageSampleImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0058, "OpImageSampleExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x0059, "OpImageSampleDrefImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x005a, "OpImageSampleDrefExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x005b, "OpImageSampleProjImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x005c, "OpImageSampleProjExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x005d, "OpImageSampleProjDrefImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x005e, "OpImageSampleProjDrefExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x005f, "OpImageFetch", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0060, "OpImageGather", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0061, "OpImageDrefGather", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0062, "OpImageRead", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0063, "OpImageWrite", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0064, "OpImage", 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}, + } + }, + { + 0x0065, "OpImageQueryFormat", 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}, + } + }, + { + 0x0066, "OpImageQueryOrder", 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}, + } + }, + { + 0x0067, "OpImageQuerySizeLod", 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}, + } + }, + { + 0x0068, "OpImageQuerySize", 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}, + } + }, + { + 0x0069, "OpImageQueryLod", 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}, + } + }, + { + 0x006a, "OpImageQueryLevels", 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}, + } + }, + { + 0x006b, "OpImageQuerySamples", 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}, + } + }, + { + 0x006d, "OpConvertFToU", 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}, + } + }, + { + 0x006e, "OpConvertFToS", 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}, + } + }, + { + 0x006f, "OpConvertSToF", 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}, + } + }, + { + 0x0070, "OpConvertUToF", 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}, + } + }, + { + 0x0071, "OpUConvert", 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}, + } + }, + { + 0x0072, "OpSConvert", 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}, + } + }, + { + 0x0073, "OpFConvert", 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}, + } + }, + { + 0x0074, "OpQuantizeToF16", 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}, + } + }, + { + 0x0075, "OpConvertPtrToU", 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}, + } + }, + { + 0x0076, "OpSatConvertSToU", 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}, + } + }, + { + 0x0077, "OpSatConvertUToS", 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}, + } + }, + { + 0x0078, "OpConvertUToPtr", 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}, + } + }, + { + 0x0079, "OpPtrCastToGeneric", 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}, + } + }, + { + 0x007a, "OpGenericCastToPtr", 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}, + } + }, + { + 0x007b, "OpGenericCastToPtrExplicit", 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_STORAGE_CLASS}, + } + }, + { + 0x007c, "OpBitcast", 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}, + } + }, + { + 0x007e, "OpSNegate", 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}, + } + }, + { + 0x007f, "OpFNegate", 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}, + } + }, + { + 0x0080, "OpIAdd", 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}, + } + }, + { + 0x0081, "OpFAdd", 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}, + } + }, + { + 0x0082, "OpISub", 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}, + } + }, + { + 0x0083, "OpFSub", 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}, + } + }, + { + 0x0084, "OpIMul", 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}, + } + }, + { + 0x0085, "OpFMul", 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}, + } + }, + { + 0x0086, "OpUDiv", 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}, + } + }, + { + 0x0087, "OpSDiv", 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}, + } + }, + { + 0x0088, "OpFDiv", 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}, + } + }, + { + 0x0089, "OpUMod", 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}, + } + }, + { + 0x008a, "OpSRem", 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}, + } + }, + { + 0x008b, "OpSMod", 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}, + } + }, + { + 0x008c, "OpFRem", 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}, + } + }, + { + 0x008d, "OpFMod", 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}, + } + }, + { + 0x008e, "OpVectorTimesScalar", 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}, + } + }, + { + 0x008f, "OpMatrixTimesScalar", 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}, + } + }, + { + 0x0090, "OpVectorTimesMatrix", 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}, + } + }, + { + 0x0091, "OpMatrixTimesVector", 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}, + } + }, + { + 0x0092, "OpMatrixTimesMatrix", 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}, + } + }, + { + 0x0093, "OpOuterProduct", 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}, + } + }, + { + 0x0094, "OpDot", 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}, + } + }, + { + 0x0095, "OpIAddCarry", 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}, + } + }, + { + 0x0096, "OpISubBorrow", 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}, + } + }, + { + 0x0097, "OpUMulExtended", 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}, + } + }, + { + 0x0098, "OpSMulExtended", 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}, + } + }, + { + 0x009a, "OpAny", 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}, + } + }, + { + 0x009b, "OpAll", 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}, + } + }, + { + 0x009c, "OpIsNan", 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}, + } + }, + { + 0x009d, "OpIsInf", 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}, + } + }, + { + 0x009e, "OpIsFinite", 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}, + } + }, + { + 0x009f, "OpIsNormal", 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}, + } + }, + { + 0x00a0, "OpSignBitSet", 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}, + } + }, + { + 0x00a1, "OpLessOrGreater", 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}, + } + }, + { + 0x00a2, "OpOrdered", 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}, + } + }, + { + 0x00a3, "OpUnordered", 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}, + } + }, + { + 0x00a4, "OpLogicalEqual", 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}, + } + }, + { + 0x00a5, "OpLogicalNotEqual", 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}, + } + }, + { + 0x00a6, "OpLogicalOr", 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}, + } + }, + { + 0x00a7, "OpLogicalAnd", 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}, + } + }, + { + 0x00a8, "OpLogicalNot", 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}, + } + }, + { + 0x00a9, "OpSelect", 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_ID_REF}, + } + }, + { + 0x00aa, "OpIEqual", 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}, + } + }, + { + 0x00ab, "OpINotEqual", 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}, + } + }, + { + 0x00ac, "OpUGreaterThan", 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}, + } + }, + { + 0x00ad, "OpSGreaterThan", 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}, + } + }, + { + 0x00ae, "OpUGreaterThanEqual", 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}, + } + }, + { + 0x00af, "OpSGreaterThanEqual", 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}, + } + }, + { + 0x00b0, "OpULessThan", 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}, + } + }, + { + 0x00b1, "OpSLessThan", 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}, + } + }, + { + 0x00b2, "OpULessThanEqual", 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}, + } + }, + { + 0x00b3, "OpSLessThanEqual", 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}, + } + }, + { + 0x00b4, "OpFOrdEqual", 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}, + } + }, + { + 0x00b5, "OpFUnordEqual", 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}, + } + }, + { + 0x00b6, "OpFOrdNotEqual", 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}, + } + }, + { + 0x00b7, "OpFUnordNotEqual", 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}, + } + }, + { + 0x00b8, "OpFOrdLessThan", 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}, + } + }, + { + 0x00b9, "OpFUnordLessThan", 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}, + } + }, + { + 0x00ba, "OpFOrdGreaterThan", 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}, + } + }, + { + 0x00bb, "OpFUnordGreaterThan", 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}, + } + }, + { + 0x00bc, "OpFOrdLessThanEqual", 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}, + } + }, + { + 0x00bd, "OpFUnordLessThanEqual", 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}, + } + }, + { + 0x00be, "OpFOrdGreaterThanEqual", 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}, + } + }, + { + 0x00bf, "OpFUnordGreaterThanEqual", 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}, + } + }, + { + 0x00c2, "OpShiftRightLogical", 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}, + } + }, + { + 0x00c3, "OpShiftRightArithmetic", 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}, + } + }, + { + 0x00c4, "OpShiftLeftLogical", 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}, + } + }, + { + 0x00c5, "OpBitwiseOr", 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}, + } + }, + { + 0x00c6, "OpBitwiseXor", 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}, + } + }, + { + 0x00c7, "OpBitwiseAnd", 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}, + } + }, + { + 0x00c8, "OpNot", 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}, + } + }, + { + 0x00c9, "OpBitFieldInsert", 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}, + } + }, + { + 0x00ca, "OpBitFieldSExtract", 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_ID_REF}, + } + }, + { + 0x00cb, "OpBitFieldUExtract", 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_ID_REF}, + } + }, + { + 0x00cc, "OpBitReverse", 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}, + } + }, + { + 0x00cd, "OpBitCount", 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}, + } + }, + { + 0x00cf, "OpDPdx", 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}, + } + }, + { + 0x00d0, "OpDPdy", 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}, + } + }, + { + 0x00d1, "OpFwidth", 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}, + } + }, + { + 0x00d2, "OpDPdxFine", 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}, + } + }, + { + 0x00d3, "OpDPdyFine", 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}, + } + }, + { + 0x00d4, "OpFwidthFine", 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}, + } + }, + { + 0x00d5, "OpDPdxCoarse", 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}, + } + }, + { + 0x00d6, "OpDPdyCoarse", 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}, + } + }, + { + 0x00d7, "OpFwidthCoarse", 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}, + } + }, + {0x00da, "OpEmitVertex"}, + {0x00db, "OpEndPrimitive"}, + { + 0x00dc, "OpEmitStreamVertex", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00dd, "OpEndStreamPrimitive", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00e0, "OpControlBarrier", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x00e1, "OpMemoryBarrier", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x00e3, "OpAtomicLoad", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x00e4, "OpAtomicStore", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00e5, "OpAtomicExchange", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00e6, "OpAtomicCompareExchange", 8, + (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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00e7, "OpAtomicCompareExchangeWeak", 8, + (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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00e8, "OpAtomicIIncrement", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x00e9, "OpAtomicIDecrement", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x00ea, "OpAtomicIAdd", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00eb, "OpAtomicISub", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00ec, "OpAtomicSMin", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00ed, "OpAtomicUMin", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00ee, "OpAtomicSMax", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00ef, "OpAtomicUMax", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00f0, "OpAtomicAnd", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00f1, "OpAtomicOr", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00f2, "OpAtomicXor", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00f5, "OpPhi", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_PAIR_ID_REF_ID_REF, '*'}, + } + }, + { + 0x00f6, "OpLoopMerge", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LOOP_CONTROL}, + } + }, + { + 0x00f7, "OpSelectionMerge", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_SELECTION_CONTROL}, + } + }, + { + 0x00f8, "OpLabel", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x00f9, "OpBranch", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x00fa, "OpBranchConditional", 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_LITERAL_INTEGER, '*'}, + } + }, + { + 0x00fb, "OpSwitch", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_PAIR_LITERAL_INTEGER_ID_REF, '*'}, + } + }, + {0x00fc, "OpKill"}, + {0x00fd, "OpReturn"}, + { + 0x00fe, "OpReturnValue", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + {0x00ff, "OpUnreachable"}, + { + 0x0100, "OpLifetimeStart", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x0101, "OpLifetimeStop", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x0103, "OpGroupAsyncCopy", 8, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {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}, + } + }, + { + 0x0104, "OpGroupWaitEvents", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0105, "OpGroupAll", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0106, "OpGroupAny", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0107, "OpGroupBroadcast", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0108, "OpGroupIAdd", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0109, "OpGroupFAdd", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x010a, "OpGroupFMin", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x010b, "OpGroupUMin", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x010c, "OpGroupSMin", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x010d, "OpGroupFMax", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x010e, "OpGroupUMax", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x010f, "OpGroupSMax", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0112, "OpReadPipe", 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}, + } + }, + { + 0x0113, "OpWritePipe", 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}, + } + }, + { + 0x0114, "OpReservedReadPipe", 8, + (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}, + } + }, + { + 0x0115, "OpReservedWritePipe", 8, + (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}, + } + }, + { + 0x0116, "OpReserveReadPipePackets", 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}, + } + }, + { + 0x0117, "OpReserveWritePipePackets", 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}, + } + }, + { + 0x0118, "OpCommitReadPipe", 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_ID_REF}, + } + }, + { + 0x0119, "OpCommitWritePipe", 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_ID_REF}, + } + }, + { + 0x011a, "OpIsValidReserveId", 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}, + } + }, + { + 0x011b, "OpGetNumPipePackets", 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_ID_REF}, + } + }, + { + 0x011c, "OpGetMaxPipePackets", 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_ID_REF}, + } + }, + { + 0x011d, "OpGroupReserveReadPipePackets", 7, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x011e, "OpGroupReserveWritePipePackets", 7, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x011f, "OpGroupCommitReadPipe", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0120, "OpGroupCommitWritePipe", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0123, "OpEnqueueMarker", 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}, + } + }, + { + 0x0124, "OpEnqueueKernel", 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_ID_REF, '*'}, + } + }, + { + 0x0125, "OpGetKernelNDrangeSubGroupCount", 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_ID_REF}, + } + }, + { + 0x0126, "OpGetKernelNDrangeMaxSubGroupSize", 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_ID_REF}, + } + }, + { + 0x0127, "OpGetKernelWorkGroupSize", 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}, + } + }, + { + 0x0128, "OpGetKernelPreferredWorkGroupSizeMultiple", 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}, + } + }, + { + 0x0129, "OpRetainEvent", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x012a, "OpReleaseEvent", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x012b, "OpCreateUserEvent", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x012c, "OpIsValidEvent", 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}, + } + }, + { + 0x012d, "OpSetUserEventStatus", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x012e, "OpCaptureEventProfilingInfo", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x012f, "OpGetDefaultQueue", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0130, "OpBuildNDRange", 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_ID_REF}, + } + }, + { + 0x0131, "OpImageSparseSampleImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0132, "OpImageSparseSampleExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x0133, "OpImageSparseSampleDrefImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0134, "OpImageSparseSampleDrefExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x0135, "OpImageSparseSampleProjImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0136, "OpImageSparseSampleProjExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x0137, "OpImageSparseSampleProjDrefImplicitLod", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0138, "OpImageSparseSampleProjDrefExplicitLod", 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_IMAGE_OPERANDS}, + } + }, + { + 0x0139, "OpImageSparseFetch", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x013a, "OpImageSparseGather", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x013b, "OpImageSparseDrefGather", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x013c, "OpImageSparseTexelsResident", 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}, + } + }, + {0x013d, "OpNoLine"}, + { + 0x013e, "OpAtomicFlagTestAndSet", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x013f, "OpAtomicFlagClear", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x0140, "OpImageSparseRead", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x0141, "OpSizeOf", 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}, + } + }, + { + 0x0142, "OpTypePipeStorage", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0143, "OpConstantPipeStorage", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x0144, "OpCreatePipeFromPipeStorage", 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}, + } + }, + { + 0x0145, "OpGetKernelLocalSizeForSubgroupCount", 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_ID_REF}, + } + }, + { + 0x0146, "OpGetKernelMaxNumSubgroups", 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}, + } + }, + { + 0x0147, "OpTypeNamedBarrier", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x0148, "OpNamedBarrierInitialize", 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}, + } + }, + { + 0x0149, "OpMemoryNamedBarrier", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x014a, "OpModuleProcessed", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x014b, "OpExecutionModeId", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE}, + } + }, + { + 0x014c, "OpDecorateId", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_DECORATION}, + } + }, + { + 0x014d, "OpGroupNonUniformElect", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + } + }, + { + 0x014e, "OpGroupNonUniformAll", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x014f, "OpGroupNonUniformAny", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0150, "OpGroupNonUniformAllEqual", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0151, "OpGroupNonUniformBroadcast", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0152, "OpGroupNonUniformBroadcastFirst", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0153, "OpGroupNonUniformBallot", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0154, "OpGroupNonUniformInverseBallot", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0155, "OpGroupNonUniformBallotBitExtract", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0156, "OpGroupNonUniformBallotBitCount", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0157, "OpGroupNonUniformBallotFindLSB", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0158, "OpGroupNonUniformBallotFindMSB", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0159, "OpGroupNonUniformShuffle", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x015a, "OpGroupNonUniformShuffleXor", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x015b, "OpGroupNonUniformShuffleUp", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x015c, "OpGroupNonUniformShuffleDown", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x015d, "OpGroupNonUniformIAdd", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x015e, "OpGroupNonUniformFAdd", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x015f, "OpGroupNonUniformIMul", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0160, "OpGroupNonUniformFMul", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0161, "OpGroupNonUniformSMin", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0162, "OpGroupNonUniformUMin", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0163, "OpGroupNonUniformFMin", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0164, "OpGroupNonUniformSMax", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0165, "OpGroupNonUniformUMax", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0166, "OpGroupNonUniformFMax", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0167, "OpGroupNonUniformBitwiseAnd", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0168, "OpGroupNonUniformBitwiseOr", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x0169, "OpGroupNonUniformBitwiseXor", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x016a, "OpGroupNonUniformLogicalAnd", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x016b, "OpGroupNonUniformLogicalOr", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x016c, "OpGroupNonUniformLogicalXor", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x016d, "OpGroupNonUniformQuadBroadcast", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x016e, "OpGroupNonUniformQuadSwap", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x0190, "OpCopyLogical", 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}, + } + }, + { + 0x0191, "OpPtrEqual", 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}, + } + }, + { + 0x0192, "OpPtrNotEqual", 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}, + } + }, + { + 0x0193, "OpPtrDiff", 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}, + } + }, + { + 0x1040, "OpColorAttachmentReadEXT", 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, '?'}, + } + }, + { + 0x1041, "OpDepthAttachmentReadEXT", 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, '?'}, + } + }, + { + 0x1042, "OpStencilAttachmentReadEXT", 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, '?'}, + } + }, + {0x1140, "OpTerminateInvocation"}, + { + 0x1141, "OpTypeUntypedPointerKHR", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS}, + } + }, + { + 0x1142, "OpUntypedVariableKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x1143, "OpUntypedAccessChainKHR", 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_ID_REF, '*'}, + } + }, + { + 0x1144, "OpUntypedInBoundsAccessChainKHR", 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_ID_REF, '*'}, + } + }, + { + 0x1145, "OpSubgroupBallotKHR", 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}, + } + }, + { + 0x1146, "OpSubgroupFirstInvocationKHR", 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}, + } + }, + { + 0x1147, "OpUntypedPtrAccessChainKHR", 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, '*'}, + } + }, + { + 0x1148, "OpUntypedInBoundsPtrAccessChainKHR", 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, '*'}, + } + }, + { + 0x1149, "OpUntypedArrayLengthKHR", 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_LITERAL_INTEGER}, + } + }, + { + 0x114a, "OpUntypedPrefetchKHR", 5, + (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, '?'}, + } + }, + { + 0x114c, "OpSubgroupAllKHR", 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}, + } + }, + { + 0x114d, "OpSubgroupAnyKHR", 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}, + } + }, + { + 0x114e, "OpSubgroupAllEqualKHR", 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}, + } + }, + { + 0x114f, "OpGroupNonUniformRotateKHR", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x1150, "OpSubgroupReadInvocationKHR", 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}, + } + }, + { + 0x1151, "OpExtInstWithForwardRefsKHR", 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_LITERAL_EXT_INST_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x115d, "OpTraceRayKHR", 11, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x115e, "OpExecuteCallableKHR", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x115f, "OpConvertUToAccelerationStructureKHR", 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}, + } + }, + {0x1160, "OpIgnoreIntersectionKHR"}, + {0x1161, "OpTerminateRayKHR"}, + { + 0x1162, "OpSDot", 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_PACKED_VECTOR_FORMAT, '?'}, + } + }, + { + 0x1163, "OpUDot", 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_PACKED_VECTOR_FORMAT, '?'}, + } + }, + { + 0x1164, "OpSUDot", 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_PACKED_VECTOR_FORMAT, '?'}, + } + }, + { + 0x1165, "OpSDotAccSat", 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_PACKED_VECTOR_FORMAT, '?'}, + } + }, + { + 0x1166, "OpUDotAccSat", 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_PACKED_VECTOR_FORMAT, '?'}, + } + }, + { + 0x1167, "OpSUDotAccSat", 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_PACKED_VECTOR_FORMAT, '?'}, + } + }, + { + 0x1168, "OpTypeCooperativeMatrixKHR", 6, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1169, "OpCooperativeMatrixLoadKHR", 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_MEMORY_ACCESS, '?'}, + } + }, + { + 0x116a, "OpCooperativeMatrixStoreKHR", 5, + (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_MEMORY_ACCESS, '?'}, + } + }, + { + 0x116b, "OpCooperativeMatrixMulAddKHR", 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_COOPERATIVE_MATRIX_OPERANDS, '?'}, + } + }, + { + 0x116c, "OpCooperativeMatrixLengthKHR", 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}, + } + }, + { + 0x116d, "OpConstantCompositeReplicateEXT", 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}, + } + }, + { + 0x116e, "OpSpecConstantCompositeReplicateEXT", 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}, + } + }, + { + 0x116f, "OpCompositeConstructReplicateEXT", 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}, + } + }, + { + 0x1178, "OpTypeRayQueryKHR", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1179, "OpRayQueryInitializeKHR", 8, + (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}, + } + }, + { + 0x117a, "OpRayQueryTerminateKHR", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x117b, "OpRayQueryGenerateIntersectionKHR", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x117c, "OpRayQueryConfirmIntersectionKHR", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x117d, "OpRayQueryProceedKHR", 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}, + } + }, + { + 0x117f, "OpRayQueryGetIntersectionTypeKHR", 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}, + } + }, + { + 0x1180, "OpImageSampleWeightedQCOM", 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_ID_REF}, + } + }, + { + 0x1181, "OpImageBoxFilterQCOM", 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_ID_REF}, + } + }, + { + 0x1182, "OpImageBlockMatchSSDQCOM", 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_ID_REF}, + } + }, + { + 0x1183, "OpImageBlockMatchSADQCOM", 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_ID_REF}, + } + }, + { + 0x1194, "OpImageBlockMatchWindowSSDQCOM", 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_ID_REF}, + } + }, + { + 0x1195, "OpImageBlockMatchWindowSADQCOM", 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_ID_REF}, + } + }, + { + 0x1196, "OpImageBlockMatchGatherSSDQCOM", 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_ID_REF}, + } + }, + { + 0x1197, "OpImageBlockMatchGatherSADQCOM", 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_ID_REF}, + } + }, + { + 0x1388, "OpGroupIAddNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1389, "OpGroupFAddNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x138a, "OpGroupFMinNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x138b, "OpGroupUMinNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x138c, "OpGroupSMinNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x138d, "OpGroupFMaxNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x138e, "OpGroupUMaxNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x138f, "OpGroupSMaxNonUniformAMD", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1393, "OpFragmentMaskFetchAMD", 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}, + } + }, + { + 0x1394, "OpFragmentFetchAMD", 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_ID_REF}, + } + }, + { + 0x13c0, "OpReadClockKHR", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + } + }, + { + 0x13d2, "OpAllocateNodePayloadsAMDX", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x13d3, "OpEnqueueNodePayloadsAMDX", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x13d4, "OpTypeNodePayloadArrayAMDX", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x13d6, "OpFinishWritingNodePayloadAMDX", 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}, + } + }, + { + 0x13e2, "OpNodePayloadArrayLengthAMDX", 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}, + } + }, + { + 0x13ed, "OpIsNodePayloadValidAMDX", 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}, + } + }, + { + 0x13ef, "OpConstantStringAMDX", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x13f0, "OpSpecConstantStringAMDX", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x13f6, "OpGroupNonUniformQuadAllKHR", 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}, + } + }, + { + 0x13f7, "OpGroupNonUniformQuadAnyKHR", 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}, + } + }, + { + 0x1481, "OpHitObjectRecordHitMotionNV", 14, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1482, "OpHitObjectRecordHitWithIndexMotionNV", 13, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1483, "OpHitObjectRecordMissMotionNV", 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}, + } + }, + { + 0x1484, "OpHitObjectGetWorldToObjectNV", 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}, + } + }, + { + 0x1485, "OpHitObjectGetObjectToWorldNV", 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}, + } + }, + { + 0x1486, "OpHitObjectGetObjectRayDirectionNV", 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}, + } + }, + { + 0x1487, "OpHitObjectGetObjectRayOriginNV", 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}, + } + }, + { + 0x1488, "OpHitObjectTraceRayMotionNV", 13, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1489, "OpHitObjectGetShaderRecordBufferHandleNV", 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}, + } + }, + { + 0x148a, "OpHitObjectGetShaderBindingTableRecordIndexNV", 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}, + } + }, + { + 0x148b, "OpHitObjectRecordEmptyNV", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x148c, "OpHitObjectTraceRayNV", 12, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x148d, "OpHitObjectRecordHitNV", 13, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x148e, "OpHitObjectRecordHitWithIndexNV", 12, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x148f, "OpHitObjectRecordMissNV", 6, + (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}, + } + }, + { + 0x1490, "OpHitObjectExecuteShaderNV", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1491, "OpHitObjectGetCurrentTimeNV", 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}, + } + }, + { + 0x1492, "OpHitObjectGetAttributesNV", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1493, "OpHitObjectGetHitKindNV", 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}, + } + }, + { + 0x1494, "OpHitObjectGetPrimitiveIndexNV", 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}, + } + }, + { + 0x1495, "OpHitObjectGetGeometryIndexNV", 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}, + } + }, + { + 0x1496, "OpHitObjectGetInstanceIdNV", 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}, + } + }, + { + 0x1497, "OpHitObjectGetInstanceCustomIndexNV", 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}, + } + }, + { + 0x1498, "OpHitObjectGetWorldRayDirectionNV", 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}, + } + }, + { + 0x1499, "OpHitObjectGetWorldRayOriginNV", 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}, + } + }, + { + 0x149a, "OpHitObjectGetRayTMaxNV", 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}, + } + }, + { + 0x149b, "OpHitObjectGetRayTMinNV", 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}, + } + }, + { + 0x149c, "OpHitObjectIsEmptyNV", 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}, + } + }, + { + 0x149d, "OpHitObjectIsHitNV", 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}, + } + }, + { + 0x149e, "OpHitObjectIsMissNV", 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}, + } + }, + { + 0x149f, "OpReorderThreadWithHitObjectNV", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x14a0, "OpReorderThreadWithHintNV", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14a1, "OpTypeHitObjectNV", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x14a3, "OpImageSampleFootprintNV", 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_IMAGE_OPERANDS, '?'}, + } + }, + { + 0x14ad, "OpCooperativeMatrixConvertNV", 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}, + } + }, + { + 0x14ae, "OpEmitMeshTasksEXT", 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_ID_REF, '?'}, + } + }, + { + 0x14af, "OpSetMeshOutputsEXT", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14b0, "OpGroupNonUniformPartitionNV", 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}, + } + }, + { + 0x14b3, "OpWritePackedPrimitiveIndices4x8NV", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14b4, "OpFetchMicroTriangleVertexPositionNV", 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_ID_REF}, + } + }, + { + 0x14b5, "OpFetchMicroTriangleVertexBarycentricNV", 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_ID_REF}, + } + }, + { + 0x14d6, "OpReportIntersectionKHR", 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}, + } + }, + {0x14d7, "OpIgnoreIntersectionNV"}, + {0x14d8, "OpTerminateRayNV"}, + { + 0x14d9, "OpTraceNV", 11, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14da, "OpTraceMotionNV", 12, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14db, "OpTraceRayMotionNV", 12, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14dc, "OpRayQueryGetIntersectionTriangleVertexPositionsKHR", 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}, + } + }, + { + 0x14dd, "OpTypeAccelerationStructureKHR", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x14e0, "OpExecuteCallableNV", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14ee, "OpTypeCooperativeMatrixNV", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14ef, "OpCooperativeMatrixLoadNV", 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_MEMORY_ACCESS, '?'}, + } + }, + { + 0x14f0, "OpCooperativeMatrixStoreNV", 5, + (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_MEMORY_ACCESS, '?'}, + } + }, + { + 0x14f1, "OpCooperativeMatrixMulAddNV", 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_ID_REF}, + } + }, + { + 0x14f2, "OpCooperativeMatrixLengthNV", 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}, + } + }, + {0x14f4, "OpBeginInvocationInterlockEXT"}, + {0x14f5, "OpEndInvocationInterlockEXT"}, + { + 0x14f6, "OpCooperativeMatrixReduceNV", 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_COOPERATIVE_MATRIX_REDUCE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14f7, "OpCooperativeMatrixLoadTensorNV", 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_MEMORY_ACCESS}, + {SPIRV_PARSER_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS}, + } + }, + { + 0x14f8, "OpCooperativeMatrixStoreTensorNV", 5, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_TENSOR_ADDRESSING_OPERANDS}, + } + }, + { + 0x14f9, "OpCooperativeMatrixPerElementOpNV", 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_ID_REF, '*'}, + } + }, + { + 0x14fa, "OpTypeTensorLayoutNV", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x14fb, "OpTypeTensorViewNV", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x14fc, "OpCreateTensorLayoutNV", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x14fd, "OpTensorLayoutSetDimensionNV", 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, '*'}, + } + }, + { + 0x14fe, "OpTensorLayoutSetStrideNV", 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, '*'}, + } + }, + { + 0x14ff, "OpTensorLayoutSliceNV", 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, '*'}, + } + }, + { + 0x1500, "OpTensorLayoutSetClampValueNV", 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}, + } + }, + { + 0x1501, "OpCreateTensorViewNV", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1502, "OpTensorViewSetDimensionNV", 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, '*'}, + } + }, + { + 0x1503, "OpTensorViewSetStrideNV", 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, '*'}, + } + }, + {0x1504, "OpDemoteToHelperInvocation"}, + { + 0x1505, "OpIsHelperInvocationEXT", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1506, "OpTensorViewSetClipNV", 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_ID_REF}, + } + }, + { + 0x1508, "OpTensorLayoutSetBlockSizeNV", 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, '*'}, + } + }, + { + 0x150e, "OpCooperativeMatrixTransposeNV", 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}, + } + }, + { + 0x150f, "OpConvertUToImageNV", 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}, + } + }, + { + 0x1510, "OpConvertUToSamplerNV", 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}, + } + }, + { + 0x1511, "OpConvertImageToUNV", 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}, + } + }, + { + 0x1512, "OpConvertSamplerToUNV", 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}, + } + }, + { + 0x1513, "OpConvertUToSampledImageNV", 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}, + } + }, + { + 0x1514, "OpConvertSampledImageToUNV", 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}, + } + }, + { + 0x1515, "OpSamplerImageAddressingModeNV", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x1516, "OpRawAccessChainNV", 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_RAW_ACCESS_CHAIN_OPERANDS, '?'}, + } + }, + { + 0x15c3, "OpSubgroupShuffleINTEL", 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}, + } + }, + { + 0x15c4, "OpSubgroupShuffleDownINTEL", 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_ID_REF}, + } + }, + { + 0x15c5, "OpSubgroupShuffleUpINTEL", 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_ID_REF}, + } + }, + { + 0x15c6, "OpSubgroupShuffleXorINTEL", 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}, + } + }, + { + 0x15c7, "OpSubgroupBlockReadINTEL", 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}, + } + }, + { + 0x15c8, "OpSubgroupBlockWriteINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x15c9, "OpSubgroupImageBlockReadINTEL", 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}, + } + }, + { + 0x15ca, "OpSubgroupImageBlockWriteINTEL", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x15cc, "OpSubgroupImageMediaBlockReadINTEL", 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}, + } + }, + { + 0x15cd, "OpSubgroupImageMediaBlockWriteINTEL", 5, + (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}, + } + }, + { + 0x15d1, "OpUCountLeadingZerosINTEL", 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}, + } + }, + { + 0x15d2, "OpUCountTrailingZerosINTEL", 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}, + } + }, + { + 0x15d3, "OpAbsISubINTEL", 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}, + } + }, + { + 0x15d4, "OpAbsUSubINTEL", 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}, + } + }, + { + 0x15d5, "OpIAddSatINTEL", 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}, + } + }, + { + 0x15d6, "OpUAddSatINTEL", 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}, + } + }, + { + 0x15d7, "OpIAverageINTEL", 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}, + } + }, + { + 0x15d8, "OpUAverageINTEL", 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}, + } + }, + { + 0x15d9, "OpIAverageRoundedINTEL", 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}, + } + }, + { + 0x15da, "OpUAverageRoundedINTEL", 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}, + } + }, + { + 0x15db, "OpISubSatINTEL", 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}, + } + }, + { + 0x15dc, "OpUSubSatINTEL", 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}, + } + }, + { + 0x15dd, "OpIMul32x16INTEL", 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}, + } + }, + { + 0x15de, "OpUMul32x16INTEL", 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}, + } + }, + { + 0x15e0, "OpConstantFunctionPointerINTEL", 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}, + } + }, + { + 0x15e1, "OpFunctionPointerCallINTEL", 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, '*'}, + } + }, + { + 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}, + } + }, + { + 0x15ea, "OpAsmINTEL", 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_LITERAL_STRING}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, + } + }, + { + 0x15eb, "OpAsmCallINTEL", 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, '*'}, + } + }, + { + 0x15ee, "OpAtomicFMinEXT", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x15ef, "OpAtomicFMaxEXT", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x15fe, "OpAssumeTrueKHR", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x15ff, "OpExpectKHR", 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}, + } + }, + { + 0x1600, "OpDecorateString", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_DECORATION}, + } + }, + { + 0x1601, "OpMemberDecorateString", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_DECORATION}, + } + }, + { + 0x1643, "OpVmeImageINTEL", 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}, + } + }, + { + 0x1644, "OpTypeVmeImageINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1645, "OpTypeAvcImePayloadINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1646, "OpTypeAvcRefPayloadINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1647, "OpTypeAvcSicPayloadINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1648, "OpTypeAvcMcePayloadINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1649, "OpTypeAvcMceResultINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x164a, "OpTypeAvcImeResultINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x164b, "OpTypeAvcImeResultSingleReferenceStreamoutINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x164c, "OpTypeAvcImeResultDualReferenceStreamoutINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x164d, "OpTypeAvcImeSingleReferenceStreaminINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x164e, "OpTypeAvcImeDualReferenceStreaminINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x164f, "OpTypeAvcRefResultINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1650, "OpTypeAvcSicResultINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1651, "OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL", 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}, + } + }, + { + 0x1652, "OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL", 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}, + } + }, + { + 0x1653, "OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL", 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}, + } + }, + { + 0x1654, "OpSubgroupAvcMceSetInterShapePenaltyINTEL", 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}, + } + }, + { + 0x1655, "OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL", 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}, + } + }, + { + 0x1656, "OpSubgroupAvcMceSetInterDirectionPenaltyINTEL", 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}, + } + }, + { + 0x1657, "OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL", 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}, + } + }, + { + 0x1658, "OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL", 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}, + } + }, + { + 0x1659, "OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x165a, "OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x165b, "OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x165c, "OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL", 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}, + } + }, + { + 0x165d, "OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL", 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}, + } + }, + { + 0x165e, "OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x165f, "OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x1660, "OpSubgroupAvcMceSetAcOnlyHaarINTEL", 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}, + } + }, + { + 0x1661, "OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL", 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}, + } + }, + { + 0x1662, "OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL", 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}, + } + }, + { + 0x1663, "OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL", 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_ID_REF}, + } + }, + { + 0x1664, "OpSubgroupAvcMceConvertToImePayloadINTEL", 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}, + } + }, + { + 0x1665, "OpSubgroupAvcMceConvertToImeResultINTEL", 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}, + } + }, + { + 0x1666, "OpSubgroupAvcMceConvertToRefPayloadINTEL", 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}, + } + }, + { + 0x1667, "OpSubgroupAvcMceConvertToRefResultINTEL", 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}, + } + }, + { + 0x1668, "OpSubgroupAvcMceConvertToSicPayloadINTEL", 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}, + } + }, + { + 0x1669, "OpSubgroupAvcMceConvertToSicResultINTEL", 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}, + } + }, + { + 0x166a, "OpSubgroupAvcMceGetMotionVectorsINTEL", 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}, + } + }, + { + 0x166b, "OpSubgroupAvcMceGetInterDistortionsINTEL", 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}, + } + }, + { + 0x166c, "OpSubgroupAvcMceGetBestInterDistortionsINTEL", 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}, + } + }, + { + 0x166d, "OpSubgroupAvcMceGetInterMajorShapeINTEL", 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}, + } + }, + { + 0x166e, "OpSubgroupAvcMceGetInterMinorShapeINTEL", 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}, + } + }, + { + 0x166f, "OpSubgroupAvcMceGetInterDirectionsINTEL", 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}, + } + }, + { + 0x1670, "OpSubgroupAvcMceGetInterMotionVectorCountINTEL", 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}, + } + }, + { + 0x1671, "OpSubgroupAvcMceGetInterReferenceIdsINTEL", 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}, + } + }, + { + 0x1672, "OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL", 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_ID_REF}, + } + }, + { + 0x1673, "OpSubgroupAvcImeInitializeINTEL", 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_ID_REF}, + } + }, + { + 0x1674, "OpSubgroupAvcImeSetSingleReferenceINTEL", 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_ID_REF}, + } + }, + { + 0x1675, "OpSubgroupAvcImeSetDualReferenceINTEL", 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}, + } + }, + { + 0x1676, "OpSubgroupAvcImeRefWindowSizeINTEL", 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}, + } + }, + { + 0x1677, "OpSubgroupAvcImeAdjustRefOffsetINTEL", 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}, + } + }, + { + 0x1678, "OpSubgroupAvcImeConvertToMcePayloadINTEL", 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}, + } + }, + { + 0x1679, "OpSubgroupAvcImeSetMaxMotionVectorCountINTEL", 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}, + } + }, + { + 0x167a, "OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL", 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}, + } + }, + { + 0x167b, "OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL", 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}, + } + }, + { + 0x167c, "OpSubgroupAvcImeSetWeightedSadINTEL", 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}, + } + }, + { + 0x167d, "OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL", 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_ID_REF}, + } + }, + { + 0x167e, "OpSubgroupAvcImeEvaluateWithDualReferenceINTEL", 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}, + } + }, + { + 0x167f, "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL", 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}, + } + }, + { + 0x1680, "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL", 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_ID_REF}, + } + }, + { + 0x1681, "OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL", 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_ID_REF}, + } + }, + { + 0x1682, "OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL", 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}, + } + }, + { + 0x1683, "OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL", 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}, + } + }, + { + 0x1684, "OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL", 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_ID_REF}, + } + }, + { + 0x1685, "OpSubgroupAvcImeConvertToMceResultINTEL", 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}, + } + }, + { + 0x1686, "OpSubgroupAvcImeGetSingleReferenceStreaminINTEL", 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}, + } + }, + { + 0x1687, "OpSubgroupAvcImeGetDualReferenceStreaminINTEL", 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}, + } + }, + { + 0x1688, "OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL", 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}, + } + }, + { + 0x1689, "OpSubgroupAvcImeStripDualReferenceStreamoutINTEL", 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}, + } + }, + { + 0x168a, "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL", 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}, + } + }, + { + 0x168b, "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL", 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}, + } + }, + { + 0x168c, "OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL", 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}, + } + }, + { + 0x168d, "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL", 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_ID_REF}, + } + }, + { + 0x168e, "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL", 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_ID_REF}, + } + }, + { + 0x168f, "OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL", 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_ID_REF}, + } + }, + { + 0x1690, "OpSubgroupAvcImeGetBorderReachedINTEL", 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}, + } + }, + { + 0x1691, "OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL", 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}, + } + }, + { + 0x1692, "OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL", 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}, + } + }, + { + 0x1693, "OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL", 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}, + } + }, + { + 0x1694, "OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL", 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}, + } + }, + { + 0x1695, "OpSubgroupAvcFmeInitializeINTEL", 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_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}, + } + }, + { + 0x1696, "OpSubgroupAvcBmeInitializeINTEL", 10, + (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}, + } + }, + { + 0x1697, "OpSubgroupAvcRefConvertToMcePayloadINTEL", 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}, + } + }, + { + 0x1698, "OpSubgroupAvcRefSetBidirectionalMixDisableINTEL", 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}, + } + }, + { + 0x1699, "OpSubgroupAvcRefSetBilinearFilterEnableINTEL", 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}, + } + }, + { + 0x169a, "OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL", 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_ID_REF}, + } + }, + { + 0x169b, "OpSubgroupAvcRefEvaluateWithDualReferenceINTEL", 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}, + } + }, + { + 0x169c, "OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL", 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_ID_REF}, + } + }, + { + 0x169d, "OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL", 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}, + } + }, + { + 0x169e, "OpSubgroupAvcRefConvertToMceResultINTEL", 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}, + } + }, + { + 0x169f, "OpSubgroupAvcSicInitializeINTEL", 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}, + } + }, + { + 0x16a0, "OpSubgroupAvcSicConfigureSkcINTEL", 8, + (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}, + } + }, + { + 0x16a1, "OpSubgroupAvcSicConfigureIpeLumaINTEL", 10, + (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}, + } + }, + { + 0x16a2, "OpSubgroupAvcSicConfigureIpeLumaChromaINTEL", 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_ID_REF}, + } + }, + { + 0x16a3, "OpSubgroupAvcSicGetMotionVectorMaskINTEL", 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}, + } + }, + { + 0x16a4, "OpSubgroupAvcSicConvertToMcePayloadINTEL", 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}, + } + }, + { + 0x16a5, "OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL", 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}, + } + }, + { + 0x16a6, "OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL", 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}, + } + }, + { + 0x16a7, "OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL", 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}, + } + }, + { + 0x16a8, "OpSubgroupAvcSicSetBilinearFilterEnableINTEL", 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}, + } + }, + { + 0x16a9, "OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL", 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}, + } + }, + { + 0x16aa, "OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL", 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}, + } + }, + { + 0x16ab, "OpSubgroupAvcSicEvaluateIpeINTEL", 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}, + } + }, + { + 0x16ac, "OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL", 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_ID_REF}, + } + }, + { + 0x16ad, "OpSubgroupAvcSicEvaluateWithDualReferenceINTEL", 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}, + } + }, + { + 0x16ae, "OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL", 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_ID_REF}, + } + }, + { + 0x16af, "OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL", 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}, + } + }, + { + 0x16b0, "OpSubgroupAvcSicConvertToMceResultINTEL", 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}, + } + }, + { + 0x16b1, "OpSubgroupAvcSicGetIpeLumaShapeINTEL", 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}, + } + }, + { + 0x16b2, "OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL", 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}, + } + }, + { + 0x16b3, "OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL", 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}, + } + }, + { + 0x16b4, "OpSubgroupAvcSicGetPackedIpeLumaModesINTEL", 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}, + } + }, + { + 0x16b5, "OpSubgroupAvcSicGetIpeChromaModeINTEL", 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}, + } + }, + { + 0x16b6, "OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL", 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}, + } + }, + { + 0x16b7, "OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL", 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}, + } + }, + { + 0x16b8, "OpSubgroupAvcSicGetInterRawSadsINTEL", 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}, + } + }, + { + 0x16ba, "OpVariableLengthArrayINTEL", 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}, + } + }, + { + 0x16bb, "OpSaveMemoryINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + } + }, + { + 0x16bc, "OpRestoreMemoryINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 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_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16d1, "OpArbitraryFloatCastINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16d2, "OpArbitraryFloatCastFromIntINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16d3, "OpArbitraryFloatCastToIntINTEL", 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}, + } + }, + { + 0x16d6, "OpArbitraryFloatAddINTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16d7, "OpArbitraryFloatSubINTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16d8, "OpArbitraryFloatMulINTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16d9, "OpArbitraryFloatDivINTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16da, "OpArbitraryFloatGTINTEL", 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_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16db, "OpArbitraryFloatGEINTEL", 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_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16dc, "OpArbitraryFloatLTINTEL", 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_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16dd, "OpArbitraryFloatLEINTEL", 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_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16de, "OpArbitraryFloatEQINTEL", 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_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16df, "OpArbitraryFloatRecipINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e0, "OpArbitraryFloatRSqrtINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e1, "OpArbitraryFloatCbrtINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e2, "OpArbitraryFloatHypotINTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e3, "OpArbitraryFloatSqrtINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e4, "OpArbitraryFloatLogINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e5, "OpArbitraryFloatLog2INTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e6, "OpArbitraryFloatLog10INTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e7, "OpArbitraryFloatLog1pINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e8, "OpArbitraryFloatExpINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16e9, "OpArbitraryFloatExp2INTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16ea, "OpArbitraryFloatExp10INTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16eb, "OpArbitraryFloatExpm1INTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16ec, "OpArbitraryFloatSinINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16ed, "OpArbitraryFloatCosINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16ee, "OpArbitraryFloatSinCosINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16ef, "OpArbitraryFloatSinPiINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f0, "OpArbitraryFloatCosPiINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f1, "OpArbitraryFloatASinINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f2, "OpArbitraryFloatASinPiINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f3, "OpArbitraryFloatACosINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f4, "OpArbitraryFloatACosPiINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f5, "OpArbitraryFloatATanINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f6, "OpArbitraryFloatATanPiINTEL", 8, + (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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f7, "OpArbitraryFloatATan2INTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f8, "OpArbitraryFloatPowINTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16f9, "OpArbitraryFloatPowRINTEL", 10, + (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_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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x16fa, "OpArbitraryFloatPowNINTEL", 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_LITERAL_INTEGER}, + {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}, + } + }, + { + 0x16ff, "OpLoopControlINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, '*'}, + } + }, + { + 0x1717, "OpAliasDomainDeclINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x1718, "OpAliasScopeDeclINTEL", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, + } + }, + { + 0x1719, "OpAliasScopeListDeclINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 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}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + } + }, + { + 0x172e, "OpPtrCastToCrossWorkgroupINTEL", 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}, + } + }, + { + 0x1732, "OpCrossWorkgroupCastToPtrINTEL", 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}, + } + }, + { + 0x173a, "OpReadPipeBlockingINTEL", 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}, + } + }, + { + 0x173b, "OpWritePipeBlockingINTEL", 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}, + } + }, + { + 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}, + } + }, + { + 0x1780, "OpRayQueryGetRayTMinKHR", 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}, + } + }, + { + 0x1781, "OpRayQueryGetRayFlagsKHR", 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}, + } + }, + { + 0x1782, "OpRayQueryGetIntersectionTKHR", 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}, + } + }, + { + 0x1783, "OpRayQueryGetIntersectionInstanceCustomIndexKHR", 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}, + } + }, + { + 0x1784, "OpRayQueryGetIntersectionInstanceIdKHR", 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}, + } + }, + { + 0x1785, "OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR", 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}, + } + }, + { + 0x1786, "OpRayQueryGetIntersectionGeometryIndexKHR", 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}, + } + }, + { + 0x1787, "OpRayQueryGetIntersectionPrimitiveIndexKHR", 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}, + } + }, + { + 0x1788, "OpRayQueryGetIntersectionBarycentricsKHR", 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}, + } + }, + { + 0x1789, "OpRayQueryGetIntersectionFrontFaceKHR", 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}, + } + }, + { + 0x178a, "OpRayQueryGetIntersectionCandidateAABBOpaqueKHR", 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}, + } + }, + { + 0x178b, "OpRayQueryGetIntersectionObjectRayDirectionKHR", 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}, + } + }, + { + 0x178c, "OpRayQueryGetIntersectionObjectRayOriginKHR", 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}, + } + }, + { + 0x178d, "OpRayQueryGetWorldRayDirectionKHR", 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}, + } + }, + { + 0x178e, "OpRayQueryGetWorldRayOriginKHR", 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}, + } + }, + { + 0x178f, "OpRayQueryGetIntersectionObjectToWorldKHR", 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}, + } + }, + { + 0x1790, "OpRayQueryGetIntersectionWorldToObjectKHR", 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}, + } + }, + { + 0x1793, "OpAtomicFAddEXT", 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_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x17c6, "OpTypeBufferSurfaceINTEL", 2, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ACCESS_QUALIFIER}, + } + }, + { + 0x17ca, "OpTypeStructContinuedINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x17cb, "OpConstantCompositeContinuedINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x17cc, "OpSpecConstantCompositeContinuedINTEL", 1, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, + } + }, + { + 0x17d0, "OpCompositeConstructContinuedINTEL", 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, '*'}, + } + }, + { + 0x17e4, "OpConvertFToBF16INTEL", 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}, + } + }, + { + 0x17e5, "OpConvertBF16ToFINTEL", 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}, + } + }, + { + 0x17fe, "OpControlBarrierArriveINTEL", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x17ff, "OpControlBarrierWaitINTEL", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_MEMORY_SEMANTICS}, + } + }, + { + 0x1801, "OpArithmeticFenceEXT", 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}, + } + }, + { + 0x184d, "OpSubgroupBlockPrefetchINTEL", 3, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, + } + }, + { + 0x1901, "OpGroupIMulKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1902, "OpGroupFMulKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1903, "OpGroupBitwiseAndKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1904, "OpGroupBitwiseOrKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1905, "OpGroupBitwiseXorKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1906, "OpGroupLogicalAndKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1907, "OpGroupLogicalOrKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x1908, "OpGroupLogicalXorKHR", 5, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, + {SPIRV_PARSER_OPERAND_TYPE_ID_SCOPE}, + {SPIRV_PARSER_OPERAND_TYPE_GROUP_OPERATION}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x191c, "OpMaskedGatherINTEL", 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_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, + { + 0x191d, "OpMaskedScatterINTEL", 4, + (struct spirv_parser_instruction_operand[]) + { + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + } + }, +}; diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h index ec1dd70c9b2..beb23257fb7 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -65,9 +65,12 @@ #define vkd3d_clamp(value, lower, upper) max(min(value, upper), lower)
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') +#define TAG_CLI4 VKD3D_MAKE_TAG('C', 'L', 'I', '4') +#define TAG_CTAB VKD3D_MAKE_TAG('C', 'T', 'A', 'B') #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') #define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') #define TAG_FX10 VKD3D_MAKE_TAG('F', 'X', '1', '0') +#define TAG_FXLC VKD3D_MAKE_TAG('F', 'X', 'L', 'C') #define TAG_ISG1 VKD3D_MAKE_TAG('I', 'S', 'G', '1') #define TAG_ISGN VKD3D_MAKE_TAG('I', 'S', 'G', 'N') #define TAG_OSG1 VKD3D_MAKE_TAG('O', 'S', 'G', '1') diff --git a/libs/vkd3d/include/private/vkd3d_shader_utils.h b/libs/vkd3d/include/private/vkd3d_shader_utils.h index c9f8001e590..00052a89988 100644 --- a/libs/vkd3d/include/private/vkd3d_shader_utils.h +++ b/libs/vkd3d/include/private/vkd3d_shader_utils.h @@ -43,16 +43,12 @@ static inline enum vkd3d_result vkd3d_shader_parse_dxbc_source_type(const struct if (tag == TAG_SHDR || tag == TAG_SHEX) { *type = VKD3D_SHADER_SOURCE_DXBC_TPF; -#ifndef VKD3D_SHADER_UNSUPPORTED_DXIL - break; -#else } else if (tag == TAG_DXIL) { *type = VKD3D_SHADER_SOURCE_DXBC_DXIL; /* Default to DXIL if both are present. */ break; -#endif } }
diff --git a/libs/vkd3d/include/vkd3d.h b/libs/vkd3d/include/vkd3d.h index 279c6b38be8..2cb150dce16 100644 --- a/libs/vkd3d/include/vkd3d.h +++ b/libs/vkd3d/include/vkd3d.h @@ -100,6 +100,7 @@ enum vkd3d_api_version VKD3D_API_VERSION_1_13, VKD3D_API_VERSION_1_14, VKD3D_API_VERSION_1_15, + VKD3D_API_VERSION_1_16,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_API_VERSION), }; diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index 058166aa2f9..30b6a070018 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -58,6 +58,7 @@ enum vkd3d_shader_api_version VKD3D_SHADER_API_VERSION_1_13, VKD3D_SHADER_API_VERSION_1_14, VKD3D_SHADER_API_VERSION_1_15, + VKD3D_SHADER_API_VERSION_1_16,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_API_VERSION), }; @@ -249,6 +250,10 @@ enum vkd3d_shader_compile_option_feature_flags * QUAD bits set. * - supportedStages include COMPUTE and FRAGMENT. \since 1.12 */ VKD3D_SHADER_COMPILE_OPTION_FEATURE_WAVE_OPS = 0x00000004, + /** The SPIR-V target environment supports zero-initializing workgroup + * memory. This corresponds to the "shaderZeroInitializeWorkgroupMemory" + * Vulkan feature. \since 1.16 */ + VKD3D_SHADER_COMPILE_OPTION_FEATURE_ZERO_INITIALIZE_WORKGROUP_MEMORY = 0x00000008,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLAGS), }; @@ -2072,6 +2077,11 @@ enum vkd3d_shader_resource_type */ enum vkd3d_shader_resource_data_type { + /** + * The descriptor has no relevant data type. This value is returned for + * samplers. \since 1.16 + */ + VKD3D_SHADER_RESOURCE_DATA_NONE = 0x0, /** Unsigned normalized integer. */ VKD3D_SHADER_RESOURCE_DATA_UNORM = 0x1, /** Signed normalized integer. */ @@ -2286,6 +2296,14 @@ enum vkd3d_shader_component_type VKD3D_SHADER_COMPONENT_DOUBLE = 0x5, /** 64-bit unsigned integer. \since 1.11 */ VKD3D_SHADER_COMPONENT_UINT64 = 0x6, + /** 64-bit signed integer. \since 1.16 */ + VKD3D_SHADER_COMPONENT_INT64 = 0x7, + /** 16-bit IEEE floating-point. \since 1.16 */ + VKD3D_SHADER_COMPONENT_FLOAT16 = 0x8, + /** 16-bit unsigned integer. \since 1.16 */ + VKD3D_SHADER_COMPONENT_UINT16 = 0x9, + /** 16-bit signed integer. \since 1.16 */ + VKD3D_SHADER_COMPONENT_INT16 = 0xa,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_COMPONENT_TYPE), }; @@ -2723,6 +2741,10 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported * source code or byte code. * * This version of vkd3d-shader supports the following transformations: + * - VKD3D_SHADER_SOURCE_DXBC_DXIL to VKD3D_SHADER_TARGET_SPIRV_BINARY + * - VKD3D_SHADER_SOURCE_DXBC_DXIL to VKD3D_SHADER_TARGET_SPIRV_TEXT + * (if vkd3d was compiled with SPIRV-Tools) + * - VKD3D_SHADER_SOURCE_DXBC_DXIL to VKD3D_SHADER_TARGET_D3D_ASM * - VKD3D_SHADER_SOURCE_DXBC_TPF to VKD3D_SHADER_TARGET_SPIRV_BINARY * - VKD3D_SHADER_SOURCE_DXBC_TPF to VKD3D_SHADER_TARGET_SPIRV_TEXT * (if vkd3d was compiled with SPIRV-Tools) @@ -2935,6 +2957,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver * VKD3D_SHADER_RESOURCE_DATA_FLOAT.) * * Currently this function supports the following code types: + * - VKD3D_SHADER_SOURCE_DXBC_DXIL * - VKD3D_SHADER_SOURCE_DXBC_TPF * - VKD3D_SHADER_SOURCE_D3D_BYTECODE * @@ -2991,7 +3014,8 @@ VKD3D_SHADER_API void vkd3d_shader_free_scan_descriptor_info( * signature. To retrieve signatures from other shader types, or other signature * types, use vkd3d_shader_scan() and struct vkd3d_shader_scan_signature_info. * This function returns the same input signature that is returned in - * struct vkd3d_shader_scan_signature_info. + * struct vkd3d_shader_scan_signature_info for dxbc-tpf shaders, but may return + * different information for dxbc-dxil shaders. * * \param dxbc Compiled byte code, in DXBC format. * diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index 0639da83aa6..4521bfabd8e 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -687,7 +687,7 @@ static void shader_print_input_sysval_semantic(struct vkd3d_d3d_asm_compiler *co prefix, compiler->colours.error, semantic, compiler->colours.reset, suffix); }
-static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_resource_type type) +static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_resource_type type) { static const char *const resource_type_names[] = { @@ -707,10 +707,11 @@ static void shader_dump_resource_type(struct vkd3d_d3d_asm_compiler *compiler, e if (type < ARRAY_SIZE(resource_type_names)) vkd3d_string_buffer_printf(&compiler->buffer, "%s", resource_type_names[type]); else - vkd3d_string_buffer_printf(&compiler->buffer, "unknown"); + vkd3d_string_buffer_printf(&compiler->buffer, "%s<unhandled resource type %#x>%s", + compiler->colours.error, type, compiler->colours.reset); }
-static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) +static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) { static const char *const data_type_names[] = { @@ -731,14 +732,11 @@ static void shader_dump_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum [VKD3D_DATA_HALF ] = "half", };
- const char *name; - if (type < ARRAY_SIZE(data_type_names)) - name = data_type_names[type]; + vkd3d_string_buffer_printf(&compiler->buffer, "%s", data_type_names[type]); else - name = "<unknown>"; - - vkd3d_string_buffer_printf(&compiler->buffer, "%s", name); + vkd3d_string_buffer_printf(&compiler->buffer, "%s<unhandled data type %#x>%s", + compiler->colours.error, type, compiler->colours.reset); }
static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type) @@ -750,7 +748,7 @@ static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compil for (i = 0; i < 4; i++) { vkd3d_string_buffer_printf(&compiler->buffer, "%s", i == 0 ? "" : ","); - shader_dump_data_type(compiler, type[i]); + shader_print_data_type(compiler, type[i]); }
vkd3d_string_buffer_printf(&compiler->buffer, ")"); @@ -793,7 +791,7 @@ static void shader_print_dcl_usage(struct vkd3d_d3d_asm_compiler *compiler, if (semantic->resource.reg.reg.type == VKD3DSPR_RESOURCE) vkd3d_string_buffer_printf(buffer, "resource_");
- shader_dump_resource_type(compiler, semantic->resource_type); + shader_print_resource_type(compiler, semantic->resource_type); if (semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS || semantic->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) { @@ -1294,7 +1292,7 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, dimension = "??";
vkd3d_string_buffer_printf(buffer, "%s <%s", prefix, dimension); - shader_dump_data_type(compiler, reg->data_type); + shader_print_data_type(compiler, reg->data_type); vkd3d_string_buffer_printf(buffer, ">%s", suffix); }
@@ -1998,7 +1996,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, vkd3d_string_buffer_printf(buffer, "raw_"); if (ins->structured) vkd3d_string_buffer_printf(buffer, "structured_"); - shader_dump_resource_type(compiler, ins->resource_type); + shader_print_resource_type(compiler, ins->resource_type); if (ins->resource_stride) shader_print_uint_literal(compiler, ", stride=", ins->resource_stride, ""); vkd3d_string_buffer_printf(buffer, ")"); @@ -2069,15 +2067,22 @@ static const char *get_component_type_name(enum vkd3d_shader_component_type type { switch (type) { - case VKD3D_SHADER_COMPONENT_VOID: return "void"; - case VKD3D_SHADER_COMPONENT_UINT: return "uint"; - case VKD3D_SHADER_COMPONENT_INT: return "int"; - case VKD3D_SHADER_COMPONENT_FLOAT: return "float"; - case VKD3D_SHADER_COMPONENT_BOOL: return "bool"; - case VKD3D_SHADER_COMPONENT_DOUBLE: return "double"; - case VKD3D_SHADER_COMPONENT_UINT64: return "uint64"; - default: return "??"; + case VKD3D_SHADER_COMPONENT_VOID: return "void"; + case VKD3D_SHADER_COMPONENT_UINT: return "uint"; + case VKD3D_SHADER_COMPONENT_INT: return "int"; + case VKD3D_SHADER_COMPONENT_FLOAT: return "float"; + case VKD3D_SHADER_COMPONENT_BOOL: return "bool"; + case VKD3D_SHADER_COMPONENT_DOUBLE: return "double"; + case VKD3D_SHADER_COMPONENT_UINT64: return "uint64"; + case VKD3D_SHADER_COMPONENT_INT64: return "int64"; + case VKD3D_SHADER_COMPONENT_FLOAT16: return "float16"; + case VKD3D_SHADER_COMPONENT_UINT16: return "uint16"; + case VKD3D_SHADER_COMPONENT_INT16: return "int16"; + case VKD3D_SHADER_COMPONENT_TYPE_FORCE_32BIT: + break; } + + return "??"; }
static const char *get_minimum_precision_name(enum vkd3d_shader_minimum_precision prec) @@ -2097,6 +2102,7 @@ static const char *get_semantic_register_name(enum vkd3d_shader_sysval_semantic { switch (semantic) { + case VKD3D_SHADER_SV_PRIMITIVE_ID: return "primID"; case VKD3D_SHADER_SV_DEPTH: return "oDepth"; case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: return "oDepthGE"; case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: return "oDepthLE"; @@ -2194,10 +2200,80 @@ static enum vkd3d_result dump_dxbc_signatures(struct vkd3d_d3d_asm_compiler *com &program->patch_constant_signature)) < 0) return ret;
- vkd3d_string_buffer_printf(&compiler->buffer, "%s.text%s\n", + return VKD3D_OK; +} + +static void shader_print_descriptor_name(struct vkd3d_d3d_asm_compiler *compiler, + enum vkd3d_shader_descriptor_type t, unsigned int id) +{ + const char *type = NULL; + + switch (t) + { + case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: + type = shader_register_names[VKD3DSPR_RESOURCE]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: + type = shader_register_names[VKD3DSPR_UAV]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: + type = shader_register_names[VKD3DSPR_CONSTBUFFER]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: + type = shader_register_names[VKD3DSPR_SAMPLER]; + break; + case VKD3D_SHADER_DESCRIPTOR_TYPE_FORCE_32BIT: + break; + } + + if (type) + vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%u%s", + compiler->colours.reg, type, id, compiler->colours.reset); + else + vkd3d_string_buffer_printf(&compiler->buffer, "%s<unhandled descriptor type %#x>%u%s", + compiler->colours.error, t, id, compiler->colours.reset); +} + +static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, + const struct vkd3d_shader_scan_descriptor_info1 *descriptors) +{ + struct vkd3d_string_buffer *buffer = &compiler->buffer; + unsigned int i; + + vkd3d_string_buffer_printf(buffer, "%s.descriptors%s\n", compiler->colours.opcode, compiler->colours.reset); + for (i = 0; i < descriptors->descriptor_count; ++i) + { + const struct vkd3d_shader_descriptor_info1 *d = &descriptors->descriptors[i];
- return VKD3D_OK; + vkd3d_string_buffer_printf(buffer, "%s.descriptor%s ", compiler->colours.opcode, compiler->colours.reset); + shader_print_descriptor_name(compiler, d->type, d->register_id); + shader_print_subscript_range(compiler, d->register_index, + d->count == ~0u ? ~0u : d->register_index + d->count - 1); + shader_dump_register_space(compiler, d->register_space); + + if (d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SRV || d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + { + vkd3d_string_buffer_printf(buffer, ", "); + shader_print_resource_type(compiler, d->resource_type); + vkd3d_string_buffer_printf(buffer, " <v4:"); + shader_print_data_type(compiler, d->resource_data_type); + if (d->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || d->resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + shader_print_uint_literal(compiler, ", ", d->sample_count, ""); + vkd3d_string_buffer_printf(buffer, ">"); + } + + if (d->buffer_size) + shader_print_hex_literal(compiler, ", size=", d->buffer_size, ""); + if (d->structure_stride) + shader_print_hex_literal(compiler, ", stride=", d->structure_stride, ""); + if (d->flags) + shader_print_hex_literal(compiler, ", flags=", d->flags, ""); + if (d->uav_flags) + shader_print_hex_literal(compiler, ", uav_flags=", d->uav_flags, ""); + vkd3d_string_buffer_printf(buffer, "\n"); + } }
enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, @@ -2263,6 +2339,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, indent_str = " "; else indent_str = ""; + /* The signatures we emit only make sense for DXBC shaders. d3dbc doesn't + * even have an explicit concept of signature. */ + if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) + compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES;
buffer = &compiler.buffer; vkd3d_string_buffer_init(buffer); @@ -2273,17 +2353,19 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, shader_get_type_prefix(shader_version->type), shader_version->major, shader_version->minor, compiler.colours.reset);
- /* The signatures we emit only make sense for DXBC shaders. D3DBC - * doesn't even have an explicit concept of signature. */ - if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) + if (compiler.flags & VSIR_ASM_FLAG_DUMP_SIGNATURES + && (result = dump_dxbc_signatures(&compiler, program)) < 0) { - if ((result = dump_dxbc_signatures(&compiler, program)) < 0) - { - vkd3d_string_buffer_cleanup(buffer); - return result; - } + vkd3d_string_buffer_cleanup(buffer); + return result; }
+ if (compiler.flags & VSIR_ASM_FLAG_DUMP_DESCRIPTORS) + shader_print_descriptors(&compiler, &program->descriptors); + + if (compiler.flags & (VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS)) + vkd3d_string_buffer_printf(buffer, "%s.text%s\n", compiler.colours.opcode, compiler.colours.reset); + indent = 0; for (i = 0; i < program->instructions.count; ++i) { @@ -2380,6 +2462,77 @@ static void trace_signature(const struct shader_signature *signature, const char vkd3d_string_buffer_cleanup(&buffer); }
+static void shader_print_io_declaration(struct vkd3d_string_buffer *buffer, enum vkd3d_shader_register_type type) +{ + switch (type) + { +#define X(x) case VKD3DSPR_ ## x: vkd3d_string_buffer_printf(buffer, #x); return; + X(TEMP) + X(INPUT) + X(CONST) + X(ADDR) + X(TEXTURE) + X(RASTOUT) + X(ATTROUT) + X(TEXCRDOUT) + X(OUTPUT) + X(CONSTINT) + X(COLOROUT) + X(DEPTHOUT) + X(COMBINED_SAMPLER) + X(CONSTBOOL) + X(LOOP) + X(TEMPFLOAT16) + X(MISCTYPE) + X(LABEL) + X(PREDICATE) + X(IMMCONST) + X(IMMCONST64) + X(CONSTBUFFER) + X(IMMCONSTBUFFER) + X(PRIMID) + X(NULL) + X(SAMPLER) + X(RESOURCE) + X(UAV) + X(OUTPOINTID) + X(FORKINSTID) + X(JOININSTID) + X(INCONTROLPOINT) + X(OUTCONTROLPOINT) + X(PATCHCONST) + X(TESSCOORD) + X(GROUPSHAREDMEM) + X(THREADID) + X(THREADGROUPID) + X(LOCALTHREADID) + X(LOCALTHREADINDEX) + X(IDXTEMP) + X(STREAM) + X(FUNCTIONBODY) + X(FUNCTIONPOINTER) + X(COVERAGE) + X(SAMPLEMASK) + X(GSINSTID) + X(DEPTHOUTGE) + X(DEPTHOUTLE) + X(RASTERIZER) + X(OUTSTENCILREF) + X(UNDEF) + X(SSA) + X(WAVELANECOUNT) + X(WAVELANEINDEX) + X(PARAMETER) + X(POINT_COORD) +#undef X + case VKD3DSPR_INVALID: + case VKD3DSPR_COUNT: + break; + } + + vkd3d_string_buffer_printf(buffer, "<invalid register type %#x>", type); +} + static void trace_io_declarations(const struct vsir_program *program) { struct vkd3d_string_buffer buffer; @@ -2392,11 +2545,12 @@ static void trace_io_declarations(const struct vsir_program *program)
for (i = 0; i < sizeof(program->io_dcls) * CHAR_BIT; ++i) { - if (bitmap_is_set(program->io_dcls, i)) - { - empty = false; - vkd3d_string_buffer_printf(&buffer, " %u", i); - } + if (!bitmap_is_set(program->io_dcls, i)) + continue; + + vkd3d_string_buffer_printf(&buffer, empty ? " " : " | "); + shader_print_io_declaration(&buffer, i); + empty = false; }
if (empty) @@ -2409,7 +2563,8 @@ static void trace_io_declarations(const struct vsir_program *program)
void vsir_program_trace(const struct vsir_program *program) { - const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES; + const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES + | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; struct vkd3d_shader_code code; const char *p, *q, *end;
diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 58e35cf22e8..57d874efe37 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -1215,6 +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; + unsigned int vsir_dst_count, vsir_src_count; struct vkd3d_shader_dst_param *dst_param; const uint32_t **ptr = &sm1->ptr; uint32_t opcode_token; @@ -1241,6 +1242,17 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str goto fail; }
+ if (opcode_info->vkd3d_opcode == VKD3DSIH_TEXKILL) + { + vsir_src_count = 1; + vsir_dst_count = 0; + } + else + { + vsir_src_count = opcode_info->src_count; + vsir_dst_count = opcode_info->dst_count; + } + vsir_instruction_init(ins, &sm1->p.location, opcode_info->vkd3d_opcode); ins->flags = (opcode_token & VKD3D_SM1_INSTRUCTION_FLAGS_MASK) >> VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT; ins->coissue = opcode_token & VKD3D_SM1_COISSUE; @@ -1248,9 +1260,9 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str ins->structured = false; predicated = !!(opcode_token & VKD3D_SM1_INSTRUCTION_PREDICATED); ins->predicate = predicate = predicated ? vsir_program_get_src_params(program, 1) : NULL; - ins->dst_count = opcode_info->dst_count; + ins->dst_count = vsir_dst_count; ins->dst = dst_param = vsir_program_get_dst_params(program, ins->dst_count); - ins->src_count = opcode_info->src_count; + ins->src_count = vsir_src_count; ins->src = src_params = vsir_program_get_src_params(program, ins->src_count); if ((!predicate && predicated) || (!src_params && ins->src_count) || (!dst_param && ins->dst_count)) { @@ -1298,6 +1310,25 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } + else if (ins->opcode == VKD3DSIH_TEXKILL) + { + /* TEXKILL, uniquely, encodes its argument as a destination, when it is + * semantically a source. Since we have multiple passes which operate + * generically on sources or destinations, normalize that. */ + const struct vkd3d_shader_register *reg; + struct vkd3d_shader_dst_param tmp_dst; + + reg = &tmp_dst.reg; + shader_sm1_read_dst_param(sm1, &p, &tmp_dst); + shader_sm1_scan_register(sm1, reg, tmp_dst.write_mask, false); + + vsir_src_param_init(&src_params[0], reg->type, reg->data_type, reg->idx_count); + src_params[0].reg = *reg; + src_params[0].swizzle = vsir_swizzle_from_writemask(tmp_dst.write_mask); + + if (ins->predicate) + shader_sm1_read_src_param(sm1, &p, predicate); + } else { /* Destination token */ @@ -1491,7 +1522,8 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c }
bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, - unsigned int semantic_index, bool output, enum vkd3d_shader_register_type *type, unsigned int *reg) + unsigned int semantic_index, bool output, enum vkd3d_shader_sysval_semantic *sysval, + enum vkd3d_shader_register_type *type, unsigned int *reg) { unsigned int i;
@@ -1501,42 +1533,43 @@ bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, bool output; enum vkd3d_shader_type shader_type; unsigned int major_version; + enum vkd3d_shader_sysval_semantic sysval; enum vkd3d_shader_register_type type; unsigned int offset; } register_table[] = { - {"color", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3DSPR_INPUT}, - {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3DSPR_TEXTURE}, - - {"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_COLOROUT}, - {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_DEPTHOUT}, - {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_DEPTHOUT}, - {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_COLOROUT}, - {"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_INPUT}, - {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3DSPR_TEXTURE}, - - {"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_COLOROUT}, - {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT}, - {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_DEPTHOUT}, - {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_COLOROUT}, - {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, - {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_FACE}, - {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, - - {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_ATTROUT}, - {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3DSPR_TEXCRDOUT}, - - {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_ATTROUT}, - {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, - {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, - {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, - {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3DSPR_TEXCRDOUT}, + {"color", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_INPUT}, + {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXTURE}, + + {"color", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"color", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_INPUT}, + {"texcoord", false, VKD3D_SHADER_TYPE_PIXEL, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXTURE}, + + {"color", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_depth", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_DEPTH, VKD3DSPR_DEPTHOUT}, + {"sv_target", true, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_TARGET, VKD3DSPR_COLOROUT}, + {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_POSITION, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, + {"vface", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_IS_FRONT_FACE, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_FACE}, + {"vpos", false, VKD3D_SHADER_TYPE_PIXEL, 3, VKD3D_SHADER_SV_POSITION, VKD3DSPR_MISCTYPE, VKD3D_SM1_MISC_POSITION}, + + {"color", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_ATTROUT}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 1, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXCRDOUT}, + + {"color", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_ATTROUT}, + {"fog", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_FOG}, + {"position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"psize", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POINT_SIZE}, + {"sv_position", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_POSITION, VKD3DSPR_RASTOUT, VSIR_RASTOUT_POSITION}, + {"texcoord", true, VKD3D_SHADER_TYPE_VERTEX, 2, VKD3D_SHADER_SV_NONE, VKD3DSPR_TEXCRDOUT}, };
for (i = 0; i < ARRAY_SIZE(register_table); ++i) @@ -1546,6 +1579,8 @@ bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, && version->type == register_table[i].shader_type && version->major == register_table[i].major_version) { + if (sysval) + *sysval = register_table[i].sysval; *type = register_table[i].type; if (register_table[i].type == VKD3DSPR_MISCTYPE || register_table[i].type == VKD3DSPR_RASTOUT) *reg = register_table[i].offset; @@ -1759,27 +1794,40 @@ static bool is_inconsequential_instr(const struct vkd3d_shader_instruction *ins)
static void write_sm1_dst_register(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_dst_param *reg) { + uint32_t offset = reg->reg.idx_count ? reg->reg.idx[0].offset : 0; + VKD3D_ASSERT(reg->write_mask); put_u32(buffer, VKD3D_SM1_INSTRUCTION_PARAMETER | sm1_encode_register_type(®->reg) | (reg->modifiers << VKD3D_SM1_DST_MODIFIER_SHIFT) | (reg->write_mask << VKD3D_SM1_WRITEMASK_SHIFT) - | (reg->reg.idx[0].offset & VKD3D_SM1_REGISTER_NUMBER_MASK)); + | (offset & VKD3D_SM1_REGISTER_NUMBER_MASK)); }
static void write_sm1_src_register(struct vkd3d_bytecode_buffer *buffer, const struct vkd3d_shader_src_param *reg) { + uint32_t address_mode = VKD3D_SM1_ADDRESS_MODE_ABSOLUTE, offset = 0; + + if (reg->reg.idx_count) + { + offset = reg->reg.idx[0].offset; + if (reg->reg.idx[0].rel_addr) + address_mode = VKD3D_SM1_ADDRESS_MODE_RELATIVE; + } + put_u32(buffer, VKD3D_SM1_INSTRUCTION_PARAMETER | sm1_encode_register_type(®->reg) + | (address_mode << VKD3D_SM1_ADDRESS_MODE_SHIFT) | (reg->modifiers << VKD3D_SM1_SRC_MODIFIER_SHIFT) | (swizzle_from_vsir(reg->swizzle) << VKD3D_SM1_SWIZZLE_SHIFT) - | (reg->reg.idx[0].offset & VKD3D_SM1_REGISTER_NUMBER_MASK)); + | (offset & VKD3D_SM1_REGISTER_NUMBER_MASK)); }
static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) { const struct vkd3d_shader_version *version = &d3dbc->program->shader_version; struct vkd3d_bytecode_buffer *buffer = &d3dbc->buffer; + const struct vkd3d_shader_src_param *src; const struct vkd3d_sm1_opcode_info *info; unsigned int i; uint32_t token; @@ -1810,16 +1858,34 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v
for (i = 0; i < ins->src_count; ++i) { - if (ins->src[i].reg.idx[0].rel_addr) - { - vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_NOT_IMPLEMENTED, - "Unhandled relative addressing on source register."); - d3dbc->failed = true; - } - write_sm1_src_register(buffer, &ins->src[i]); + src = &ins->src[i]; + write_sm1_src_register(buffer, src); + if (src->reg.idx_count && src->reg.idx[0].rel_addr) + write_sm1_src_register(buffer, src->reg.idx[0].rel_addr); } };
+static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) +{ + const struct vkd3d_shader_register *reg = &ins->src[0].reg; + struct vkd3d_shader_instruction tmp; + struct vkd3d_shader_dst_param dst; + + /* TEXKILL, uniquely, encodes its argument as a destination, when it is + * semantically a source. We store it as a source in vsir, so convert it. */ + + vsir_dst_param_init(&dst, reg->type, reg->data_type, reg->idx_count); + dst.reg = *reg; + dst.write_mask = mask_from_swizzle(ins->src[0].swizzle); + + tmp = *ins; + tmp.dst_count = 1; + tmp.dst = &dst; + tmp.src_count = 0; + + d3dbc_write_instruction(d3dbc, &tmp); +} + static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) { const struct vkd3d_shader_version *version = &d3dbc->program->shader_version; @@ -1831,6 +1897,7 @@ static void d3dbc_write_vsir_def(struct d3dbc_compiler *d3dbc, const struct vkd3 .reg.type = VKD3DSPR_CONST, .write_mask = VKD3DSP_WRITEMASK_ALL, .reg.idx[0].offset = ins->dst[0].reg.idx[0].offset, + .reg.idx_count = 1, };
token = VKD3D_SM1_OP_DEF; @@ -1863,6 +1930,7 @@ static void d3dbc_write_vsir_sampler_dcl(struct d3dbc_compiler *d3dbc, reg.reg.type = VKD3DSPR_COMBINED_SAMPLER; reg.write_mask = VKD3DSP_WRITEMASK_ALL; reg.reg.idx[0].offset = reg_id; + reg.reg.idx_count = 1;
write_sm1_dst_register(buffer, ®); } @@ -1922,6 +1990,10 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str d3dbc_write_vsir_dcl(d3dbc, ins); break;
+ case VKD3DSIH_TEXKILL: + d3dbc_write_texkill(d3dbc, ins); + break; + case VKD3DSIH_ABS: case VKD3DSIH_ADD: case VKD3DSIH_CMP: @@ -1938,11 +2010,11 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str case VKD3DSIH_MAX: case VKD3DSIH_MIN: case VKD3DSIH_MOV: + case VKD3DSIH_MOVA: case VKD3DSIH_MUL: case VKD3DSIH_SINCOS: case VKD3DSIH_SLT: case VKD3DSIH_TEX: - case VKD3DSIH_TEXKILL: case VKD3DSIH_TEXLDD: d3dbc_write_instruction(d3dbc, ins); break; @@ -1982,8 +2054,9 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, uint32_t token, usage_idx; bool ret;
+ reg.reg.idx_count = 1; if (sm1_register_from_semantic_name(version, element->semantic_name, - element->semantic_index, output, ®.reg.type, ®.reg.idx[0].offset)) + element->semantic_index, output, NULL, ®.reg.type, ®.reg.idx[0].offset)) { usage = 0; usage_idx = 0; diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c index 81af62f7810..9e3a57132a1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c @@ -381,7 +381,8 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s uint32_t count, header_size; struct signature_element *e; const char *ptr = data; - unsigned int i, j; + bool fail = false; + unsigned int i;
if (!require_space(0, 2, sizeof(uint32_t), section->data.size)) { @@ -436,17 +437,19 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s if (!(name = shader_get_string(data, section->data.size, name_offset)) || !(e[i].semantic_name = vkd3d_strdup(name))) { - WARN("Invalid name offset %#zx (data size %#zx).\n", name_offset, section->data.size); - for (j = 0; j < i; ++j) - { - vkd3d_free((void *)e[j].semantic_name); - } - vkd3d_free(e); - return VKD3D_ERROR_INVALID_ARGUMENT; + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE, + "Element %u has invalid semantic name reference %#zx (data size %#zx).\n", + i, name_offset, section->data.size); + fail = true; } e[i].semantic_index = read_u32(&ptr); e[i].sysval_semantic = read_u32(&ptr); - e[i].component_type = read_u32(&ptr); + if ((e[i].component_type = read_u32(&ptr)) > VKD3D_SHADER_COMPONENT_FLOAT) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE, + "Element %u has invalid component type %#x.\n", i, e[i].component_type); + fail = true; + } e[i].register_index = read_u32(&ptr); e[i].target_location = e[i].register_index; e[i].register_count = 1; @@ -477,8 +480,15 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s }
s->elements = e; + s->elements_capacity = count; s->element_count = count;
+ if (fail) + { + shader_signature_cleanup(s); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + return VKD3D_OK; }
@@ -542,6 +552,8 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, { case TAG_ISGN: case TAG_ISG1: + if (desc->is_dxil) + break; if (desc->input_signature.elements) { FIXME("Multiple input signatures.\n"); @@ -554,6 +566,8 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section, case TAG_OSGN: case TAG_OSG5: case TAG_OSG1: + if (desc->is_dxil) + break; if (desc->output_signature.elements) { FIXME("Multiple output signatures.\n"); @@ -565,6 +579,8 @@ static int shdr_handler(const struct vkd3d_shader_dxbc_section_desc *section,
case TAG_PCSG: case TAG_PSG1: + if (desc->is_dxil) + break; if (desc->patch_constant_signature.elements) { FIXME("Multiple patch constant signatures.\n"); diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index a10de68008a..ca79939a39b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -645,8 +645,14 @@ enum sm6_value_type { VALUE_TYPE_FUNCTION, VALUE_TYPE_REG, - VALUE_TYPE_ICB, + VALUE_TYPE_DATA, VALUE_TYPE_HANDLE, + VALUE_TYPE_SSA, + VALUE_TYPE_ICB, + VALUE_TYPE_IDXTEMP, + VALUE_TYPE_GROUPSHAREDMEM, + VALUE_TYPE_UNDEFINED, + VALUE_TYPE_INVALID, };
struct sm6_function_data @@ -659,7 +665,29 @@ struct sm6_function_data struct sm6_handle_data { const struct sm6_descriptor_info *d; - struct vkd3d_shader_register reg; + const struct sm6_value *index; + bool non_uniform; +}; + +struct sm6_ssa_data +{ + unsigned int id; +}; + +struct sm6_icb_data +{ + unsigned int data_id; + unsigned int id; +}; + +struct sm6_idxtemp_data +{ + unsigned int id; +}; + +struct sm6_groupsharedmem_data +{ + unsigned int id; };
struct sm6_value @@ -667,15 +695,18 @@ struct sm6_value const struct sm6_type *type; enum sm6_value_type value_type; unsigned int structure_stride; - bool is_undefined; bool is_back_ref; union { struct sm6_function_data function; - struct vkd3d_shader_register reg; - const struct vkd3d_shader_immediate_constant_buffer *icb; + const struct vkd3d_shader_immediate_constant_buffer *data; struct sm6_handle_data handle; + struct sm6_ssa_data ssa; + struct sm6_icb_data icb; + struct sm6_idxtemp_data idxtemp; + struct sm6_groupsharedmem_data groupsharedmem; } u; + struct vkd3d_shader_register reg; };
struct dxil_record @@ -2231,7 +2262,20 @@ static inline struct sm6_value *sm6_parser_get_current_value(const struct sm6_pa
static inline bool sm6_value_is_register(const struct sm6_value *value) { - return value->value_type == VALUE_TYPE_REG; + switch (value->value_type) + { + case VALUE_TYPE_REG: + case VALUE_TYPE_SSA: + case VALUE_TYPE_ICB: + case VALUE_TYPE_IDXTEMP: + case VALUE_TYPE_GROUPSHAREDMEM: + case VALUE_TYPE_UNDEFINED: + case VALUE_TYPE_INVALID: + return true; + + default: + return false; + } }
static bool sm6_value_is_handle(const struct sm6_value *value) @@ -2241,18 +2285,18 @@ static bool sm6_value_is_handle(const struct sm6_value *value)
static inline bool sm6_value_is_constant(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_constant(&value->u.reg); + return sm6_value_is_register(value) && register_is_constant(&value->reg); }
static bool sm6_value_is_constant_zero(const struct sm6_value *value) { /* Constant vectors do not occur. */ - return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->u.reg); + return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->reg); }
static inline bool sm6_value_is_undef(const struct sm6_value *value) { - return sm6_value_is_register(value) && value->u.reg.type == VKD3DSPR_UNDEF; + return sm6_value_is_register(value) && value->reg.type == VKD3DSPR_UNDEF; }
static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count) @@ -2264,33 +2308,33 @@ static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **value return true; }
-static bool sm6_value_is_icb(const struct sm6_value *value) +static bool sm6_value_is_data(const struct sm6_value *value) { - return value->value_type == VALUE_TYPE_ICB; + return value->value_type == VALUE_TYPE_DATA; }
static bool sm6_value_is_ssa(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_ssa(&value->u.reg); + return sm6_value_is_register(value) && register_is_ssa(&value->reg); }
static bool sm6_value_is_numeric_array(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_numeric_array(&value->u.reg); + return sm6_value_is_register(value) && register_is_numeric_array(&value->reg); }
static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) { if (!sm6_value_is_constant(value)) return UINT_MAX; - return register_get_uint_value(&value->u.reg); + return register_get_uint_value(&value->reg); }
static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value) { if (!sm6_value_is_constant(value)) return UINT64_MAX; - return register_get_uint64_value(&value->u.reg); + return register_get_uint64_value(&value->reg); }
static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) @@ -2389,30 +2433,64 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type return VKD3D_DATA_UINT; }
-static void register_init_ssa_vector(struct vkd3d_shader_register *reg, const struct sm6_type *type, - unsigned int component_count, struct sm6_value *value, struct sm6_parser *sm6) +static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value) { enum vkd3d_data_type data_type; + + data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(value->type, 0)); + + switch (value->value_type) + { + case VALUE_TYPE_REG: + *reg = value->reg; + break; + + case VALUE_TYPE_SSA: + register_init_with_id(reg, VKD3DSPR_SSA, data_type, value->u.ssa.id); + reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4; + break; + + case VALUE_TYPE_ICB: + register_init_with_id(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, value->u.icb.id); + break; + + case VALUE_TYPE_IDXTEMP: + register_init_with_id(reg, VKD3DSPR_IDXTEMP, data_type, value->u.idxtemp.id); + break; + + case VALUE_TYPE_GROUPSHAREDMEM: + register_init_with_id(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, value->u.groupsharedmem.id); + break; + + case VALUE_TYPE_UNDEFINED: + case VALUE_TYPE_INVALID: + vsir_register_init(reg, VKD3DSPR_UNDEF, data_type, 0); + break; + + case VALUE_TYPE_FUNCTION: + case VALUE_TYPE_HANDLE: + case VALUE_TYPE_DATA: + vkd3d_unreachable(); + } +} + +static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *value) +{ unsigned int id;
- if (value && register_is_ssa(&value->u.reg) && value->u.reg.idx[0].offset) + if (register_is_ssa(&value->reg) && value->reg.idx[0].offset) { - id = value->u.reg.idx[0].offset; + id = value->reg.idx[0].offset; TRACE("Using forward-allocated id %u.\n", id); } else { id = sm6_parser_alloc_ssa_id(sm6); } - data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(type, 0)); - register_init_with_id(reg, VKD3DSPR_SSA, data_type, id); - reg->dimension = component_count > 1 ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; -}
-static void register_init_ssa_scalar(struct vkd3d_shader_register *reg, const struct sm6_type *type, - struct sm6_value *value, struct sm6_parser *sm6) -{ - register_init_ssa_vector(reg, sm6_type_get_scalar_type(type, 0), 1, value, sm6); + value->value_type = VALUE_TYPE_SSA; + value->u.ssa.id = id; + sm6_register_from_value(&value->reg, value); }
static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value) @@ -2449,13 +2527,6 @@ static void dst_param_init_vector(struct vkd3d_shader_dst_param *param, unsigned param->shift = 0; }
-static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *param, const struct sm6_type *type, - struct sm6_value *value, struct sm6_parser *sm6) -{ - dst_param_init(param); - register_init_ssa_scalar(¶m->reg, type, value, sm6); -} - static inline void src_param_init(struct vkd3d_shader_src_param *param) { param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); @@ -2479,7 +2550,7 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) { src_param_init(param); - param->reg = src->u.reg; + sm6_register_from_value(¶m->reg, src); }
static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, @@ -2519,6 +2590,25 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, } }
+static void sm6_register_from_handle(struct sm6_parser *sm6, + const struct sm6_handle_data *handle, struct vkd3d_shader_register *reg) +{ + vsir_register_init(reg, handle->d->reg_type, handle->d->reg_data_type, 2); + reg->dimension = VSIR_DIMENSION_VEC4; + reg->idx[0].offset = handle->d->id; + register_index_address_init(®->idx[1], handle->index, sm6); + reg->non_uniform = handle->non_uniform; +} + +static void src_param_init_vector_from_handle(struct sm6_parser *sm6, + struct vkd3d_shader_src_param *param, const struct sm6_handle_data *handle) +{ + struct vkd3d_shader_register reg; + + sm6_register_from_handle(sm6, handle, ®); + src_param_init_vector_from_reg(param, ®); +} + static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) { struct sm6_value *dst = sm6_parser_get_current_value(sm6); @@ -2527,9 +2617,9 @@ static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio if (!(param = instruction_dst_params_alloc(ins, 1, sm6))) return false;
- dst_param_init_ssa_scalar(param, dst->type, dst, sm6); - param->write_mask = VKD3DSP_WRITEMASK_0; - dst->u.reg = param->reg; + dst_param_init(param); + sm6_parser_init_ssa_value(sm6, dst); + sm6_register_from_value(¶m->reg, dst); return true; }
@@ -2540,8 +2630,8 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio struct sm6_value *dst = sm6_parser_get_current_value(sm6);
dst_param_init_vector(param, component_count); - register_init_ssa_vector(¶m->reg, sm6_type_get_scalar_type(dst->type, 0), component_count, dst, sm6); - dst->u.reg = param->reg; + sm6_parser_init_ssa_value(sm6, dst); + sm6_register_from_value(¶m->reg, dst); }
static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) @@ -2556,7 +2646,7 @@ static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instructi param->write_mask = VKD3DSP_WRITEMASK_ALL; param->reg.idx[0].offset = 0; param->reg.dimension = VSIR_DIMENSION_VEC4; - dst->u.reg = param->reg; + dst->reg = param->reg;
return true; } @@ -2836,11 +2926,9 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru else { value->type = fwd_type; - value->value_type = VALUE_TYPE_REG; - register_init_with_id(&value->u.reg, VKD3DSPR_SSA, vkd3d_data_type_from_sm6_type( - sm6_type_get_scalar_type(fwd_type, 0)), sm6_parser_alloc_ssa_id(sm6)); - value->u.reg.dimension = sm6_type_is_scalar(fwd_type) ? VSIR_DIMENSION_SCALAR - : VSIR_DIMENSION_VEC4; + value->value_type = VALUE_TYPE_SSA; + value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); + sm6_register_from_value(&value->reg, value); } }
@@ -3014,8 +3102,8 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co return VKD3D_ERROR_OUT_OF_MEMORY; }
- dst->value_type = VALUE_TYPE_ICB; - dst->u.icb = icb; + dst->value_type = VALUE_TYPE_DATA; + dst->u.data = icb;
icb->register_idx = sm6->icb_count++; icb->data_type = vkd3d_data_type_from_sm6_type(elem_type); @@ -3046,6 +3134,7 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c struct sm6_value *dst) { const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type; + struct vkd3d_shader_register reg; struct sm6_value *operands[3]; unsigned int i, j, offset; uint64_t value; @@ -3089,7 +3178,9 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c } }
- if (operands[0]->u.reg.idx_count > 1) + sm6_register_from_value(®, operands[0]); + + if (reg.idx_count > 1) { WARN("Unsupported stacked GEP.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -3150,10 +3241,10 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c "Module does not define a pointer type for a constexpr GEP result."); return VKD3D_ERROR_INVALID_SHADER; } - dst->u.reg = operands[0]->u.reg; - dst->u.reg.idx[1].offset = offset; - dst->u.reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; - dst->u.reg.idx_count = 2; + dst->reg = reg; + dst->reg.idx[1].offset = offset; + dst->reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; + dst->reg.idx_count = 2;
return VKD3D_OK; } @@ -3212,7 +3303,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const dst->type = type; dst->value_type = VALUE_TYPE_REG; dst->is_back_ref = true; - vsir_register_init(&dst->u.reg, reg_type, reg_data_type, 0); + vsir_register_init(&dst->reg, reg_type, reg_data_type, 0);
switch (record->code) { @@ -3237,9 +3328,9 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
value = decode_rotated_signed_value(record->operands[0]); if (type->u.width <= 32) - dst->u.reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1); + dst->reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1); else - dst->u.reg.u.immconst_u64[0] = value; + dst->reg.u.immconst_u64[0] = value;
break;
@@ -3254,11 +3345,11 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const }
if (type->u.width == 16) - dst->u.reg.u.immconst_u32[0] = record->operands[0]; + dst->reg.u.immconst_u32[0] = record->operands[0]; else if (type->u.width == 32) - dst->u.reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); + dst->reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); else if (type->u.width == 64) - dst->u.reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); + dst->reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); else vkd3d_unreachable();
@@ -3324,22 +3415,22 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
/* Resolve later in case forward refs exist. */ dst->type = type; - dst->u.reg.type = VKD3DSPR_COUNT; - dst->u.reg.idx[0].offset = value; + dst->reg.type = VKD3DSPR_COUNT; + dst->reg.idx[0].offset = value; break;
case CST_CODE_UNDEF: dxil_record_validate_operand_max_count(record, 0, sm6); - dst->u.reg.type = VKD3DSPR_UNDEF; - /* Mark as explicitly undefined, not the result of a missing constant code or instruction. */ - dst->is_undefined = true; + dst->value_type = VALUE_TYPE_UNDEFINED; + sm6_register_from_value(&dst->reg, dst); break;
default: FIXME("Unhandled constant code %u.\n", record->code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Constant code %u is unhandled.", record->code); - dst->u.reg.type = VKD3DSPR_UNDEF; + dst->value_type = VALUE_TYPE_INVALID; + sm6_register_from_value(&dst->reg, dst); break; }
@@ -3357,12 +3448,12 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const for (i = base_value_idx; i < sm6->value_count; ++i) { dst = &sm6->values[i]; - if (dst->u.reg.type != VKD3DSPR_COUNT) + if (dst->reg.type != VKD3DSPR_COUNT) continue;
type = dst->type;
- src = &sm6->values[dst->u.reg.idx[0].offset]; + src = &sm6->values[dst->reg.idx[0].offset]; if (!sm6_value_is_numeric_array(src)) { WARN("Value is not an array.\n"); @@ -3373,7 +3464,7 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
*dst = *src; dst->type = type; - dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); + dst->reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); }
return VKD3D_OK; @@ -3416,13 +3507,13 @@ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_pa static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst) { - enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); struct vkd3d_shader_instruction *ins;
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER); /* The icb value index will be resolved later so forward references can be handled. */ ins->declaration.icb = (void *)(intptr_t)init; - register_init_with_id(&dst->u.reg, VKD3DSPR_IMMCONSTBUFFER, data_type, init); + dst->value_type = VALUE_TYPE_ICB; + dst->u.icb.data_id = init; }
static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const struct sm6_type *elem_type, @@ -3444,21 +3535,24 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru /* The initialiser value index will be resolved later so forward references can be handled. */ ins->declaration.indexable_temp.initialiser = (void *)(uintptr_t)init;
- register_init_with_id(&dst->u.reg, VKD3DSPR_IDXTEMP, data_type, ins->declaration.indexable_temp.register_idx); + dst->value_type = VALUE_TYPE_IDXTEMP; + dst->u.idxtemp.id = ins->declaration.indexable_temp.register_idx; + sm6_register_from_value(&dst->reg, dst); }
static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int alignment, unsigned int init, struct sm6_value *dst) { - enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); struct vkd3d_shader_instruction *ins; unsigned int byte_count;
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_RAW); dst_param_init(&ins->declaration.tgsm_raw.reg); - register_init_with_id(&ins->declaration.tgsm_raw.reg.reg, VKD3DSPR_GROUPSHAREDMEM, data_type, sm6->tgsm_count++); - dst->u.reg = ins->declaration.tgsm_raw.reg.reg; + dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; + dst->u.groupsharedmem.id = sm6->tgsm_count++; dst->structure_stride = 0; + sm6_register_from_value(&dst->reg, dst); + sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst); ins->declaration.tgsm_raw.alignment = alignment; byte_count = elem_type->u.width / 8u; if (byte_count != 4) @@ -3475,25 +3569,23 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const struct sm6_type *elem_type, unsigned int count, unsigned int alignment, unsigned int init, struct sm6_value *dst) { - enum vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); struct vkd3d_shader_instruction *ins; - unsigned int structure_stride;
ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_STRUCTURED); dst_param_init(&ins->declaration.tgsm_structured.reg); - register_init_with_id(&ins->declaration.tgsm_structured.reg.reg, VKD3DSPR_GROUPSHAREDMEM, - data_type, sm6->tgsm_count++); - dst->u.reg = ins->declaration.tgsm_structured.reg.reg; - structure_stride = elem_type->u.width / 8u; - if (structure_stride != 4) - { - FIXME("Unsupported structure stride %u.\n", structure_stride); + dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; + dst->u.groupsharedmem.id = sm6->tgsm_count++; + dst->structure_stride = elem_type->u.width / 8u; + sm6_register_from_value(&dst->reg, dst); + sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst); + if (dst->structure_stride != 4) + { + FIXME("Unsupported structure stride %u.\n", dst->structure_stride); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Structured TGSM byte stride %u is not supported.", structure_stride); + "Structured TGSM byte stride %u is not supported.", dst->structure_stride); } - dst->structure_stride = structure_stride; ins->declaration.tgsm_structured.alignment = alignment; - ins->declaration.tgsm_structured.byte_stride = structure_stride; + ins->declaration.tgsm_structured.byte_stride = dst->structure_stride; ins->declaration.tgsm_structured.structure_count = count; /* The initialiser value index will be resolved later when forward references can be handled. */ ins->flags = init; @@ -3656,16 +3748,16 @@ static const struct vkd3d_shader_immediate_constant_buffer *resolve_forward_init
VKD3D_ASSERT(index); --index; - if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_icb(value) && !sm6_value_is_undef(value))) + if (!(value = sm6_parser_get_value_safe(sm6, index)) || (!sm6_value_is_data(value) && !sm6_value_is_undef(value))) { WARN("Invalid initialiser index %zu.\n", index); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Global variable initialiser value index %zu is invalid.", index); return NULL; } - else if (sm6_value_is_icb(value)) + else if (sm6_value_is_data(value)) { - return value->u.icb; + return value->u.data; } /* In VSIR, initialisation with undefined values of objects is implied, not explicit. */ return NULL; @@ -3680,14 +3772,14 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm
--index; if (!(value = sm6_parser_get_value_safe(sm6, index)) - || (!sm6_value_is_icb(value) && !sm6_value_is_constant(value) && !sm6_value_is_undef(value))) + || (!sm6_value_is_data(value) && !sm6_value_is_constant(value) && !sm6_value_is_undef(value))) { WARN("Invalid initialiser index %zu.\n", index); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "TGSM initialiser value index %zu is invalid.", index); return false; } - else if ((sm6_value_is_icb(value) && value->u.icb->is_null) || sm6_value_is_constant_zero(value)) + else if ((sm6_value_is_data(value) && value->u.data->is_null) || sm6_value_is_constant_zero(value)) { return true; } @@ -3792,11 +3884,14 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) const struct vkd3d_shader_immediate_constant_buffer *icb; struct sm6_value *value = &sm6->values[i];
- if (!sm6_value_is_register(value) || value->u.reg.type != VKD3DSPR_IMMCONSTBUFFER) + if (value->value_type != VALUE_TYPE_ICB) continue;
- if ((icb = resolve_forward_initialiser(value->u.reg.idx[0].offset, sm6))) - value->u.reg.idx[0].offset = icb->register_idx; + if ((icb = resolve_forward_initialiser(value->u.icb.data_id, sm6))) + value->u.icb.id = icb->register_idx; + else + value->u.icb.id = 0; + sm6_register_from_value(&value->reg, value); }
return VKD3D_OK; @@ -3911,23 +4006,51 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade } }
-static void sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) +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))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate output parameters."); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + sm6_parser_init_signature(sm6, output_signature, false, VKD3DSPR_OUTPUT, sm6->output_params); + + return VKD3D_OK; }
-static void sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) +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))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate input parameters."); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + sm6_parser_init_signature(sm6, input_signature, true, VKD3DSPR_INPUT, sm6->input_params); + + return VKD3D_OK; }
-static void sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, +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;
+ if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->p.program, + patch_constant_signature->element_count))) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Failed to allocate patch constant parameters."); + return VKD3D_ERROR_OUT_OF_MEMORY; + } + sm6_parser_init_signature(sm6, patch_constant_signature, is_input, VKD3DSPR_PATCHCONST, sm6->patch_constant_params); + + return VKD3D_OK; }
static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_parser *sm6) @@ -3979,8 +4102,9 @@ struct function_emission_state unsigned int temp_idx; };
-static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, - unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg); +static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, + const struct vkd3d_shader_register *operand_regs, unsigned int component_count, + struct function_emission_state *state, struct vkd3d_shader_register *reg);
static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_record *record, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) @@ -4088,11 +4212,11 @@ static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code) static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_record *record, struct function_emission_state *state, struct sm6_value *dst) { - struct vkd3d_shader_register coord, const_offset, const_zero; - const struct vkd3d_shader_register *regs[2]; struct vkd3d_shader_dst_param *dst_params; struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_register regs[2], reg; struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_register coord; const struct sm6_value *ptr, *src; enum vkd3d_shader_opcode op; unsigned int i = 0; @@ -4104,7 +4228,9 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ || !sm6_value_validate_is_backward_ref(ptr, sm6)) return;
- if (ptr->u.reg.type != VKD3DSPR_GROUPSHAREDMEM) + sm6_register_from_value(®, ptr); + + if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { WARN("Register is not groupshared.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -4139,17 +4265,11 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_
if (ptr->structure_stride) { - if (ptr->u.reg.idx[1].rel_addr) - { - regs[0] = &ptr->u.reg.idx[1].rel_addr->reg; - } + if (reg.idx[1].rel_addr) + regs[0] = reg.idx[1].rel_addr->reg; else - { - register_make_constant_uint(&const_offset, ptr->u.reg.idx[1].offset); - regs[0] = &const_offset; - } - register_make_constant_uint(&const_zero, 0); - regs[1] = &const_zero; + register_make_constant_uint(®s[0], reg.idx[1].offset); + register_make_constant_uint(®s[1], 0); if (!sm6_parser_emit_reg_composite_construct(sm6, regs, 2, state, &coord)) return; } @@ -4166,18 +4286,18 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ src_param_make_constant_uint(&src_params[0], 0); src_param_init_from_value(&src_params[1], src);
+ sm6_parser_init_ssa_value(sm6, dst); + dst_params = instruction_dst_params_alloc(ins, 2, sm6); - register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6); + sm6_register_from_value(&dst_params[0].reg, dst); dst_param_init(&dst_params[0]);
- dst_params[1].reg = ptr->u.reg; + dst_params[1].reg = reg; dst_params[1].reg.data_type = VKD3D_DATA_UNUSED; dst_params[1].reg.idx[1].rel_addr = NULL; dst_params[1].reg.idx[1].offset = ~0u; dst_params[1].reg.idx_count = 1; dst_param_init(&dst_params[1]); - - dst->u.reg = dst_params[0].reg; }
static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_type *type_a, @@ -4353,9 +4473,9 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
dst_param_init(&dst_params[0]); dst_param_init(&dst_params[1]); - register_init_ssa_scalar(&dst_params[index].reg, a->type, dst, sm6); - vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); - dst->u.reg = dst_params[index].reg; + sm6_parser_init_ssa_value(sm6, dst); + sm6_register_from_value(&dst_params[index].reg, dst); + vsir_dst_param_init_null(&dst_params[index ^ 1]); } else { @@ -4416,7 +4536,7 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record dxil_record_validate_operand_max_count(record, i, sm6);
code_block->terminator.type = TERMINATOR_COND_BR; - code_block->terminator.conditional_reg = value->u.reg; + sm6_register_from_value(&code_block->terminator.conditional_reg, value); code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6); code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6); } @@ -4424,8 +4544,9 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record ins->opcode = VKD3DSIH_NOP; }
-static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, const struct vkd3d_shader_register **operand_regs, - unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) +static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, + const struct vkd3d_shader_register *operand_regs, unsigned int component_count, + struct function_emission_state *state, struct vkd3d_shader_register *reg) { struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_params; @@ -4435,25 +4556,25 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, cons
if (component_count == 1) { - *reg = *operand_regs[0]; + *reg = operand_regs[0]; return true; }
for (i = 0; i < component_count; ++i) - all_constant &= register_is_constant(operand_regs[i]); + all_constant &= register_is_constant(&operand_regs[i]);
if (all_constant) { - vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0]->data_type, 0); + vsir_register_init(reg, VKD3DSPR_IMMCONST, operand_regs[0].data_type, 0); reg->dimension = VSIR_DIMENSION_VEC4; for (i = 0; i < component_count; ++i) - reg->u.immconst_u32[i] = operand_regs[i]->u.immconst_u32[0]; + reg->u.immconst_u32[i] = operand_regs[i].u.immconst_u32[0]; for (; i < VKD3D_VEC4_SIZE; ++i) reg->u.immconst_u32[i] = 0; return true; }
- register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0]->data_type, state->temp_idx++); + register_init_with_id(reg, VKD3DSPR_TEMP, operand_regs[0].data_type, state->temp_idx++); reg->dimension = VSIR_DIMENSION_VEC4;
for (i = 0; i < component_count; ++i, ++ins) @@ -4464,7 +4585,7 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, cons return false;
src_param_init(&src_params[0]); - src_params[0].reg = *operand_regs[i]; + src_params[0].reg = operand_regs[i];
if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) return false; @@ -4482,11 +4603,11 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, cons static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const struct sm6_value **operands, unsigned int component_count, struct function_emission_state *state, struct vkd3d_shader_register *reg) { - const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; + struct vkd3d_shader_register operand_regs[VKD3D_VEC4_SIZE]; unsigned int i;
for (i = 0; i < component_count; ++i) - operand_regs[i] = &operands[i]->u.reg; + sm6_register_from_value(&operand_regs[i], operands[i]);
return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } @@ -4495,19 +4616,18 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s unsigned int max_operands, const struct sm6_value *z_operand, struct function_emission_state *state, struct vkd3d_shader_register *reg) { - const struct vkd3d_shader_register *operand_regs[VKD3D_VEC4_SIZE]; + struct vkd3d_shader_register operand_regs[VKD3D_VEC4_SIZE]; unsigned int component_count;
for (component_count = 0; component_count < max_operands; ++component_count) { - if (!z_operand && operands[component_count]->is_undefined) + if (!z_operand && operands[component_count]->value_type == VALUE_TYPE_UNDEFINED) break; - operand_regs[component_count] = &operands[component_count]->u.reg; + sm6_register_from_value(&operand_regs[component_count], operands[component_count]); } + if (z_operand) - { - operand_regs[component_count++] = &z_operand->u.reg; - } + sm6_register_from_value(&operand_regs[component_count++], z_operand);
return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } @@ -4732,12 +4852,12 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr } else { - reg = operands[coord_idx]->u.reg; + sm6_register_from_value(®, operands[coord_idx]); }
for (i = coord_idx + coord_count; i < coord_idx + 3; ++i) { - if (!operands[i]->is_undefined) + if (operands[i]->value_type != VALUE_TYPE_UNDEFINED) { WARN("Ignoring unexpected operand.\n"); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, @@ -4756,13 +4876,13 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr src_param_init_from_value(&src_params[1], operands[4]); src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]);
+ sm6_parser_init_ssa_value(sm6, dst); + dst_params = instruction_dst_params_alloc(ins, 2, sm6); dst_param_init(&dst_params[0]); - register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6); + sm6_register_from_value(&dst_params[0].reg, dst); dst_param_init(&dst_params[1]); - dst_params[1].reg = resource->u.handle.reg; - - dst->u.reg = dst_params[0].reg; + sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); }
static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -4818,7 +4938,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VKD3DSIH_IMM_ATOMIC_CONSUME : VKD3DSIH_IMM_ATOMIC_ALLOC); if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -4850,9 +4970,9 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; src_param_init_vector_from_reg(&src_params[0], &coord); - src_params[1].reg = resource->u.handle.reg; + sm6_register_from_handle(sm6, &resource->u.handle, &src_params[1].reg); src_param_init_scalar(&src_params[1], !clamp); - src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[2], &sampler->u.handle);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -4874,7 +4994,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_vector_from_reg(src_param, &buffer->u.handle.reg); + src_param_init_vector_from_handle(sm6, src_param, &buffer->u.handle); /* Differently from other descriptors, constant buffers require an * additional index, used to index within the constant buffer itself. */ src_param->reg.idx_count = 3; @@ -4958,7 +5078,6 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int struct vkd3d_shader_instruction *ins = state->ins; enum vkd3d_shader_descriptor_type type; const struct sm6_descriptor_info *d; - struct vkd3d_shader_register *reg; struct sm6_value *dst; unsigned int id;
@@ -4975,13 +5094,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int dst = sm6_parser_get_current_value(sm6); dst->value_type = VALUE_TYPE_HANDLE; dst->u.handle.d = d; - - reg = &dst->u.handle.reg; - vsir_register_init(reg, d->reg_type, d->reg_data_type, 2); - reg->dimension = VSIR_DIMENSION_VEC4; - reg->idx[0].offset = id; - register_index_address_init(®->idx[1], operands[2], sm6); - reg->non_uniform = !!sm6_value_get_constant_uint(operands[3]); + dst->u.handle.index = operands[2]; + dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]);
/* NOP is used to flag no instruction emitted. */ ins->opcode = VKD3DSIH_NOP; @@ -5256,7 +5370,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6))) return; - src_param_init_vector_from_reg(&src_params[is_texture], &resource->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[is_texture], &resource->u.handle);
if (is_texture) { @@ -5276,7 +5390,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
if (!instruction_dst_param_init_temp_vector(ins, sm6)) @@ -5298,7 +5412,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in } else { - if (!operands[1]->is_undefined) + if (operands[1]->value_type != VALUE_TYPE_UNDEFINED) { WARN("Ignoring unexpected operand.\n"); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, @@ -5355,7 +5469,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin row_index = sm6_value_get_constant_uint(operands[0]); column_index = sm6_value_get_constant_uint(operands[2]);
- if (is_control_point && operands[3]->is_undefined) + if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED) { /* dxcompiler will compile source which does this, so let it pass. */ WARN("Control point id is undefined.\n"); @@ -5398,7 +5512,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin if (e->register_count > 1) register_index_address_init(&src_param->reg.idx[count++], operands[1], sm6);
- if (!is_patch_constant && !operands[3]->is_undefined) + if (!is_patch_constant && operands[3]->value_type != VALUE_TYPE_UNDEFINED) { VKD3D_ASSERT(src_param->reg.idx_count > count); register_index_address_init(&src_param->reg.idx[count], operands[3], sm6); @@ -5518,7 +5632,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) return; src_params_init_from_operands(src_params, &operands[1], operand_count - 1); - src_param_init_vector_from_reg(&src_params[operand_count - 1], &resource->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[operand_count - 1], &resource->u.handle);
instruction_dst_param_init_ssa_vector(ins, component_count, sm6); } @@ -5589,7 +5703,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_
dst_param = instruction_dst_params_alloc(ins, 1, sm6); dst_param_init_with_mask(dst_param, write_mask); - dst_param->reg = resource->u.handle.reg; + sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); dst_param->reg.alignment = alignment; }
@@ -5630,7 +5744,7 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, "Ignoring structure offset for a typed buffer load."); } - src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle);
instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } @@ -5699,7 +5813,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr
dst_param = instruction_dst_params_alloc(ins, 1, sm6); dst_param_init_with_mask(dst_param, write_mask); - dst_param->reg = resource->u.handle.reg; + sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); }
static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -5741,7 +5855,7 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in return; if (op == DX_TEX2DMS_GET_SAMPLE_POS) { - src_param_init_vector_from_reg(&src_params[0], &resource->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); src_param_init_from_value(&src_params[1], operands[1]); } else @@ -5845,8 +5959,8 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ }
src_param_init_vector_from_reg(&src_params[0], &coord); - src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); - src_param_init_vector_from_reg(&src_params[2], &sampler->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); + src_param_init_vector_from_handle(sm6, &src_params[2], &sampler->u.handle); instruction_set_texel_offset(ins, &operands[6], sm6);
instruction_dst_param_init_ssa_vector(ins, component_count, sm6); @@ -5909,13 +6023,14 @@ static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_ return; src_param_init_from_value(src_param, operands[0]);
+ sm6_parser_init_ssa_value(sm6, dst); + index = op == DX_COS; dst_params = instruction_dst_params_alloc(ins, 2, sm6); dst_param_init(&dst_params[0]); dst_param_init(&dst_params[1]); - register_init_ssa_scalar(&dst_params[index].reg, dst->type, dst, sm6); - vsir_register_init(&dst_params[index ^ 1].reg, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); - dst->u.reg = dst_params[index].reg; + sm6_register_from_value(&dst_params[index].reg, dst); + vsir_dst_param_init_null(&dst_params[index ^ 1]); }
static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -6043,8 +6158,8 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in src_param_init_vector_from_reg(&src_params[1], &offset); else instruction_set_texel_offset(ins, &operands[6], sm6); - src_param_init_vector_from_reg(&src_params[1 + extended_offset], &resource->u.handle.reg); - src_param_init_vector_from_reg(&src_params[2 + extended_offset], &sampler->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[1 + extended_offset], &resource->u.handle); + src_param_init_vector_from_handle(sm6, &src_params[2 + extended_offset], &sampler->u.handle); /* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */ swizzle = sm6_value_get_constant_uint(operands[8]); if (swizzle >= VKD3D_VEC4_SIZE) @@ -6096,7 +6211,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr if (!(src_params = instruction_src_params_alloc(ins, 2 + is_multisample, sm6))) return; src_param_init_vector_from_reg(&src_params[0], &coord); - src_param_init_vector_from_reg(&src_params[1], &resource->u.handle.reg); + src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); if (is_multisample) src_param_init_from_value(&src_params[2], mip_level_or_sample_count);
@@ -6149,7 +6264,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int src_param_init_vector_from_reg(&src_params[1], &texel);
dst_param = instruction_dst_params_alloc(ins, 1, sm6); - dst_param->reg = resource->u.handle.reg; + sm6_register_from_handle(sm6, &resource->u.handle, &dst_param->reg); dst_param_init_with_mask(dst_param, write_mask); }
@@ -6524,16 +6639,13 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { - const struct sm6_type *type; - ins->opcode = VKD3DSIH_NOP;
if (!dst->type) return;
- type = sm6_type_get_scalar_type(dst->type, 0); - vsir_register_init(&dst->u.reg, VKD3DSPR_UNDEF, vkd3d_data_type_from_sm6_type(type), 0); - /* dst->is_undefined is not set here because it flags only explicitly undefined values. */ + dst->value_type = VALUE_TYPE_INVALID; + sm6_register_from_value(&dst->reg, dst); }
static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -6638,7 +6750,7 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor "Expected a constant integer dx intrinsic function id."); return; } - sm6_parser_decode_dx_op(sm6, register_get_uint_value(&op_value->u.reg), + sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value), fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); }
@@ -6784,10 +6896,10 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor
if (handler_idx == VKD3DSIH_NOP) { - dst->u.reg = value->u.reg; + sm6_register_from_value(&dst->reg, value); /* Set the result type for casts from 16-bit min precision. */ if (type->u.width != 16) - dst->u.reg.data_type = vkd3d_data_type_from_sm6_type(type); + dst->reg.data_type = vkd3d_data_type_from_sm6_type(type); return; }
@@ -6799,7 +6911,7 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor
/* bitcast */ if (handler_idx == VKD3DSIH_MOV) - src_param->reg.data_type = dst->u.reg.data_type; + src_param->reg.data_type = dst->reg.data_type; }
struct sm6_cmp_info @@ -6952,6 +7064,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re struct vkd3d_shader_dst_param *dst_params; struct vkd3d_shader_src_param *src_params; const struct sm6_value *ptr, *cmp, *new; + struct vkd3d_shader_register reg; unsigned int i = 0; bool is_volatile; uint64_t code; @@ -6961,7 +7074,9 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re || !sm6_value_validate_is_backward_ref(ptr, sm6)) return;
- if (ptr->u.reg.type != VKD3DSPR_GROUPSHAREDMEM) + sm6_register_from_value(®, ptr); + + if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { WARN("Register is not groupshared.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -7017,14 +7132,14 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re src_param_init_from_value(&src_params[1], cmp); src_param_init_from_value(&src_params[2], new);
+ sm6_parser_init_ssa_value(sm6, dst); + if (!(dst_params = instruction_dst_params_alloc(ins, 2, sm6))) return; - register_init_ssa_scalar(&dst_params[0].reg, dst->type, dst, sm6); + sm6_register_from_value(&dst_params[0].reg, dst); dst_param_init(&dst_params[0]); - dst_params[1].reg = ptr->u.reg; + dst_params[1].reg = reg; dst_param_init(&dst_params[1]); - - dst->u.reg = dst_params[0].reg; }
static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil_record *record, @@ -7080,7 +7195,7 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param->reg = src->u.reg; + sm6_register_from_value(&src_param->reg, src); src_param_init_scalar(src_param, elem_idx);
instruction_dst_param_init_ssa_scalar(ins, sm6); @@ -7093,7 +7208,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record unsigned int elem_idx, operand_idx = 2; enum bitcode_address_space addr_space; const struct sm6_value *elem_value; - struct vkd3d_shader_register *reg; + struct vkd3d_shader_register reg; const struct sm6_value *src; bool is_in_bounds;
@@ -7107,7 +7222,9 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; }
- if (src->u.reg.idx_count > 1) + sm6_register_from_value(®, src); + + if (reg.idx_count > 1) { WARN("Unsupported stacked GEP.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -7176,12 +7293,12 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; }
- reg = &dst->u.reg; - *reg = src->u.reg; - reg->idx[1].offset = 0; - register_index_address_init(®->idx[1], elem_value, sm6); - reg->idx[1].is_in_bounds = is_in_bounds; - reg->idx_count = 2; + reg.idx[1].offset = 0; + register_index_address_init(®.idx[1], elem_value, sm6); + reg.idx[1].is_in_bounds = is_in_bounds; + reg.idx_count = 2; + + dst->reg = reg; dst->structure_stride = src->structure_stride;
ins->opcode = VKD3DSIH_NOP; @@ -7193,6 +7310,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor const struct sm6_type *elem_type = NULL, *pointee_type; unsigned int alignment, operand_count, i = 0; struct vkd3d_shader_src_param *src_params; + struct vkd3d_shader_register reg; const struct sm6_value *ptr; uint64_t alignment_code;
@@ -7230,25 +7348,29 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor if (record->operands[i]) WARN("Ignoring volatile modifier.\n");
+ sm6_register_from_value(®, ptr); + if (ptr->structure_stride) { - VKD3D_ASSERT(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); + VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LD_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; - if (ptr->u.reg.idx[1].rel_addr) - src_params[0] = *ptr->u.reg.idx[1].rel_addr; + if (reg.idx[1].rel_addr) + src_params[0] = *reg.idx[1].rel_addr; else - src_param_make_constant_uint(&src_params[0], ptr->u.reg.idx[1].offset); + src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); /* Struct offset is always zero as there is no struct, just an array. */ src_param_make_constant_uint(&src_params[1], 0); src_param_init_from_value(&src_params[2], ptr); src_params[2].reg.alignment = alignment; + /* The offset is already in src_params[0]. */ + src_params[2].reg.idx_count = 1; } else { - operand_count = 1 + (ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); + operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_LD_RAW : VKD3DSIH_MOV);
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) @@ -7299,11 +7421,11 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record }
dst->type = type; - register_init_ssa_scalar(&dst->u.reg, type, dst, sm6); + sm6_parser_init_ssa_value(sm6, dst);
if (!(phi = sm6_block_phi_require_space(code_block, sm6))) return; - phi->reg = dst->u.reg; + sm6_register_from_value(&phi->reg, dst); phi->incoming_count = record->operand_count / 2u;
if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, @@ -7379,6 +7501,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco struct vkd3d_shader_src_param *src_params; struct vkd3d_shader_dst_param *dst_param; const struct sm6_value *ptr, *src; + struct vkd3d_shader_register reg; uint64_t alignment_code;
if (!(ptr = sm6_parser_get_value_by_ref(sm6, record, NULL, &i)) @@ -7413,24 +7536,26 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco if (record->operands[i]) WARN("Ignoring volatile modifier.\n");
+ sm6_register_from_value(®, ptr); + if (ptr->structure_stride) { - VKD3D_ASSERT(ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); + VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; - if (ptr->u.reg.idx[1].rel_addr) - src_params[0] = *ptr->u.reg.idx[1].rel_addr; + if (reg.idx[1].rel_addr) + src_params[0] = *reg.idx[1].rel_addr; else - src_param_make_constant_uint(&src_params[0], ptr->u.reg.idx[1].offset); + src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); /* Struct offset is always zero as there is no struct, just an array. */ src_param_make_constant_uint(&src_params[1], 0); src_param_init_from_value(&src_params[2], src); } else { - operand_count = 1 + (ptr->u.reg.type == VKD3DSPR_GROUPSHAREDMEM); + operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_STORE_RAW : VKD3DSIH_MOV);
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) @@ -7442,7 +7567,7 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco
dst_param = instruction_dst_params_alloc(ins, 1, sm6); dst_param_init(dst_param); - dst_param->reg = ptr->u.reg; + dst_param->reg = reg; dst_param->reg.alignment = alignment; /* Groupshared stores contain the address in the src params. */ if (dst_param->reg.type != VKD3DSPR_IDXTEMP) @@ -7487,7 +7612,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec return; }
- terminator->conditional_reg = src->u.reg; + sm6_register_from_value(&terminator->conditional_reg, src); terminator->type = TERMINATOR_SWITCH;
terminator->case_count = record->operand_count / 2u; @@ -7603,7 +7728,7 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false;
- *u = register_get_uint_value(&value->u.reg); + *u = sm6_value_get_constant_uint(value);
return true; } @@ -7622,7 +7747,7 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false;
- *u = register_get_uint64_value(&value->u.reg); + *u = sm6_value_get_constant_uint(value);
return true; } @@ -7641,7 +7766,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, if (!sm6_type_is_floating_point(value->type)) return false;
- *f = register_get_float_value(&value->u.reg); + *f = register_get_float_value(&value->reg);
return true; } @@ -7826,7 +7951,7 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e } else if (metadata_node_get_unary_uint(node, &operand, sm6)) { - dst->u.reg.non_uniform = !!operand; + dst->reg.non_uniform = !!operand; } } else @@ -7898,13 +8023,13 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun "A PHI incoming value is not a constant or SSA register."); return VKD3D_ERROR_INVALID_SHADER; } - if (src->u.reg.data_type != phi->reg.data_type) + if (src->reg.data_type != phi->reg.data_type) { WARN("Type mismatch.\n"); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, "The type of a phi incoming value does not match the result type."); } - phi->incoming[j].reg = src->u.reg; + sm6_register_from_value(&phi->incoming[j].reg, src); } } } @@ -8519,7 +8644,7 @@ static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const if (!(value = sm6_parser_get_value_safe(sm6, value_idx))) return VKD3D_ERROR_INVALID_SHADER;
- if (!sm6_value_is_constant(value) && !sm6_value_is_undef(value) && !sm6_value_is_icb(value) + if (!sm6_value_is_constant(value) && !sm6_value_is_undef(value) && !sm6_value_is_data(value) && !sm6_value_is_function_dcl(value)) { WARN("Value at index %u is not a constant or a function declaration.\n", value_idx); @@ -8550,19 +8675,29 @@ static enum vkd3d_result sm6_parser_metadata_init(struct sm6_parser *sm6, const return VKD3D_OK; }
-static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component_type(enum dxil_component_type type) +static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component_type( + enum dxil_component_type type, bool native_16bit) { switch (type) { case COMPONENT_TYPE_I1: return VKD3D_SHADER_COMPONENT_BOOL; case COMPONENT_TYPE_I16: + if (native_16bit) + return VKD3D_SHADER_COMPONENT_INT16; + return VKD3D_SHADER_COMPONENT_INT; case COMPONENT_TYPE_I32: return VKD3D_SHADER_COMPONENT_INT; case COMPONENT_TYPE_U16: + if (native_16bit) + return VKD3D_SHADER_COMPONENT_UINT16; + return VKD3D_SHADER_COMPONENT_UINT; case COMPONENT_TYPE_U32: return VKD3D_SHADER_COMPONENT_UINT; case COMPONENT_TYPE_F16: + if (native_16bit) + return VKD3D_SHADER_COMPONENT_FLOAT16; + return VKD3D_SHADER_COMPONENT_FLOAT; case COMPONENT_TYPE_F32: case COMPONENT_TYPE_SNORMF32: case COMPONENT_TYPE_UNORMF32: @@ -8577,8 +8712,12 @@ static enum vkd3d_shader_component_type vkd3d_component_type_from_dxil_component } }
-static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component_type(enum dxil_component_type type) +static enum vkd3d_shader_minimum_precision minimum_precision_from_dxil_component_type( + enum dxil_component_type type, bool native_16bit) { + if (native_16bit) + return VKD3D_SHADER_MINIMUM_PRECISION_NONE; + switch (type) { case COMPONENT_TYPE_F16: @@ -9404,8 +9543,10 @@ 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 signature_element *elements, *e; unsigned int values[10]; + bool native_16bit; bool is_register;
if (!m) @@ -9430,6 +9571,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const return VKD3D_ERROR_OUT_OF_MEMORY; }
+ native_16bit = program->global_flags & VKD3DSGF_FORCE_NATIVE_LOW_PRECISION; for (i = 0; i < operand_count; ++i) { m = node->operands[i]; @@ -9490,8 +9632,8 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const } e->semantic_name = element_node->operands[1]->u.string_value;
- e->component_type = vkd3d_component_type_from_dxil_component_type(values[2]); - e->min_precision = minimum_precision_from_dxil_component_type(values[2]); + e->component_type = vkd3d_component_type_from_dxil_component_type(values[2], native_16bit); + e->min_precision = minimum_precision_from_dxil_component_type(values[2], native_16bit);
j = values[3]; e->sysval_semantic = sysval_semantic_from_dxil_semantic_kind(j, tessellator_domain); @@ -9631,23 +9773,24 @@ static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, cons
if (m->u.node->operand_count && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[0], &program->input_signature, tessellator_domain, true)) < 0) - { return ret; - } + if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[1], &program->output_signature, tessellator_domain, false)) < 0) - { return ret; - } + if (m->u.node->operand_count > 1 && (ret = sm6_parser_read_signature(sm6, m->u.node->operands[2], &program->patch_constant_signature, tessellator_domain, false)) < 0) - { return ret; - }
- sm6_parser_init_input_signature(sm6, &program->input_signature); - sm6_parser_init_output_signature(sm6, &program->output_signature); - sm6_parser_init_patch_constant_signature(sm6, &program->patch_constant_signature); + if ((ret = sm6_parser_init_input_signature(sm6, &program->input_signature)) < 0) + return ret; + + if ((ret = sm6_parser_init_output_signature(sm6, &program->output_signature)) < 0) + return ret; + + if ((ret = sm6_parser_init_patch_constant_signature(sm6, &program->patch_constant_signature)) < 0) + return ret;
return VKD3D_OK; } @@ -9917,6 +10060,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s { input_primitive = VKD3D_PT_PATCH; patch_vertex_count = i - INPUT_PRIMITIVE_PATCH1 + 1; + input_control_point_count = patch_vertex_count; break; }
@@ -9927,6 +10071,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s }
sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_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;
i = operands[1]; @@ -9938,6 +10083,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, VKD3DSIH_DCL_VERTICES_OUT, i); + sm6->p.program->vertices_out_count = i;
if (operands[2] > 1) { @@ -9955,6 +10101,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, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); + sm6->p.program->output_topology = output_primitive;
i = operands[4]; if (!i || i > MAX_GS_INSTANCE_COUNT) @@ -10432,9 +10579,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro input_signature = &program->input_signature; output_signature = &program->output_signature; patch_constant_signature = &program->patch_constant_signature; - *input_signature = dxbc_desc->input_signature; - *output_signature = dxbc_desc->output_signature; - *patch_constant_signature = dxbc_desc->patch_constant_signature; program->features = dxbc_desc->features; memset(dxbc_desc, 0, sizeof(*dxbc_desc));
@@ -10498,18 +10642,6 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro goto fail; }
- if (!(sm6->output_params = vsir_program_get_dst_params(program, output_signature->element_count)) - || !(sm6->input_params = vsir_program_get_dst_params(program, input_signature->element_count)) - || !(sm6->patch_constant_params = vsir_program_get_dst_params(program, - patch_constant_signature->element_count))) - { - ERR("Failed to allocate input/output parameters.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, - "Out of memory allocating input/output parameters."); - ret = VKD3D_ERROR_OUT_OF_MEMORY; - goto fail; - } - function_count = dxil_block_compute_function_count(&sm6->root_block); if (!(sm6->functions = vkd3d_calloc(function_count, sizeof(*sm6->functions)))) { @@ -10669,8 +10801,6 @@ int dxil_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t co uint32_t *byte_code = NULL; int ret;
- MESSAGE("Creating a DXIL parser. This is unsupported; you get to keep all the pieces if it breaks.\n"); - dxbc_desc.is_dxil = true; if ((ret = shader_extract_from_dxbc(&compile_info->source, message_context, compile_info->source_name, &dxbc_desc)) < 0) diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c index bd7e7b420db..a4f1a371299 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -25,6 +25,49 @@ static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uin return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value)); }
+enum fx_2_type_constants +{ + /* Assignment types */ + FX_2_ASSIGNMENT_CODE_BLOB = 0x0, + FX_2_ASSIGNMENT_PARAMETER = 0x1, + FX_2_ASSIGNMENT_ARRAY_SELECTOR = 0x2, +}; + +enum state_property_component_type +{ + FX_BOOL, + FX_FLOAT, + FX_UINT, + FX_UINT8, + FX_DEPTHSTENCIL, + FX_RASTERIZER, + FX_DOMAINSHADER, + FX_HULLSHADER, + FX_COMPUTESHADER, + FX_TEXTURE, + FX_DEPTHSTENCILVIEW, + FX_RENDERTARGETVIEW, + FX_BLEND, + FX_VERTEXSHADER, + FX_PIXELSHADER, + FX_GEOMETRYSHADER, + FX_COMPONENT_TYPE_COUNT, +}; + +struct rhs_named_value +{ + const char *name; + unsigned int value; +}; + +struct fx_assignment +{ + uint32_t id; + uint32_t lhs_index; + uint32_t type; + uint32_t value; +}; + struct fx_4_binary_type { uint32_t name; @@ -246,6 +289,15 @@ static void set_status(struct fx_write_context *fx, int status) fx->status = status; }
+static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix, + const char *s, size_t len) +{ + if (len) + --len; /* Trim terminating null. */ + vkd3d_string_buffer_printf(buffer, "%s", prefix); + vkd3d_string_buffer_print_string_escaped(buffer, s, len); +} + static uint32_t write_string(const char *string, struct fx_write_context *fx) { return fx->ops->write_string(string, fx); @@ -461,6 +513,461 @@ static void write_fx_2_annotations(struct hlsl_ir_var *var, uint32_t count_offse set_u32(buffer, count_offset, count); }
+static const struct rhs_named_value fx_2_zenable_values[] = +{ + { "USEW", 2 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_fillmode_values[] = +{ + { "POINT", 1 }, + { "WIREFRAME", 2 }, + { "SOLID", 3 }, + { NULL }, +}; + +static const struct rhs_named_value fx_2_shademode_values[] = +{ + { "FLAT", 1 }, + { "GOURAUD", 2 }, + { "PHONG", 3 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_blendmode_values[] = +{ + { "ZERO", 1 }, + { "ONE", 2 }, + { "SRCCOLOR", 3 }, + { "INVSRCCOLOR", 4 }, + { "SRCALPHA", 5 }, + { "INVSRCALPHA", 6 }, + { "DESTALPHA", 7 }, + { "INVDESTALPHA", 8 }, + { "DESTCOLOR", 9 }, + { "INVDESTCOLOR", 10 }, + { "SRCALPHASAT", 11 }, + { "BOTHSRCALPHA", 12 }, + { "BOTHINVSRCALPHA", 13 }, + { "BLENDFACTOR", 14 }, + { "INVBLENDFACTOR", 15 }, + { "SRCCOLOR2", 16 }, + { "INVSRCCOLOR2", 17 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_cullmode_values[] = +{ + { "NONE", 1 }, + { "CW", 2 }, + { "CCW", 3 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_cmpfunc_values[] = +{ + { "NEVER", 1 }, + { "LESS", 2 }, + { "EQUAL", 3 }, + { "LESSEQUAL", 4 }, + { "GREATER", 5 }, + { "NOTEQUAL", 6 }, + { "GREATEREQUAL", 7 }, + { "ALWAYS", 8 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_fogmode_values[] = +{ + { "NONE", 0 }, + { "EXP", 1 }, + { "EXP2", 2 }, + { "LINEAR", 3 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_stencilcaps_values[] = +{ + { "KEEP", 0x1 }, + { "ZERO", 0x2 }, + { "REPLACE", 0x4 }, + { "INCRSAT", 0x8 }, + { "DECRSAT", 0x10 }, + { "INVERT", 0x20 }, + { "INCR", 0x40 }, + { "DECR", 0x80 }, + { "TWOSIDED", 0x100 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_wrap_values[] = +{ + { "COORD_0", 0x1 }, + { "COORD_1", 0x2 }, + { "COORD_2", 0x4 }, + { "COORD_3", 0x8 }, + { "U", 0x1 }, + { "V", 0x2 }, + { "W", 0x4 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_materialcolorsource_values[] = +{ + { "MATERIAL", 0 }, + { "COORD1", 1 }, + { "COORD2", 2 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_vertexblend_values[] = +{ + { "DISABLE", 0 }, + { "1WEIGHTS", 1 }, + { "2WEIGHTS", 2 }, + { "3WEIGHTS", 3 }, + { "TWEENING", 255 }, + { "0WEIGHTS", 256 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_clipplane_values[] = +{ + { "CLIPPLANE0", 0x1 }, + { "CLIPPLANE1", 0x2 }, + { "CLIPPLANE2", 0x4 }, + { "CLIPPLANE3", 0x8 }, + { "CLIPPLANE4", 0x10 }, + { "CLIPPLANE5", 0x20 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_patchedgestyle_values[] = +{ + { "DISCRETE", 0 }, + { "CONTINUOUS", 1 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_colorwriteenable_values[] = +{ + { "RED", 0x1 }, + { "GREEN", 0x2 }, + { "BLUE", 0x4 }, + { "ALPHA", 0x8 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_blendop_values[] = +{ + { "ADD", 1 }, + { "SUBTRACT", 2 }, + { "REVSUBTRACT", 3 }, + { "MIN", 4 }, + { "MAX", 5 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_degree_values[] = +{ + { "LINEAR", 1 }, + { "QUADRATIC", 2 }, + { "CUBIC", 3 }, + { "QUINTIC", 4 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_textureop_values[] = +{ + { "DISABLE", 1 }, + { "SELECTARG1", 2 }, + { "SELECTARG2", 3 }, + { "MODULATE", 4 }, + { "MODULATE2X", 5 }, + { "MODULATE4X", 6 }, + { "ADD", 7 }, + { "ADDSIGNED", 8 }, + { "ADDSIGNED2X", 9 }, + { "SUBTRACT", 10 }, + { "ADDSMOOTH", 11 }, + { "BLENDDIFFUSEALPHA", 12 }, + { "BLENDTEXTUREALPHA", 13 }, + { "BLENDFACTORALPHA", 14 }, + { "BLENDTEXTUREALPHAPM", 15 }, + { "BLENDCURRENTALPHA", 16 }, + { "PREMODULATE", 17 }, + { "MODULATEALPHA_ADDCOLOR", 18 }, + { "MODULATECOLOR_ADDALPHA", 19 }, + { "MODULATEINVALPHA_ADDCOLOR", 20 }, + { "MODULATEINVCOLOR_ADDALPHA", 21 }, + { "BUMPENVMAP", 22 }, + { "BUMPENVMAPLUMINANCE", 23 }, + { "DOTPRODUCT3", 24 }, + { "MULTIPLYADD", 25 }, + { "LERP", 26 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_colorarg_values[] = +{ + { "DIFFUSE", 0x0 }, + { "CURRENT", 0x1 }, + { "TEXTURE", 0x2 }, + { "TFACTOR", 0x3 }, + { "SPECULAR", 0x4 }, + { "TEMP", 0x5 }, + { "CONSTANT", 0x6 }, + { "COMPLEMENT", 0x10 }, + { "ALPHAREPLICATE", 0x20 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_texturetransform_values[] = +{ + { "DISABLE", 0 }, + { "COUNT1", 1 }, + { "COUNT2", 2 }, + { "COUNT3", 3 }, + { "COUNT4", 4 }, + { "PROJECTED", 256 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_lighttype_values[] = +{ + { "POINT", 1 }, + { "SPOT", 2 }, + { "DIRECTIONAL", 3 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_address_values[] = +{ + { "WRAP", 1 }, + { "MIRROR", 2 }, + { "CLAMP", 3 }, + { "BORDER", 4 }, + { "MIRROR_ONCE", 5 }, + { NULL } +}; + +static const struct rhs_named_value fx_2_filter_values[] = +{ + { "NONE", 0 }, + { "POINT", 1 }, + { "LINEAR", 2 }, + { "ANISOTROPIC", 3 }, + { "PYRAMIDALQUAD", 6 }, + { "GAUSSIANQUAD", 7 }, + { "CONVOLUTIONMONO", 8 }, + { NULL } +}; + +static const struct fx_2_state +{ + const char *name; + enum hlsl_type_class class; + enum state_property_component_type type; + unsigned int dimx; + uint32_t array_size; + uint32_t id; + const struct rhs_named_value *values; +} +fx_2_states[] = +{ + { "ZEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values }, + { "FillMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values }, + { "ShadeMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 2, fx_2_shademode_values }, + { "ZWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 3 }, + { "AlphaTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 4 }, + { "LastPixel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 5 }, + { "SrcBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 6, fx_2_blendmode_values }, + { "DestBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 7, fx_2_blendmode_values }, + { "CullMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 8, fx_2_cullmode_values }, + { "ZFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9, fx_2_cmpfunc_values }, + { "AlphaRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 10 }, + { "AlphaFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11, fx_2_cmpfunc_values }, + { "DitherEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12 }, + { "AlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13 }, + { "FogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 14 }, + { "SpecularEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, + { "FogColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 16 }, + { "FogTableMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 17, fx_2_fogmode_values }, + { "FogStart", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 18 }, + { "FogEnd", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 19 }, + { "FogDensity", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 20 }, + { "RangeFogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 21 }, + { "StencilEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 22 }, + { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, fx_2_stencilcaps_values }, + { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, fx_2_stencilcaps_values }, + { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 25, fx_2_stencilcaps_values }, + { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 26, fx_2_cmpfunc_values }, + { "StencilRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 27 }, + { "StencilMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28 }, + { "StencilWriteMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 29 }, + { "TextureFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 30 }, + { "Wrap0", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 31, fx_2_wrap_values }, + { "Wrap1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 32, fx_2_wrap_values }, + { "Wrap2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 33, fx_2_wrap_values }, + { "Wrap3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 34, fx_2_wrap_values }, + { "Wrap4", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 35, fx_2_wrap_values }, + { "Wrap5", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 36, fx_2_wrap_values }, + { "Wrap6", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 37, fx_2_wrap_values }, + { "Wrap7", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, fx_2_wrap_values }, + { "Wrap8", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, fx_2_wrap_values }, + { "Wrap9", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, fx_2_wrap_values }, + { "Wrap10", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, fx_2_wrap_values }, + { "Wrap11", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, fx_2_wrap_values }, + { "Wrap12", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, fx_2_wrap_values }, + { "Wrap13", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 44, fx_2_wrap_values }, + { "Wrap14", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 45, fx_2_wrap_values }, + { "Wrap15", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 46, fx_2_wrap_values }, + { "Clipping", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 47 }, + { "Lighting", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 48 }, + { "Ambient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 49 }, + { "FogVertexMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 50, fx_2_fogmode_values }, + { "ColorVertex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 51 }, + { "LocalViewer", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 52 }, + { "NormalizeNormals", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 53 }, + + { "DiffuseMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 54, fx_2_materialcolorsource_values }, + { "SpecularMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 55, fx_2_materialcolorsource_values }, + { "AmbientMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 56, fx_2_materialcolorsource_values }, + { "EmissiveMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 57, fx_2_materialcolorsource_values }, + + { "VertexBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 58, fx_2_vertexblend_values }, + { "ClipPlaneEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 59, fx_2_clipplane_values }, + { "PointSize", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 60 }, + { "PointSize_Min", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 61 }, + { "PointSize_Max", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 62 }, + { "PointSpriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 63 }, + { "PointScaleEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 64 }, + { "PointScale_A", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 65 }, + { "PointScale_B", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 66 }, + { "PointScale_C", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 67 }, + + { "MultiSampleAntialias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 68 }, + { "MultiSampleMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 69 }, + { "PatchEdgeStyle", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 70, fx_2_patchedgestyle_values }, + { "DebugMonitorToken", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 71 }, + { "IndexedVertexBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 72 }, + { "ColorWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 73, fx_2_colorwriteenable_values }, + { "TweenFactor", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 74 }, + { "BlendOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 75, fx_2_blendop_values }, + { "PositionDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 76, fx_2_degree_values }, + { "NormalDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 77, fx_2_degree_values }, + { "ScissorTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 78 }, + { "SlopeScaleDepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 79 }, + + { "AntialiasedLineEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 80 }, + { "MinTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 81 }, + { "MaxTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 82 }, + { "AdaptiveTess_X", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 83 }, + { "AdaptiveTess_Y", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 }, + { "AdaptiveTess_Z", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 }, + { "AdaptiveTess_W", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 }, + { "EnableAdaptiveTesselation", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 }, + { "TwoSidedStencilMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 }, + { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values }, + { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values }, + { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 91, fx_2_stencilcaps_values }, + { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 92, fx_2_cmpfunc_values }, + + { "ColorWriteEnable1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 93, fx_2_colorwriteenable_values }, + { "ColorWriteEnable2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 94, fx_2_colorwriteenable_values }, + { "ColorWriteEnable3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 95, fx_2_colorwriteenable_values }, + { "BlendFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 96 }, + { "SRGBWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 97 }, + { "DepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 98 }, + { "SeparateAlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 99 }, + { "SrcBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 100, fx_2_blendmode_values }, + { "DestBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 101, fx_2_blendmode_values }, + { "BlendOpAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 102, fx_2_blendmode_values }, + + { "ColorOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 103, fx_2_textureop_values }, + { "ColorArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 104, fx_2_colorarg_values }, + { "ColorArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 105, fx_2_colorarg_values }, + { "ColorArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 106, fx_2_colorarg_values }, + { "AlphaOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 107, fx_2_textureop_values }, + { "AlphaArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 108, fx_2_colorarg_values }, + { "AlphaArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 109, fx_2_colorarg_values }, + { "AlphaArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 110, fx_2_colorarg_values }, + { "ResultArg", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 111, fx_2_colorarg_values }, + { "BumpEnvMat00", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 112 }, + { "BumpEnvMat01", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 }, + { "BumpEnvMat10", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 }, + { "BumpEnvMat11", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 }, + { "TextCoordIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 }, + { "BumpEnvLScale", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 }, + { "BumpEnvLOffset", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 }, + { "TextureTransformFlags", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values }, + { "Constant", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 }, + { "NPatchMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 }, + { "FVF", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 }, + + { "ProjectionTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 }, + { "ViewTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 }, + { "WorldTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 125 }, + { "TextureTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 }, + + { "MaterialAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 }, + { "MaterialDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 128 }, + { "MaterialSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 129 }, + { "MaterialEmissive", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 }, + { "MaterialPower", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 }, + + { "LightType", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 132, fx_2_lighttype_values }, + { "LightDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 133 }, + { "LightSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 134 }, + { "LightAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 135 }, + { "LightPosition", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 136 }, + { "LightDirection", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 137 }, + { "LightRange", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 138 }, + { "LightFalloff", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 139 }, + { "LightAttenuation0", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 140 }, + { "LightAttenuation1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 141 }, + { "LightAttenuation2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 142 }, + { "LightTheta", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 143 }, + { "LightPhi", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 144 }, + { "LightEnable", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 145 }, + + { "VertexShader", HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 }, + { "PixelShader", HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 }, + + { "VertexShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 148 }, + { "VertexShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 149 }, + { "VertexShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 150 }, + { "VertexShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 151 }, + { "VertexShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 152 }, + { "VertexShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 153 }, + { "VertexShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 154 }, + { "VertexShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 155 }, + + { "PixelShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 156 }, + { "PixelShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 157 }, + { "PixelShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 158 }, + { "PixelShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 159 }, + { "PixelShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 160 }, + { "PixelShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 161 }, + { "PixelShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 162 }, + { "PixelShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 163 }, + + { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, + { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, + { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, + { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, + { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, + { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, + { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, + { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, + { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, + { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, + { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, + { "SRBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, + { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, +}; + static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; @@ -560,8 +1067,21 @@ enum fx_4_type_constants FX_4_ASSIGNMENT_VARIABLE = 0x2, FX_4_ASSIGNMENT_ARRAY_CONSTANT_INDEX = 0x3, FX_4_ASSIGNMENT_ARRAY_VARIABLE_INDEX = 0x4, + FX_4_ASSIGNMENT_INDEX_EXPRESSION = 0x5, + FX_4_ASSIGNMENT_VALUE_EXPRESSION = 0x6, FX_4_ASSIGNMENT_INLINE_SHADER = 0x7, FX_5_ASSIGNMENT_INLINE_SHADER = 0x8, + + /* FXLVM constants */ + FX_4_FXLC_COMP_COUNT_MASK = 0xffff, + FX_4_FXLC_OPCODE_MASK = 0x7ff, + FX_4_FXLC_OPCODE_SHIFT = 20, + FX_4_FXLC_IS_SCALAR_MASK = 0x80000000, + + FX_4_FXLC_REG_LITERAL = 1, + FX_4_FXLC_REG_CB = 2, + FX_4_FXLC_REG_OUTPUT = 4, + FX_4_FXLC_REG_TEMP = 7, };
static const uint32_t fx_4_numeric_base_types[] = @@ -1210,7 +1730,13 @@ static uint32_t write_fx_2_object_initializer(const struct hlsl_ir_var *var, str put_u32(buffer, id); put_u32(buffer, size); if (size) + { + static const uint32_t pad; + bytecode_put_bytes(buffer, data, size); + if (size % 4) + bytecode_put_bytes_unaligned(buffer, &pad, 4 - (size % 4)); + } } }
@@ -1594,12 +2120,6 @@ static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_conte } }
-struct rhs_named_value -{ - const char *name; - unsigned int value; -}; - static bool get_fx_4_state_enum_value(const struct rhs_named_value *pairs, const char *name, unsigned int *value) { @@ -1831,27 +2351,6 @@ static bool replace_state_block_constant(struct hlsl_ctx *ctx, struct hlsl_ir_no return true; }
-enum state_property_component_type -{ - FX_BOOL, - FX_FLOAT, - FX_UINT, - FX_UINT8, - FX_DEPTHSTENCIL, - FX_RASTERIZER, - FX_DOMAINSHADER, - FX_HULLSHADER, - FX_COMPUTESHADER, - FX_TEXTURE, - FX_DEPTHSTENCILVIEW, - FX_RENDERTARGETVIEW, - FX_BLEND, - FX_VERTEXSHADER, - FX_PIXELSHADER, - FX_GEOMETRYSHADER, - FX_COMPONENT_TYPE_COUNT, -}; - static inline bool is_object_fx_type(enum state_property_component_type type) { switch (type) @@ -1867,6 +2366,7 @@ static inline bool is_object_fx_type(enum state_property_component_type type) case FX_BLEND: case FX_VERTEXSHADER: case FX_PIXELSHADER: + case FX_GEOMETRYSHADER: return true; default: return false; @@ -1920,6 +2420,23 @@ static inline enum hlsl_base_type hlsl_type_from_fx_type(enum state_property_com } }
+static inline bool hlsl_type_state_compatible(struct hlsl_type *lhs, enum hlsl_base_type rhs) +{ + if (!hlsl_is_numeric_type(lhs)) + return false; + switch (lhs->e.numeric.type) + { + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + return rhs == HLSL_TYPE_INT || rhs == HLSL_TYPE_UINT; + + default: + return lhs->e.numeric.type == rhs; + } + + vkd3d_unreachable(); +} + static const struct rhs_named_value filter_values[] = { { "MIN_MAG_MIP_POINT", 0x00 }, @@ -2138,38 +2655,31 @@ fx_4_states[] = { "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 }, };
-static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl_state_block_entry *entry, - struct fx_write_context *fx) +static const struct fx_4_state fx_5_blend_states[] = { - static const struct fx_4_state fx_5_blend_states[] = - { - { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, - { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, - { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values }, - { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values }, - { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values }, - { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values }, - { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values }, - { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values }, - { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, - }; + { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, + { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, + { "SrcBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 38, blend_values }, + { "DestBlend", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 39, blend_values }, + { "BlendOp", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 40, blendop_values }, + { "SrcBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 41, blend_values }, + { "DestBlendAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 42, blend_values }, + { "BlendOpAlpha", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 43, blendop_values }, + { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, +};
- struct state_table - { - const struct fx_4_state *ptr; - unsigned int count; - } table; +struct fx_4_state_table +{ + const struct fx_4_state *ptr; + unsigned int count; +};
- const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); - struct replace_state_context replace_context; - const struct fx_4_state *state = NULL; - struct hlsl_type *state_type = NULL; - struct hlsl_ir_node *node, *cast; - struct hlsl_ctx *ctx = fx->ctx; - enum hlsl_base_type base_type; - unsigned int i; +static struct fx_4_state_table fx_4_get_state_table(enum hlsl_type_class type_class, + unsigned int major, unsigned int minor) +{ + struct fx_4_state_table table;
- if (type->class == HLSL_CLASS_BLEND_STATE && ctx->profile->major_version == 5) + if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1))) { table.ptr = fx_5_blend_states; table.count = ARRAY_SIZE(fx_5_blend_states); @@ -2180,6 +2690,24 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl table.count = ARRAY_SIZE(fx_4_states); }
+ return table; +} + +static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, + struct hlsl_state_block_entry *entry, struct fx_write_context *fx) +{ + const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); + struct replace_state_context replace_context; + const struct fx_4_state *state = NULL; + struct hlsl_type *state_type = NULL; + struct hlsl_ctx *ctx = fx->ctx; + enum hlsl_base_type base_type; + struct fx_4_state_table table; + struct hlsl_ir_node *node; + unsigned int i; + + table = fx_4_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version); + for (i = 0; i < table.count; ++i) { if (type->class == table.ptr[i].container @@ -2262,7 +2790,8 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl struct hlsl_ir_constant *c = hlsl_ir_constant(node); struct hlsl_type *data_type = c->node.data_type;
- if (data_type->class == HLSL_CLASS_SCALAR && data_type->e.numeric.type == HLSL_TYPE_UINT) + if (data_type->class == HLSL_CLASS_SCALAR + && (data_type->e.numeric.type == HLSL_TYPE_INT || data_type->e.numeric.type == HLSL_TYPE_UINT)) { if (c->value.u[0].u != 0) hlsl_error(ctx, &ctx->location, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, @@ -2302,9 +2831,15 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl if (state_type) { node = entry->args->node; - if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc))) - return; - list_add_after(&node->entry, &cast->entry); + if (state->type == FX_UINT8 || !hlsl_type_state_compatible(node->data_type, base_type)) + { + struct hlsl_ir_node *cast; + + if (!(cast = hlsl_new_cast(ctx, node, state_type, &var->loc))) + return; + list_add_after(&node->entry, &cast->entry); + node = cast; + }
/* FX_UINT8 values are using 32-bits in the binary. Mask higher 24 bits for those. */ if (state->type == FX_UINT8) @@ -2313,15 +2848,18 @@ static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, struct hlsl
if (!(mask = hlsl_new_uint_constant(ctx, 0xff, &var->loc))) return; - list_add_after(&cast->entry, &mask->entry); + list_add_after(&node->entry, &mask->entry);
- if (!(cast = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, cast, mask))) + if (!(node = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, node, mask))) return; - list_add_after(&mask->entry, &cast->entry); + list_add_after(&mask->entry, &node->entry); }
- hlsl_src_remove(entry->args); - hlsl_src_from_node(entry->args, cast); + if (node != entry->args->node) + { + hlsl_src_remove(entry->args); + hlsl_src_from_node(entry->args, node); + }
hlsl_run_const_passes(ctx, entry->instrs); } @@ -2395,7 +2933,15 @@ static unsigned int decompose_fx_4_state_function_call(struct hlsl_ir_var *var, static unsigned int decompose_fx_4_state_block_expand_array(struct hlsl_ir_var *var, struct hlsl_state_block *block, unsigned int entry_index, struct fx_write_context *fx) { - static const char *states[] = { "SrcBlend", "DestBlend", "BlendOp", "SrcBlendAlpha", "DestBlendAlpha", "BlendOpAlpha" }; + static const char *const states[] = + { + "SrcBlend", + "DestBlend", + "BlendOp", + "SrcBlendAlpha", + "DestBlendAlpha", + "BlendOpAlpha", + }; const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); struct hlsl_state_block_entry *entry = block->entries[entry_index]; static const unsigned int array_size = 8; @@ -2904,7 +3450,11 @@ struct fx_parser struct vkd3d_shader_message_context *message_context; struct vkd3d_string_buffer buffer; unsigned int indent; - unsigned int version; + struct + { + unsigned int major; + unsigned int minor; + } version; struct { const uint8_t *ptr; @@ -2914,6 +3464,11 @@ struct fx_parser uint32_t buffer_count; uint32_t object_count; uint32_t group_count; + struct + { + uint32_t count; + uint32_t *types; + } objects; bool failed; };
@@ -2965,13 +3520,6 @@ static void VKD3D_PRINTF_FUNC(3, 4) fx_parser_error(struct fx_parser *parser, en parser->failed = true; }
-static int fx_2_parse(struct fx_parser *parser) -{ - fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED, "Parsing fx_2_0 binaries is not implemented."); - - return -1; -} - static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint32_t offset, size_t size) { const uint8_t *ptr = parser->unstructured.ptr; @@ -2986,21 +3534,764 @@ static const void *fx_parser_get_unstructured_ptr(struct fx_parser *parser, uint return &ptr[offset]; }
-static void fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size) +static const void *fx_parser_get_ptr(struct fx_parser *parser, size_t size) +{ + if (parser->end - parser->ptr < size) + { + parser->failed = true; + return NULL; + } + + return parser->ptr; +} + +static uint32_t fx_parser_read_unstructured(struct fx_parser *parser, void *dst, uint32_t offset, size_t size) { const uint8_t *ptr;
memset(dst, 0, size); if (!(ptr = fx_parser_get_unstructured_ptr(parser, offset, size))) - return; + return offset;
memcpy(dst, ptr, size); + return offset + size; }
-static const char *fx_4_get_string(struct fx_parser *parser, uint32_t offset) +static void parse_fx_start_indent(struct fx_parser *parser) { - const uint8_t *ptr = parser->unstructured.ptr; - const uint8_t *end = parser->unstructured.end; + ++parser->indent; +} + +static void parse_fx_end_indent(struct fx_parser *parser) +{ + --parser->indent; +} + +static void parse_fx_print_indent(struct fx_parser *parser) +{ + vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); +} + +static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size) +{ + const char *ptr; + + fx_parser_read_unstructured(parser, size, offset, sizeof(*size)); + ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size); + + if (!ptr) + { + parser->failed = true; + return "<invalid>"; + } + + return ptr; +} + +static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset) +{ + uint32_t element_count, member_count, class, columns, rows; + unsigned int size = 0; + + fx_parser_read_unstructured(parser, &class, *offset + 4, sizeof(class)); + fx_parser_read_unstructured(parser, &element_count, *offset + 16, sizeof(element_count)); + + if (class == D3DXPC_STRUCT) + { + *offset = fx_parser_read_unstructured(parser, &member_count, *offset + 20, sizeof(member_count)); + + for (uint32_t i = 0; i < member_count; ++i) + size += fx_get_fx_2_type_size(parser, offset); + } + else if (class == D3DXPC_VECTOR) + { + fx_parser_read_unstructured(parser, &columns, *offset + 20, sizeof(columns)); + *offset = fx_parser_read_unstructured(parser, &rows, *offset + 24, sizeof(rows)); + size = rows * columns * sizeof(float); + } + else if (class == D3DXPC_MATRIX_ROWS + || class == D3DXPC_MATRIX_COLUMNS + || class == D3DXPC_SCALAR) + { + fx_parser_read_unstructured(parser, &rows, *offset + 20, sizeof(rows)); + *offset = fx_parser_read_unstructured(parser, &columns, *offset + 24, sizeof(columns)); + size = rows * columns * sizeof(float); + } + else + { + *offset += 20; + } + + if (element_count) + size *= element_count; + return size; +} + +static const char *const fx_2_types[] = +{ + [D3DXPT_VOID] = "void", + [D3DXPT_BOOL] = "bool", + [D3DXPT_INT] = "int", + [D3DXPT_FLOAT] = "float", + [D3DXPT_STRING] = "string", + [D3DXPT_TEXTURE] = "texture", + [D3DXPT_TEXTURE1D] = "texture1D", + [D3DXPT_TEXTURE2D] = "texture2D", + [D3DXPT_TEXTURE3D] = "texture3D", + [D3DXPT_TEXTURECUBE] = "textureCUBE", + [D3DXPT_SAMPLER] = "sampler", + [D3DXPT_SAMPLER1D] = "sampler1D", + [D3DXPT_SAMPLER2D] = "sampler2D", + [D3DXPT_SAMPLER3D] = "sampler3D", + [D3DXPT_SAMPLERCUBE] = "samplerCUBE", + [D3DXPT_PIXELSHADER] = "PixelShader", + [D3DXPT_VERTEXSHADER] = "VertexShader", + [D3DXPT_PIXELFRAGMENT] = "<pixel-fragment>", + [D3DXPT_VERTEXFRAGMENT] = "<vertex-fragment>", + [D3DXPT_UNSUPPORTED] = "<unsupported>", +}; + +static void fx_parse_fx_2_type(struct fx_parser *parser, uint32_t offset) +{ + uint32_t type, class, rows, columns; + const char *name; + + fx_parser_read_unstructured(parser, &type, offset, sizeof(type)); + fx_parser_read_unstructured(parser, &class, offset + 4, sizeof(class)); + + if (class == D3DXPC_STRUCT) + name = "struct"; + else + name = type < ARRAY_SIZE(fx_2_types) ? fx_2_types[type] : "<unknown>"; + + vkd3d_string_buffer_printf(&parser->buffer, "%s", name); + if (class == D3DXPC_VECTOR) + { + fx_parser_read_unstructured(parser, &columns, offset + 20, sizeof(columns)); + fx_parser_read_unstructured(parser, &rows, offset + 24, sizeof(rows)); + vkd3d_string_buffer_printf(&parser->buffer, "%u", columns); + } + else if (class == D3DXPC_MATRIX_ROWS || class == D3DXPC_MATRIX_COLUMNS) + { + fx_parser_read_unstructured(parser, &rows, offset + 20, sizeof(rows)); + fx_parser_read_unstructured(parser, &columns, offset + 24, sizeof(columns)); + vkd3d_string_buffer_printf(&parser->buffer, "%ux%u", rows, columns); + } +} + +static void parse_fx_2_object_value(struct fx_parser *parser, uint32_t element_count, + uint32_t type, uint32_t offset) +{ + uint32_t id; + + element_count = max(element_count, 1); + + for (uint32_t i = 0; i < element_count; ++i, offset += 4) + { + fx_parser_read_unstructured(parser, &id, offset, sizeof(id)); + vkd3d_string_buffer_printf(&parser->buffer, "<object id %u>", id); + if (element_count > 1) + vkd3d_string_buffer_printf(&parser->buffer, ", "); + if (id < parser->objects.count) + parser->objects.types[id] = type; + else + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Initializer object id exceeds the number of objects in the effect."); + } + + +} + +static void parse_fx_2_numeric_value(struct fx_parser *parser, uint32_t offset, + unsigned int size, uint32_t base_type) +{ + unsigned int i, comp_count; + + comp_count = size / sizeof(uint32_t); + if (comp_count > 1) + vkd3d_string_buffer_printf(&parser->buffer, "{"); + for (i = 0; i < comp_count; ++i) + { + union hlsl_constant_value_component value; + + fx_parser_read_unstructured(parser, &value, offset, sizeof(uint32_t)); + + if (base_type == D3DXPT_INT) + vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i); + else if (base_type == D3DXPT_BOOL) + vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false" ); + else + vkd3d_string_buffer_print_f32(&parser->buffer, value.f); + + if (i < comp_count - 1) + vkd3d_string_buffer_printf(&parser->buffer, ", "); + + offset += sizeof(uint32_t); + } + if (comp_count > 1) + vkd3d_string_buffer_printf(&parser->buffer, "}"); +} + +static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset) +{ + struct fx_2_var + { + uint32_t type; + uint32_t class; + uint32_t name; + uint32_t semantic; + uint32_t element_count; + } var; + const char *name; + uint32_t size; + + fx_parser_read_unstructured(parser, &var, offset, sizeof(var)); + + fx_parse_fx_2_type(parser, offset); + + name = fx_2_get_string(parser, var.name, &size); + fx_print_string(&parser->buffer, " ", name, size); + if (var.element_count) + vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count); +} + +static bool is_fx_2_sampler(uint32_t type) +{ + return type == D3DXPT_SAMPLER + || type == D3DXPT_SAMPLER1D + || type == D3DXPT_SAMPLER2D + || type == D3DXPT_SAMPLER3D + || type == D3DXPT_SAMPLERCUBE; +} + +static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry); + +static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, + uint32_t offset) +{ + struct fx_assignment entry; + uint32_t count; + + element_count = max(element_count, 1); + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + for (uint32_t i = 0; i < element_count; ++i) + { + fx_parser_read_unstructured(parser, &count, offset, sizeof(count)); + offset += sizeof(count); + + parse_fx_start_indent(parser); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "{\n"); + parse_fx_start_indent(parser); + for (uint32_t j = 0; j < count; ++j, offset += sizeof(entry)) + { + fx_parser_read_unstructured(parser, &entry, offset, sizeof(entry)); + + parse_fx_print_indent(parser); + fx_parse_fx_2_assignment(parser, &entry); + } + parse_fx_end_indent(parser); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "},\n"); + parse_fx_end_indent(parser); + } +} + +static void fx_parse_fx_2_initial_value(struct fx_parser *parser, uint32_t param, uint32_t value) +{ + struct fx_2_var + { + uint32_t type; + uint32_t class; + uint32_t name; + uint32_t semantic; + uint32_t element_count; + } var; + unsigned int size; + uint32_t offset; + + if (!value) + return; + + fx_parser_read_unstructured(parser, &var, param, sizeof(var)); + + offset = param; + size = fx_get_fx_2_type_size(parser, &offset); + + vkd3d_string_buffer_printf(&parser->buffer, " = "); + if (var.element_count) + vkd3d_string_buffer_printf(&parser->buffer, "{ "); + + if (var.class == D3DXPC_OBJECT) + { + if (is_fx_2_sampler(var.type)) + parse_fx_2_sampler(parser, var.element_count, value); + else + parse_fx_2_object_value(parser, var.element_count, var.type, value); + } + else + { + parse_fx_2_numeric_value(parser, value, size, var.type); + } + + if (var.element_count) + vkd3d_string_buffer_printf(&parser->buffer, " }"); +} + +static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count) +{ + uint32_t param, value; + + if (parser->failed || !count) + return; + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "<\n"); + parse_fx_start_indent(parser); + + for (uint32_t i = 0; i < count; ++i) + { + param = fx_parser_read_u32(parser); + value = fx_parser_read_u32(parser); + + parse_fx_print_indent(parser); + fx_parse_fx_2_parameter(parser, param); + fx_parse_fx_2_initial_value(parser, param, value); + vkd3d_string_buffer_printf(&parser->buffer, ";\n"); + } + + parse_fx_end_indent(parser); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, ">"); +} + +static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry) +{ + const struct rhs_named_value *named_value = NULL; + const struct fx_2_state *state = NULL; + + if (entry->id <= ARRAY_SIZE(fx_2_states)) + { + state = &fx_2_states[entry->id]; + + vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name); + if (state->array_size > 1) + vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index); + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "<unrecognized state %u>", entry->id); + } + vkd3d_string_buffer_printf(&parser->buffer, " = "); + + if (state && state->type == FX_UINT) + { + const struct rhs_named_value *ptr = state->values; + uint32_t value; + + fx_parser_read_unstructured(parser, &value, entry->value, sizeof(value)); + + while (ptr->name) + { + if (value == ptr->value) + { + named_value = ptr; + break; + } + ++ptr; + } + } + + if (named_value) + { + vkd3d_string_buffer_printf(&parser->buffer, "%s /* %u */", named_value->name, named_value->value); + } + else if (state) + { + if (state->type == FX_UINT || state->type == FX_FLOAT) + { + uint32_t offset = entry->type; + unsigned int size; + + size = fx_get_fx_2_type_size(parser, &offset); + parse_fx_2_numeric_value(parser, entry->value, size, entry->type); + } + else if (state->type == FX_VERTEXSHADER || state->type == FX_PIXELSHADER) + { + uint32_t id; + + fx_parser_read_unstructured(parser, &id, entry->value, sizeof(id)); + vkd3d_string_buffer_printf(&parser->buffer, "<object id %u>", id); + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "<ignored>"); + } + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "<ignored>"); + } + vkd3d_string_buffer_printf(&parser->buffer, ";\n"); +} + +static void fx_parse_fx_2_technique(struct fx_parser *parser) +{ + struct fx_technique + { + uint32_t name; + uint32_t annotation_count; + uint32_t pass_count; + } technique; + struct fx_pass + { + uint32_t name; + uint32_t annotation_count; + uint32_t assignment_count; + } pass; + const char *name; + uint32_t size; + + if (parser->failed) + return; + + fx_parser_read_u32s(parser, &technique, sizeof(technique)); + + name = fx_2_get_string(parser, technique.name, &size); + + parse_fx_print_indent(parser); + fx_print_string(&parser->buffer, "technique ", name, size); + fx_parse_fx_2_annotations(parser, technique.annotation_count); + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "{\n"); + + parse_fx_start_indent(parser); + for (uint32_t i = 0; i < technique.pass_count; ++i) + { + fx_parser_read_u32s(parser, &pass, sizeof(pass)); + name = fx_2_get_string(parser, pass.name, &size); + + parse_fx_print_indent(parser); + fx_print_string(&parser->buffer, "pass ", name, size); + fx_parse_fx_2_annotations(parser, pass.annotation_count); + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "{\n"); + + parse_fx_start_indent(parser); + for (uint32_t j = 0; j < pass.assignment_count; ++j) + { + struct fx_assignment entry; + + parse_fx_print_indent(parser); + fx_parser_read_u32s(parser, &entry, sizeof(entry)); + fx_parse_fx_2_assignment(parser, &entry); + } + parse_fx_end_indent(parser); + + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "}\n\n"); + } + + parse_fx_end_indent(parser); + + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "}\n\n"); +} + +static void fx_2_parse_parameters(struct fx_parser *parser, uint32_t count) +{ + struct fx_2_parameter + { + uint32_t type; + uint32_t value; + uint32_t flags; + uint32_t annotation_count; + } param; + + for (uint32_t i = 0; i < count; ++i) + { + fx_parser_read_u32s(parser, ¶m, sizeof(param)); + + fx_parse_fx_2_parameter(parser, param.type); + fx_parse_fx_2_annotations(parser, param.annotation_count); + fx_parse_fx_2_initial_value(parser, param.type, param.value); + vkd3d_string_buffer_printf(&parser->buffer, ";\n"); + } + if (count) + vkd3d_string_buffer_printf(&parser->buffer, "\n"); +} + +static void fx_parse_shader_blob(struct fx_parser *parser, enum vkd3d_shader_source_type source_type, + const void *data, uint32_t data_size) +{ + struct vkd3d_shader_compile_info info = { 0 }; + struct vkd3d_shader_code output; + const char *p, *q, *end; + int ret; + + static const struct vkd3d_shader_compile_option options[] = + { + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, + }; + + info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; + info.source.code = data; + info.source.size = data_size; + info.source_type = source_type; + info.target_type = VKD3D_SHADER_TARGET_D3D_ASM; + info.options = options; + info.option_count = ARRAY_SIZE(options); + info.log_level = VKD3D_SHADER_LOG_INFO; + + if ((ret = vkd3d_shader_compile(&info, &output, NULL)) < 0) + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Failed to disassemble shader blob."); + return; + } + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "asm {\n"); + + parse_fx_start_indent(parser); + + end = (const char *)output.code + output.size; + for (p = output.code; p < end; p = q) + { + if (!(q = memchr(p, '\n', end - p))) + q = end; + else + ++q; + + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "%.*s", (int)(q - p), p); + } + + parse_fx_end_indent(parser); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "}"); + + vkd3d_shader_free_shader_code(&output); +} + +static void fx_parse_fx_2_data_blob(struct fx_parser *parser) +{ + uint32_t id, size; + const void *data; + + id = fx_parser_read_u32(parser); + size = fx_parser_read_u32(parser); + + parse_fx_print_indent(parser); + if (id < parser->objects.count) + { + uint32_t type = parser->objects.types[id]; + switch (type) + { + case D3DXPT_STRING: + case D3DXPT_TEXTURE: + case D3DXPT_TEXTURE1D: + case D3DXPT_TEXTURE2D: + case D3DXPT_TEXTURE3D: + case D3DXPT_TEXTURECUBE: + case D3DXPT_PIXELSHADER: + case D3DXPT_VERTEXSHADER: + vkd3d_string_buffer_printf(&parser->buffer, "%s object %u size %u bytes%s\n", + fx_2_types[type], id, size, size ? ":" : ","); + + if (size) + { + data = fx_parser_get_ptr(parser, size); + + if (type == D3DXPT_STRING) + { + parse_fx_start_indent(parser); + parse_fx_print_indent(parser); + fx_print_string(&parser->buffer, """, (const char *)data, size); + vkd3d_string_buffer_printf(&parser->buffer, """); + parse_fx_end_indent(parser); + } + else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER) + { + fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_D3D_BYTECODE, data, size); + } + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + } + break; + default: + vkd3d_string_buffer_printf(&parser->buffer, "<type%u> object %u size %u bytes\n", type, id, size); + } + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "object %u - out-of-range id\n", id); + } + + fx_parser_skip(parser, align(size, 4)); +} + +static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t size) +{ + const uint32_t *data = blob; + unsigned int i, j, n; + + size /= sizeof(*data); + i = 0; + while (i < size) + { + parse_fx_print_indent(parser); + n = min(size - i, 8); + for (j = 0; j < n; ++j) + vkd3d_string_buffer_printf(&parser->buffer, "0x%08x,", data[i + j]); + i += n; + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + } +} + +static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size) +{ + const uint8_t *end = parser->ptr + size; + uint32_t name_size, blob_size = 0; + const void *blob = NULL; + const char *name; + + name_size = fx_parser_read_u32(parser); + name = fx_parser_get_ptr(parser, name_size); + fx_parser_skip(parser, name_size); + + if (!name || (uint8_t *)name >= end) + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Malformed name entry in the array selector."); + + if (parser->ptr <= end) + { + blob_size = end - parser->ptr; + blob = fx_parser_get_ptr(parser, blob_size); + fx_parser_skip(parser, blob_size); + } + else + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Malformed blob entry in the array selector."); + } + + if (name) + { + fx_print_string(&parser->buffer, "array "", name, name_size); + vkd3d_string_buffer_printf(&parser->buffer, ""\n"); + } + if (blob) + { + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "selector blob size %u\n", blob_size); + fx_dump_blob(parser, blob, blob_size); + } +} + +static void fx_parse_fx_2_complex_state(struct fx_parser *parser) +{ + struct + { + uint32_t technique; + uint32_t index; + uint32_t element; + uint32_t state; + uint32_t assignment_type; + } state; + const char *data; + uint32_t size; + + fx_parser_read_u32s(parser, &state, sizeof(state)); + + if (state.technique == ~0u) + { + vkd3d_string_buffer_printf(&parser->buffer, "parameter %u[%u], state %u =\n", + state.index, state.element, state.state); + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "technique %u, pass %u, state %u =\n", + state.technique, state.index, state.state); + } + + size = fx_parser_read_u32(parser); + + parse_fx_print_indent(parser); + + if (state.assignment_type == FX_2_ASSIGNMENT_PARAMETER) + { + data = fx_parser_get_ptr(parser, size); + fx_print_string(&parser->buffer, "parameter "", data, size); + vkd3d_string_buffer_printf(&parser->buffer, ""\n"); + fx_parser_skip(parser, align(size, 4)); + } + else if (state.assignment_type == FX_2_ASSIGNMENT_ARRAY_SELECTOR) + { + fx_parse_fx_2_array_selector(parser, size); + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); + data = fx_parser_get_ptr(parser, size); + fx_dump_blob(parser, data, size); + fx_parser_skip(parser, align(size, 4)); + } +} + +static void fx_2_parse(struct fx_parser *parser) +{ + uint32_t i, size, parameter_count, technique_count, blob_count, state_count; + + fx_parser_skip(parser, sizeof(uint32_t)); /* Version */ + size = fx_parser_read_u32(parser); + + parser->unstructured.ptr = parser->ptr; + parser->unstructured.end = parser->ptr + size; + parser->unstructured.size = size; + fx_parser_skip(parser, size); + + parameter_count = fx_parser_read_u32(parser); + technique_count = fx_parser_read_u32(parser); + fx_parser_read_u32(parser); /* Shader count */ + parser->objects.count = fx_parser_read_u32(parser); + + if (!(parser->objects.types = calloc(parser->objects.count, sizeof(*parser->objects.types)))) + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_OUT_OF_MEMORY, "Out of memory."); + return; + } + + fx_2_parse_parameters(parser, parameter_count); + for (i = 0; i < technique_count; ++i) + fx_parse_fx_2_technique(parser); + + blob_count = fx_parser_read_u32(parser); + state_count = fx_parser_read_u32(parser); + + vkd3d_string_buffer_printf(&parser->buffer, "object data {\n"); + parse_fx_start_indent(parser); + for (i = 0; i < blob_count; ++i) + fx_parse_fx_2_data_blob(parser); + parse_fx_end_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "}\n\n"); + + vkd3d_string_buffer_printf(&parser->buffer, "state data {\n"); + parse_fx_start_indent(parser); + for (i = 0; i < state_count; ++i) + fx_parse_fx_2_complex_state(parser); + parse_fx_end_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "}\n"); +} + +static const char *fx_4_get_string(struct fx_parser *parser, uint32_t offset) +{ + const uint8_t *ptr = parser->unstructured.ptr; + const uint8_t *end = parser->unstructured.end;
if (offset >= parser->unstructured.size) { @@ -3022,21 +4313,6 @@ static const char *fx_4_get_string(struct fx_parser *parser, uint32_t offset) return (const char *)(parser->unstructured.ptr + offset); }
-static void parse_fx_start_indent(struct fx_parser *parser) -{ - ++parser->indent; -} - -static void parse_fx_end_indent(struct fx_parser *parser) -{ - --parser->indent; -} - -static void parse_fx_print_indent(struct fx_parser *parser) -{ - vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); -} - static void parse_fx_4_numeric_value(struct fx_parser *parser, uint32_t offset, const struct fx_4_binary_type *type) { @@ -3053,7 +4329,7 @@ static void parse_fx_4_numeric_value(struct fx_parser *parser, uint32_t offset, fx_parser_read_unstructured(parser, &value, offset, sizeof(uint32_t));
if (base_type == FX_4_NUMERIC_TYPE_FLOAT) - vkd3d_string_buffer_printf(&parser->buffer, "%f", value.f); + vkd3d_string_buffer_print_f32(&parser->buffer, value.f); else if (base_type == FX_4_NUMERIC_TYPE_INT) vkd3d_string_buffer_printf(&parser->buffer, "%d", value.i); else if (base_type == FX_4_NUMERIC_TYPE_UINT) @@ -3228,17 +4504,15 @@ static void fx_parse_buffers(struct fx_parser *parser)
static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object_type, const struct fx_5_shader *shader) { - struct vkd3d_shader_compile_info info = { 0 }; - struct vkd3d_shader_code output; const void *data = NULL; - const char *p, *q, *end; uint32_t data_size; - int ret;
- static const struct vkd3d_shader_compile_option options[] = + if (!shader->offset) { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_15}, - }; + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "NULL"); + return; + }
fx_parser_read_unstructured(parser, &data_size, shader->offset, sizeof(data_size)); if (data_size) @@ -3247,42 +4521,8 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object if (!data) return;
- info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; - info.source.code = data; - info.source.size = data_size; - info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; - info.target_type = VKD3D_SHADER_TARGET_D3D_ASM; - info.options = options; - info.option_count = ARRAY_SIZE(options); - info.log_level = VKD3D_SHADER_LOG_INFO; - - if ((ret = vkd3d_shader_compile(&info, &output, NULL)) < 0) - { - fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, - "Failed to disassemble shader blob."); - return; - } - parse_fx_print_indent(parser); - vkd3d_string_buffer_printf(&parser->buffer, "asm {\n"); - - parse_fx_start_indent(parser); - - end = (const char *)output.code + output.size; - for (p = output.code; p < end; p = q) - { - if (!(q = memchr(p, '\n', end - p))) - q = end; - else - ++q; - - parse_fx_print_indent(parser); - vkd3d_string_buffer_printf(&parser->buffer, "%.*s", (int)(q - p), p); - } - - parse_fx_end_indent(parser); + fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_DXBC_TPF, data, data_size);
- parse_fx_print_indent(parser); - vkd3d_string_buffer_printf(&parser->buffer, "}"); if (object_type == FX_4_OBJECT_TYPE_GEOMETRY_SHADER_SO && shader->sodecl[0]) { vkd3d_string_buffer_printf(&parser->buffer, "\n/* Stream output declaration: "%s" */", @@ -3299,8 +4539,6 @@ static void fx_4_parse_shader_blob(struct fx_parser *parser, unsigned int object if (shader->sodecl_count) vkd3d_string_buffer_printf(&parser->buffer, "\n/* Rasterized stream %u */", shader->rast_stream); } - - vkd3d_shader_free_shader_code(&output); }
static void fx_4_parse_shader_initializer(struct fx_parser *parser, unsigned int object_type) @@ -3366,16 +4604,298 @@ static int fx_4_state_id_compare(const void *a, const void *b) return id - state->id; }
+static const struct +{ + uint32_t opcode; + const char *name; +} +fx_4_fxlc_opcodes[] = +{ + { 0x100, "mov" }, + { 0x101, "neg" }, + { 0x103, "rcp" }, + { 0x104, "frc" }, + { 0x105, "exp" }, + { 0x106, "log" }, + { 0x107, "rsq" }, + { 0x108, "sin" }, + { 0x109, "cos" }, + { 0x10a, "asin" }, + { 0x10b, "acos" }, + { 0x10c, "atan" }, + { 0x112, "sqrt" }, + { 0x120, "ineg" }, + { 0x121, "not" }, + { 0x130, "itof" }, + { 0x131, "utof" }, + { 0x133, "ftou" }, + { 0x137, "ftob" }, + { 0x139, "floor" }, + { 0x13a, "ceil" }, + { 0x200, "min" }, + { 0x201, "max" }, + { 0x204, "add" }, + { 0x205, "mul" }, + { 0x206, "atan2" }, + { 0x208, "div" }, + { 0x210, "bilt" }, + { 0x211, "bige" }, + { 0x212, "bieq" }, + { 0x213, "bine" }, + { 0x214, "buge" }, + { 0x215, "bult" }, + { 0x216, "iadd" }, + { 0x219, "imul" }, + { 0x21a, "udiv" }, + { 0x21d, "imin" }, + { 0x21e, "imax" }, + { 0x21f, "umin" }, + { 0x220, "umax" }, + { 0x230, "and" }, + { 0x231, "or" }, + { 0x233, "xor" }, + { 0x234, "ishl" }, + { 0x235, "ishr" }, + { 0x236, "ushr" }, + { 0x301, "movc" }, + { 0x500, "dot" }, + { 0x70e, "d3ds_dotswiz" }, +}; + +static const char *fx_4_get_fxlc_opcode_name(uint32_t opcode) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(fx_4_fxlc_opcodes); ++i) + { + if (fx_4_fxlc_opcodes[i].opcode == opcode) + return fx_4_fxlc_opcodes[i].name; + } + + return "<unrecognized>"; +} + +struct fx_4_fxlc_argument +{ + uint32_t flags; + uint32_t reg_type; + uint32_t address; +}; + +struct fx_4_ctab_entry +{ + uint32_t name; + uint16_t register_set; + uint16_t register_index; + uint16_t register_count; + uint16_t reserved; + uint32_t typeinfo; + uint32_t default_value; +}; + +struct fxlvm_code +{ + const float *cli4; + uint32_t cli4_count; + + const struct fx_4_ctab_entry *constants; + uint32_t ctab_offset; + uint32_t ctab_count; + const char *ctab; + + unsigned int comp_count; + bool scalar; +}; + +static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) +{ + unsigned int comp_count = code->scalar ? 1 : code->comp_count; + static const char comp[] = "xyzw"; + + if (comp_count < 4) + vkd3d_string_buffer_printf(&parser->buffer, ".%.*s", comp_count, &comp[addr % 4]); +} + +static void fx_4_parse_fxlc_constant_argument(struct fx_parser *parser, + const struct fx_4_fxlc_argument *arg, const struct fxlvm_code *code) +{ + uint32_t i, offset, register_index = arg->address / 4; /* Address counts in components. */ + + for (i = 0; i < code->ctab_count; ++i) + { + const struct fx_4_ctab_entry *c = &code->constants[i]; + + if (register_index < c->register_index || register_index - c->register_index >= c->register_count) + continue; + + vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); + + /* Register offset within variable */ + offset = arg->address - c->register_index * 4; + + if (offset / 4) + vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); + fx_4_parse_print_swizzle(parser, code, offset); + return; + } + + vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); +} + +static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, const struct fxlvm_code *code) +{ + struct fx_4_fxlc_argument arg; + uint32_t count; + + fx_parser_read_unstructured(parser, &arg, offset, sizeof(arg)); + + switch (arg.reg_type) + { + case FX_4_FXLC_REG_LITERAL: + count = code->scalar ? 1 : code->comp_count; + if (arg.address >= code->cli4_count || count > code->cli4_count - arg.address) + { + vkd3d_string_buffer_printf(&parser->buffer, "(<out-of-bounds>)"); + parser->failed = true; + break; + } + + vkd3d_string_buffer_printf(&parser->buffer, "("); + vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address]); + for (unsigned int i = 1; i < code->comp_count; ++i) + { + vkd3d_string_buffer_printf(&parser->buffer, ", "); + vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address + (code->scalar ? 0 : i)]); + } + vkd3d_string_buffer_printf(&parser->buffer, ")"); + break; + + case FX_4_FXLC_REG_CB: + fx_4_parse_fxlc_constant_argument(parser, &arg, code); + break; + + case FX_4_FXLC_REG_OUTPUT: + case FX_4_FXLC_REG_TEMP: + if (arg.reg_type == FX_4_FXLC_REG_OUTPUT) + vkd3d_string_buffer_printf(&parser->buffer, "expr"); + else + vkd3d_string_buffer_printf(&parser->buffer, "r%u", arg.address / 4); + fx_4_parse_print_swizzle(parser, code, arg.address); + break; + + default: + vkd3d_string_buffer_printf(&parser->buffer, "<unknown register %u>", arg.reg_type); + break; + } +} + +static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offset) +{ + struct vkd3d_shader_dxbc_section_desc *section, fxlc, cli4, ctab; + struct vkd3d_shader_dxbc_desc dxbc_desc; + struct vkd3d_shader_code dxbc; + uint32_t size, ins_count; + struct fxlvm_code code; + size_t i, j; + + offset = fx_parser_read_unstructured(parser, &size, offset, sizeof(size)); + + dxbc.size = size; + dxbc.code = fx_parser_get_unstructured_ptr(parser, offset, size); + if (!dxbc.code) + return; + + if (vkd3d_shader_parse_dxbc(&dxbc, 0, &dxbc_desc, NULL) < 0) + { + parser->failed = true; + return; + } + + memset(&fxlc, 0, sizeof(fxlc)); + memset(&cli4, 0, sizeof(cli4)); + memset(&ctab, 0, sizeof(ctab)); + for (i = 0; i < dxbc_desc.section_count; ++i) + { + section = &dxbc_desc.sections[i]; + + if (section->tag == TAG_FXLC) + fxlc = *section; + else if (section->tag == TAG_CLI4) + cli4 = *section; + else if (section->tag == TAG_CTAB) + ctab = *section; + } + + vkd3d_shader_free_dxbc(&dxbc_desc); + + if (cli4.data.code) + { + uint32_t cli4_offset = offset + (size_t)cli4.data.code - (size_t)dxbc.code; + + fx_parser_read_unstructured(parser, &code.cli4_count, cli4_offset, sizeof(code.cli4_count)); + code.cli4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli4_count * sizeof(float)); + } + + if (ctab.data.code) + { + uint32_t ctab_offset = offset + (size_t)ctab.data.code - (size_t)dxbc.code; + uint32_t consts_offset; + + fx_parser_read_unstructured(parser, &code.ctab_count, ctab_offset + 12, sizeof(code.ctab_count)); + fx_parser_read_unstructured(parser, &consts_offset, ctab_offset + 16, sizeof(consts_offset)); + + code.ctab = ctab.data.code; + code.constants = fx_parser_get_unstructured_ptr(parser, + ctab_offset + consts_offset, code.ctab_count * sizeof(*code.constants)); + } + + offset += (size_t)fxlc.data.code - (size_t)dxbc.code; + offset = fx_parser_read_unstructured(parser, &ins_count, offset, sizeof(ins_count)); + + parse_fx_start_indent(parser); + + for (i = 0; i < ins_count; ++i) + { + uint32_t instr, opcode, src_count; + struct fx_4_fxlc_argument arg; + + offset = fx_parser_read_unstructured(parser, &instr, offset, sizeof(instr)); + offset = fx_parser_read_unstructured(parser, &src_count, offset, sizeof(src_count)); + + opcode = (instr >> FX_4_FXLC_OPCODE_SHIFT) & FX_4_FXLC_OPCODE_MASK; + code.comp_count = instr & FX_4_FXLC_COMP_COUNT_MASK; + code.scalar = false; + + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "%s ", fx_4_get_fxlc_opcode_name(opcode)); + + /* Destination first. */ + fx_4_parse_fxlc_argument(parser, offset + sizeof(arg) * src_count, &code); + + for (j = 0; j < src_count; ++j) + { + vkd3d_string_buffer_printf(&parser->buffer, ", "); + + /* Scalar modifier applies only to first source. */ + code.scalar = j == 0 && !!(instr & FX_4_FXLC_IS_SCALAR_MASK); + fx_4_parse_fxlc_argument(parser, offset, &code); + + offset += sizeof(arg); + } + + /* Destination */ + offset += sizeof(arg); + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + } + + parse_fx_end_indent(parser); +} + static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32_t count, enum hlsl_type_class type_class) { - struct fx_4_assignment - { - uint32_t id; - uint32_t lhs_index; - uint32_t type; - uint32_t value; - } entry; + struct fx_assignment entry; struct { uint32_t name; @@ -3390,7 +4910,7 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 float f; }; } value; - static const char *value_types[FX_COMPONENT_TYPE_COUNT] = + static const char *const value_types[FX_COMPONENT_TYPE_COUNT] = { [FX_BOOL] = "bool", [FX_FLOAT] = "float", @@ -3399,16 +4919,18 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 }; const struct rhs_named_value *named_value; struct fx_5_shader shader = { 0 }; + struct fx_4_state_table table; unsigned int shader_type = 0; uint32_t i, j, comp_count; struct fx_4_state *state;
+ table = fx_4_get_state_table(type_class, parser->version.major, parser->version.minor); + for (i = 0; i < count; ++i) { fx_parser_read_u32s(parser, &entry, sizeof(entry));
- if (!(state = bsearch(&entry.id, fx_4_states, ARRAY_SIZE(fx_4_states), - sizeof(*fx_4_states), fx_4_state_id_compare))) + if (!(state = bsearch(&entry.id, table.ptr, table.count, sizeof(*table.ptr), fx_4_state_id_compare))) { fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Unrecognized state id %#x.", entry.id); break; @@ -3496,6 +5018,19 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 vkd3d_string_buffer_printf(&parser->buffer, "%s[%s]", fx_4_get_string(parser, index.name), fx_4_get_string(parser, index.index)); break; + case FX_4_ASSIGNMENT_INDEX_EXPRESSION: + fx_parser_read_unstructured(parser, &index, entry.value, sizeof(index)); + vkd3d_string_buffer_printf(&parser->buffer, "%s[eval(\n", fx_4_get_string(parser, index.name)); + fx_4_parse_fxlvm_expression(parser, index.index); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, ")]"); + break; + case FX_4_ASSIGNMENT_VALUE_EXPRESSION: + vkd3d_string_buffer_printf(&parser->buffer, "eval(\n"); + fx_4_parse_fxlvm_expression(parser, entry.value); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, ")"); + break; case FX_4_ASSIGNMENT_INLINE_SHADER: case FX_5_ASSIGNMENT_INLINE_SHADER: { @@ -3544,12 +5079,14 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct }; unsigned int i, element_count, count; uint32_t value; + bool is_array;
if (!fx_4_object_has_initializer(type)) return;
vkd3d_string_buffer_printf(&parser->buffer, " = {\n"); element_count = max(type->element_count, 1); + is_array = element_count > 1; for (i = 0; i < element_count; ++i) { switch (type->typeinfo) @@ -3565,9 +5102,21 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct case FX_4_OBJECT_TYPE_SAMPLER_STATE: count = fx_parser_read_u32(parser);
+ if (is_array) + { + parse_fx_start_indent(parser); + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "{\n"); + } parse_fx_start_indent(parser); fx_4_parse_state_object_initializer(parser, count, type_classes[type->typeinfo]); parse_fx_end_indent(parser); + if (is_array) + { + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "}"); + parse_fx_end_indent(parser); + } break; case FX_4_OBJECT_TYPE_PIXEL_SHADER: case FX_4_OBJECT_TYPE_VERTEX_SHADER: @@ -3586,7 +5135,7 @@ static void fx_4_parse_object_initializer(struct fx_parser *parser, const struct "Parsing object type %u is not implemented.", type->typeinfo); return; } - vkd3d_string_buffer_printf(&parser->buffer, ",\n"); + vkd3d_string_buffer_printf(&parser->buffer, is_array ? ",\n" : "\n"); } vkd3d_string_buffer_printf(&parser->buffer, "}"); } @@ -3651,7 +5200,7 @@ static void fx_parse_fx_4_technique(struct fx_parser *parser) name = fx_4_get_string(parser, technique.name);
parse_fx_print_indent(parser); - vkd3d_string_buffer_printf(&parser->buffer, "technique%u %s", parser->version, name); + vkd3d_string_buffer_printf(&parser->buffer, "technique%u %s", parser->version.major == 4 ? 10 : 11, name); fx_parse_fx_4_annotations(parser);
vkd3d_string_buffer_printf(&parser->buffer, "\n"); @@ -3719,7 +5268,7 @@ static void fx_parse_groups(struct fx_parser *parser) } }
-static int fx_4_parse(struct fx_parser *parser) +static void fx_4_parse(struct fx_parser *parser) { struct fx_4_header { @@ -3745,15 +5294,15 @@ static int fx_4_parse(struct fx_parser *parser) } header; uint32_t i;
- parser->version = 10; fx_parser_read_u32s(parser, &header, sizeof(header)); parser->buffer_count = header.buffer_count; parser->object_count = header.object_count;
if (parser->end - parser->ptr < header.unstructured_size) { - parser->failed = true; - return -1; + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_SIZE, + "Invalid unstructured data size %u.", header.unstructured_size); + return; }
parser->unstructured.ptr = parser->ptr; @@ -3766,11 +5315,9 @@ static int fx_4_parse(struct fx_parser *parser)
for (i = 0; i < header.technique_count; ++i) fx_parse_fx_4_technique(parser); - - return parser->failed ? - 1 : 0; }
-static int fx_5_parse(struct fx_parser *parser) +static void fx_5_parse(struct fx_parser *parser) { struct fx_5_header { @@ -3800,7 +5347,6 @@ static int fx_5_parse(struct fx_parser *parser) uint32_t class_instance_element_count; } header;
- parser->version = 11; fx_parser_read_u32s(parser, &header, sizeof(header)); parser->buffer_count = header.buffer_count; parser->object_count = header.object_count; @@ -3808,8 +5354,9 @@ static int fx_5_parse(struct fx_parser *parser)
if (parser->end - parser->ptr < header.unstructured_size) { - parser->failed = true; - return -1; + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_SIZE, + "Invalid unstructured data size %u.", header.unstructured_size); + return; }
parser->unstructured.ptr = parser->ptr; @@ -3821,48 +5368,69 @@ static int fx_5_parse(struct fx_parser *parser) fx_4_parse_objects(parser);
fx_parse_groups(parser); +}
- return parser->failed ? - 1 : 0; +static void fx_parser_init(struct fx_parser *parser, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context) +{ + memset(parser, 0, sizeof(*parser)); + parser->start = compile_info->source.code; + parser->ptr = compile_info->source.code; + parser->end = (uint8_t *)compile_info->source.code + compile_info->source.size; + parser->message_context = message_context; + vkd3d_string_buffer_init(&parser->buffer); +} + +static void fx_parser_cleanup(struct fx_parser *parser) +{ + free(parser->objects.types); }
int fx_parse(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { - struct fx_parser parser = - { - .start = compile_info->source.code, - .ptr = compile_info->source.code, - .end = (uint8_t *)compile_info->source.code + compile_info->source.size, - .message_context = message_context, - }; + struct fx_parser parser; uint32_t version; - int ret;
- vkd3d_string_buffer_init(&parser.buffer); + fx_parser_init(&parser, compile_info, message_context);
if (parser.end - parser.start < sizeof(version)) - return -1; + { + fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_SIZE, + "Source size %zu is smaller than the FX header size.", compile_info->source.size); + return VKD3D_ERROR_INVALID_SHADER; + } version = *(uint32_t *)parser.ptr;
switch (version) { case 0xfeff0901: - ret = fx_2_parse(&parser); + parser.version.major = 3; + fx_2_parse(&parser); break; case 0xfeff1001: + parser.version.major = 4; + fx_4_parse(&parser); + break; case 0xfeff1011: - ret = fx_4_parse(&parser); + parser.version.major = 4; + parser.version.minor = 1; + fx_4_parse(&parser); break; case 0xfeff2001: - ret = fx_5_parse(&parser); + parser.version.major = 5; + fx_5_parse(&parser); break; default: fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_VERSION, "Invalid effect binary version value 0x%08x.", version); - ret = -1; + break; }
vkd3d_shader_code_from_string_buffer(out, &parser.buffer); + fx_parser_cleanup(&parser);
- return ret; + if (parser.failed) + return VKD3D_ERROR_INVALID_SHADER; + return VKD3D_OK; } diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index ab6604bd703..e4497b9ac5b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -64,7 +64,6 @@ struct vkd3d_glsl_generator
const struct vkd3d_shader_interface_info *interface_info; const struct vkd3d_shader_descriptor_offset_info *offset_info; - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info; const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; };
@@ -130,7 +129,7 @@ static const struct glsl_resource_type_info *shader_glsl_get_resource_type_info( static const struct vkd3d_shader_descriptor_info1 *shader_glsl_get_descriptor(struct vkd3d_glsl_generator *gen, enum vkd3d_shader_descriptor_type type, unsigned int idx, unsigned int space) { - const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; + const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors;
for (unsigned int i = 0; i < info->descriptor_count; ++i) { @@ -146,7 +145,7 @@ static const struct vkd3d_shader_descriptor_info1 *shader_glsl_get_descriptor(st static const struct vkd3d_shader_descriptor_info1 *shader_glsl_get_descriptor_by_id( struct vkd3d_glsl_generator *gen, enum vkd3d_shader_descriptor_type type, unsigned int id) { - const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; + const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors;
for (unsigned int i = 0; i < info->descriptor_count; ++i) { @@ -269,15 +268,15 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); break; } - if (reg->idx[0].rel_addr || reg->idx[2].rel_addr) + if (reg->idx[0].rel_addr) { vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled constant buffer register indirect addressing."); vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); break; } - vkd3d_string_buffer_printf(buffer, "%s_cb_%u[%u]", - gen->prefix, reg->idx[0].offset, reg->idx[2].offset); + vkd3d_string_buffer_printf(buffer, "%s_cb_%u", gen->prefix, reg->idx[0].offset); + shader_glsl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); break;
case VKD3DSPR_THREADID: @@ -485,8 +484,7 @@ static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, stru vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer); if (offset) vkd3d_string_buffer_printf(buffer, " + %u", offset); - else - vkd3d_string_buffer_printf(buffer, "]"); + vkd3d_string_buffer_printf(buffer, "]"); glsl_src_cleanup(&r, &gen->string_buffers); }
@@ -789,7 +787,6 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ unsigned int 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_component_type sampled_type; enum vkd3d_shader_resource_type resource_type; struct vkd3d_string_buffer *fetch; enum vkd3d_data_type data_type; @@ -812,8 +809,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ resource_type = d->resource_type; resource_space = d->register_space; sample_count = d->sample_count; - sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); - data_type = vkd3d_data_type_from_component_type(sampled_type); + data_type = d->resource_data_type; } else { @@ -905,7 +901,6 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk unsigned int resource_id, resource_idx, resource_space; unsigned int sampler_id, sampler_idx, sampler_space; const struct vkd3d_shader_descriptor_info1 *d; - enum vkd3d_shader_component_type sampled_type; enum vkd3d_shader_resource_type resource_type; unsigned int component_idx, coord_size; struct vkd3d_string_buffer *sample; @@ -935,8 +930,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk { resource_type = d->resource_type; resource_space = d->register_space; - sampled_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); - data_type = vkd3d_data_type_from_component_type(sampled_type); + data_type = d->resource_data_type; } else { @@ -1055,11 +1049,11 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct glsl_resource_type_info *resource_type_info; - enum vkd3d_shader_component_type component_type; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; unsigned int uav_id, uav_idx, uav_space; struct vkd3d_string_buffer *load; + enum vkd3d_data_type data_type; struct glsl_src coord; struct glsl_dst dst; uint32_t coord_mask; @@ -1074,7 +1068,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s { resource_type = d->resource_type; uav_space = d->register_space; - component_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); + data_type = d->resource_data_type; } else { @@ -1082,7 +1076,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); uav_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - component_type = VKD3D_SHADER_COMPONENT_FLOAT; + data_type = VKD3D_DATA_FLOAT; }
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -1105,8 +1099,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s vkd3d_string_buffer_printf(load, ", %s)", coord.str->buffer); shader_glsl_print_swizzle(load, ins->src[1].swizzle, ins->dst[0].write_mask);
- shader_glsl_print_assignment_ext(gen, &dst, - vkd3d_data_type_from_component_type(component_type), "%s", load->buffer); + shader_glsl_print_assignment_ext(gen, &dst, data_type, "%s", load->buffer);
vkd3d_string_buffer_release(&gen->string_buffers, load); glsl_src_cleanup(&coord, &gen->string_buffers); @@ -1116,11 +1109,11 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct glsl_resource_type_info *resource_type_info; - enum vkd3d_shader_component_type component_type; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; unsigned int uav_id, uav_idx, uav_space; struct vkd3d_string_buffer *image_data; + enum vkd3d_data_type data_type; struct glsl_src image_coord; uint32_t coord_mask;
@@ -1134,7 +1127,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const { resource_type = d->resource_type; uav_space = d->register_space; - component_type = vkd3d_component_type_from_resource_data_type(d->resource_data_type); + data_type = d->resource_data_type; } else { @@ -1142,7 +1135,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); uav_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - component_type = VKD3D_SHADER_COMPONENT_FLOAT; + data_type = VKD3D_DATA_FLOAT; }
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -1161,25 +1154,26 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const
if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) { - switch (component_type) + switch (data_type) { - case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_DATA_UINT: vkd3d_string_buffer_printf(image_data, "uvec4("); break; - case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_DATA_INT: vkd3d_string_buffer_printf(image_data, "ivec4("); break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled component type %#x.", component_type); + "Internal compiler error: Unhandled data type %#x.", data_type); /* fall through */ - case VKD3D_SHADER_COMPONENT_FLOAT: + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: vkd3d_string_buffer_printf(image_data, "vec4("); break; } } - shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, - vkd3d_data_type_from_component_type(component_type)); + shader_glsl_print_src(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, data_type); if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)");
@@ -1298,7 +1292,7 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled SV_POSITION index %u.", idx); if (version->type == VKD3D_SHADER_TYPE_PIXEL) - vkd3d_string_buffer_printf(buffer, "gl_FragCoord"); + vkd3d_string_buffer_printf(buffer, "vec4(gl_FragCoord.xyz, 1.0 / gl_FragCoord.w)"); else vkd3d_string_buffer_printf(buffer, "gl_Position"); break; @@ -1658,6 +1652,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VKD3DSIH_SWITCH: shader_glsl_switch(gen, ins); break; + case VKD3DSIH_XOR: + shader_glsl_binop(gen, ins, "^"); + break; default: shader_glsl_unhandled(gen, ins); break; @@ -1734,7 +1731,6 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge const struct vkd3d_shader_descriptor_binding *binding; const struct vkd3d_shader_descriptor_offset *offset; struct vkd3d_string_buffer *buffer = gen->buffer; - enum vkd3d_shader_component_type component_type; unsigned int binding_idx;
if (uav->count != 1) @@ -1791,22 +1787,24 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge image_type = "<unhandled image type>"; }
- switch ((component_type = vkd3d_component_type_from_resource_data_type(uav->resource_data_type))) + switch (uav->resource_data_type) { - case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_DATA_UINT: image_type_prefix = "u"; read_format = "r32ui"; break; - case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_DATA_INT: image_type_prefix = "i"; read_format = "r32i"; break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled component type %#x for UAV %u.", - component_type, uav->register_id); + "Internal compiler error: Unhandled data type %#x for UAV %u.", + uav->resource_data_type, uav->register_id); /* fall through */ - case VKD3D_SHADER_COMPONENT_FLOAT: + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: image_type_prefix = ""; read_format = "r32f"; break; @@ -1961,7 +1959,6 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator const struct glsl_resource_type_info *resource_type_info; const struct vkd3d_shader_descriptor_binding *binding; struct vkd3d_string_buffer *buffer = gen->buffer; - enum vkd3d_shader_component_type component_type; const char *sampler_type, *sampler_type_prefix; enum vkd3d_shader_resource_type resource_type; unsigned int binding_idx; @@ -2019,21 +2016,23 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator sampler_type = "<unhandled sampler type>"; }
- switch ((component_type = vkd3d_component_type_from_resource_data_type(srv->resource_data_type))) + switch (srv->resource_data_type) { - case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_DATA_UINT: sampler_type_prefix = "u"; break; - case VKD3D_SHADER_COMPONENT_INT: + case VKD3D_DATA_INT: sampler_type_prefix = "i"; break; - case VKD3D_SHADER_COMPONENT_FLOAT: + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: sampler_type_prefix = ""; break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled component type %#x for combined resource/sampler " - "for resource %u, space %u and sampler %u, space %u.", component_type, + "Internal compiler error: Unhandled data type %#x for combined resource/sampler " + "for resource %u, space %u and sampler %u, space %u.", srv->resource_data_type, crs->resource_index, crs->resource_space, crs->sampler_index, crs->sampler_space); sampler_type_prefix = ""; break; @@ -2078,7 +2077,7 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator static void shader_glsl_generate_descriptor_declarations(struct vkd3d_glsl_generator *gen) { const struct vkd3d_shader_scan_combined_resource_sampler_info *sampler_info = gen->combined_sampler_info; - const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; + const struct vkd3d_shader_scan_descriptor_info1 *info = &gen->program->descriptors; const struct vkd3d_shader_descriptor_info1 *descriptor; unsigned int i;
@@ -2429,7 +2428,6 @@ static void shader_glsl_init_limits(struct vkd3d_glsl_generator *gen, const stru
static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen, struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, struct vkd3d_shader_message_context *message_context) { @@ -2453,12 +2451,10 @@ static void vkd3d_glsl_generator_init(struct vkd3d_glsl_generator *gen,
gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); gen->offset_info = vkd3d_find_struct(compile_info->next, DESCRIPTOR_OFFSET_INFO); - gen->descriptor_info = descriptor_info; gen->combined_sampler_info = combined_sampler_info; }
int glsl_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) @@ -2470,9 +2466,10 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, return ret;
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info);
vkd3d_glsl_generator_init(&generator, program, compile_info, - descriptor_info, combined_sampler_info, message_context); + combined_sampler_info, message_context); ret = vkd3d_glsl_generator_generate(&generator, out); vkd3d_glsl_generator_cleanup(&generator);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index 41586550203..653ddd2e8be 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -234,6 +234,33 @@ unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type) return 1; }
+const struct hlsl_type *hlsl_get_stream_output_type(const struct hlsl_type *type) +{ + unsigned int i; + + switch (type->class) + { + case HLSL_CLASS_ARRAY: + return hlsl_get_stream_output_type(type->e.array.type); + + case HLSL_CLASS_STRUCT: + for (i = 0; i < type->e.record.field_count; ++i) + { + const struct hlsl_type *field_type = hlsl_get_stream_output_type(type->e.record.fields[i].type); + + if (field_type) + return field_type; + } + return NULL; + + case HLSL_CLASS_STREAM_OUTPUT: + return type; + + default: + return NULL; + } +} + bool hlsl_type_is_resource(const struct hlsl_type *type) { switch (type->class) @@ -292,12 +319,94 @@ bool hlsl_type_is_shader(const struct hlsl_type *type) return false; }
+bool hlsl_type_is_minimum_precision(const struct hlsl_type *type) +{ + if (!hlsl_is_numeric_type(type)) + return false; + + switch (type->e.numeric.type) + { + case HLSL_TYPE_BOOL: + case HLSL_TYPE_DOUBLE: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + return false; + + case HLSL_TYPE_MIN16UINT: + return true; + } + + vkd3d_unreachable(); +} + bool hlsl_type_is_patch_array(const struct hlsl_type *type) { return type->class == HLSL_CLASS_ARRAY && (type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT || type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT); }
+bool hlsl_type_is_primitive_array(const struct hlsl_type *type) +{ + return type->class == HLSL_CLASS_ARRAY && (type->e.array.array_type != HLSL_ARRAY_GENERIC + || (type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK)); +} + +bool hlsl_base_type_is_integer(enum hlsl_base_type type) +{ + switch (type) + { + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: + case HLSL_TYPE_UINT: + return true; + + case HLSL_TYPE_DOUBLE: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + return false; + } + + vkd3d_unreachable(); +} + +bool hlsl_type_is_signed_integer(const struct hlsl_type *type) +{ + VKD3D_ASSERT(hlsl_is_numeric_type(type)); + + switch (type->e.numeric.type) + { + case HLSL_TYPE_INT: + return true; + + case HLSL_TYPE_BOOL: + case HLSL_TYPE_DOUBLE: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + case HLSL_TYPE_MIN16UINT: + case HLSL_TYPE_UINT: + return false; + } + + vkd3d_unreachable(); +} + +bool hlsl_type_is_integer(const struct hlsl_type *type) +{ + VKD3D_ASSERT(hlsl_is_numeric_type(type)); + return hlsl_base_type_is_integer(type->e.numeric.type); +} + +bool hlsl_type_is_floating_point(const struct hlsl_type *type) +{ + if (!hlsl_is_numeric_type(type)) + return false; + + return !hlsl_type_is_integer(type); +} + /* Only intended to be used for derefs (after copies have been lowered to components or vectors) or * resources, since for both their data types span across a single regset. */ static enum hlsl_regset type_get_regset(const struct hlsl_type *type) @@ -321,6 +430,9 @@ static enum hlsl_regset type_get_regset(const struct hlsl_type *type) case HLSL_CLASS_UAV: return HLSL_REGSET_UAVS;
+ case HLSL_CLASS_STREAM_OUTPUT: + return HLSL_REGSET_STREAM_OUTPUTS; + default: break; } @@ -427,6 +539,10 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type type->reg_size[HLSL_REGSET_UAVS] = 1; break;
+ case HLSL_CLASS_STREAM_OUTPUT: + type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] = 1; + break; + case HLSL_CLASS_DEPTH_STENCIL_STATE: case HLSL_CLASS_DEPTH_STENCIL_VIEW: case HLSL_CLASS_EFFECT_GROUP: @@ -445,7 +561,6 @@ static void hlsl_type_calculate_reg_size(struct hlsl_ctx *ctx, struct hlsl_type case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: case HLSL_CLASS_BLEND_STATE: - case HLSL_CLASS_STREAM_OUTPUT: case HLSL_CLASS_NULL: break; } @@ -484,6 +599,8 @@ static struct hlsl_type *hlsl_new_type(struct hlsl_ctx *ctx, const char *name, e { struct hlsl_type *type;
+ TRACE("New type %s.\n", name); + if (!(type = hlsl_alloc(ctx, sizeof(*type)))) return NULL; if (!(type->name = hlsl_strdup(ctx, name))) @@ -523,6 +640,7 @@ static bool type_is_single_component(const struct hlsl_type *type) case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_STREAM_OUTPUT: case HLSL_CLASS_NULL: return true;
@@ -537,7 +655,6 @@ static bool type_is_single_component(const struct hlsl_type *type) case HLSL_CLASS_PASS: case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_VOID: - case HLSL_CLASS_STREAM_OUTPUT: break; } vkd3d_unreachable(); @@ -683,6 +800,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_STREAM_OUTPUT: VKD3D_ASSERT(idx == 0); break;
@@ -694,7 +812,6 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty case HLSL_CLASS_SCALAR: case HLSL_CLASS_CONSTANT_BUFFER: case HLSL_CLASS_NULL: - case HLSL_CLASS_STREAM_OUTPUT: vkd3d_unreachable(); } type = next_type; @@ -704,8 +821,7 @@ unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_ty return offset[*regset]; }
-static bool init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, - unsigned int path_len) +bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len) { deref->var = var; deref->path_len = path_len; @@ -763,7 +879,7 @@ bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *d } load = hlsl_ir_load(ptr);
- if (!init_deref(ctx, deref, load->src.var, load->src.path_len + chain_len)) + if (!hlsl_init_deref(ctx, deref, load->src.var, load->src.path_len + chain_len)) return false;
for (i = 0; i < load->src.path_len; ++i) @@ -832,7 +948,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl ++path_len; }
- if (!init_deref(ctx, deref, prefix->var, prefix->path_len + path_len)) + if (!hlsl_init_deref(ctx, deref, prefix->var, prefix->path_len + path_len)) return false;
deref_path_len = 0; @@ -845,13 +961,7 @@ static bool init_deref_from_component_index(struct hlsl_ctx *ctx, struct hlsl_bl { unsigned int next_index = traverse_path_from_component_index(ctx, &path_type, &path_index);
- if (!(c = hlsl_new_uint_constant(ctx, next_index, loc))) - { - hlsl_block_cleanup(block); - return false; - } - hlsl_block_add_instr(block, c); - + c = hlsl_block_add_uint_constant(ctx, block, next_index, loc); hlsl_src_from_node(&deref->path[deref_path_len++], c); }
@@ -923,6 +1033,7 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, type->class = HLSL_CLASS_STREAM_OUTPUT; type->e.so.so_type = so_type; type->e.so.type = data_type; + hlsl_type_calculate_reg_size(ctx, type);
list_add_tail(&ctx->types, &type->entry);
@@ -1104,6 +1215,7 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) case HLSL_CLASS_HULL_SHADER: case HLSL_CLASS_GEOMETRY_SHADER: case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_STREAM_OUTPUT: case HLSL_CLASS_NULL: return 1;
@@ -1111,7 +1223,6 @@ unsigned int hlsl_type_component_count(const struct hlsl_type *type) case HLSL_CLASS_PASS: case HLSL_CLASS_TECHNIQUE: case HLSL_CLASS_VOID: - case HLSL_CLASS_STREAM_OUTPUT: break; }
@@ -1305,6 +1416,10 @@ struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, type->e.version = old->e.version; break;
+ case HLSL_CLASS_STREAM_OUTPUT: + type->e.so.so_type = old->e.so.so_type; + break; + default: break; } @@ -1324,15 +1439,16 @@ bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type) return true; }
-struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type, - const struct vkd3d_shader_location *loc) +static struct hlsl_ir_node *append_new_instr(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *instr) { - struct hlsl_ir_node *cast; + if (!instr) + { + block->value = ctx->error_instr; + return ctx->error_instr; + }
- cast = hlsl_new_unary_expr(ctx, HLSL_OP1_CAST, node, loc); - if (cast) - cast->data_type = type; - return cast; + hlsl_block_add_instr(block, instr); + return instr; }
struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node) @@ -1429,7 +1545,7 @@ bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struc
VKD3D_ASSERT(!hlsl_deref_is_lowered(other));
- if (!init_deref(ctx, deref, other->var, other->path_len)) + if (!hlsl_init_deref(ctx, deref, other->var, other->path_len)) return false;
for (i = 0; i < deref->path_len; ++i) @@ -1491,7 +1607,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls return NULL; init_node(&store->node, HLSL_IR_STORE, NULL, loc);
- if (!init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx)) + if (!hlsl_init_deref(ctx, &store->lhs, lhs->var, lhs->path_len + !!idx)) { vkd3d_free(store); return NULL; @@ -1510,22 +1626,73 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls return &store->node; }
-bool hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, +void hlsl_block_add_store_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, + unsigned int writemask, const struct vkd3d_shader_location *loc) +{ + append_new_instr(ctx, block, hlsl_new_store_index(ctx, lhs, idx, rhs, writemask, loc)); +} + +void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) +{ + struct hlsl_deref lhs_deref; + + hlsl_init_simple_deref_from_var(&lhs_deref, lhs); + hlsl_block_add_store_index(ctx, block, &lhs_deref, NULL, rhs, 0, &rhs->loc); +} + +static struct hlsl_ir_node *hlsl_new_store_parent(struct hlsl_ctx *ctx, + const struct hlsl_deref *lhs, unsigned int path_len, struct hlsl_ir_node *rhs, + unsigned int writemask, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_store *store; + + VKD3D_ASSERT(!hlsl_deref_is_lowered(lhs)); + VKD3D_ASSERT(lhs->path_len >= path_len); + + if (!(store = hlsl_alloc(ctx, sizeof(*store)))) + return NULL; + init_node(&store->node, HLSL_IR_STORE, NULL, loc); + + if (!hlsl_init_deref(ctx, &store->lhs, lhs->var, path_len)) + { + vkd3d_free(store); + return NULL; + } + for (unsigned int i = 0; i < path_len; ++i) + hlsl_src_from_node(&store->lhs.path[i], lhs->path[i].node); + + hlsl_src_from_node(&store->rhs, rhs); + + if (!writemask && type_is_single_reg(rhs->data_type)) + writemask = (1 << rhs->data_type->e.numeric.dimx) - 1; + store->writemask = writemask; + + return &store->node; +} + +void hlsl_block_add_store_parent(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, unsigned int path_len, struct hlsl_ir_node *rhs, + unsigned int writemask, const struct vkd3d_shader_location *loc) +{ + append_new_instr(ctx, block, hlsl_new_store_parent(ctx, lhs, path_len, rhs, writemask, loc)); +} + +void hlsl_block_add_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs) { struct hlsl_block comp_path_block; struct hlsl_ir_store *store;
- hlsl_block_init(block); - if (!(store = hlsl_alloc(ctx, sizeof(*store)))) - return false; + return; init_node(&store->node, HLSL_IR_STORE, NULL, &rhs->loc);
if (!init_deref_from_component_index(ctx, &comp_path_block, &store->lhs, lhs, comp, &rhs->loc)) { vkd3d_free(store); - return false; + return; } hlsl_block_add_block(block, &comp_path_block); hlsl_src_from_node(&store->rhs, rhs); @@ -1534,8 +1701,6 @@ bool hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, store->writemask = (1 << rhs->data_type->e.numeric.dimx) - 1;
hlsl_block_add_instr(block, &store->node); - - return true; }
struct hlsl_ir_node *hlsl_new_call(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *decl, @@ -1575,7 +1740,7 @@ struct hlsl_ir_node *hlsl_new_bool_constant(struct hlsl_ctx *ctx, bool b, const return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &value, loc); }
-struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, +static struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, const struct vkd3d_shader_location *loc) { struct hlsl_constant_value value; @@ -1584,7 +1749,14 @@ struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, float f, return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), &value, loc); }
-struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, const struct vkd3d_shader_location *loc) +struct hlsl_ir_node *hlsl_block_add_float_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + float f, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_float_constant(ctx, f, loc)); +} + +static struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, + const struct vkd3d_shader_location *loc) { struct hlsl_constant_value value;
@@ -1592,6 +1764,12 @@ struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, cons return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), &value, loc); }
+struct hlsl_ir_node *hlsl_block_add_int_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + int32_t n, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_int_constant(ctx, n, loc)); +} + struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location *loc) { @@ -1601,6 +1779,12 @@ struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n return hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &value, loc); }
+struct hlsl_ir_node *hlsl_block_add_uint_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + unsigned int n, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_uint_constant(ctx, n, loc)); +} + struct hlsl_ir_node *hlsl_new_string_constant(struct hlsl_ctx *ctx, const char *str, const struct vkd3d_shader_location *loc) { @@ -1625,7 +1809,7 @@ 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); }
-struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, +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) { @@ -1641,7 +1825,14 @@ struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op return &expr->node; }
-struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, +struct hlsl_ir_node *hlsl_block_add_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_expr(ctx, op, operands, data_type, loc)); +} + +static struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg}; @@ -1649,6 +1840,12 @@ struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr return hlsl_new_expr(ctx, op, operands, arg->data_type, loc); }
+struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_unary_expr(ctx, op, arg, loc)); +} + struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) { @@ -1657,16 +1854,37 @@ struct hlsl_ir_node *hlsl_new_binary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_exp return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); }
+struct hlsl_ir_node *hlsl_block_add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2) +{ + return append_new_instr(ctx, block, hlsl_new_binary_expr(ctx, op, arg1, arg2)); +} + 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) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2, arg3};
- VKD3D_ASSERT(hlsl_types_are_equal(arg1->data_type, arg2->data_type)); - VKD3D_ASSERT(hlsl_types_are_equal(arg1->data_type, arg3->data_type)); return hlsl_new_expr(ctx, op, operands, arg1->data_type, &arg1->loc); }
+struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_type *type, + const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *cast; + + cast = hlsl_new_unary_expr(ctx, HLSL_OP1_CAST, node, loc); + if (cast) + cast->data_type = type; + return cast; +} + +struct hlsl_ir_node *hlsl_block_add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_node *arg, struct hlsl_type *type, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_cast(ctx, arg, type, loc)); +} + static struct hlsl_ir_node *hlsl_new_error_expr(struct hlsl_ctx *ctx) { static const struct vkd3d_shader_location loc = {.source_name = "<error>"}; @@ -1694,6 +1912,23 @@ struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *cond return &iff->node; }
+void hlsl_block_add_if(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *condition, + struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *instr = hlsl_new_if(ctx, condition, then_block, else_block, loc); + + if (instr) + { + hlsl_block_add_instr(block, instr); + } + else + { + hlsl_block_cleanup(then_block); + if (else_block) + hlsl_block_cleanup(else_block); + } +} + struct hlsl_ir_switch_case *hlsl_new_switch_case(struct hlsl_ctx *ctx, unsigned int value, bool is_default, struct hlsl_block *body, const struct vkd3d_shader_location *loc) { @@ -1745,7 +1980,7 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl return NULL; init_node(&load->node, HLSL_IR_LOAD, type, loc);
- if (!init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx)) + if (!hlsl_init_deref(ctx, &load->src, deref->var, deref->path_len + !!idx)) { vkd3d_free(load); return NULL; @@ -1758,6 +1993,14 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl return load; }
+struct hlsl_ir_node *hlsl_block_add_load_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_load *load = hlsl_new_load_index(ctx, deref, idx, loc); + + return append_new_instr(ctx, block, load ? &load->node : NULL); +} + struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc) { @@ -1780,17 +2023,27 @@ struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var return hlsl_new_load_index(ctx, &var_deref, NULL, loc); }
-struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, +struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc) +{ + struct hlsl_deref var_deref; + + hlsl_init_simple_deref_from_var(&var_deref, var); + return hlsl_block_add_load_index(ctx, block, &var_deref, NULL, loc); +} + +struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc) { struct hlsl_type *type, *comp_type; struct hlsl_block comp_path_block; struct hlsl_ir_load *load;
- hlsl_block_init(block); - if (!(load = hlsl_alloc(ctx, sizeof(*load)))) - return NULL; + { + block->value = ctx->error_instr; + return ctx->error_instr; + }
type = hlsl_deref_get_type(ctx, deref); comp_type = hlsl_type_get_component_type(ctx, type, comp); @@ -1799,7 +2052,8 @@ struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b if (!init_deref_from_component_index(ctx, &comp_path_block, &load->src, deref, comp, loc)) { vkd3d_free(load); - return NULL; + block->value = ctx->error_instr; + return ctx->error_instr; } hlsl_block_add_block(block, &comp_path_block);
@@ -1808,7 +2062,7 @@ struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_b return &load->node; }
-struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, +static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load; @@ -1847,26 +2101,45 @@ struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, return &load->node; }
-struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, - struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) +struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc)); +} + +static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type, + const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, + const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_store *store;
if (!(store = hlsl_alloc(ctx, sizeof(*store)))) return NULL; init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); + store->store_type = type; + hlsl_copy_deref(ctx, &store->resource, resource); hlsl_src_from_node(&store->coords, coords); hlsl_src_from_node(&store->value, value); return &store->node; }
+void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, + struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) +{ + append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc)); +} + struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) { struct hlsl_ir_swizzle *swizzle; struct hlsl_type *type;
+ if (val->data_type->class == HLSL_CLASS_ERROR) + return val; + VKD3D_ASSERT(val->data_type->class <= HLSL_CLASS_VECTOR);
if (!(swizzle = hlsl_alloc(ctx, sizeof(*swizzle)))) @@ -1882,6 +2155,12 @@ struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned return &swizzle->node; }
+struct hlsl_ir_node *hlsl_block_add_swizzle(struct hlsl_ctx *ctx, struct hlsl_block *block, uint32_t s, + unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_swizzle(ctx, s, width, val, loc)); +} + struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s, unsigned int component_count, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc) { @@ -2055,6 +2334,26 @@ struct hlsl_ir_node *hlsl_new_interlocked(struct hlsl_ctx *ctx, enum hlsl_interl return &interlocked->node; }
+static struct hlsl_ir_node *hlsl_new_sync(struct hlsl_ctx *ctx, + uint32_t sync_flags, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_sync *sync; + + if (!(sync = hlsl_alloc(ctx, sizeof(*sync)))) + return NULL; + + init_node(&sync->node, HLSL_IR_SYNC, NULL, loc); + sync->sync_flags = sync_flags; + + return &sync->node; +} + +struct hlsl_ir_node *hlsl_block_add_sync(struct hlsl_ctx *ctx, struct hlsl_block *block, + uint32_t sync_flags, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_sync(ctx, sync_flags, loc)); +} + bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index) { struct hlsl_type *type = index->val.node->data_type; @@ -2078,7 +2377,7 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) return false; }
-struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, +static struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) { struct hlsl_type *type = val->data_type; @@ -2100,7 +2399,13 @@ struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *v return &index->node; }
-struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, +struct hlsl_ir_node *hlsl_block_add_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_node *val, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) +{ + return append_new_instr(ctx, block, hlsl_new_index(ctx, val, idx, loc)); +} + +static struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc) { struct hlsl_ir_jump *jump; @@ -2113,7 +2418,13 @@ struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type return &jump->node; }
-struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, struct hlsl_block *iter, +void hlsl_block_add_jump(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_jump_type type, + struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc) +{ + append_new_instr(ctx, block, hlsl_new_jump(ctx, type, condition, loc)); +} + +static struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, struct hlsl_block *iter, struct hlsl_block *block, enum hlsl_loop_unroll_type unroll_type, unsigned int unroll_limit, const struct vkd3d_shader_location *loc) { @@ -2134,6 +2445,18 @@ struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, struct hlsl_block *iter return &loop->node; }
+void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_block *iter, struct hlsl_block *body, enum hlsl_loop_unroll_type unroll_type, + unsigned int unroll_limit, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *instr = hlsl_new_loop(ctx, iter, body, unroll_type, unroll_limit, loc); + + if (instr) + hlsl_block_add_instr(block, instr); + else + hlsl_block_cleanup(body); +} + struct clone_instr_map { struct @@ -2203,7 +2526,7 @@ static bool clone_deref(struct hlsl_ctx *ctx, struct clone_instr_map *map,
VKD3D_ASSERT(!hlsl_deref_is_lowered(src));
- if (!init_deref(ctx, dst, src->var, src->path_len)) + if (!hlsl_init_deref(ctx, dst, src->var, src->path_len)) return false;
for (i = 0; i < src->path_len; ++i) @@ -2344,6 +2667,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) return NULL; init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); + dst->store_type = src->store_type; if (!clone_deref(ctx, map, &dst->resource, &src->resource)) { vkd3d_free(dst); @@ -2406,7 +2730,7 @@ static struct hlsl_ir_node *clone_interlocked(struct hlsl_ctx *ctx,
if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) return NULL; - init_node(&dst->node, HLSL_IR_INTERLOCKED, NULL, &src->node.loc); + init_node(&dst->node, HLSL_IR_INTERLOCKED, src->node.data_type, &src->node.loc); dst->op = src->op;
if (!clone_deref(ctx, map, &dst->dst, &src->dst)) @@ -2420,6 +2744,18 @@ static struct hlsl_ir_node *clone_interlocked(struct hlsl_ctx *ctx, return &dst->node; }
+static struct hlsl_ir_node *clone_sync(struct hlsl_ctx *ctx, struct hlsl_ir_sync *src) +{ + struct hlsl_ir_sync *dst; + + if (!(dst = hlsl_alloc(ctx, sizeof(*dst)))) + return NULL; + init_node(&dst->node, HLSL_IR_SYNC, NULL, &src->node.loc); + dst->sync_flags = src->sync_flags; + + return &dst->node; +} + static struct hlsl_ir_node *clone_compile(struct hlsl_ctx *ctx, struct clone_instr_map *map, struct hlsl_ir_compile *compile) { @@ -2623,6 +2959,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, case HLSL_IR_INTERLOCKED: return clone_interlocked(ctx, map, hlsl_ir_interlocked(instr));
+ case HLSL_IR_SYNC: + return clone_sync(ctx, hlsl_ir_sync(instr)); + case HLSL_IR_COMPILE: return clone_compile(ctx, map, hlsl_ir_compile(instr));
@@ -2650,8 +2989,8 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *constant, *store; struct hlsl_ir_function_decl *decl; + struct hlsl_ir_node *constant;
if (!(decl = hlsl_alloc(ctx, sizeof(*decl)))) return NULL; @@ -2679,9 +3018,7 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, return decl; hlsl_block_add_instr(&decl->body, constant);
- if (!(store = hlsl_new_simple_store(ctx, decl->early_return_var, constant))) - return decl; - hlsl_block_add_instr(&decl->body, store); + hlsl_block_add_simple_store(ctx, &decl->body, decl->early_return_var, constant);
return decl; } @@ -2796,6 +3133,7 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl [HLSL_TYPE_HALF] = "half", [HLSL_TYPE_DOUBLE] = "double", [HLSL_TYPE_INT] = "int", + [HLSL_TYPE_MIN16UINT] = "min16uint", [HLSL_TYPE_UINT] = "uint", [HLSL_TYPE_BOOL] = "bool", }; @@ -3040,6 +3378,16 @@ struct vkd3d_string_buffer *hlsl_modifiers_to_string(struct hlsl_ctx *ctx, uint3 vkd3d_string_buffer_printf(string, "row_major "); if (modifiers & HLSL_MODIFIER_COLUMN_MAJOR) vkd3d_string_buffer_printf(string, "column_major "); + if (modifiers & HLSL_PRIMITIVE_POINT) + vkd3d_string_buffer_printf(string, "point "); + if (modifiers & HLSL_PRIMITIVE_LINE) + vkd3d_string_buffer_printf(string, "line "); + if (modifiers & HLSL_PRIMITIVE_TRIANGLE) + vkd3d_string_buffer_printf(string, "triangle "); + if (modifiers & HLSL_PRIMITIVE_LINEADJ) + vkd3d_string_buffer_printf(string, "lineadj "); + if (modifiers & HLSL_PRIMITIVE_TRIANGLEADJ) + vkd3d_string_buffer_printf(string, "triangleadj "); if ((modifiers & (HLSL_STORAGE_IN | HLSL_STORAGE_OUT)) == (HLSL_STORAGE_IN | HLSL_STORAGE_OUT)) vkd3d_string_buffer_printf(string, "inout "); else if (modifiers & HLSL_STORAGE_IN) @@ -3071,7 +3419,9 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) [HLSL_IR_STORE ] = "HLSL_IR_STORE", [HLSL_IR_SWITCH ] = "HLSL_IR_SWITCH", [HLSL_IR_SWIZZLE ] = "HLSL_IR_SWIZZLE", + [HLSL_IR_INTERLOCKED ] = "HLSL_IR_INTERLOCKED", + [HLSL_IR_SYNC ] = "HLSL_IR_SYNC",
[HLSL_IR_COMPILE] = "HLSL_IR_COMPILE", [HLSL_IR_SAMPLER_STATE] = "HLSL_IR_SAMPLER_STATE", @@ -3263,6 +3613,7 @@ static void dump_ir_constant(struct vkd3d_string_buffer *buffer, const struct hl vkd3d_string_buffer_printf(buffer, "%d ", value->i); break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: vkd3d_string_buffer_printf(buffer, "%u ", value->u); break; @@ -3465,12 +3816,26 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru
static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) { - vkd3d_string_buffer_printf(buffer, "store_resource(resource = "); + static const char *const type_names[] = + { + [HLSL_RESOURCE_STORE] = "store_resource", + [HLSL_RESOURCE_STREAM_APPEND] = "stream_append", + [HLSL_RESOURCE_STREAM_RESTART] = "stream_restart", + }; + + VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names)); + vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]); dump_deref(buffer, &store->resource); - vkd3d_string_buffer_printf(buffer, ", coords = "); - dump_src(buffer, &store->coords); - vkd3d_string_buffer_printf(buffer, ", value = "); - dump_src(buffer, &store->value); + if (store->coords.node) + { + vkd3d_string_buffer_printf(buffer, ", coords = "); + dump_src(buffer, &store->coords); + } + if (store->value.node) + { + vkd3d_string_buffer_printf(buffer, ", value = "); + dump_src(buffer, &store->value); + } vkd3d_string_buffer_printf(buffer, ")"); }
@@ -3546,6 +3911,19 @@ static void dump_ir_interlocked(struct vkd3d_string_buffer *buffer, const struct vkd3d_string_buffer_printf(buffer, ")"); }
+static void dump_ir_sync(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_sync *sync) +{ + vkd3d_string_buffer_printf(buffer, "sync"); + if (sync->sync_flags & VKD3DSSF_GLOBAL_UAV) + vkd3d_string_buffer_printf(buffer, "_uglobal"); + if (sync->sync_flags & VKD3DSSF_THREAD_GROUP_UAV) + vkd3d_string_buffer_printf(buffer, "_ugroup"); + if (sync->sync_flags & VKD3DSSF_GROUP_SHARED_MEMORY) + vkd3d_string_buffer_printf(buffer, "_g"); + if (sync->sync_flags & VKD3DSSF_THREAD_GROUP) + vkd3d_string_buffer_printf(buffer, "_t"); +} + static void dump_ir_compile(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_compile *compile) { @@ -3683,6 +4061,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, dump_ir_interlocked(buffer, hlsl_ir_interlocked(instr)); break;
+ case HLSL_IR_SYNC: + dump_ir_sync(buffer, hlsl_ir_sync(instr)); + break; + case HLSL_IR_COMPILE: dump_ir_compile(ctx, buffer, hlsl_ir_compile(instr)); break; @@ -3920,6 +4302,11 @@ static void free_ir_interlocked(struct hlsl_ir_interlocked *interlocked) vkd3d_free(interlocked); }
+static void free_ir_sync(struct hlsl_ir_sync *sync) +{ + vkd3d_free(sync); +} + static void free_ir_compile(struct hlsl_ir_compile *compile) { unsigned int i; @@ -4010,6 +4397,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) free_ir_interlocked(hlsl_ir_interlocked(node)); break;
+ case HLSL_IR_SYNC: + free_ir_sync(hlsl_ir_sync(node)); + break; + case HLSL_IR_COMPILE: free_ir_compile(hlsl_ir_compile(node)); break; @@ -4289,17 +4680,17 @@ static void declare_predefined_types(struct hlsl_ctx *ctx)
static const char * const names[] = { - [HLSL_TYPE_FLOAT] = "float", - [HLSL_TYPE_HALF] = "half", - [HLSL_TYPE_DOUBLE] = "double", - [HLSL_TYPE_INT] = "int", - [HLSL_TYPE_UINT] = "uint", - [HLSL_TYPE_BOOL] = "bool", + [HLSL_TYPE_FLOAT] = "float", + [HLSL_TYPE_HALF] = "half", + [HLSL_TYPE_DOUBLE] = "double", + [HLSL_TYPE_INT] = "int", + [HLSL_TYPE_UINT] = "uint", + [HLSL_TYPE_BOOL] = "bool", + [HLSL_TYPE_MIN16UINT] = "min16uint", };
static const char *const variants_float[] = {"min10float", "min16float"}; static const char *const variants_int[] = {"min12int", "min16int"}; - static const char *const variants_uint[] = {"min16uint"};
static const char *const sampler_names[] = { @@ -4390,11 +4781,6 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) n_variants = ARRAY_SIZE(variants_int); break;
- case HLSL_TYPE_UINT: - variants = variants_uint; - n_variants = ARRAY_SIZE(variants_uint); - break; - default: n_variants = 0; variants = NULL; @@ -4577,6 +4963,9 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil ctx->output_primitive = 0; ctx->partitioning = 0; ctx->input_control_point_count = UINT_MAX; + ctx->max_vertex_count = 0; + ctx->input_primitive_type = VKD3D_PT_UNDEFINED; + ctx->output_topology_type = VKD3D_PT_UNDEFINED;
return true; } @@ -4742,6 +5131,7 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d
if (target_type == VKD3D_SHADER_TARGET_SPIRV_BINARY || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT + || target_type == VKD3D_SHADER_TARGET_GLSL || target_type == VKD3D_SHADER_TARGET_D3D_ASM) { uint64_t config_flags = vkd3d_shader_init_config_flags(); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index f614e12036e..58f579cd9f9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -103,6 +103,7 @@ enum hlsl_base_type HLSL_TYPE_DOUBLE, HLSL_TYPE_INT, HLSL_TYPE_UINT, + HLSL_TYPE_MIN16UINT, HLSL_TYPE_BOOL, HLSL_TYPE_LAST_SCALAR = HLSL_TYPE_BOOL, }; @@ -140,7 +141,8 @@ enum hlsl_regset HLSL_REGSET_SAMPLERS, HLSL_REGSET_TEXTURES, HLSL_REGSET_UAVS, - HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_UAVS, + HLSL_REGSET_STREAM_OUTPUTS, + HLSL_REGSET_LAST_OBJECT = HLSL_REGSET_STREAM_OUTPUTS, HLSL_REGSET_NUMERIC, HLSL_REGSET_LAST = HLSL_REGSET_NUMERIC, }; @@ -232,6 +234,8 @@ struct hlsl_type /* Offset where the type's description starts in the output bytecode, in bytes. */ size_t bytecode_offset;
+ bool is_typedef; + uint32_t is_minimum_precision : 1; };
@@ -327,7 +331,9 @@ enum hlsl_ir_node_type HLSL_IR_STORE, HLSL_IR_SWIZZLE, HLSL_IR_SWITCH, + HLSL_IR_INTERLOCKED, + HLSL_IR_SYNC,
HLSL_IR_COMPILE, HLSL_IR_SAMPLER_STATE, @@ -416,6 +422,11 @@ struct hlsl_attribute #define HLSL_STORAGE_ANNOTATION 0x00080000 #define HLSL_MODIFIER_UNORM 0x00100000 #define HLSL_MODIFIER_SNORM 0x00200000 +#define HLSL_PRIMITIVE_POINT 0x00400000 +#define HLSL_PRIMITIVE_LINE 0x00800000 +#define HLSL_PRIMITIVE_TRIANGLE 0x01000000 +#define HLSL_PRIMITIVE_LINEADJ 0x02000000 +#define HLSL_PRIMITIVE_TRIANGLEADJ 0x04000000
#define HLSL_TYPE_MODIFIERS_MASK (HLSL_MODIFIER_PRECISE | HLSL_MODIFIER_VOLATILE | \ HLSL_MODIFIER_CONST | HLSL_MODIFIER_ROW_MAJOR | \ @@ -426,6 +437,9 @@ struct hlsl_attribute
#define HLSL_MODIFIERS_MAJORITY_MASK (HLSL_MODIFIER_ROW_MAJOR | HLSL_MODIFIER_COLUMN_MAJOR)
+#define HLSL_PRIMITIVE_MODIFIERS_MASK (HLSL_PRIMITIVE_POINT | HLSL_PRIMITIVE_LINE | HLSL_PRIMITIVE_TRIANGLE | \ + HLSL_PRIMITIVE_LINEADJ | HLSL_PRIMITIVE_TRIANGLEADJ) + #define HLSL_ARRAY_ELEMENTS_COUNT_IMPLICIT 0
/* Reservation of a register and/or an offset for objects inside constant buffers, to be used as a @@ -482,6 +496,9 @@ struct hlsl_ir_var union hlsl_constant_value_component number; } *default_values;
+ /* Pointer to the temp copy of the variable, in case it is uniform. */ + struct hlsl_ir_var *temp_copy; + /* A dynamic array containing the state block on the variable's declaration, if any. * An array variable may contain multiple state blocks. * A technique pass will always contain one. @@ -882,9 +899,17 @@ struct hlsl_ir_resource_load enum hlsl_sampler_dim sampling_dim; };
+enum hlsl_resource_store_type +{ + HLSL_RESOURCE_STORE, + HLSL_RESOURCE_STREAM_APPEND, + HLSL_RESOURCE_STREAM_RESTART, +}; + struct hlsl_ir_resource_store { struct hlsl_ir_node node; + enum hlsl_resource_store_type store_type; struct hlsl_deref resource; struct hlsl_src coords, value; }; @@ -985,6 +1010,15 @@ struct hlsl_ir_interlocked struct hlsl_src coords, cmp_value, value; };
+/* Represents a thread synchronization instruction such as GroupMemoryBarrier().*/ +struct hlsl_ir_sync +{ + struct hlsl_ir_node node; + + /* Flags from enum vkd3d_shader_sync_flags. */ + uint32_t sync_flags; +}; + struct hlsl_scope { /* Item entry for hlsl_ctx.scopes. */ @@ -1143,6 +1177,7 @@ struct hlsl_ctx struct hlsl_constant_register { uint32_t index; + uint32_t allocated_mask; struct hlsl_vec4 value; struct vkd3d_shader_location loc; } *regs; @@ -1180,10 +1215,20 @@ struct hlsl_ctx unsigned int input_control_point_count; struct hlsl_type *input_control_point_type;
+ /* The first declared input primitive parameter in tessellation and geometry shaders. */ + struct hlsl_ir_var *input_primitive_param; + /* Whether the current function being processed during HLSL codegen is * the patch constant function in a hull shader. */ bool is_patch_constant_func;
+ /* The maximum output vertex count of a geometry shader. */ + unsigned int max_vertex_count; + /* The input primitive type of a geometry shader. */ + enum vkd3d_primitive_type input_primitive_type; + /* The output topology type of a geometry shader. */ + enum vkd3d_primitive_type output_topology_type; + /* In some cases we generate opcodes by parsing an HLSL function and then * invoking it. If not NULL, this field is the name of the function that we * are currently parsing, "mangled" with an internal prefix to avoid @@ -1311,6 +1356,12 @@ static inline struct hlsl_ir_interlocked *hlsl_ir_interlocked(const struct hlsl_ return CONTAINING_RECORD(node, struct hlsl_ir_interlocked, node); }
+static inline struct hlsl_ir_sync *hlsl_ir_sync(const struct hlsl_ir_node *node) +{ + VKD3D_ASSERT(node->type == HLSL_IR_SYNC); + return CONTAINING_RECORD(node, struct hlsl_ir_sync, node); +} + static inline struct hlsl_ir_compile *hlsl_ir_compile(const struct hlsl_ir_node *node) { VKD3D_ASSERT(node->type == HLSL_IR_COMPILE); @@ -1454,6 +1505,11 @@ static inline bool hlsl_is_numeric_type(const struct hlsl_type *type) return type->class <= HLSL_CLASS_LAST_NUMERIC; }
+static inline bool hlsl_is_vec1(const struct hlsl_type *type) +{ + return type->class == HLSL_CLASS_SCALAR || (type->class == HLSL_CLASS_VECTOR && type->e.numeric.dimx == 1); +} + static inline unsigned int hlsl_sampler_dim_count(enum hlsl_sampler_dim dim) { switch (dim) @@ -1502,6 +1558,55 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc void hlsl_add_function(struct hlsl_ctx *ctx, char *name, struct hlsl_ir_function_decl *decl); void hlsl_add_var(struct hlsl_ctx *ctx, struct hlsl_ir_var *decl);
+struct hlsl_ir_node *hlsl_block_add_binary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2); +struct hlsl_ir_node *hlsl_block_add_cast(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_node *arg, struct hlsl_type *type, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], + struct hlsl_type *data_type, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_float_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + float f, const struct vkd3d_shader_location *loc); +void hlsl_block_add_if(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *condition, + struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_node *val, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_int_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + int32_t n, const struct vkd3d_shader_location *loc); +void hlsl_block_add_jump(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_ir_jump_type type, + struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_load_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *deref, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); +void hlsl_block_add_loop(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_block *iter, struct hlsl_block *body, enum hlsl_loop_unroll_type unroll_type, + unsigned int unroll_limit, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); +void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, + struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc); +void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); +void hlsl_block_add_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs); +void hlsl_block_add_store_index(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, + unsigned int writemask, const struct vkd3d_shader_location *loc); +void hlsl_block_add_store_parent(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct hlsl_deref *lhs, unsigned int path_len, struct hlsl_ir_node *rhs, + unsigned int writemask, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_swizzle(struct hlsl_ctx *ctx, struct hlsl_block *block, uint32_t s, + unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_sync(struct hlsl_ctx *ctx, struct hlsl_block *block, + uint32_t sync_flags, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_uint_constant(struct hlsl_ctx *ctx, struct hlsl_block *block, + unsigned int n, const struct vkd3d_shader_location *loc); +struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc); void hlsl_block_cleanup(struct hlsl_block *block); bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block);
@@ -1524,6 +1629,7 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out);
+bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len); bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain); bool hlsl_copy_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, const struct hlsl_deref *other);
@@ -1573,19 +1679,11 @@ struct hlsl_ir_node *hlsl_new_cast(struct hlsl_ctx *ctx, struct hlsl_ir_node *no struct hlsl_ir_node *hlsl_new_constant(struct hlsl_ctx *ctx, struct hlsl_type *type, const struct hlsl_constant_value *value, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_copy(struct hlsl_ctx *ctx, struct hlsl_ir_node *node); -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); -struct hlsl_ir_node *hlsl_new_float_constant(struct hlsl_ctx *ctx, - float f, const struct vkd3d_shader_location *loc); struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_if(struct hlsl_ctx *ctx, struct hlsl_ir_node *condition, struct hlsl_block *then_block, struct hlsl_block *else_block, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_int_constant(struct hlsl_ctx *ctx, int32_t n, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_jump(struct hlsl_ctx *ctx, - enum hlsl_ir_jump_type type, struct hlsl_ir_node *condition, const struct vkd3d_shader_location *loc); struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, enum hlsl_so_object_type so_type, struct hlsl_type *type); struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, @@ -1599,16 +1697,12 @@ struct hlsl_ir_load *hlsl_new_load_index(struct hlsl_ctx *ctx, const struct hlsl struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); struct hlsl_ir_load *hlsl_new_load_parent(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_deref *deref, unsigned int comp, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_add_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *var_instr, unsigned int comp, const struct vkd3d_shader_location *loc);
struct hlsl_ir_node *hlsl_new_simple_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs); struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hlsl_deref *lhs, struct hlsl_ir_node *idx, struct hlsl_ir_node *rhs, unsigned int writemask, const struct vkd3d_shader_location *loc); -bool hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, - const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index); bool hlsl_index_is_resource_access(struct hlsl_ir_index *index); @@ -1617,20 +1711,11 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count, struct hlsl_block *args_instrs, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, - struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op op, struct hlsl_type *type, const struct hlsl_deref *dst, struct hlsl_ir_node *coords, struct hlsl_ir_node *cmp_value, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_loop(struct hlsl_ctx *ctx, struct hlsl_block *iter, - struct hlsl_block *block, enum hlsl_loop_unroll_type unroll_type, - unsigned int unroll_limit, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_matrix_swizzle(struct hlsl_ctx *ctx, struct hlsl_matrix_swizzle s, unsigned int width, struct hlsl_ir_node *val, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, - const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, const struct hlsl_deref *resource, - struct hlsl_ir_node *coords, struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); struct hlsl_type *hlsl_new_struct_type(struct hlsl_ctx *ctx, const char *name, struct hlsl_struct_field *fields, size_t field_count); struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int components, @@ -1653,8 +1738,6 @@ struct hlsl_type *hlsl_new_cb_type(struct hlsl_ctx *ctx, struct hlsl_type *forma struct hlsl_ir_node *hlsl_new_uint_constant(struct hlsl_ctx *ctx, unsigned int n, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc); -struct hlsl_ir_node *hlsl_new_unary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, - const struct vkd3d_shader_location *loc); struct hlsl_ir_var *hlsl_new_var(struct hlsl_ctx *ctx, const char *name, struct hlsl_type *type, const struct vkd3d_shader_location *loc, const struct hlsl_semantic *semantic, uint32_t modifiers, const struct hlsl_reg_reservation *reg_reservation); @@ -1677,6 +1760,8 @@ void hlsl_pop_scope(struct hlsl_ctx *ctx);
bool hlsl_scope_add_type(struct hlsl_scope *scope, struct hlsl_type *type);
+bool hlsl_base_type_is_integer(enum hlsl_base_type type); + struct hlsl_type *hlsl_type_clone(struct hlsl_ctx *ctx, struct hlsl_type *old, unsigned int default_majority, uint32_t modifiers); unsigned int hlsl_type_component_count(const struct hlsl_type *type); @@ -1685,13 +1770,19 @@ struct hlsl_type *hlsl_type_get_component_type(struct hlsl_ctx *ctx, struct hlsl unsigned int index); unsigned int hlsl_type_get_component_offset(struct hlsl_ctx *ctx, struct hlsl_type *type, unsigned int index, enum hlsl_regset *regset); +bool hlsl_type_is_integer(const struct hlsl_type *type); +bool hlsl_type_is_floating_point(const struct hlsl_type *type); bool hlsl_type_is_row_major(const struct hlsl_type *type); +bool hlsl_type_is_signed_integer(const struct hlsl_type *type); unsigned int hlsl_type_minor_size(const struct hlsl_type *type); unsigned int hlsl_type_major_size(const struct hlsl_type *type); unsigned int hlsl_type_element_count(const struct hlsl_type *type); +bool hlsl_type_is_integer(const struct hlsl_type *type); +bool hlsl_type_is_minimum_precision(const struct hlsl_type *type); bool hlsl_type_is_resource(const struct hlsl_type *type); bool hlsl_type_is_shader(const struct hlsl_type *type); bool hlsl_type_is_patch_array(const struct hlsl_type *type); +bool hlsl_type_is_primitive_array(const struct hlsl_type *type); unsigned int hlsl_type_get_sm4_offset(const struct hlsl_type *type, unsigned int offset); bool hlsl_types_are_equal(const struct hlsl_type *t1, const struct hlsl_type *t2);
@@ -1700,6 +1791,8 @@ void hlsl_calculate_buffer_offsets(struct hlsl_ctx *ctx); const struct hlsl_type *hlsl_get_multiarray_element_type(const struct hlsl_type *type); unsigned int hlsl_get_multiarray_size(const struct hlsl_type *type);
+const struct hlsl_type *hlsl_get_stream_output_type(const struct hlsl_type *type); + uint32_t hlsl_combine_swizzles(uint32_t first, uint32_t second, unsigned int dim); unsigned int hlsl_combine_writemasks(unsigned int first, unsigned int second); uint32_t hlsl_map_swizzle(uint32_t swizzle, unsigned int writemask); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l index 605a9abaa93..d9fd43b5e78 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l @@ -106,6 +106,8 @@ inline {return KW_INLINE; } inout {return KW_INOUT; } InputPatch {return KW_INPUTPATCH; } LineStream {return KW_LINESTREAM; } +line {return KW_LINE; } +lineadj {return KW_LINEADJ; } linear {return KW_LINEAR; } matrix {return KW_MATRIX; } namespace {return KW_NAMESPACE; } @@ -119,6 +121,7 @@ pass {return KW_PASS; } PixelShader {return KW_PIXELSHADER; } PointStream {return KW_POINTSTREAM; } pixelshader {return KW_PIXELSHADER; } +point {return KW_POINT; } RasterizerOrderedBuffer {return KW_RASTERIZERORDEREDBUFFER; } RasterizerOrderedStructuredBuffer {return KW_RASTERIZERORDEREDSTRUCTUREDBUFFER; } RasterizerOrderedTexture1D {return KW_RASTERIZERORDEREDTEXTURE1D; } @@ -175,6 +178,8 @@ TextureCube {return KW_TEXTURECUBE; } textureCUBE {return KW_TEXTURECUBE; } TextureCubeArray {return KW_TEXTURECUBEARRAY; } TriangleStream {return KW_TRIANGLESTREAM; } +triangle {return KW_TRIANGLE; } +triangleadj {return KW_TRIANGLEADJ; } true {return KW_TRUE; } typedef {return KW_TYPEDEF; } unsigned {return KW_UNSIGNED; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 7afc9274c2e..5aee1e701cd 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -351,7 +351,6 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl struct hlsl_ir_node *node, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) { struct hlsl_type *src_type = node->data_type; - struct hlsl_ir_node *cast;
if (hlsl_types_are_equal(src_type, dst_type)) return node; @@ -359,11 +358,7 @@ static struct hlsl_ir_node *add_cast(struct hlsl_ctx *ctx, struct hlsl_block *bl if (src_type->class == HLSL_CLASS_NULL) return node;
- if (!(cast = hlsl_new_cast(ctx, node, dst_type, loc))) - return NULL; - hlsl_block_add_instr(block, cast); - - return cast; + return hlsl_block_add_cast(ctx, block, node, dst_type, loc); }
static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -377,7 +372,15 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct if (node->type == HLSL_IR_SAMPLER_STATE && dst_type->class == HLSL_CLASS_SAMPLER) return node;
- if (!implicit_compatible_data_types(ctx, src_type, dst_type)) + if (implicit_compatible_data_types(ctx, src_type, dst_type)) + { + if (hlsl_is_numeric_type(dst_type) && hlsl_is_numeric_type(src_type) + && dst_type->e.numeric.dimx * dst_type->e.numeric.dimy < src_type->e.numeric.dimx * src_type->e.numeric.dimy + && ctx->warn_implicit_truncation) + hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", + src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix"); + } + else { struct vkd3d_string_buffer *src_string, *dst_string;
@@ -388,19 +391,12 @@ static struct hlsl_ir_node *add_implicit_conversion(struct hlsl_ctx *ctx, struct "Can't implicitly convert from %s to %s.", src_string->buffer, dst_string->buffer); hlsl_release_string_buffer(ctx, src_string); hlsl_release_string_buffer(ctx, dst_string); - return NULL; }
- if (hlsl_is_numeric_type(dst_type) && hlsl_is_numeric_type(src_type) - && dst_type->e.numeric.dimx * dst_type->e.numeric.dimy < src_type->e.numeric.dimx * src_type->e.numeric.dimy - && ctx->warn_implicit_truncation) - hlsl_warning(ctx, loc, VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION, "Implicit truncation of %s type.", - src_type->class == HLSL_CLASS_VECTOR ? "vector" : "matrix"); - return add_cast(ctx, block, node, dst_type, loc); }
-static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block, +static void add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_type *dst_type, const struct parse_array_sizes *arrays, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *instr = node_from_block(block); @@ -419,7 +415,7 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo }
if (instr->data_type->class == HLSL_CLASS_ERROR) - return true; + return;
if (!explicit_compatible_data_types(ctx, src_type, dst_type)) { @@ -432,10 +428,9 @@ static bool add_explicit_conversion(struct hlsl_ctx *ctx, struct hlsl_block *blo src_string->buffer, dst_string->buffer); hlsl_release_string_buffer(ctx, src_string); hlsl_release_string_buffer(ctx, dst_string); - return false; }
- return add_cast(ctx, block, instr, dst_type, loc); + add_cast(ctx, block, instr, dst_type, loc); }
static uint32_t add_modifiers(struct hlsl_ctx *ctx, uint32_t modifiers, uint32_t mod, @@ -454,15 +449,15 @@ static uint32_t add_modifiers(struct hlsl_ctx *ctx, uint32_t modifiers, uint32_t return modifiers | mod; }
-static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *cond_block) +static void append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *cond_block) { - struct hlsl_ir_node *condition, *cast, *not, *iff, *jump; + struct hlsl_ir_node *condition, *cast, *not; struct hlsl_block then_block; struct hlsl_type *bool_type;
/* E.g. "for (i = 0; ; ++i)". */ if (list_empty(&cond_block->instrs)) - return true; + return;
condition = node_from_block(cond_block);
@@ -471,23 +466,12 @@ static bool append_conditional_break(struct hlsl_ctx *ctx, struct hlsl_block *co bool_type = hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL); /* We already checked for a 1-component numeric type, so * add_implicit_conversion() is equivalent to add_cast() here. */ - if (!(cast = add_cast(ctx, cond_block, condition, bool_type, &condition->loc))) - return false; - - if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, cast, &condition->loc))) - return false; - hlsl_block_add_instr(cond_block, not); + cast = add_cast(ctx, cond_block, condition, bool_type, &condition->loc); + not = hlsl_block_add_unary_expr(ctx, cond_block, HLSL_OP1_LOGIC_NOT, cast, &condition->loc);
hlsl_block_init(&then_block); - - if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &condition->loc))) - return false; - hlsl_block_add_instr(&then_block, jump); - - if (!(iff = hlsl_new_if(ctx, not, &then_block, NULL, &condition->loc))) - return false; - hlsl_block_add_instr(cond_block, iff); - return true; + hlsl_block_add_jump(ctx, &then_block, HLSL_IR_JUMP_BREAK, NULL, &condition->loc); + hlsl_block_add_if(ctx, cond_block, not, &then_block, NULL, &condition->loc); }
static void check_attribute_list_for_duplicates(struct hlsl_ctx *ctx, const struct parse_attribute_list *attrs) @@ -531,11 +515,7 @@ static void resolve_loop_continue(struct hlsl_ctx *ctx, struct hlsl_block *block { if (!hlsl_clone_block(ctx, &cond_block, cond)) return; - if (!append_conditional_break(ctx, &cond_block)) - { - hlsl_block_cleanup(&cond_block); - return; - } + append_conditional_break(ctx, &cond_block); list_move_before(&instr->entry, &cond_block.instrs); } } @@ -594,13 +574,14 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx /* fall-through */ case HLSL_IR_CALL: case HLSL_IR_IF: + case HLSL_IR_INTERLOCKED: case HLSL_IR_LOOP: case HLSL_IR_JUMP: case HLSL_IR_RESOURCE_LOAD: case HLSL_IR_RESOURCE_STORE: case HLSL_IR_SWITCH: - case HLSL_IR_INTERLOCKED: case HLSL_IR_STATEBLOCK_CONSTANT: + case HLSL_IR_SYNC: hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Expected literal expression."); break; @@ -611,11 +592,7 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx return ret; hlsl_block_add_block(&expr, block);
- if (!(node = add_implicit_conversion(ctx, &expr, node_from_block(&expr), dst_type, loc))) - { - hlsl_block_cleanup(&expr); - return ret; - } + node = add_implicit_conversion(ctx, &expr, node_from_block(&expr), dst_type, loc);
/* Wrap the node into a src to allow the reference to survive the multiple const passes. */ hlsl_src_from_node(&src, node); @@ -668,7 +645,6 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum hlsl_loop_type { enum hlsl_loop_unroll_type unroll_type = HLSL_LOOP_UNROLL; unsigned int i, unroll_limit = 0; - struct hlsl_ir_node *loop;
check_attribute_list_for_duplicates(ctx, attributes); check_loop_attributes(ctx, attributes, loc); @@ -719,17 +695,14 @@ static struct hlsl_block *create_loop(struct hlsl_ctx *ctx, enum hlsl_loop_type if (!init && !(init = make_empty_block(ctx))) goto oom;
- if (!append_conditional_break(ctx, cond)) - goto oom; + append_conditional_break(ctx, cond);
if (type == HLSL_LOOP_DO_WHILE) list_move_tail(&body->instrs, &cond->instrs); else list_move_head(&body->instrs, &cond->instrs);
- if (!(loop = hlsl_new_loop(ctx, iter, body, unroll_type, unroll_limit, loc))) - goto oom; - hlsl_block_add_instr(init, loop); + hlsl_block_add_loop(ctx, init, iter, body, unroll_type, unroll_limit, loc);
destroy_block(cond); destroy_block(body); @@ -858,23 +831,16 @@ static bool add_return(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *return_value, const struct vkd3d_shader_location *loc) { struct hlsl_type *return_type = ctx->cur_function->return_type; - struct hlsl_ir_node *jump;
if (ctx->cur_function->return_var) { if (return_value) { - struct hlsl_ir_node *store; - if (return_value->data_type->class == HLSL_CLASS_ERROR) return true;
- if (!(return_value = add_implicit_conversion(ctx, block, return_value, return_type, loc))) - return false; - - if (!(store = hlsl_new_simple_store(ctx, ctx->cur_function->return_var, return_value))) - return false; - list_add_after(&return_value->entry, &store->entry); + return_value = add_implicit_conversion(ctx, block, return_value, return_type, loc); + hlsl_block_add_simple_store(ctx, block, ctx->cur_function->return_var, return_value); } else { @@ -888,52 +854,37 @@ static bool add_return(struct hlsl_ctx *ctx, struct hlsl_block *block, hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RETURN, "Void functions cannot return a value."); }
- if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_RETURN, NULL, loc))) - return false; - hlsl_block_add_instr(block, jump); - + hlsl_block_add_jump(ctx, block, HLSL_IR_JUMP_RETURN, NULL, loc); return true; }
struct hlsl_ir_node *hlsl_add_load_component(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *var_instr, unsigned int comp, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *load, *store; - struct hlsl_block load_block; struct hlsl_ir_var *var; struct hlsl_deref src;
if (!(var = hlsl_new_synthetic_var(ctx, "deref", var_instr->data_type, &var_instr->loc))) - return NULL; + { + block->value = ctx->error_instr; + return ctx->error_instr; + }
- if (!(store = hlsl_new_simple_store(ctx, var, var_instr))) - return NULL; - hlsl_block_add_instr(block, store); + hlsl_block_add_simple_store(ctx, block, var, var_instr);
hlsl_init_simple_deref_from_var(&src, var); - if (!(load = hlsl_new_load_component(ctx, &load_block, &src, comp, loc))) - return NULL; - hlsl_block_add_block(block, &load_block); - - return load; + return hlsl_block_add_load_component(ctx, block, &src, comp, loc); }
-static bool add_record_access(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *record, +static void add_record_access(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *record, unsigned int idx, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *index, *c; + struct hlsl_ir_node *c;
VKD3D_ASSERT(idx < record->data_type->e.record.field_count);
- if (!(c = hlsl_new_uint_constant(ctx, idx, loc))) - return false; - hlsl_block_add_instr(block, c); - - if (!(index = hlsl_new_index(ctx, record, c, loc))) - return false; - hlsl_block_add_instr(block, index); - - return true; + c = hlsl_block_add_uint_constant(ctx, block, idx, loc); + hlsl_block_add_index(ctx, block, record, c, loc); }
static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -944,7 +895,6 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) { const struct hlsl_type *expr_type = array->data_type, *index_type = index->data_type; - struct hlsl_ir_node *return_index, *cast;
if (array->data_type->class == HLSL_CLASS_ERROR || index->data_type->class == HLSL_CLASS_ERROR) { @@ -968,14 +918,9 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str return false; }
- if (!(index = add_implicit_conversion(ctx, block, index, - hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc))) - return false; - - if (!(return_index = hlsl_new_index(ctx, array, index, loc))) - return false; - hlsl_block_add_instr(block, return_index); - + index = add_implicit_conversion(ctx, block, index, + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, dim_count), &index->loc); + hlsl_block_add_index(ctx, block, array, index, loc); return true; }
@@ -985,10 +930,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str return false; }
- if (!(cast = hlsl_new_cast(ctx, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc))) - return false; - hlsl_block_add_instr(block, cast); - index = cast; + index = hlsl_block_add_cast(ctx, block, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &index->loc);
if (expr_type->class != HLSL_CLASS_ARRAY && expr_type->class != HLSL_CLASS_VECTOR && expr_type->class != HLSL_CLASS_MATRIX) { @@ -999,10 +941,7 @@ static bool add_array_access(struct hlsl_ctx *ctx, struct hlsl_block *block, str return false; }
- if (!(return_index = hlsl_new_index(ctx, array, index, loc))) - return false; - hlsl_block_add_instr(block, return_index); - + hlsl_block_add_index(ctx, block, array, index, loc); return true; }
@@ -1059,10 +998,24 @@ static void free_parse_variable_def(struct parse_variable_def *v) vkd3d_free(v->arrays.sizes); vkd3d_free(v->name); hlsl_cleanup_semantic(&v->semantic); - VKD3D_ASSERT(!v->state_blocks); + if (v->state_block_count) + { + for (unsigned int i = 0; i < v->state_block_count; ++i) + hlsl_free_state_block(v->state_blocks[i]); + vkd3d_free(v->state_blocks); + } vkd3d_free(v); }
+static void destroy_parse_variable_defs(struct list *defs) +{ + struct parse_variable_def *v, *v_next; + + LIST_FOR_EACH_ENTRY_SAFE(v, v_next, defs, struct parse_variable_def, entry) + free_parse_variable_def(v); + vkd3d_free(defs); +} + static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, struct hlsl_type *type, uint32_t modifiers, struct list *defs) { @@ -1144,31 +1097,34 @@ static bool gen_struct_fields(struct hlsl_ctx *ctx, struct parse_fields *fields, return true; }
-static bool add_record_access_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, +static void add_record_access_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, const char *name, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *record = node_from_block(block); const struct hlsl_type *type = record->data_type; const struct hlsl_struct_field *field, *base;
+ if (type->class == HLSL_CLASS_ERROR) + return; + if ((field = get_struct_field(type->e.record.fields, type->e.record.field_count, name))) { unsigned int field_idx = field - type->e.record.fields;
- return add_record_access(ctx, block, record, field_idx, loc); + add_record_access(ctx, block, record, field_idx, loc); } else if ((base = get_struct_field(type->e.record.fields, type->e.record.field_count, "$super"))) { unsigned int base_idx = base - type->e.record.fields;
- if (!add_record_access(ctx, block, record, base_idx, loc)) - return false; - return add_record_access_recurse(ctx, block, name, loc); + add_record_access(ctx, block, record, base_idx, loc); + add_record_access_recurse(ctx, block, name, loc); + } + else + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field "%s" is not defined.", name); + block->value = ctx->error_instr; } - - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Field "%s" is not defined.", name); - block->value = ctx->error_instr; - return true; }
static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, struct list *list) @@ -1227,6 +1183,7 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type,
vkd3d_free((void *)type->name); type->name = v->name; + type->is_typedef = true;
ret = hlsl_scope_add_type(ctx->cur_scope, type); if (!ret) @@ -1239,6 +1196,14 @@ static bool add_typedef(struct hlsl_ctx *ctx, struct hlsl_type *const orig_type, return true; }
+static void check_invalid_stream_output_object(struct hlsl_ctx *ctx, const struct hlsl_type *type, + const char *name, const struct vkd3d_shader_location* loc) +{ + if (hlsl_type_component_count(type) != 1) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Stream output object '%s' is not single-element.", name); +} + static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *instrs, struct hlsl_ir_var *dst, unsigned int *store_index, struct hlsl_ir_node *src, bool is_default_values_initializer); @@ -1273,6 +1238,9 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Output parameter '%s' has a default value.", param->name);
+ if (hlsl_get_stream_output_type(param->type)) + check_invalid_stream_output_object(ctx, param->type, param->name, loc); + if (!(var = hlsl_new_var(ctx, param->name, param->type, loc, ¶m->semantic, param->modifiers, ¶m->reg_reservation))) return false; @@ -1289,9 +1257,7 @@ static bool add_func_parameter(struct hlsl_ctx *ctx, struct hlsl_func_parameters
if (!param->initializer.braces) { - if (!(add_implicit_conversion(ctx, param->initializer.instrs, param->initializer.args[0], param->type, loc))) - return false; - + add_implicit_conversion(ctx, param->initializer.instrs, param->initializer.args[0], param->type, loc); param->initializer.args[0] = node_from_block(param->initializer.instrs); }
@@ -1517,7 +1483,11 @@ static enum hlsl_base_type expr_common_base_type(enum hlsl_base_type t1, enum hl return HLSL_TYPE_FLOAT; if (t1 == HLSL_TYPE_UINT || t2 == HLSL_TYPE_UINT) return HLSL_TYPE_UINT; - return HLSL_TYPE_INT; + if (t1 == HLSL_TYPE_INT || t2 == HLSL_TYPE_INT) + return HLSL_TYPE_INT; + if (t1 == HLSL_TYPE_MIN16UINT || t2 == HLSL_TYPE_MIN16UINT) + return HLSL_TYPE_MIN16UINT; + vkd3d_unreachable(); }
static bool expr_common_shape(struct hlsl_ctx *ctx, struct hlsl_type *t1, struct hlsl_type *t2, @@ -1600,15 +1570,12 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *bl enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *type, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *expr; unsigned int i;
if (type->class == HLSL_CLASS_MATRIX) { struct hlsl_type *scalar_type; - struct hlsl_ir_load *var_load; struct hlsl_deref var_deref; - struct hlsl_ir_node *load; struct hlsl_ir_var *var;
scalar_type = hlsl_get_scalar_type(ctx, type->e.numeric.type); @@ -1620,58 +1587,24 @@ static struct hlsl_ir_node *add_expr(struct hlsl_ctx *ctx, struct hlsl_block *bl for (i = 0; i < type->e.numeric.dimy * type->e.numeric.dimx; ++i) { struct hlsl_ir_node *value, *cell_operands[HLSL_MAX_OPERANDS] = { NULL }; - struct hlsl_block store_block; unsigned int j;
for (j = 0; j < HLSL_MAX_OPERANDS; j++) { if (operands[j]) - { - if (!(load = hlsl_add_load_component(ctx, block, operands[j], i, loc))) - return NULL; - - cell_operands[j] = load; - } + cell_operands[j] = hlsl_add_load_component(ctx, block, operands[j], i, loc); }
if (!(value = add_expr(ctx, block, op, cell_operands, scalar_type, loc))) return NULL;
- if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, value)) - return NULL; - hlsl_block_add_block(block, &store_block); + hlsl_block_add_store_component(ctx, block, &var_deref, i, value); }
- if (!(var_load = hlsl_new_var_load(ctx, var, loc))) - return NULL; - hlsl_block_add_instr(block, &var_load->node); - - return &var_load->node; + return hlsl_block_add_simple_load(ctx, block, var, loc); }
- if (!(expr = hlsl_new_expr(ctx, op, operands, type, loc))) - return NULL; - hlsl_block_add_instr(block, expr); - - return expr; -} - -static bool type_is_integer(enum hlsl_base_type type) -{ - switch (type) - { - case HLSL_TYPE_BOOL: - case HLSL_TYPE_INT: - case HLSL_TYPE_UINT: - return true; - - case HLSL_TYPE_DOUBLE: - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - return false; - } - - vkd3d_unreachable(); + return hlsl_block_add_expr(ctx, block, op, operands, type, loc); }
static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) @@ -1679,7 +1612,7 @@ static void check_integer_type(struct hlsl_ctx *ctx, const struct hlsl_ir_node * const struct hlsl_type *type = instr->data_type; struct vkd3d_string_buffer *string;
- if (type_is_integer(type->e.numeric.type)) + if (hlsl_type_is_integer(type)) return;
if ((string = hlsl_type_to_string(ctx, type))) @@ -1721,10 +1654,7 @@ static struct hlsl_ir_node *add_unary_logical_expr(struct hlsl_ctx *ctx, struct
bool_type = hlsl_get_numeric_type(ctx, arg->data_type->class, HLSL_TYPE_BOOL, arg->data_type->e.numeric.dimx, arg->data_type->e.numeric.dimy); - - if (!(args[0] = add_implicit_conversion(ctx, block, arg, bool_type, loc))) - return NULL; - + args[0] = add_implicit_conversion(ctx, block, arg, bool_type, loc); return add_expr(ctx, block, op, args, bool_type, loc); }
@@ -1754,12 +1684,8 @@ static struct hlsl_ir_node *add_binary_arithmetic_expr(struct hlsl_ctx *ctx, str return block->value; }
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc))) - return NULL; - + args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc); + args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc); return add_expr(ctx, block, op, args, common_type, loc); }
@@ -1790,12 +1716,8 @@ static struct hlsl_ir_node *add_binary_comparison_expr(struct hlsl_ctx *ctx, str common_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); return_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy);
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc))) - return NULL; - + args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc); + args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc); return add_expr(ctx, block, op, args, return_type, loc); }
@@ -1813,12 +1735,8 @@ static struct hlsl_ir_node *add_binary_logical_expr(struct hlsl_ctx *ctx, struct
common_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_BOOL, dimx, dimy);
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc))) - return NULL; - + args[0] = add_implicit_conversion(ctx, block, arg1, common_type, loc); + args[1] = add_implicit_conversion(ctx, block, arg2, common_type, loc); return add_expr(ctx, block, op, args, common_type, loc); }
@@ -1844,12 +1762,8 @@ static struct hlsl_ir_node *add_binary_shift_expr(struct hlsl_ctx *ctx, struct h return_type = hlsl_get_numeric_type(ctx, type, base, dimx, dimy); integer_type = hlsl_get_numeric_type(ctx, type, HLSL_TYPE_INT, dimx, dimy);
- if (!(args[0] = add_implicit_conversion(ctx, block, arg1, return_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, block, arg2, integer_type, loc))) - return NULL; - + args[0] = add_implicit_conversion(ctx, block, arg1, return_type, loc); + args[1] = add_implicit_conversion(ctx, block, arg2, integer_type, loc); return add_expr(ctx, block, op, args, return_type, loc); }
@@ -1897,12 +1811,8 @@ static struct hlsl_ir_node *add_binary_dot_expr(struct hlsl_ctx *ctx, struct hls common_type = hlsl_get_vector_type(ctx, base, dim); ret_type = hlsl_get_scalar_type(ctx, base);
- if (!(args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc))) - return NULL; - - if (!(args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc))) - return NULL; - + args[0] = add_implicit_conversion(ctx, instrs, arg1, common_type, loc); + args[1] = add_implicit_conversion(ctx, instrs, arg2, common_type, loc); return add_expr(ctx, instrs, op, args, ret_type, loc); }
@@ -2098,8 +2008,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc width = size; }
- if (!(rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc))) - return false; + rhs = add_implicit_conversion(ctx, block, rhs, lhs_type, &rhs->loc);
while (lhs->type != HLSL_IR_LOAD && lhs->type != HLSL_IR_INDEX) { @@ -2129,7 +2038,6 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc else if (lhs->type == HLSL_IR_SWIZZLE) { struct hlsl_ir_swizzle *swizzle = hlsl_ir_swizzle(lhs); - struct hlsl_ir_node *new_swizzle; uint32_t s;
VKD3D_ASSERT(!matrix_writemask); @@ -2160,13 +2068,9 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc } }
- if (!(new_swizzle = hlsl_new_swizzle(ctx, s, width, rhs, &swizzle->node.loc))) - return false; - hlsl_block_add_instr(block, new_swizzle); - + rhs = hlsl_block_add_swizzle(ctx, block, s, width, rhs, &swizzle->node.loc); lhs = swizzle->val.node; lhs_type = hlsl_get_vector_type(ctx, lhs_type->e.numeric.type, width); - rhs = new_swizzle; } else { @@ -2178,15 +2082,13 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc /* lhs casts could have resulted in a discrepancy between the * rhs->data_type and the type of the variable that will be ulimately * stored to. This is corrected. */ - if (!(rhs = add_cast(ctx, block, rhs, lhs_type, &rhs->loc))) - return false; + rhs = add_cast(ctx, block, rhs, lhs_type, &rhs->loc);
if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_resource_access(hlsl_ir_index(lhs))) { struct hlsl_ir_node *coords = hlsl_ir_index(lhs)->idx.node; struct hlsl_deref resource_deref; struct hlsl_type *resource_type; - struct hlsl_ir_node *store; unsigned int dim_count;
if (!hlsl_index_is_resource_access(hlsl_ir_index(lhs))) @@ -2215,12 +2117,7 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
- if (!(store = hlsl_new_resource_store(ctx, &resource_deref, coords, rhs, &lhs->loc))) - { - hlsl_cleanup_deref(&resource_deref); - return false; - } - hlsl_block_add_instr(block, store); + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc); hlsl_cleanup_deref(&resource_deref); } else if (matrix_writemask) @@ -2235,25 +2132,14 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc for (j = 0; j < lhs->data_type->e.numeric.dimx; ++j) { struct hlsl_ir_node *load; - struct hlsl_block store_block; const unsigned int idx = i * 4 + j; const unsigned int component = i * lhs->data_type->e.numeric.dimx + j;
if (!(writemask & (1 << idx))) continue;
- if (!(load = hlsl_add_load_component(ctx, block, rhs, k++, &rhs->loc))) - { - hlsl_cleanup_deref(&deref); - return false; - } - - if (!hlsl_new_store_component(ctx, &store_block, &deref, component, load)) - { - hlsl_cleanup_deref(&deref); - return false; - } - hlsl_block_add_block(block, &store_block); + load = hlsl_add_load_component(ctx, block, rhs, k++, &rhs->loc); + hlsl_block_add_store_component(ctx, block, &deref, component, load); } }
@@ -2269,49 +2155,32 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc
for (i = 0; i < mat->data_type->e.numeric.dimx; ++i) { - struct hlsl_ir_node *cell, *load, *store, *c; + struct hlsl_ir_node *cell, *load, *c; struct hlsl_deref deref;
if (!(writemask & (1 << i))) continue;
- if (!(c = hlsl_new_uint_constant(ctx, i, &lhs->loc))) - return false; - hlsl_block_add_instr(block, c); - - if (!(cell = hlsl_new_index(ctx, &row->node, c, &lhs->loc))) - return false; - hlsl_block_add_instr(block, cell); + c = hlsl_block_add_uint_constant(ctx, block, i, &lhs->loc);
- if (!(load = hlsl_add_load_component(ctx, block, rhs, k++, &rhs->loc))) - return false; + cell = hlsl_block_add_index(ctx, block, &row->node, c, &lhs->loc); + load = hlsl_add_load_component(ctx, block, rhs, k++, &rhs->loc);
if (!hlsl_init_deref_from_index_chain(ctx, &deref, cell)) return false;
- if (!(store = hlsl_new_store_index(ctx, &deref, NULL, load, 0, &rhs->loc))) - { - hlsl_cleanup_deref(&deref); - return false; - } - hlsl_block_add_instr(block, store); + hlsl_block_add_store_index(ctx, block, &deref, NULL, load, 0, &rhs->loc); hlsl_cleanup_deref(&deref); } } else { - struct hlsl_ir_node *store; struct hlsl_deref deref;
if (!hlsl_init_deref_from_index_chain(ctx, &deref, lhs)) return false;
- if (!(store = hlsl_new_store_index(ctx, &deref, NULL, rhs, writemask, &rhs->loc))) - { - hlsl_cleanup_deref(&deref); - return false; - } - hlsl_block_add_instr(block, store); + hlsl_block_add_store_index(ctx, block, &deref, NULL, rhs, writemask, &rhs->loc); hlsl_cleanup_deref(&deref); }
@@ -2332,9 +2201,7 @@ static bool add_increment(struct hlsl_ctx *ctx, struct hlsl_block *block, bool d hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Argument to %s%screment operator is const.", post ? "post" : "pre", decrement ? "de" : "in");
- if (!(one = hlsl_new_int_constant(ctx, 1, loc))) - return false; - hlsl_block_add_instr(block, one); + one = hlsl_block_add_int_constant(ctx, block, 1, loc);
if (!add_assignment(ctx, block, lhs, decrement ? ASSIGN_OP_SUB : ASSIGN_OP_ADD, one, false)) return false; @@ -2371,8 +2238,7 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i struct hlsl_type *dst_comp_type; struct hlsl_block block;
- if (!(load = hlsl_add_load_component(ctx, instrs, src, k, &src->loc))) - return; + load = hlsl_add_load_component(ctx, instrs, src, k, &src->loc);
dst_comp_type = hlsl_type_get_component_type(ctx, dst->data_type, *store_index);
@@ -2438,12 +2304,8 @@ static void initialize_var_components(struct hlsl_ctx *ctx, struct hlsl_block *i } else { - if (!(conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc))) - return; - - if (!hlsl_new_store_component(ctx, &block, &dst_deref, *store_index, conv)) - return; - hlsl_block_add_block(instrs, &block); + conv = add_implicit_conversion(ctx, instrs, load, dst_comp_type, &src->loc); + hlsl_block_add_store_component(ctx, instrs, &dst_deref, *store_index, conv); } }
@@ -2516,10 +2378,10 @@ static bool type_has_numeric_components(struct hlsl_type *type) return false; }
-static void check_invalid_in_out_modifiers(struct hlsl_ctx *ctx, unsigned int modifiers, +static void check_invalid_non_parameter_modifiers(struct hlsl_ctx *ctx, unsigned int modifiers, const struct vkd3d_shader_location *loc) { - modifiers &= (HLSL_STORAGE_IN | HLSL_STORAGE_OUT); + modifiers &= (HLSL_STORAGE_IN | HLSL_STORAGE_OUT | HLSL_PRIMITIVE_MODIFIERS_MASK); if (modifiers) { struct vkd3d_string_buffer *string; @@ -2553,6 +2415,7 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) bool constant_buffer = false; struct hlsl_ir_var *var; struct hlsl_type *type; + bool stream_output; char *var_name; unsigned int i;
@@ -2644,6 +2507,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) hlsl_fixme(ctx, &v->loc, "Shader model 5.1+ resource array."); }
+ stream_output = !!hlsl_get_stream_output_type(type); + if (stream_output) + check_invalid_stream_output_object(ctx, type, v->name, &v->loc); + if (!(var_name = vkd3d_strdup(v->name))) return;
@@ -2698,6 +2565,10 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) if (!(modifiers & HLSL_STORAGE_STATIC)) var->storage_modifiers |= HLSL_STORAGE_UNIFORM;
+ if (stream_output) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT, + "Stream output object '%s' is not allowed in the global scope.", var->name); + if ((ctx->profile->major_version < 5 || ctx->profile->type == VKD3D_SHADER_TYPE_EFFECT) && (var->storage_modifiers & HLSL_STORAGE_UNIFORM)) { @@ -2763,11 +2634,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var
if (!(initializers = make_empty_block(ctx))) { - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, var_list, struct parse_variable_def, entry) - { - free_parse_variable_def(v); - } - vkd3d_free(var_list); + destroy_parse_variable_defs(var_list); return NULL; }
@@ -2828,15 +2695,8 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var }
if (!v->initializer.braces) - { - if (!(add_implicit_conversion(ctx, v->initializer.instrs, v->initializer.args[0], type, &v->loc))) - { - free_parse_variable_def(v); - continue; - } - - v->initializer.args[0] = node_from_block(v->initializer.instrs); - } + v->initializer.args[0] = add_implicit_conversion(ctx, + v->initializer.instrs, v->initializer.args[0], type, &v->loc);
if (var->data_type->class != HLSL_CLASS_ERROR) initialize_var(ctx, var, &v->initializer, is_default_values_initializer); @@ -2859,7 +2719,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var } else if (var->storage_modifiers & HLSL_STORAGE_STATIC) { - struct hlsl_ir_node *cast, *store, *zero; + struct hlsl_ir_node *cast, *zero;
/* Initialize statics to zero by default. */
@@ -2869,25 +2729,9 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var continue; }
- if (!(zero = hlsl_new_uint_constant(ctx, 0, &var->loc))) - { - free_parse_variable_def(v); - continue; - } - hlsl_block_add_instr(&ctx->static_initializers, zero); - - if (!(cast = add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc))) - { - free_parse_variable_def(v); - continue; - } - - if (!(store = hlsl_new_simple_store(ctx, var, cast))) - { - free_parse_variable_def(v); - continue; - } - hlsl_block_add_instr(&ctx->static_initializers, store); + zero = hlsl_block_add_uint_constant(ctx, &ctx->static_initializers, 0, &var->loc); + cast = add_cast(ctx, &ctx->static_initializers, zero, var->data_type, &var->loc); + hlsl_block_add_simple_store(ctx, &ctx->static_initializers, var, cast); } free_parse_variable_def(v); } @@ -2934,6 +2778,7 @@ static enum hlsl_base_type hlsl_base_type_class(enum hlsl_base_type t) return HLSL_TYPE_FLOAT;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: return HLSL_TYPE_INT;
@@ -2949,6 +2794,7 @@ static unsigned int hlsl_base_type_width(enum hlsl_base_type t) switch (t) { case HLSL_TYPE_HALF: + case HLSL_TYPE_MIN16UINT: return 16;
case HLSL_TYPE_FLOAT: @@ -3123,11 +2969,12 @@ static struct hlsl_ir_function_decl *find_function_call(struct hlsl_ctx *ctx, return decl; }
-static struct hlsl_ir_node *hlsl_new_void_expr(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) +static void add_void_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0};
- return hlsl_new_expr(ctx, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc); + hlsl_block_add_expr(ctx, block, HLSL_OP0_VOID, operands, ctx->builtin_types.Void, loc); }
static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, @@ -3154,20 +3001,10 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx,
if (param->storage_modifiers & HLSL_STORAGE_IN) { - struct hlsl_ir_node *store; - if (!hlsl_types_are_equal(arg->data_type, param->data_type)) - { - struct hlsl_ir_node *cast; - - if (!(cast = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc))) - return NULL; - arg = cast; - } + arg = add_cast(ctx, args->instrs, arg, param->data_type, &arg->loc);
- if (!(store = hlsl_new_simple_store(ctx, param, arg))) - return NULL; - hlsl_block_add_instr(args->instrs, store); + hlsl_block_add_simple_store(ctx, args->instrs, param, arg); }
++k; @@ -3192,7 +3029,6 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, struct hlsl_type *type = hlsl_type_get_component_type(ctx, param->data_type, j); struct hlsl_constant_value value; struct hlsl_ir_node *comp; - struct hlsl_block store_block;
if (!param->default_values[j].string) { @@ -3201,9 +3037,7 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx, return NULL; hlsl_block_add_instr(args->instrs, comp);
- if (!hlsl_new_store_component(ctx, &store_block, ¶m_deref, j, comp)) - return NULL; - hlsl_block_add_block(args->instrs, &store_block); + hlsl_block_add_store_component(ctx, args->instrs, ¶m_deref, j, comp); } } } @@ -3222,37 +3056,22 @@ static struct hlsl_ir_node *add_user_call(struct hlsl_ctx *ctx,
if (param->storage_modifiers & HLSL_STORAGE_OUT) { - struct hlsl_ir_load *load; + struct hlsl_ir_node *load;
if (arg->data_type->modifiers & HLSL_MODIFIER_CONST) hlsl_error(ctx, &arg->loc, VKD3D_SHADER_ERROR_HLSL_MODIFIES_CONST, "Output argument to "%s" is const.", func->func->name);
- if (!(load = hlsl_new_var_load(ctx, param, &arg->loc))) - return NULL; - hlsl_block_add_instr(args->instrs, &load->node); - - if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, &load->node, true)) + load = hlsl_block_add_simple_load(ctx, args->instrs, param, &arg->loc); + if (!add_assignment(ctx, args->instrs, arg, ASSIGN_OP_ASSIGN, load, true)) return NULL; } }
if (func->return_var) - { - struct hlsl_ir_load *load; - - if (!(load = hlsl_new_var_load(ctx, func->return_var, loc))) - return false; - hlsl_block_add_instr(args->instrs, &load->node); - } + hlsl_block_add_simple_load(ctx, args->instrs, func->return_var, loc); else - { - struct hlsl_ir_node *expr; - - if (!(expr = hlsl_new_void_expr(ctx, loc))) - return false; - hlsl_block_add_instr(args->instrs, expr); - } + add_void_expr(ctx, args->instrs, loc);
return call; } @@ -3262,28 +3081,20 @@ static struct hlsl_ir_node *intrinsic_float_convert_arg(struct hlsl_ctx *ctx, { struct hlsl_type *type = arg->data_type;
- if (!type_is_integer(type->e.numeric.type)) + if (!hlsl_type_is_integer(type)) return arg;
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy); return add_implicit_conversion(ctx, params->instrs, arg, type, loc); }
-static bool convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params, +static void convert_args(struct hlsl_ctx *ctx, const struct parse_initializer *params, struct hlsl_type *type, const struct vkd3d_shader_location *loc) { unsigned int i;
for (i = 0; i < params->args_count; ++i) - { - struct hlsl_ir_node *new_arg; - - if (!(new_arg = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc))) - return false; - params->args[i] = new_arg; - } - - return true; + params->args[i] = add_implicit_conversion(ctx, params->instrs, params->args[i], type, loc); }
static struct hlsl_type *elementwise_intrinsic_get_common_type(struct hlsl_ctx *ctx, @@ -3344,7 +3155,8 @@ static bool elementwise_intrinsic_convert_args(struct hlsl_ctx *ctx, if (!(common_type = elementwise_intrinsic_get_common_type(ctx, params, loc))) return false;
- return convert_args(ctx, params, common_type, loc); + convert_args(ctx, params, common_type, loc); + return true; }
static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx, @@ -3354,10 +3166,11 @@ static bool elementwise_intrinsic_float_convert_args(struct hlsl_ctx *ctx,
if (!(type = elementwise_intrinsic_get_common_type(ctx, params, loc))) return false; - if (type_is_integer(type->e.numeric.type)) + if (hlsl_type_is_integer(type)) type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy);
- return convert_args(ctx, params, type, loc); + convert_args(ctx, params, type, loc); + return true; }
static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx, @@ -3370,12 +3183,18 @@ static bool elementwise_intrinsic_uint_convert_args(struct hlsl_ctx *ctx,
type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy);
- return convert_args(ctx, params, type, loc); + convert_args(ctx, params, type, loc); + return true; }
static bool intrinsic_abs(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { + const struct hlsl_type *type = params->args[0]->data_type; + + if (!hlsl_type_is_floating_point(type) && !hlsl_type_is_signed_integer(type)) + return true; + return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ABS, params->args[0], loc); }
@@ -3407,8 +3226,7 @@ static bool write_acos_or_asin(struct hlsl_ctx *ctx,
const char *fn_name = asin_mode ? fn_name_asin : fn_name_acos;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc); type = arg->data_type;
if (!(body = hlsl_sprintf_alloc(ctx, template, @@ -3438,7 +3256,7 @@ static struct hlsl_type *convert_numeric_type(const struct hlsl_ctx *ctx, return hlsl_get_numeric_type(ctx, type->class, base_type, type->e.numeric.dimx, type->e.numeric.dimy); }
-static bool add_combine_components(struct hlsl_ctx *ctx, const struct parse_initializer *params, +static void add_combine_components(struct hlsl_ctx *ctx, const struct parse_initializer *params, struct hlsl_ir_node *arg, enum hlsl_ir_expr_op op, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *res, *load; @@ -3446,20 +3264,13 @@ static bool add_combine_components(struct hlsl_ctx *ctx, const struct parse_init
count = hlsl_type_component_count(arg->data_type);
- if (!(res = hlsl_add_load_component(ctx, params->instrs, arg, 0, loc))) - return false; + res = hlsl_add_load_component(ctx, params->instrs, arg, 0, loc);
for (i = 1; i < count; ++i) { - if (!(load = hlsl_add_load_component(ctx, params->instrs, arg, i, loc))) - return false; - - if (!(res = hlsl_new_binary_expr(ctx, op, res, load))) - return NULL; - hlsl_block_add_instr(params->instrs, res); + load = hlsl_add_load_component(ctx, params->instrs, arg, i, loc); + res = hlsl_block_add_binary_expr(ctx, params->instrs, op, res, load); } - - return true; }
static bool intrinsic_all(struct hlsl_ctx *ctx, @@ -3469,10 +3280,9 @@ static bool intrinsic_all(struct hlsl_ctx *ctx, struct hlsl_type *bool_type;
bool_type = convert_numeric_type(ctx, arg->data_type, HLSL_TYPE_BOOL); - if (!(cast = add_cast(ctx, params->instrs, arg, bool_type, loc))) - return false; - - return add_combine_components(ctx, params, cast, HLSL_OP2_LOGIC_AND, loc); + cast = add_cast(ctx, params->instrs, arg, bool_type, loc); + add_combine_components(ctx, params, cast, HLSL_OP2_LOGIC_AND, loc); + return true; }
static bool intrinsic_any(struct hlsl_ctx *ctx, const struct parse_initializer *params, @@ -3482,10 +3292,9 @@ static bool intrinsic_any(struct hlsl_ctx *ctx, const struct parse_initializer * struct hlsl_type *bool_type;
bool_type = convert_numeric_type(ctx, arg->data_type, HLSL_TYPE_BOOL); - if (!(cast = add_cast(ctx, params->instrs, arg, bool_type, loc))) - return false; - - return add_combine_components(ctx, params, cast, HLSL_OP2_LOGIC_OR, loc); + cast = add_cast(ctx, params->instrs, arg, bool_type, loc); + add_combine_components(ctx, params, cast, HLSL_OP2_LOGIC_OR, loc); + return true; }
static bool intrinsic_asin(struct hlsl_ctx *ctx, @@ -3671,10 +3480,7 @@ static bool intrinsic_asuint(struct hlsl_ctx *ctx, static bool intrinsic_ceil(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *arg; - - if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + struct hlsl_ir_node *arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_CEIL, arg, loc); } @@ -3696,7 +3502,7 @@ static bool intrinsic_clamp(struct hlsl_ctx *ctx, static bool intrinsic_clip(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *condition, *jump; + struct hlsl_ir_node *condition;
if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) return false; @@ -3714,20 +3520,14 @@ static bool intrinsic_clip(struct hlsl_ctx *ctx, return false; }
- if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD_NEG, condition, loc))) - return false; - hlsl_block_add_instr(params->instrs, jump); - + hlsl_block_add_jump(ctx, params->instrs, HLSL_IR_JUMP_DISCARD_NEG, condition, loc); return true; }
static bool intrinsic_cos(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *arg; - - if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + struct hlsl_ir_node *arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_COS, arg, loc); } @@ -3748,8 +3548,7 @@ static bool write_cosh_or_sinh(struct hlsl_ctx *ctx, static const char fn_name_sinh[] = "sinh"; static const char fn_name_cosh[] = "cosh";
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
type_name = arg->data_type->name; fn_name = sinh_mode ? fn_name_sinh : fn_name_cosh; @@ -3782,39 +3581,23 @@ static bool intrinsic_cross(struct hlsl_ctx *ctx, enum hlsl_base_type base;
base = expr_common_base_type(arg1->data_type->e.numeric.type, arg2->data_type->e.numeric.type); - if (type_is_integer(base)) + if (hlsl_base_type_is_integer(base)) base = HLSL_TYPE_FLOAT;
cast_type = hlsl_get_vector_type(ctx, base, 3);
- if (!(arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc))) - return false; - - if (!(arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc))) - return false; - - if (!(arg1_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc))) - return false; - hlsl_block_add_instr(params->instrs, arg1_swzl1); - - if (!(arg2_swzl1 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc))) - return false; - hlsl_block_add_instr(params->instrs, arg2_swzl1); + arg1_cast = add_implicit_conversion(ctx, params->instrs, arg1, cast_type, loc); + arg2_cast = add_implicit_conversion(ctx, params->instrs, arg2, cast_type, loc); + arg1_swzl1 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg1_cast, loc); + arg2_swzl1 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg2_cast, loc);
if (!(mul1 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl1, arg2_swzl1, loc))) return false;
- if (!(mul1_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, loc))) - return false; - hlsl_block_add_instr(params->instrs, mul1_neg); + mul1_neg = hlsl_block_add_unary_expr(ctx, params->instrs, HLSL_OP1_NEG, mul1, loc);
- if (!(arg1_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc))) - return false; - hlsl_block_add_instr(params->instrs, arg1_swzl2); - - if (!(arg2_swzl2 = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc))) - return false; - hlsl_block_add_instr(params->instrs, arg2_swzl2); + arg1_swzl2 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Y, Z, X, Y), 3, arg1_cast, loc); + arg2_swzl2 = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, X, Y, Z), 3, arg2_cast, loc);
if (!(mul2 = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg1_swzl2, arg2_swzl2, loc))) return false; @@ -3827,8 +3610,7 @@ static bool intrinsic_ddx(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX, arg, loc); } @@ -3838,8 +3620,7 @@ static bool intrinsic_ddx_coarse(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX_COARSE, arg, loc); } @@ -3849,8 +3630,7 @@ static bool intrinsic_ddx_fine(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSX_FINE, arg, loc); } @@ -3860,8 +3640,7 @@ static bool intrinsic_ddy(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY, arg, loc); } @@ -3871,8 +3650,7 @@ static bool intrinsic_ddy_coarse(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY_COARSE, arg, loc); } @@ -3882,14 +3660,10 @@ static bool intrinsic_degrees(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg, *deg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
/* 1 rad = 180/pi degree = 57.2957795 degree */ - if (!(deg = hlsl_new_float_constant(ctx, 57.2957795f, loc))) - return false; - hlsl_block_add_instr(params->instrs, deg); - + deg = hlsl_block_add_float_constant(ctx, params->instrs, 57.2957795f, loc); return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, deg, loc); }
@@ -3898,8 +3672,7 @@ static bool intrinsic_ddy_fine(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_DSY_FINE, arg, loc); } @@ -3953,8 +3726,7 @@ static bool intrinsic_determinant(struct hlsl_ctx *ctx, return false; }
- if (!(arg = intrinsic_float_convert_arg(ctx, params, arg, loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, arg, loc);
dim = min(type->e.numeric.dimx, type->e.numeric.dimy); if (dim == 1) @@ -3996,11 +3768,8 @@ static bool intrinsic_distance(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg1, *arg2, *neg, *add, *dot;
- if (!(arg1 = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; - - if (!(arg2 = intrinsic_float_convert_arg(ctx, params, params->args[1], loc))) - return false; + arg1 = intrinsic_float_convert_arg(ctx, params, params->args[0], loc); + arg2 = intrinsic_float_convert_arg(ctx, params, params->args[1], loc);
if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, arg2, loc))) return false; @@ -4069,13 +3838,10 @@ static bool intrinsic_exp(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg, *mul, *coeff;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
/* 1/ln(2) */ - if (!(coeff = hlsl_new_float_constant(ctx, 1.442695f, loc))) - return false; - hlsl_block_add_instr(params->instrs, coeff); + coeff = hlsl_block_add_float_constant(ctx, params->instrs, 1.442695f, loc);
if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, coeff, arg, loc))) return false; @@ -4088,8 +3854,7 @@ static bool intrinsic_exp2(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, arg, loc); } @@ -4157,8 +3922,7 @@ static bool intrinsic_floor(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FLOOR, arg, loc); } @@ -4170,11 +3934,8 @@ static bool intrinsic_fmod(struct hlsl_ctx *ctx, const struct parse_initializer struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; static const struct hlsl_constant_value zero_value;
- if (!(x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; - - if (!(y = intrinsic_float_convert_arg(ctx, params, params->args[1], loc))) - return false; + x = intrinsic_float_convert_arg(ctx, params, params->args[0], loc); + y = intrinsic_float_convert_arg(ctx, params, params->args[1], loc);
if (!(div = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, x, y, loc))) return false; @@ -4209,8 +3970,7 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); } @@ -4285,8 +4045,7 @@ static bool intrinsic_length(struct hlsl_ctx *ctx, hlsl_release_string_buffer(ctx, string); }
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) return false; @@ -4314,21 +4073,6 @@ static bool intrinsic_lerp(struct hlsl_ctx *ctx, return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_ADD, params->args[0], mul, loc); }
-static struct hlsl_ir_node * add_pow_expr(struct hlsl_ctx *ctx, - struct hlsl_block *instrs, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, - const struct vkd3d_shader_location *loc) -{ - struct hlsl_ir_node *log, *mul; - - if (!(log = add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_LOG2, arg1, loc))) - return NULL; - - if (!(mul = add_binary_arithmetic_expr(ctx, instrs, HLSL_OP2_MUL, arg2, log, loc))) - return NULL; - - return add_unary_arithmetic_expr(ctx, instrs, HLSL_OP1_EXP2, mul, loc); -} - static bool intrinsic_lit(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -4363,17 +4107,13 @@ static bool intrinsic_log(struct hlsl_ctx *ctx, { struct hlsl_ir_node *log, *arg, *coeff;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
if (!(log = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc))) return false;
/* ln(2) */ - if (!(coeff = hlsl_new_float_constant(ctx, 0.69314718055f, loc))) - return false; - hlsl_block_add_instr(params->instrs, coeff); - + coeff = hlsl_block_add_float_constant(ctx, params->instrs, 0.69314718055f, loc); return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, log, coeff, loc); }
@@ -4382,17 +4122,13 @@ static bool intrinsic_log10(struct hlsl_ctx *ctx, { struct hlsl_ir_node *log, *arg, *coeff;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
if (!(log = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc))) return false;
/* 1 / log2(10) */ - if (!(coeff = hlsl_new_float_constant(ctx, 0.301029996f, loc))) - return false; - hlsl_block_add_instr(params->instrs, coeff); - + coeff = hlsl_block_add_float_constant(ctx, params->instrs, 0.301029996f, loc); return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, log, coeff, loc); }
@@ -4401,8 +4137,7 @@ static bool intrinsic_log2(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, arg, loc); } @@ -4476,7 +4211,7 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, struct hlsl_type *cast_type1 = arg1->data_type, *cast_type2 = arg2->data_type, *matrix_type, *ret_type; unsigned int i, j, k, vect_count = 0; struct hlsl_deref var_deref; - struct hlsl_ir_load *load; + struct hlsl_ir_node *load; struct hlsl_ir_var *var;
if (arg1->data_type->class == HLSL_CLASS_SCALAR || arg2->data_type->class == HLSL_CLASS_SCALAR) @@ -4510,11 +4245,8 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, ret_type = hlsl_get_scalar_type(ctx, base); }
- if (!(cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc))) - return false; - - if (!(cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc))) - return false; + cast1 = add_implicit_conversion(ctx, params->instrs, arg1, cast_type1, loc); + cast2 = add_implicit_conversion(ctx, params->instrs, arg2, cast_type2, loc);
if (!(var = hlsl_new_synthetic_var(ctx, "mul", matrix_type, loc))) return false; @@ -4525,19 +4257,15 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, for (j = 0; j < matrix_type->e.numeric.dimy; ++j) { struct hlsl_ir_node *instr = NULL; - struct hlsl_block block;
for (k = 0; k < cast_type1->e.numeric.dimx && k < cast_type2->e.numeric.dimy; ++k) { struct hlsl_ir_node *value1, *value2, *mul;
- if (!(value1 = hlsl_add_load_component(ctx, params->instrs, - cast1, j * cast1->data_type->e.numeric.dimx + k, loc))) - return false; - - if (!(value2 = hlsl_add_load_component(ctx, params->instrs, - cast2, k * cast2->data_type->e.numeric.dimx + i, loc))) - return false; + value1 = hlsl_add_load_component(ctx, params->instrs, + cast1, j * cast1->data_type->e.numeric.dimx + k, loc); + value2 = hlsl_add_load_component(ctx, params->instrs, + cast2, k * cast2->data_type->e.numeric.dimx + i, loc);
if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, value1, value2, loc))) return false; @@ -4553,17 +4281,14 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, } }
- if (!hlsl_new_store_component(ctx, &block, &var_deref, j * matrix_type->e.numeric.dimx + i, instr)) - return false; - hlsl_block_add_block(params->instrs, &block); + hlsl_block_add_store_component(ctx, params->instrs, &var_deref, + j * matrix_type->e.numeric.dimx + i, instr); } }
- if (!(load = hlsl_new_var_load(ctx, var, loc))) - return false; - hlsl_block_add_instr(params->instrs, &load->node); - - return !!add_implicit_conversion(ctx, params->instrs, &load->node, ret_type, loc); + load = hlsl_block_add_simple_load(ctx, params->instrs, var, loc); + add_implicit_conversion(ctx, params->instrs, load, ret_type, loc); + return true; }
static bool intrinsic_normalize(struct hlsl_ctx *ctx, @@ -4582,8 +4307,7 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, hlsl_release_string_buffer(ctx, string); }
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
if (!(dot = add_binary_dot_expr(ctx, params->instrs, arg, arg, loc))) return false; @@ -4597,10 +4321,18 @@ static bool intrinsic_normalize(struct hlsl_ctx *ctx, static bool intrinsic_pow(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { + struct hlsl_ir_node *log, *mul; + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) return false;
- return !!add_pow_expr(ctx, params->instrs, params->args[0], params->args[1], loc); + if (!(log = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_LOG2, params->args[0], loc))) + return NULL; + + if (!(mul = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, params->args[1], log, loc))) + return NULL; + + return add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_EXP2, mul, loc); }
static bool intrinsic_radians(struct hlsl_ctx *ctx, @@ -4608,14 +4340,10 @@ static bool intrinsic_radians(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg, *rad;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
/* 1 degree = pi/180 rad = 0.0174532925f rad */ - if (!(rad = hlsl_new_float_constant(ctx, 0.0174532925f, loc))) - return false; - hlsl_block_add_instr(params->instrs, rad); - + rad = hlsl_block_add_float_constant(ctx, params->instrs, 0.0174532925f, loc); return !!add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, rad, loc); }
@@ -4624,8 +4352,7 @@ static bool intrinsic_rcp(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RCP, arg, loc); } @@ -4656,7 +4383,6 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, { struct hlsl_type *type, *scalar_type; struct hlsl_ir_function_decl *func; - struct hlsl_ir_node *index; char *body;
static const char template[] = @@ -4686,9 +4412,7 @@ static bool intrinsic_refract(struct hlsl_ctx *ctx, * which we will only use the first component of. */
scalar_type = hlsl_get_scalar_type(ctx, params->args[2]->data_type->e.numeric.type); - if (!(index = add_implicit_conversion(ctx, params->instrs, params->args[2], scalar_type, loc))) - return false; - params->args[2] = index; + params->args[2] = add_implicit_conversion(ctx, params->instrs, params->args[2], scalar_type, loc);
if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) return false; @@ -4711,8 +4435,7 @@ static bool intrinsic_round(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_ROUND, arg, loc); } @@ -4722,8 +4445,7 @@ static bool intrinsic_rsqrt(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_RSQ, arg, loc); } @@ -4733,8 +4455,7 @@ static bool intrinsic_saturate(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SAT, arg, loc); } @@ -4757,16 +4478,14 @@ static bool intrinsic_sign(struct hlsl_ctx *ctx, if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, zero, arg, loc))) return false;
- if (!(op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) - return false; + op1 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc);
/* Check if arg < 0, cast bool to int and invert (meaning true is -1) */
if (!(lt = add_binary_comparison_expr(ctx, params->instrs, HLSL_OP2_LESS, arg, zero, loc))) return false;
- if (!(op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc))) - return false; + op2 = add_implicit_conversion(ctx, params->instrs, lt, int_type, loc);
if (!(neg = add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_NEG, op2, loc))) return false; @@ -4780,8 +4499,7 @@ static bool intrinsic_sin(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SIN, arg, loc); } @@ -4855,8 +4573,7 @@ static bool intrinsic_sqrt(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg;
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_SQRT, arg, loc); } @@ -4875,7 +4592,8 @@ static bool intrinsic_step(struct hlsl_ctx *ctx, params->args[1], params->args[0], loc))) return false;
- return !!add_implicit_conversion(ctx, params->instrs, ge, type, loc); + add_implicit_conversion(ctx, params->instrs, ge, type, loc); + return true; }
static bool intrinsic_tan(struct hlsl_ctx *ctx, @@ -4909,8 +4627,7 @@ static bool intrinsic_tanh(struct hlsl_ctx *ctx, " return (exp_pos - exp_neg) / (exp_pos + exp_neg);\n" "}\n";
- if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc); type = arg->data_type;
if (!(body = hlsl_sprintf_alloc(ctx, template, @@ -4931,7 +4648,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * unsigned int sampler_dim = hlsl_sampler_dim_count(dim); struct hlsl_resource_load_params load_params = { 0 }; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *coords, *sample; + struct hlsl_ir_node *coords;
if (params->args_count != 2 && params->args_count != 4) { @@ -4963,47 +4680,27 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * else load_params.type = HLSL_RESOURCE_SAMPLE_LOD_BIAS;
- if (!(c = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc))) - return false; - hlsl_block_add_instr(params->instrs, c); - - if (!(coords = add_implicit_conversion(ctx, params->instrs, c, - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - { - return false; - } + c = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, params->args[1], loc); + coords = add_implicit_conversion(ctx, params->instrs, c, + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
- if (!(lod = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc))) - return false; - hlsl_block_add_instr(params->instrs, lod); - - if (!(load_params.lod = add_implicit_conversion(ctx, params->instrs, lod, - hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - { - return false; - } + lod = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(W, W, W, W), 1, params->args[1], loc); + load_params.lod = add_implicit_conversion(ctx, params->instrs, lod, + hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc); } else if (!strcmp(name, "tex2Dproj") || !strcmp(name, "tex3Dproj") || !strcmp(name, "texCUBEproj")) { - if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), loc))) - { - return false; - } + coords = add_implicit_conversion(ctx, params->instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), loc);
if (hlsl_version_ge(ctx, 4, 0)) { struct hlsl_ir_node *divisor;
- if (!(divisor = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(W, W, W, W), sampler_dim, coords, loc))) - return false; - hlsl_block_add_instr(params->instrs, divisor); - - if (!(coords = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, coords, loc))) - return false; - hlsl_block_add_instr(params->instrs, coords); + divisor = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(W, W, W, W), sampler_dim, coords, loc); + coords = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(X, Y, Z, W), sampler_dim, coords, loc);
if (!(coords = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_DIV, coords, divisor, loc))) return false; @@ -5017,43 +4714,25 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * } else if (params->args_count == 4) /* Gradient sampling. */ { - if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - { - return false; - } - - if (!(load_params.ddx = add_implicit_conversion(ctx, params->instrs, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - { - return false; - } - - if (!(load_params.ddy = add_implicit_conversion(ctx, params->instrs, params->args[3], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - { - return false; - } - + coords = add_implicit_conversion(ctx, params->instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); + load_params.ddx = add_implicit_conversion(ctx, params->instrs, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); + load_params.ddy = add_implicit_conversion(ctx, params->instrs, params->args[3], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); load_params.type = HLSL_RESOURCE_SAMPLE_GRAD; } else { load_params.type = HLSL_RESOURCE_SAMPLE; - - if (!(coords = add_implicit_conversion(ctx, params->instrs, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - { - return false; - } + coords = add_implicit_conversion(ctx, params->instrs, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); }
/* tex1D() functions never produce 1D resource declarations. For newer profiles half offset is used for the second coordinate, while older ones appear to replicate first coordinate.*/ if (dim == HLSL_SAMPLER_DIM_1D) { - struct hlsl_ir_load *load; - struct hlsl_ir_node *half; struct hlsl_ir_var *var; unsigned int idx = 0;
@@ -5062,22 +4741,10 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer *
initialize_var_components(ctx, params->instrs, var, &idx, coords, false); if (hlsl_version_ge(ctx, 4, 0)) - { - if (!(half = hlsl_new_float_constant(ctx, 0.5f, loc))) - return false; - hlsl_block_add_instr(params->instrs, half); - - initialize_var_components(ctx, params->instrs, var, &idx, half, false); - } - else - initialize_var_components(ctx, params->instrs, var, &idx, coords, false); - - if (!(load = hlsl_new_var_load(ctx, var, loc))) - return false; - hlsl_block_add_instr(params->instrs, &load->node); - - coords = &load->node; + coords = hlsl_block_add_float_constant(ctx, params->instrs, 0.5f, loc); + initialize_var_components(ctx, params->instrs, var, &idx, coords, false);
+ coords = hlsl_block_add_simple_load(ctx, params->instrs, var, loc); dim = HLSL_SAMPLER_DIM_2D; }
@@ -5086,9 +4753,7 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); load_params.sampling_dim = dim;
- if (!(sample = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(params->instrs, sample); + hlsl_block_add_resource_load(ctx, params->instrs, &load_params, loc); return true; }
@@ -5175,7 +4840,6 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { struct hlsl_ir_node *arg = params->args[0]; struct hlsl_type *arg_type = arg->data_type; - struct hlsl_ir_load *var_load; struct hlsl_deref var_deref; struct hlsl_type *mat_type; struct hlsl_ir_node *load; @@ -5210,32 +4874,21 @@ static bool intrinsic_transpose(struct hlsl_ctx *ctx, { for (j = 0; j < arg_type->e.numeric.dimy; ++j) { - struct hlsl_block block; - - if (!(load = hlsl_add_load_component(ctx, params->instrs, arg, - j * arg->data_type->e.numeric.dimx + i, loc))) - return false; - - if (!hlsl_new_store_component(ctx, &block, &var_deref, i * var->data_type->e.numeric.dimx + j, load)) - return false; - hlsl_block_add_block(params->instrs, &block); + load = hlsl_add_load_component(ctx, params->instrs, arg, + j * arg->data_type->e.numeric.dimx + i, loc); + hlsl_block_add_store_component(ctx, params->instrs, &var_deref, + i * var->data_type->e.numeric.dimx + j, load); } }
- if (!(var_load = hlsl_new_var_load(ctx, var, loc))) - return false; - hlsl_block_add_instr(params->instrs, &var_load->node); - + hlsl_block_add_simple_load(ctx, params->instrs, var, loc); return true; }
static bool intrinsic_trunc(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *arg; - - if (!(arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc))) - return false; + struct hlsl_ir_node *arg = intrinsic_float_convert_arg(ctx, params, params->args[0], loc);
return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_TRUNC, arg, loc); } @@ -5243,7 +4896,7 @@ static bool intrinsic_trunc(struct hlsl_ctx *ctx, static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *arg = params->args[0], *ret, *c, *swizzle; + struct hlsl_ir_node *arg = params->args[0], *ret, *c; struct hlsl_type *arg_type = arg->data_type;
if (arg_type->class != HLSL_CLASS_SCALAR && !(arg_type->class == HLSL_CLASS_VECTOR @@ -5260,21 +4913,11 @@ static bool intrinsic_d3dcolor_to_ubyte4(struct hlsl_ctx *ctx, return false; }
- if (!(arg = intrinsic_float_convert_arg(ctx, params, arg, loc))) - return false; - - if (!(c = hlsl_new_float_constant(ctx, 255.0f + (0.5f / 256.0f), loc))) - return false; - hlsl_block_add_instr(params->instrs, c); + arg = intrinsic_float_convert_arg(ctx, params, arg, loc); + c = hlsl_block_add_float_constant(ctx, params->instrs, 255.0f + (0.5f / 256.0f), loc);
if (arg_type->class == HLSL_CLASS_VECTOR) - { - if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Z, Y, X, W), 4, arg, loc))) - return false; - hlsl_block_add_instr(params->instrs, swizzle); - - arg = swizzle; - } + arg = hlsl_block_add_swizzle(ctx, params->instrs, HLSL_SWIZZLE(Z, Y, X, W), 4, arg, loc);
if (!(ret = add_binary_arithmetic_expr(ctx, params->instrs, HLSL_OP2_MUL, arg, c, loc))) return false; @@ -5289,25 +4932,20 @@ static bool intrinsic_GetRenderTargetSampleCount(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_ir_node *expr;
if (ctx->profile->type != VKD3D_SHADER_TYPE_PIXEL || hlsl_version_lt(ctx, 4, 1)) hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, "GetRenderTargetSampleCount() can only be used from a pixel shader using version 4.1 or higher.");
- if (!(expr = hlsl_new_expr(ctx, HLSL_OP0_RASTERIZER_SAMPLE_COUNT, - operands, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))) - return false; - hlsl_block_add_instr(params->instrs, expr); - + hlsl_block_add_expr(ctx, params->instrs, HLSL_OP0_RASTERIZER_SAMPLE_COUNT, + operands, hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, 1), loc); return true; }
static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op op, const struct parse_initializer *params, const struct vkd3d_shader_location *loc, const char *name) { - struct hlsl_ir_node *lhs, *coords, *val, *cmp_val = NULL, *orig_val = NULL; - struct hlsl_ir_node *interlocked, *void_ret; + struct hlsl_ir_node *interlocked, *lhs, *coords, *val, *cmp_val = NULL, *orig_val = NULL; struct hlsl_type *lhs_type, *val_type; struct vkd3d_string_buffer *string; struct hlsl_deref dst_deref; @@ -5421,10 +5059,7 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op return false; }
- if (!(void_ret = hlsl_new_void_expr(ctx, loc))) - return false; - hlsl_block_add_instr(params->instrs, void_ret); - + add_void_expr(ctx, params->instrs, loc); return true; }
@@ -5482,6 +5117,67 @@ static bool intrinsic_InterlockedXor(struct hlsl_ctx *ctx, return intrinsic_interlocked(ctx, HLSL_INTERLOCKED_XOR, params, loc, "InterlockedXor"); }
+static void validate_group_barrier_profile(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) +{ + if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE || hlsl_version_lt(ctx, 5, 0)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "Group barriers can only be used in compute shaders 5.0 or higher."); + } +} + +static bool intrinsic_AllMemoryBarrier(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + validate_group_barrier_profile(ctx, loc); + return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV + | VKD3DSSF_GROUP_SHARED_MEMORY, loc); +} + +static bool intrinsic_AllMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + validate_group_barrier_profile(ctx, loc); + return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV + | VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc); +} + +static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + if ((ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE && ctx->profile->type != VKD3D_SHADER_TYPE_PIXEL) + || hlsl_version_lt(ctx, 5, 0)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "DeviceMemoryBarrier() can only be used in pixel and compute shaders 5.0 or higher."); + } + return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV, loc); +} + +static bool intrinsic_DeviceMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + validate_group_barrier_profile(ctx, loc); + return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV + | VKD3DSSF_THREAD_GROUP, loc); +} + +static bool intrinsic_GroupMemoryBarrier(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + validate_group_barrier_profile(ctx, loc); + return !!hlsl_block_add_sync(ctx, params->instrs, + VKD3DSSF_GROUP_SHARED_MEMORY, loc); +} + +static bool intrinsic_GroupMemoryBarrierWithGroupSync(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + validate_group_barrier_profile(ctx, loc); + return !!hlsl_block_add_sync(ctx, params->instrs, + VKD3DSSF_GROUP_SHARED_MEMORY | VKD3DSSF_THREAD_GROUP, loc); +} + static const struct intrinsic_function { const char *name; @@ -5493,8 +5189,14 @@ static const struct intrinsic_function intrinsic_functions[] = { /* Note: these entries should be kept in alphabetical order. */ + {"AllMemoryBarrier", 0, true, intrinsic_AllMemoryBarrier}, + {"AllMemoryBarrierWithGroupSync", 0, true, intrinsic_AllMemoryBarrierWithGroupSync}, {"D3DCOLORtoUBYTE4", 1, true, intrinsic_d3dcolor_to_ubyte4}, + {"DeviceMemoryBarrier", 0, true, intrinsic_DeviceMemoryBarrier}, + {"DeviceMemoryBarrierWithGroupSync", 0, true, intrinsic_DeviceMemoryBarrierWithGroupSync}, {"GetRenderTargetSampleCount", 0, true, intrinsic_GetRenderTargetSampleCount}, + {"GroupMemoryBarrier", 0, true, intrinsic_GroupMemoryBarrier}, + {"GroupMemoryBarrierWithGroupSync", 0, true, intrinsic_GroupMemoryBarrierWithGroupSync}, {"InterlockedAdd", -1, true, intrinsic_InterlockedAdd}, {"InterlockedAnd", -1, true, intrinsic_InterlockedAnd}, {"InterlockedCompareExchange", 4, true, intrinsic_InterlockedCompareExchange}, @@ -5759,7 +5461,6 @@ static struct hlsl_block *add_compile_variant(struct hlsl_ctx *ctx, enum hlsl_co static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type *type, struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_load *load; struct hlsl_ir_var *var;
if (!hlsl_is_numeric_type(type)) @@ -5778,9 +5479,7 @@ static struct hlsl_block *add_constructor(struct hlsl_ctx *ctx, struct hlsl_type
initialize_var(ctx, var, params, false);
- if (!(load = hlsl_new_var_load(ctx, var, loc))) - return NULL; - hlsl_block_add_instr(params->instrs, &load->node); + hlsl_block_add_simple_load(ctx, params->instrs, var, loc);
vkd3d_free(params->args); return params->instrs; @@ -5822,8 +5521,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block, { cond_type = hlsl_get_numeric_type(ctx, common_type->class, HLSL_TYPE_BOOL, common_type->e.numeric.dimx, common_type->e.numeric.dimy); - if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc))) - return false; + cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc); } else { @@ -5852,15 +5550,11 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
cond_type = hlsl_get_numeric_type(ctx, common_type->class, HLSL_TYPE_BOOL, common_type->e.numeric.dimx, common_type->e.numeric.dimy); - if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc))) - return false; + cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc); }
- if (!(first = add_implicit_conversion(ctx, block, first, common_type, &first->loc))) - return false; - - if (!(second = add_implicit_conversion(ctx, block, second, common_type, &second->loc))) - return false; + first = add_implicit_conversion(ctx, block, first, common_type, &first->loc); + second = add_implicit_conversion(ctx, block, second, common_type, &second->loc); } else { @@ -5880,9 +5574,7 @@ static bool add_ternary(struct hlsl_ctx *ctx, struct hlsl_block *block,
cond_type = hlsl_get_numeric_type(ctx, cond_type->class, HLSL_TYPE_BOOL, cond_type->e.numeric.dimx, cond_type->e.numeric.dimy); - if (!(cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc))) - return false; - + cond = add_implicit_conversion(ctx, block, cond, cond_type, &cond->loc); common_type = first->data_type; }
@@ -5935,7 +5627,6 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; - struct hlsl_ir_node *load; unsigned int value_dim;
if (params->args_count != 1 && params->args_count != 2) @@ -5967,16 +5658,11 @@ static bool add_raw_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bl else value_dim = 4;
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[0], - hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))) - return false; - + load_params.coords = add_implicit_conversion(ctx, block, params->args[0], + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim); load_params.resource = object; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
@@ -5986,7 +5672,6 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_type *object_type = object->data_type; struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_LOAD}; unsigned int sampler_dim, offset_dim; - struct hlsl_ir_node *load; bool multisampled;
if (object_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) @@ -6012,19 +5697,13 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, return false; }
- if (multisampled) - { - if (!(load_params.sample_index = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc))) - return false; - } + if (multisampled) + load_params.sample_index = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc);
if (!!offset_dim && params->args_count > 1 + multisampled) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[1 + multisampled], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } + load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[1 + multisampled], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
if (params->args_count > 1 + multisampled + !!offset_dim) { @@ -6032,16 +5711,11 @@ static bool add_load_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, }
/* +1 for the mipmap level for non-multisampled textures */ - if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[0], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc))) - return false; - + load_params.coords = add_implicit_conversion(ctx, block, params->args[0], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, sampler_dim + !multisampled), loc); load_params.format = object_type->e.resource.format; load_params.resource = object; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
@@ -6052,7 +5726,6 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc struct hlsl_resource_load_params load_params = {.type = HLSL_RESOURCE_SAMPLE}; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load;
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -6077,16 +5750,12 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; + load_params.coords = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
if (offset_dim && params->args_count > 2) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } + load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
if (params->args_count > 2 + !!offset_dim) hlsl_fixme(ctx, loc, "Sample() clamp parameter."); @@ -6096,11 +5765,7 @@ static bool add_sample_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); - + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
@@ -6111,7 +5776,6 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * struct hlsl_resource_load_params load_params = { 0 }; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load;
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -6142,20 +5806,14 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; - - if (!(load_params.cmp = add_implicit_conversion(ctx, block, params->args[2], - hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - load_params.cmp = params->args[2]; + load_params.coords = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); + load_params.cmp = add_implicit_conversion(ctx, block, params->args[2], + hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc);
if (offset_dim && params->args_count > 3) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } + load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
if (params->args_count > 3 + !!offset_dim) hlsl_fixme(ctx, loc, "%s() clamp parameter.", name); @@ -6165,11 +5823,7 @@ static bool add_sample_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); - + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
@@ -6180,7 +5834,6 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc struct hlsl_resource_load_params load_params = {0}; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load; unsigned int read_channel;
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); @@ -6234,9 +5887,8 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc } else if (offset_dim && params->args_count > 2) { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; + load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc); }
sampler_type = params->args[0]->data_type; @@ -6258,17 +5910,12 @@ static bool add_gather_method_call(struct hlsl_ctx *ctx, struct hlsl_block *bloc return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - return false; - + load_params.coords = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4); load_params.resource = object; load_params.sampler = params->args[0]; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
@@ -6279,7 +5926,6 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * struct hlsl_resource_load_params load_params = {0}; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load;
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -6346,10 +5992,7 @@ static bool add_gather_cmp_method_call(struct hlsl_ctx *ctx, struct hlsl_block * load_params.format = hlsl_get_vector_type(ctx, object_type->e.resource.format->e.numeric.type, 4); load_params.resource = object; load_params.sampler = params->args[0]; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
@@ -6361,9 +6004,7 @@ static bool add_assignment_from_component(struct hlsl_ctx *ctx, struct hlsl_bloc if (!dest) return true;
- if (!(load = hlsl_add_load_component(ctx, instrs, src, component, loc))) - return false; - + load = hlsl_add_load_component(ctx, instrs, src, component, loc); if (!add_assignment(ctx, instrs, dest, ASSIGN_OP_ASSIGN, load, false)) return false;
@@ -6377,7 +6018,6 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc bool uint_resinfo, has_uint_arg, has_float_arg; struct hlsl_resource_load_params load_params; struct hlsl_ir_node *sample_info, *res_info; - struct hlsl_ir_node *zero = NULL, *void_ret; struct hlsl_type *uint_type, *float_type; unsigned int i, j; enum func_argument @@ -6441,12 +6081,8 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc /* Input parameter. */ if (iter->args[j] == ARG_MIP_LEVEL) { - if (!(args[ARG_MIP_LEVEL] = add_implicit_conversion(ctx, block, args[ARG_MIP_LEVEL], - hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))) - { - return false; - } - + args[ARG_MIP_LEVEL] = add_implicit_conversion(ctx, block, args[ARG_MIP_LEVEL], + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); continue; }
@@ -6478,22 +6114,14 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc }
if (!args[ARG_MIP_LEVEL]) - { - if (!(zero = hlsl_new_uint_constant(ctx, 0, loc))) - return false; - hlsl_block_add_instr(block, zero); - args[ARG_MIP_LEVEL] = zero; - } + args[ARG_MIP_LEVEL] = hlsl_block_add_uint_constant(ctx, block, 0, loc);
memset(&load_params, 0, sizeof(load_params)); load_params.type = HLSL_RESOURCE_RESINFO; load_params.resource = object; load_params.lod = args[ARG_MIP_LEVEL]; load_params.format = hlsl_get_vector_type(ctx, uint_resinfo ? HLSL_TYPE_UINT : HLSL_TYPE_FLOAT, 4); - - if (!(res_info = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, res_info); + res_info = hlsl_block_add_resource_load(ctx, block, &load_params, loc);
if (!add_assignment_from_component(ctx, block, args[ARG_WIDTH], res_info, 0, loc)) return false; @@ -6516,18 +6144,13 @@ static bool add_getdimensions_method_call(struct hlsl_ctx *ctx, struct hlsl_bloc load_params.type = HLSL_RESOURCE_SAMPLE_INFO; load_params.resource = object; load_params.format = args[ARG_SAMPLE_COUNT]->data_type; - if (!(sample_info = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, sample_info); + sample_info = hlsl_block_add_resource_load(ctx, block, &load_params, loc);
if (!add_assignment(ctx, block, args[ARG_SAMPLE_COUNT], ASSIGN_OP_ASSIGN, sample_info, false)) return false; }
- if (!(void_ret = hlsl_new_void_expr(ctx, loc))) - return false; - hlsl_block_add_instr(block, void_ret); - + add_void_expr(ctx, block, loc); return true; }
@@ -6538,7 +6161,6 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * struct hlsl_resource_load_params load_params = { 0 }; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load;
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -6568,20 +6190,14 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - load_params.coords = params->args[1]; - - if (!(load_params.lod = add_implicit_conversion(ctx, block, params->args[2], - hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc))) - load_params.lod = params->args[2]; + load_params.coords = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); + load_params.lod = add_implicit_conversion(ctx, block, params->args[2], + hlsl_get_scalar_type(ctx, HLSL_TYPE_FLOAT), loc);
if (offset_dim && params->args_count > 3) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } + load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[3], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
if (params->args_count > 3 + !!offset_dim) hlsl_fixme(ctx, loc, "Tiled resource status argument."); @@ -6589,10 +6205,7 @@ static bool add_sample_lod_method_call(struct hlsl_ctx *ctx, struct hlsl_block * load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
@@ -6603,7 +6216,6 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block struct hlsl_resource_load_params load_params = { 0 }; unsigned int sampler_dim, offset_dim; const struct hlsl_type *sampler_type; - struct hlsl_ir_node *load;
sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); offset_dim = hlsl_offset_dim_count(object_type->sampler_dim); @@ -6630,24 +6242,16 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block return false; }
- if (!(load_params.coords = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - load_params.coords = params->args[1]; - - if (!(load_params.ddx = add_implicit_conversion(ctx, block, params->args[2], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - load_params.ddx = params->args[2]; - - if (!(load_params.ddy = add_implicit_conversion(ctx, block, params->args[3], - hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc))) - load_params.ddy = params->args[3]; + load_params.coords = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); + load_params.ddx = add_implicit_conversion(ctx, block, params->args[2], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc); + load_params.ddy = add_implicit_conversion(ctx, block, params->args[3], + hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, sampler_dim), loc);
if (offset_dim && params->args_count > 4) - { - if (!(load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[4], - hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc))) - return false; - } + load_params.texel_offset = add_implicit_conversion(ctx, block, params->args[4], + hlsl_get_vector_type(ctx, HLSL_TYPE_INT, offset_dim), loc);
if (params->args_count > 4 + !!offset_dim) hlsl_fixme(ctx, loc, "Tiled resource status argument."); @@ -6655,17 +6259,14 @@ static bool add_sample_grad_method_call(struct hlsl_ctx *ctx, struct hlsl_block load_params.format = object_type->e.resource.format; load_params.resource = object; load_params.sampler = params->args[0]; - - if (!(load = hlsl_new_resource_load(ctx, &load_params, loc))) - return false; - hlsl_block_add_instr(block, load); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); return true; }
static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *offset, *rhs, *store; + struct hlsl_ir_node *offset, *rhs; struct hlsl_deref resource_deref; unsigned int value_dim;
@@ -6685,25 +6286,62 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block else value_dim = 4;
- if (!(offset = add_implicit_conversion(ctx, block, params->args[0], - hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc))) + offset = add_implicit_conversion(ctx, block, params->args[0], + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); + rhs = add_implicit_conversion(ctx, block, params->args[1], + hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc); + + if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) + return false; + + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc); + hlsl_cleanup_deref(&resource_deref); + + return true; +} + +static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_deref so_deref; + struct hlsl_ir_node *rhs; + + if (params->args_count != 1) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected 1.", name); return false; + }
- if (!(rhs = add_implicit_conversion(ctx, block, params->args[1], - hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc))) + if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) return false;
- if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) + if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc))) return false;
- if (!(store = hlsl_new_resource_store(ctx, &resource_deref, offset, rhs, loc))) + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc); + hlsl_cleanup_deref(&so_deref); + + return true; +} + +static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *object, + const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_deref so_deref; + + if (params->args_count) { - hlsl_cleanup_deref(&resource_deref); + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Wrong number of arguments to method '%s': expected 0.", name); return false; }
- hlsl_block_add_instr(block, store); - hlsl_cleanup_deref(&resource_deref); + if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) + return false; + + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc); + hlsl_cleanup_deref(&so_deref);
return true; } @@ -6751,6 +6389,12 @@ static const struct method_function uav_methods[] = { "Store4", add_store_method_call, "00000000000001" }, };
+static const struct method_function so_methods[] = +{ + { "Append", add_so_append_method_call, "" }, + { "RestartStrip", add_so_restartstrip_method_call, "" }, +}; + static int object_method_function_name_compare(const void *a, const void *b) { const struct method_function *func = b; @@ -6762,8 +6406,7 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru const char *name, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { const struct hlsl_type *object_type = object->data_type; - const struct method_function *method, *methods; - unsigned int count; + const struct method_function *method;
if (object_type->class == HLSL_CLASS_ERROR) { @@ -6782,13 +6425,24 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru
if (object_type->class == HLSL_CLASS_TEXTURE) { - count = ARRAY_SIZE(texture_methods); - methods = texture_methods; + method = bsearch(name, texture_methods, ARRAY_SIZE(texture_methods), sizeof(*method), + object_method_function_name_compare); + + if (method && method->valid_dims[object_type->sampler_dim] != '1') + method = NULL; } else if (object_type->class == HLSL_CLASS_UAV) { - count = ARRAY_SIZE(uav_methods); - methods = uav_methods; + method = bsearch(name, uav_methods, ARRAY_SIZE(uav_methods), sizeof(*method), + object_method_function_name_compare); + + if (method && method->valid_dims[object_type->sampler_dim] != '1') + method = NULL; + } + else if (object_type->class == HLSL_CLASS_STREAM_OUTPUT) + { + method = bsearch(name, so_methods, ARRAY_SIZE(so_methods), sizeof(*method), + object_method_function_name_compare); } else { @@ -6801,17 +6455,70 @@ static bool add_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block, stru return false; }
- method = bsearch(name, methods, count, sizeof(*method), - object_method_function_name_compare); - - if (method && method->valid_dims[object_type->sampler_dim] == '1') - { + if (method) return method->handler(ctx, block, object, name, params, loc); - } else - { return raise_invalid_method_object_type(ctx, object_type, name, loc); +} + +static bool add_object_property_access(struct hlsl_ctx *ctx, + struct hlsl_block *block, struct hlsl_ir_node *object, const char *name, + const struct vkd3d_shader_location *loc) +{ + const struct hlsl_type *object_type = object->data_type; + struct hlsl_resource_load_params load_params; + struct hlsl_ir_node *zero; + unsigned int sampler_dim; + + if (!strcmp(name, "Length")) + { + if (object_type->class != HLSL_CLASS_TEXTURE && object_type->class != HLSL_CLASS_UAV) + return false; + + sampler_dim = hlsl_sampler_dim_count(object_type->sampler_dim); + + switch (object_type->sampler_dim) + { + case HLSL_SAMPLER_DIM_1D: + case HLSL_SAMPLER_DIM_2D: + case HLSL_SAMPLER_DIM_3D: + case HLSL_SAMPLER_DIM_1DARRAY: + case HLSL_SAMPLER_DIM_2DARRAY: + case HLSL_SAMPLER_DIM_2DMS: + case HLSL_SAMPLER_DIM_2DMSARRAY: + break; + + case HLSL_SAMPLER_DIM_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + hlsl_fixme(ctx, loc, "'Length' property for buffers."); + block->value = ctx->error_instr; + return true; + + default: + return false; + } + + if (hlsl_version_lt(ctx, 4, 0)) + { + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "'Length' property can only be used on profiles 4.0 or higher."); + block->value = ctx->error_instr; + return true; + } + + zero = hlsl_block_add_uint_constant(ctx, block, 0, loc); + + memset(&load_params, 0, sizeof(load_params)); + load_params.type = HLSL_RESOURCE_RESINFO; + load_params.resource = object; + load_params.lod = zero; + load_params.format = hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, sampler_dim); + hlsl_block_add_resource_load(ctx, block, &load_params, loc); + + return true; } + + return false; }
static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, @@ -6903,15 +6610,8 @@ static bool add_switch(struct hlsl_ctx *ctx, struct hlsl_block *block, return true; }
- if (!(selector = add_implicit_conversion(ctx, block, selector, - hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &selector->loc))) - { - destroy_switch_cases(cases); - destroy_block(block); - cleanup_parse_attribute_list(attributes); - return false; - } - + selector = add_implicit_conversion(ctx, block, selector, + hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), &selector->loc); s = hlsl_new_switch(ctx, selector, cases, loc);
destroy_switch_cases(cases); @@ -6990,7 +6690,6 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, bool boolval; char *name; uint32_t modifiers; - struct hlsl_ir_node *instr; struct hlsl_block *block; struct list *list; struct parse_fields fields; @@ -7052,6 +6751,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_INLINE %token KW_INOUT %token KW_INPUTPATCH +%token KW_LINE +%token KW_LINEADJ %token KW_LINEAR %token KW_LINESTREAM %token KW_MATRIX @@ -7064,6 +6765,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_PACKOFFSET %token KW_PASS %token KW_PIXELSHADER +%token KW_POINT %token KW_POINTSTREAM %token KW_RASTERIZERORDEREDBUFFER %token KW_RASTERIZERORDEREDSTRUCTUREDBUFFER @@ -7114,6 +6816,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_TEXTURE3D %token KW_TEXTURECUBE %token KW_TEXTURECUBEARRAY +%token KW_TRIANGLE +%token KW_TRIANGLEADJ %token KW_TRIANGLESTREAM %token KW_TRUE %token KW_TYPEDEF @@ -7157,6 +6861,8 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %type <list> variables_def %type <list> variables_def_typed %type <list> switch_cases +%destructor { destroy_parse_variable_defs($$); } type_specs variables_def variables_def_typed; +%destructor { destroy_switch_cases($$); } switch_cases;
%token <name> VAR_IDENTIFIER %token <name> NEW_IDENTIFIER @@ -7200,9 +6906,9 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %type <block> selection_statement %type <block> statement %type <block> statement_list -%type <block> struct_declaration_without_vars %type <block> switch_statement %type <block> unary_expr +%destructor { destroy_block($$); } <block>
%type <boolval> boolean
@@ -7253,6 +6959,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %type <state_block_index> state_block_index_opt
%type <switch_case> switch_case +%destructor { hlsl_free_ir_switch_case($$); } <switch_case>
%type <type> base_optional %type <type> field_type @@ -7269,6 +6976,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %type <variable_def> variable_decl %type <variable_def> variable_def %type <variable_def> variable_def_typed +%destructor { free_parse_variable_def($$); } <variable_def>
%%
@@ -7422,6 +7130,9 @@ buffer_type: declaration_statement_list: %empty | declaration_statement_list declaration_statement + { + destroy_block($2); + }
preproc_directive: PRE_LINE STRING @@ -7455,9 +7166,6 @@ struct_declaration_without_vars: if ($1) hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on struct type declarations."); - - if (!($$ = make_empty_block(ctx))) - YYABORT; }
struct_spec: @@ -8121,7 +7829,8 @@ parameter: parameter_decl: var_modifiers type_no_void any_identifier arrays colon_attributes { - uint32_t modifiers = $1; + uint32_t prim_modifiers = $1 & HLSL_PRIMITIVE_MODIFIERS_MASK; + uint32_t modifiers = $1 & ~HLSL_PRIMITIVE_MODIFIERS_MASK; struct hlsl_type *type; unsigned int i;
@@ -8146,6 +7855,22 @@ parameter_decl: } vkd3d_free($4.sizes);
+ if (prim_modifiers && (prim_modifiers & (prim_modifiers - 1))) + { + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Primitive type modifiers are mutually exclusive."); + prim_modifiers = 0; + } + + if (prim_modifiers) + { + if (type->class != HLSL_CLASS_ARRAY) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Primitive type modifiers can only be applied to arrays."); + else + type->modifiers |= prim_modifiers; + } + $$.type = type;
if (hlsl_version_ge(ctx, 5, 1) && type->class == HLSL_CLASS_ARRAY && hlsl_type_is_resource(type)) @@ -8458,14 +8183,14 @@ type_no_void: | TYPE_IDENTIFIER { $$ = hlsl_get_type(ctx->cur_scope, $1, true, true); - if ($$->is_minimum_precision) + if ($$->is_minimum_precision || hlsl_type_is_minimum_precision($$)) { if (hlsl_version_lt(ctx, 4, 0)) { hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Target profile doesn't support minimum-precision types."); } - else + else if ($$->is_minimum_precision) { FIXME("Reinterpreting type %s.\n", $$->name); } @@ -8495,8 +8220,8 @@ type_no_void: | KW_STRUCT TYPE_IDENTIFIER { $$ = hlsl_get_type(ctx->cur_scope, $2, true, true); - if ($$->class != HLSL_CLASS_STRUCT) - hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, ""%s" redefined as a structure.", $2); + if ($$->class != HLSL_CLASS_STRUCT || $$->is_typedef) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_REDEFINED, ""%s" is not a structure.", $2); vkd3d_free($2); } | KW_RENDERTARGETVIEW @@ -8561,6 +8286,10 @@ type: declaration_statement: declaration | struct_declaration_without_vars + { + if (!($$ = make_empty_block(ctx))) + YYABORT; + } | typedef { if (!($$ = make_empty_block(ctx))) @@ -8574,15 +8303,12 @@ typedef_type: typedef: KW_TYPEDEF var_modifiers typedef_type type_specs ';' { - struct parse_variable_def *v, *v_next; uint32_t modifiers = $2; struct hlsl_type *type;
if (!(type = apply_type_modifiers(ctx, $3, &modifiers, false, &@2))) { - LIST_FOR_EACH_ENTRY_SAFE(v, v_next, $4, struct parse_variable_def, entry) - free_parse_variable_def(v); - vkd3d_free($4); + destroy_parse_variable_defs($4); YYABORT; }
@@ -8752,6 +8478,26 @@ state_block: hlsl_src_from_node(&entry->args[i], $5.args[i]); vkd3d_free($5.args);
+ $$ = $1; + hlsl_state_block_add_entry($$, entry); + } + | state_block stateblock_lhs_identifier state_block_index_opt '=' '<' primary_expr '>' ';' + { + struct hlsl_state_block_entry *entry; + + if (!(entry = hlsl_alloc(ctx, sizeof(*entry)))) + YYABORT; + + entry->name = $2; + entry->lhs_has_index = $3.has_index; + entry->lhs_index = $3.index; + + entry->instrs = $6; + entry->args_count = 1; + if (!(entry->args = hlsl_alloc(ctx, sizeof(*entry->args) * entry->args_count))) + YYABORT; + hlsl_src_from_node(&entry->args[0], node_from_block($6)); + $$ = $1; hlsl_state_block_add_entry($$, entry); } @@ -8845,7 +8591,7 @@ variable_def_typed: if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT;
- check_invalid_in_out_modifiers(ctx, modifiers, &@1); + check_invalid_non_parameter_modifiers(ctx, modifiers, &@1);
$$ = $3; $$->basic_type = type; @@ -8860,7 +8606,7 @@ variable_def_typed: if (!(type = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT;
- check_invalid_in_out_modifiers(ctx, modifiers, &@1); + check_invalid_non_parameter_modifiers(ctx, modifiers, &@1);
$$ = $3; $$->basic_type = type; @@ -9001,6 +8747,26 @@ var_modifiers: { $$ = add_modifiers(ctx, $2, HLSL_MODIFIER_SNORM, &@1); } + | KW_LINE var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_LINE, &@1); + } + | KW_LINEADJ var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_LINEADJ, &@1); + } + | KW_POINT var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_POINT, &@1); + } + | KW_TRIANGLE var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_TRIANGLE, &@1); + } + | KW_TRIANGLEADJ var_modifiers + { + $$ = add_modifiers(ctx, $2, HLSL_PRIMITIVE_TRIANGLEADJ, &@1); + } | var_identifier var_modifiers { $$ = $2; @@ -9130,8 +8896,6 @@ statement: jump_statement: KW_BREAK ';' { - struct hlsl_ir_node *jump; - if (!is_break_allowed(ctx->cur_scope)) { hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, @@ -9140,22 +8904,15 @@ jump_statement:
if (!($$ = make_empty_block(ctx))) YYABORT; - if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &@1))) - YYABORT; - hlsl_block_add_instr($$, jump); + hlsl_block_add_jump(ctx, $$, HLSL_IR_JUMP_BREAK, NULL, &@1); } | KW_CONTINUE ';' { - struct hlsl_ir_node *jump; - check_continue(ctx, ctx->cur_scope, &@1);
if (!($$ = make_empty_block(ctx))) YYABORT; - - if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_UNRESOLVED_CONTINUE, NULL, &@1))) - YYABORT; - hlsl_block_add_instr($$, jump); + hlsl_block_add_jump(ctx, $$, HLSL_IR_JUMP_UNRESOLVED_CONTINUE, NULL, &@1); } | KW_RETURN expr ';' { @@ -9172,18 +8929,12 @@ jump_statement: } | KW_DISCARD ';' { - struct hlsl_ir_node *discard, *c; + struct hlsl_ir_node *c;
if (!($$ = make_empty_block(ctx))) YYABORT; - - if (!(c = hlsl_new_uint_constant(ctx, ~0u, &@1))) - return false; - hlsl_block_add_instr($$, c); - - if (!(discard = hlsl_new_jump(ctx, HLSL_IR_JUMP_DISCARD_NZ, c, &@1))) - return false; - hlsl_block_add_instr($$, discard); + c = hlsl_block_add_uint_constant(ctx, $$, ~0u, &@1); + hlsl_block_add_jump(ctx, $$, HLSL_IR_JUMP_DISCARD_NZ, c, &@1); }
selection_statement: @@ -9191,7 +8942,6 @@ selection_statement: { struct hlsl_ir_node *condition = node_from_block($4); const struct parse_attribute_list *attributes = &$1; - struct hlsl_ir_node *instr; unsigned int i;
check_attribute_list_for_duplicates(ctx, attributes); @@ -9213,27 +8963,14 @@ selection_statement:
check_condition_type(ctx, condition);
- if (!(condition = add_cast(ctx, $4, condition, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &@4))) - { - destroy_block($6.then_block); - destroy_block($6.else_block); - cleanup_parse_attribute_list(&$1); - YYABORT; - } + condition = add_cast(ctx, $4, condition, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &@4); + hlsl_block_add_if(ctx, $4, condition, $6.then_block, $6.else_block, &@2);
- if (!(instr = hlsl_new_if(ctx, condition, $6.then_block, $6.else_block, &@2))) - { - destroy_block($6.then_block); - destroy_block($6.else_block); - cleanup_parse_attribute_list(&$1); - YYABORT; - } destroy_block($6.then_block); destroy_block($6.else_block); cleanup_parse_attribute_list(&$1);
$$ = $4; - hlsl_block_add_instr($$, instr); }
if_body: @@ -9383,30 +9120,21 @@ func_arguments: primary_expr: C_FLOAT { - struct hlsl_ir_node *c; - - if (!(c = hlsl_new_float_constant(ctx, $1, &@1))) - YYABORT; - if (!($$ = make_block(ctx, c))) + if (!($$ = make_empty_block(ctx))) YYABORT; + hlsl_block_add_float_constant(ctx, $$, $1, &@1); } | C_INTEGER { - struct hlsl_ir_node *c; - - if (!(c = hlsl_new_int_constant(ctx, $1, &@1))) - YYABORT; - if (!($$ = make_block(ctx, c))) + if (!($$ = make_empty_block(ctx))) YYABORT; + hlsl_block_add_int_constant(ctx, $$, $1, &@1); } | C_UNSIGNED { - struct hlsl_ir_node *c; - - if (!(c = hlsl_new_uint_constant(ctx, $1, &@1))) - YYABORT; - if (!($$ = make_block(ctx, c))) + if (!($$ = make_empty_block(ctx))) YYABORT; + hlsl_block_add_uint_constant(ctx, $$, $1, &@1); } | boolean { @@ -9451,17 +9179,15 @@ primary_expr: } | VAR_IDENTIFIER { - struct hlsl_ir_load *load; struct hlsl_ir_var *var;
if ((var = hlsl_get_var(ctx->cur_scope, $1))) { vkd3d_free($1);
- if (!(load = hlsl_new_var_load(ctx, var, &@1))) - YYABORT; - if (!($$ = make_block(ctx, &load->node))) + if (!($$ = make_empty_block(ctx))) YYABORT; + hlsl_block_add_simple_load(ctx, $$, var, &@1); } else { @@ -9583,12 +9309,7 @@ postfix_expr:
if (node->data_type->class == HLSL_CLASS_STRUCT) { - if (!add_record_access_recurse(ctx, $1, $3, &@2)) - { - destroy_block($1); - vkd3d_free($3); - YYABORT; - } + add_record_access_recurse(ctx, $1, $3, &@2); } else if (hlsl_is_numeric_type(node->data_type)) { @@ -9604,6 +9325,9 @@ postfix_expr: $1->value = ctx->error_instr; } } + else if (add_object_property_access(ctx, $1, node, $3, &@2)) + { + } else if (node->data_type->class != HLSL_CLASS_ERROR) { hlsl_error(ctx, &@3, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Invalid subscript "%s".", $3); @@ -9703,12 +9427,7 @@ unary_expr: hlsl_error(ctx, &@2, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Modifiers are not allowed on casts.");
- if (!add_explicit_conversion(ctx, $6, $3, &$4, &@3)) - { - destroy_block($6); - vkd3d_free($4.sizes); - YYABORT; - } + add_explicit_conversion(ctx, $6, $3, &$4, &@3); vkd3d_free($4.sizes); $$ = $6; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 2afd3e1e1e5..38d5c55c26b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -62,14 +62,9 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str size /= 4; }
- if (!(c = hlsl_new_uint_constant(ctx, size, loc))) - return NULL; - hlsl_block_add_instr(block, c); - - if (!(idx_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, c, idx))) - return NULL; - hlsl_block_add_instr(block, idx_offset); + c = hlsl_block_add_uint_constant(ctx, block, size, loc);
+ idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); break; }
@@ -86,12 +81,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str field_offset /= 4; }
- if (!(c = hlsl_new_uint_constant(ctx, field_offset, loc))) - return NULL; - hlsl_block_add_instr(block, c); - - idx_offset = c; - + idx_offset = hlsl_block_add_uint_constant(ctx, block, field_offset, loc); break; }
@@ -100,12 +90,7 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str }
if (idx_offset) - { - if (!(base_offset = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, base_offset, idx_offset))) - return NULL; - hlsl_block_add_instr(block, base_offset); - } - + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, base_offset, idx_offset); return base_offset; }
@@ -122,9 +107,7 @@ static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, st
hlsl_block_init(block);
- if (!(offset = hlsl_new_uint_constant(ctx, 0, loc))) - return NULL; - hlsl_block_add_instr(block, offset); + offset = hlsl_block_add_uint_constant(ctx, block, 0, loc);
VKD3D_ASSERT(deref->var); type = deref->var->data_type; @@ -134,16 +117,9 @@ static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, st struct hlsl_block idx_block;
hlsl_block_init(&idx_block); - - if (!(offset = new_offset_from_path_index(ctx, &idx_block, type, offset, deref->path[i].node, - regset, offset_component, loc))) - { - hlsl_block_cleanup(&idx_block); - return NULL; - } - + offset = new_offset_from_path_index(ctx, &idx_block, type, offset, + deref->path[i].node, regset, offset_component, loc); hlsl_block_add_block(block, &idx_block); - type = hlsl_get_element_type_from_path_index(ctx, type, deref->path[i].node); }
@@ -174,8 +150,7 @@ static bool replace_deref_path_with_offset(struct hlsl_ctx *ctx, struct hlsl_der
deref->data_type = type;
- if (!(offset = new_offset_instr_from_deref(ctx, &block, deref, &offset_component, &instr->loc))) - return false; + offset = new_offset_instr_from_deref(ctx, &block, deref, &offset_component, &instr->loc); list_move_before(&instr->entry, &block.instrs);
hlsl_cleanup_deref(deref); @@ -203,41 +178,34 @@ static bool clean_constant_deref_offset_srcs(struct hlsl_ctx *ctx, struct hlsl_d }
-/* Split uniforms into two variables representing the constant and temp - * registers, and copy the former to the latter, so that writes to uniforms - * work. */ -static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_var *temp) +/* For a uniform variable, create a temp copy of it so, in case a value is + * stored to the uniform at some point the shader, all derefs can be diverted + * to this temp copy instead. + * Also, promote the uniform to an extern var. */ +static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_var *uniform) { - struct hlsl_ir_var *uniform; struct hlsl_ir_node *store; struct hlsl_ir_load *load; + struct hlsl_ir_var *temp; char *new_name;
- /* Use the synthetic name for the temp, rather than the uniform, so that we - * can write the uniform name into the shader reflection data. */ + uniform->is_uniform = 1; + list_add_tail(&ctx->extern_vars, &uniform->extern_entry);
- if (!(uniform = hlsl_new_var(ctx, temp->name, temp->data_type, - &temp->loc, NULL, temp->storage_modifiers, &temp->reg_reservation))) + if (!(new_name = hlsl_sprintf_alloc(ctx, "<temp-%s>", uniform->name))) return; - list_add_before(&temp->scope_entry, &uniform->scope_entry); - list_add_tail(&ctx->extern_vars, &uniform->extern_entry); - uniform->is_uniform = 1; - uniform->is_param = temp->is_param; - uniform->buffer = temp->buffer; - if (temp->default_values) + + if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type, + &uniform->loc, NULL, uniform->storage_modifiers, NULL))) { - /* Transfer default values from the temp to the uniform. */ - VKD3D_ASSERT(!uniform->default_values); - VKD3D_ASSERT(hlsl_type_component_count(temp->data_type) == hlsl_type_component_count(uniform->data_type)); - uniform->default_values = temp->default_values; - temp->default_values = NULL; + vkd3d_free(new_name); + return; } + list_add_before(&uniform->scope_entry, &temp->scope_entry);
- if (!(new_name = hlsl_sprintf_alloc(ctx, "<temp-%s>", temp->name))) - return; - temp->name = new_name; + uniform->temp_copy = temp;
- if (!(load = hlsl_new_var_load(ctx, uniform, &temp->loc))) + if (!(load = hlsl_new_var_load(ctx, uniform, &uniform->loc))) return; list_add_head(&block->instrs, &load->node.entry);
@@ -246,6 +214,25 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, list_add_after(&load->node.entry, &store->entry); }
+/* If a uniform is written to at some point in the shader, all dereferences + * must point to the temp copy instead, which is what this pass does. */ +static bool divert_written_uniform_derefs_to_temp(struct hlsl_ctx *ctx, struct hlsl_deref *deref, + struct hlsl_ir_node *instr) +{ + if (!deref->var->is_uniform || !deref->var->first_write) + return false; + + /* Skip derefs from instructions before first write so copies from the + * uniform to the temp are unaffected. */ + if (instr->index < deref->var->first_write) + return false; + + VKD3D_ASSERT(deref->var->temp_copy); + + deref->var = deref->var->temp_copy; + return true; +} + static void validate_field_semantic(struct hlsl_ctx *ctx, struct hlsl_struct_field *field) { if (!field->semantic.name && hlsl_is_numeric_type(hlsl_get_multiarray_element_type(field->type)) @@ -259,13 +246,23 @@ static void validate_field_semantic(struct hlsl_ctx *ctx, struct hlsl_struct_fie
static enum hlsl_base_type base_type_get_semantic_equivalent(enum hlsl_base_type base) { - if (base == HLSL_TYPE_BOOL) - return HLSL_TYPE_UINT; - if (base == HLSL_TYPE_INT) - return HLSL_TYPE_UINT; - if (base == HLSL_TYPE_HALF) - return HLSL_TYPE_FLOAT; - return base; + switch (base) + { + case HLSL_TYPE_BOOL: + case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: + case HLSL_TYPE_UINT: + return HLSL_TYPE_UINT; + + case HLSL_TYPE_HALF: + case HLSL_TYPE_FLOAT: + return HLSL_TYPE_FLOAT; + + case HLSL_TYPE_DOUBLE: + return HLSL_TYPE_DOUBLE; + } + + vkd3d_unreachable(); }
static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hlsl_type *type1, @@ -274,9 +271,9 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls if (ctx->profile->major_version < 4) return true;
- if (hlsl_type_is_patch_array(type1)) + if (hlsl_type_is_primitive_array(type1)) { - return hlsl_type_is_patch_array(type2) + return hlsl_type_is_primitive_array(type2) && type1->e.array.array_type == type2->e.array.array_type && type1->e.array.elements_count == type2->e.array.elements_count && types_are_semantic_equivalent(ctx, type1->e.array.type, type2->e.array.type); @@ -291,15 +288,15 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls
static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, - uint32_t index, bool output, bool force_align, const struct vkd3d_shader_location *loc) + uint32_t index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc) { struct hlsl_semantic new_semantic; struct hlsl_ir_var *ext_var; const char *prefix; char *new_name;
- if (hlsl_type_is_patch_array(type)) - prefix = type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT ? "inputpatch" : "outputpatch"; + if (hlsl_type_is_primitive_array(type)) + prefix = type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT ? "outputpatch" : "inputprim"; else prefix = output ? "output" : "input";
@@ -310,9 +307,14 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir { if (!ascii_strcasecmp(ext_var->name, new_name)) { - VKD3D_ASSERT(hlsl_type_is_patch_array(ext_var->data_type) + VKD3D_ASSERT(hlsl_type_is_primitive_array(ext_var->data_type) || ext_var->data_type->class <= HLSL_CLASS_VECTOR); - VKD3D_ASSERT(hlsl_type_is_patch_array(type) || type->class <= HLSL_CLASS_VECTOR); + VKD3D_ASSERT(hlsl_type_is_primitive_array(type) || type->class <= HLSL_CLASS_VECTOR); + + vkd3d_free(new_name); + + if (!create) + return ext_var;
if (output) { @@ -339,11 +341,12 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir } }
- vkd3d_free(new_name); return ext_var; } }
+ VKD3D_ASSERT(create); + if (!(hlsl_clone_semantic(ctx, &new_semantic, semantic))) { vkd3d_free(new_name); @@ -386,7 +389,7 @@ static uint32_t combine_field_storage_modifiers(uint32_t modifiers, uint32_t fie }
static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_block *block, struct hlsl_ir_var *top_var, uint32_t patch_index, struct hlsl_ir_load *lhs, + struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) { struct hlsl_type *type = lhs->node.data_type, *vector_type_src, *vector_type_dst; @@ -416,38 +419,36 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec
for (i = 0; i < hlsl_type_major_size(type); ++i) { - struct hlsl_ir_node *store, *cast; + struct hlsl_ir_node *cast; struct hlsl_ir_var *input; struct hlsl_ir_load *load;
- if (hlsl_type_is_patch_array(top_var->data_type)) + if (hlsl_type_is_primitive_array(var->data_type)) { - struct hlsl_type *top_type = top_var->data_type; - struct hlsl_type *patch_type; - struct hlsl_deref patch_deref; + struct hlsl_type *prim_type_src; + struct hlsl_deref prim_deref; struct hlsl_ir_node *idx;
- if (!(patch_type = hlsl_new_array_type(ctx, vector_type_src, top_type->e.array.elements_count, - top_type->e.array.array_type))) + if (!(prim_type_src = hlsl_new_array_type(ctx, vector_type_src, var->data_type->e.array.elements_count, + var->data_type->e.array.array_type))) return; + prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK;
- if (!(input = add_semantic_var(ctx, func, var, patch_type, - modifiers, semantic, semantic_index + i, false, force_align, loc))) + if (!(input = add_semantic_var(ctx, func, var, prim_type_src, + modifiers, semantic, semantic_index + i, false, force_align, true, loc))) return; - hlsl_init_simple_deref_from_var(&patch_deref, input); + hlsl_init_simple_deref_from_var(&prim_deref, input);
- if (!(idx = hlsl_new_uint_constant(ctx, patch_index, &var->loc))) - return; - hlsl_block_add_instr(block, idx); + idx = hlsl_block_add_uint_constant(ctx, block, prim_index, &var->loc);
- if (!(load = hlsl_new_load_index(ctx, &patch_deref, idx, loc))) + if (!(load = hlsl_new_load_index(ctx, &prim_deref, idx, loc))) return; hlsl_block_add_instr(block, &load->node); } else { if (!(input = add_semantic_var(ctx, func, var, vector_type_src, - modifiers, semantic, semantic_index + i, false, force_align, loc))) + modifiers, semantic, semantic_index + i, false, force_align, true, loc))) return;
if (!(load = hlsl_new_var_load(ctx, input, &var->loc))) @@ -455,33 +456,25 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec hlsl_block_add_instr(block, &load->node); }
- if (!(cast = hlsl_new_cast(ctx, &load->node, vector_type_dst, &var->loc))) - return; - hlsl_block_add_instr(block, cast); + cast = hlsl_block_add_cast(ctx, block, &load->node, vector_type_dst, &var->loc);
if (type->class == HLSL_CLASS_MATRIX) { - if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) - return; - hlsl_block_add_instr(block, c); + c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc);
- if (!(store = hlsl_new_store_index(ctx, &lhs->src, c, cast, 0, &var->loc))) - return; - hlsl_block_add_instr(block, store); + hlsl_block_add_store_index(ctx, block, &lhs->src, c, cast, 0, &var->loc); } else { VKD3D_ASSERT(i == 0);
- if (!(store = hlsl_new_store_index(ctx, &lhs->src, NULL, cast, 0, &var->loc))) - return; - hlsl_block_add_instr(block, store); + hlsl_block_add_store_index(ctx, block, &lhs->src, NULL, cast, 0, &var->loc); } } }
static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_block *block, struct hlsl_ir_var *top_var, uint32_t patch_index, struct hlsl_ir_load *lhs, + struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) { struct vkd3d_shader_location *loc = &lhs->node.loc; @@ -507,8 +500,8 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func element_modifiers = modifiers; force_align = true;
- if (hlsl_type_is_patch_array(type)) - patch_index = i; + if (hlsl_type_is_primitive_array(type)) + prim_index = i; } else { @@ -526,22 +519,20 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func force_align = (i == 0); }
- if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) - return; - hlsl_block_add_instr(block, c); + c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc);
/* This redundant load is expected to be deleted later by DCE. */ if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc))) return; hlsl_block_add_instr(block, &element_load->node);
- prepend_input_copy_recurse(ctx, func, block, top_var, patch_index, element_load, + prepend_input_copy_recurse(ctx, func, block, prim_index, element_load, element_modifiers, semantic, elem_semantic_index, force_align); } } else { - prepend_input_copy(ctx, func, block, var, patch_index, lhs, modifiers, semantic, semantic_index, force_align); + prepend_input_copy(ctx, func, block, prim_index, lhs, modifiers, semantic, semantic_index, force_align); } }
@@ -559,15 +550,15 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function return; hlsl_block_add_instr(&block, &load->node);
- prepend_input_copy_recurse(ctx, func, &block, var, 0, load, - var->storage_modifiers, &var->semantic, var->semantic.index, false); + prepend_input_copy_recurse(ctx, func, &block, 0, load, var->storage_modifiers, + &var->semantic, var->semantic.index, false);
list_move_head(&func->body.instrs, &block.instrs); }
-static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_ir_load *rhs, uint32_t modifiers, - struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) +static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, + struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) { struct hlsl_type *type = rhs->node.data_type, *vector_type; struct vkd3d_shader_location *loc = &rhs->node.loc; @@ -593,63 +584,52 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec
for (i = 0; i < hlsl_type_major_size(type); ++i) { - struct hlsl_ir_node *store; struct hlsl_ir_var *output; - struct hlsl_ir_load *load; + struct hlsl_ir_node *load;
if (!(output = add_semantic_var(ctx, func, var, vector_type, - modifiers, semantic, semantic_index + i, true, force_align, loc))) + modifiers, semantic, semantic_index + i, true, force_align, create, loc))) return;
if (type->class == HLSL_CLASS_MATRIX) { - if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) - return; - hlsl_block_add_instr(&func->body, c); - - if (!(load = hlsl_new_load_index(ctx, &rhs->src, c, &var->loc))) - return; - hlsl_block_add_instr(&func->body, &load->node); + c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); + load = hlsl_block_add_load_index(ctx, block, &rhs->src, c, &var->loc); } else { VKD3D_ASSERT(i == 0);
- if (!(load = hlsl_new_load_index(ctx, &rhs->src, NULL, &var->loc))) - return; - hlsl_block_add_instr(&func->body, &load->node); + load = hlsl_block_add_load_index(ctx, block, &rhs->src, NULL, &var->loc); }
- if (!(store = hlsl_new_simple_store(ctx, output, &load->node))) - return; - hlsl_block_add_instr(&func->body, store); + hlsl_block_add_simple_store(ctx, block, output, load); } }
-static void append_output_copy_recurse(struct hlsl_ctx *ctx, - struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, - struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) +static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, + struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) { struct vkd3d_shader_location *loc = &rhs->node.loc; - struct hlsl_type *type = rhs->node.data_type; struct hlsl_ir_var *var = rhs->src.var; struct hlsl_ir_node *c; unsigned int i;
if (type->class == HLSL_CLASS_ARRAY || type->class == HLSL_CLASS_STRUCT) { - struct hlsl_ir_load *element_load; - struct hlsl_struct_field *field; - uint32_t elem_semantic_index; - for (i = 0; i < hlsl_type_element_count(type); ++i) { - uint32_t element_modifiers; + uint32_t element_modifiers, elem_semantic_index; + const struct hlsl_type *element_type; + struct hlsl_ir_load *element_load; + struct hlsl_struct_field *field;
if (type->class == HLSL_CLASS_ARRAY) { elem_semantic_index = semantic_index + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; + element_type = type->e.array.type; element_modifiers = modifiers; force_align = true; } @@ -662,25 +642,24 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, semantic = &field->semantic; elem_semantic_index = semantic->index; loc = &field->loc; + element_type = field->type; element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); force_align = (i == 0); }
- if (!(c = hlsl_new_uint_constant(ctx, i, &var->loc))) - return; - hlsl_block_add_instr(&func->body, c); + c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc);
if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) return; - hlsl_block_add_instr(&func->body, &element_load->node); + hlsl_block_add_instr(block, &element_load->node);
- append_output_copy_recurse(ctx, func, element_load, element_modifiers, - semantic, elem_semantic_index, force_align); + append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic, + elem_semantic_index, force_align, create); } } else { - append_output_copy(ctx, func, rhs, modifiers, semantic, semantic_index, force_align); + append_output_copy(ctx, block, func, rhs, modifiers, semantic, semantic_index, force_align, create); } }
@@ -696,7 +675,8 @@ static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function return; hlsl_block_add_instr(&func->body, &load->node);
- append_output_copy_recurse(ctx, func, load, var->storage_modifiers, &var->semantic, var->semantic.index, false); + append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers, + &var->semantic, var->semantic.index, false, true); }
bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), @@ -705,6 +685,9 @@ bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, *next; bool progress = false;
+ if (ctx->result) + return false; + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) { if (instr->type == HLSL_IR_IF) @@ -853,9 +836,9 @@ static bool find_recursive_calls(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst static void insert_early_return_break(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_node *cf_instr) { - struct hlsl_ir_node *iff, *jump; struct hlsl_block then_block; struct hlsl_ir_load *load; + struct hlsl_ir_node *iff;
hlsl_block_init(&then_block);
@@ -863,9 +846,7 @@ static void insert_early_return_break(struct hlsl_ctx *ctx, return; list_add_after(&cf_instr->entry, &load->node.entry);
- if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &cf_instr->loc))) - return; - hlsl_block_add_instr(&then_block, jump); + hlsl_block_add_jump(ctx, &then_block, HLSL_IR_JUMP_BREAK, NULL, &cf_instr->loc);
if (!(iff = hlsl_new_if(ctx, &load->node, &then_block, NULL, &cf_instr->loc))) return; @@ -1037,9 +1018,8 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun else if (cf_instr) { struct list *tail = list_tail(&block->instrs); - struct hlsl_ir_node *not, *iff; + struct hlsl_ir_node *not, *load; struct hlsl_block then_block; - struct hlsl_ir_load *load;
/* If we're in a loop, we should have used "break" instead. */ VKD3D_ASSERT(!in_loop); @@ -1051,17 +1031,9 @@ static bool lower_return(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *fun list_move_slice_tail(&then_block.instrs, list_next(&block->instrs, &cf_instr->entry), tail); lower_return(ctx, func, &then_block, in_loop);
- if (!(load = hlsl_new_var_load(ctx, func->early_return_var, &cf_instr->loc))) - return false; - hlsl_block_add_instr(block, &load->node); - - if (!(not = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, &load->node, &cf_instr->loc))) - return false; - hlsl_block_add_instr(block, not); - - if (!(iff = hlsl_new_if(ctx, not, &then_block, NULL, &cf_instr->loc))) - return false; - list_add_tail(&block->instrs, &iff->entry); + load = hlsl_block_add_simple_load(ctx, block, func->early_return_var, &cf_instr->loc); + not = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_LOGIC_NOT, load, &cf_instr->loc); + hlsl_block_add_if(ctx, block, not, &then_block, NULL, &cf_instr->loc); }
return has_early_return; @@ -1096,10 +1068,9 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h struct hlsl_ir_node *index, const struct vkd3d_shader_location *loc) { unsigned int dim_count = index->data_type->e.numeric.dimx; - struct hlsl_ir_node *store, *zero; - struct hlsl_ir_load *coords_load; struct hlsl_deref coords_deref; struct hlsl_ir_var *coords; + struct hlsl_ir_node *zero;
VKD3D_ASSERT(dim_count < 4);
@@ -1108,23 +1079,12 @@ static struct hlsl_ir_node *add_zero_mipmap_level(struct hlsl_ctx *ctx, struct h return NULL;
hlsl_init_simple_deref_from_var(&coords_deref, coords); - if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, index, (1u << dim_count) - 1, loc))) - return NULL; - hlsl_block_add_instr(block, store); - - if (!(zero = hlsl_new_uint_constant(ctx, 0, loc))) - return NULL; - hlsl_block_add_instr(block, zero); - - if (!(store = hlsl_new_store_index(ctx, &coords_deref, NULL, zero, 1u << dim_count, loc))) - return NULL; - hlsl_block_add_instr(block, store); + hlsl_block_add_store_index(ctx, block, &coords_deref, NULL, index, (1u << dim_count) - 1, loc);
- if (!(coords_load = hlsl_new_var_load(ctx, coords, loc))) - return NULL; - hlsl_block_add_instr(block, &coords_load->node); + zero = hlsl_block_add_uint_constant(ctx, block, 0, loc); + hlsl_block_add_store_index(ctx, block, &coords_deref, NULL, zero, 1u << dim_count, loc);
- return &coords_load->node; + return hlsl_block_add_simple_load(ctx, block, coords, loc); }
static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) @@ -1133,7 +1093,6 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr struct hlsl_type *src_type, *dst_type; struct hlsl_deref var_deref; bool broadcast, matrix_cast; - struct hlsl_ir_load *load; struct hlsl_ir_node *arg; struct hlsl_ir_var *var; unsigned int dst_idx; @@ -1172,7 +1131,6 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr { struct hlsl_ir_node *component_load, *cast; struct hlsl_type *dst_comp_type; - struct hlsl_block store_block; unsigned int src_idx;
if (broadcast) @@ -1191,23 +1149,13 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr }
dst_comp_type = hlsl_type_get_component_type(ctx, dst_type, dst_idx); + component_load = hlsl_add_load_component(ctx, block, arg, src_idx, &arg->loc); + cast = hlsl_block_add_cast(ctx, block, component_load, dst_comp_type, &arg->loc);
- if (!(component_load = hlsl_add_load_component(ctx, block, arg, src_idx, &arg->loc))) - return false; - - if (!(cast = hlsl_new_cast(ctx, component_load, dst_comp_type, &arg->loc))) - return false; - hlsl_block_add_instr(block, cast); - - if (!hlsl_new_store_component(ctx, &store_block, &var_deref, dst_idx, cast)) - return false; - hlsl_block_add_block(block, &store_block); + hlsl_block_add_store_component(ctx, block, &var_deref, dst_idx, cast); }
- if (!(load = hlsl_new_var_load(ctx, var, &instr->loc))) - return false; - hlsl_block_add_instr(block, &load->node); - + hlsl_block_add_simple_load(ctx, block, var, &instr->loc); return true; }
@@ -1219,7 +1167,6 @@ static bool lower_complex_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_swizzle *swizzle; - struct hlsl_ir_load *var_load; struct hlsl_deref var_deref; struct hlsl_type *matrix_type; struct hlsl_ir_var *var; @@ -1238,23 +1185,15 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins
for (i = 0; i < instr->data_type->e.numeric.dimx; ++i) { - struct hlsl_block store_block; struct hlsl_ir_node *load;
k = swizzle->u.matrix.components[i].y * matrix_type->e.numeric.dimx + swizzle->u.matrix.components[i].x;
- if (!(load = hlsl_add_load_component(ctx, block, swizzle->val.node, k, &instr->loc))) - return false; - - if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, load)) - return false; - hlsl_block_add_block(block, &store_block); + load = hlsl_add_load_component(ctx, block, swizzle->val.node, k, &instr->loc); + hlsl_block_add_store_component(ctx, block, &var_deref, i, load); }
- if (!(var_load = hlsl_new_var_load(ctx, var, &instr->loc))) - return false; - hlsl_block_add_instr(block, &var_load->node); - + hlsl_block_add_simple_load(ctx, block, var, &instr->loc); return true; }
@@ -1266,10 +1205,10 @@ static bool lower_matrix_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins * resource access. */ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *val, *store; struct hlsl_deref var_deref; struct hlsl_ir_index *index; struct hlsl_ir_load *load; + struct hlsl_ir_node *val; struct hlsl_ir_var *var;
if (instr->type != HLSL_IR_INDEX) @@ -1282,7 +1221,6 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, unsigned int dim_count = hlsl_sampler_dim_count(val->data_type->sampler_dim); struct hlsl_ir_node *coords = index->idx.node; struct hlsl_resource_load_params params = {0}; - struct hlsl_ir_node *resource_load;
VKD3D_ASSERT(coords->data_type->class == HLSL_CLASS_VECTOR); VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); @@ -1295,10 +1233,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, params.resource = val; params.coords = coords; params.format = val->data_type->e.resource.format; - - if (!(resource_load = hlsl_new_resource_load(ctx, ¶ms, &instr->loc))) - return false; - hlsl_block_add_instr(block, resource_load); + hlsl_block_add_resource_load(ctx, block, ¶ms, &instr->loc); return true; }
@@ -1306,9 +1241,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; hlsl_init_simple_deref_from_var(&var_deref, var);
- if (!(store = hlsl_new_simple_store(ctx, var, val))) - return false; - hlsl_block_add_instr(block, store); + hlsl_block_add_simple_store(ctx, block, var, val);
if (hlsl_index_is_noncontiguous(index)) { @@ -1326,9 +1259,7 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, { struct hlsl_ir_node *c;
- if (!(c = hlsl_new_uint_constant(ctx, i, &instr->loc))) - return false; - hlsl_block_add_instr(block, c); + c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc);
if (!(load = hlsl_new_load_index(ctx, &var_deref, c, &instr->loc))) return false; @@ -1338,20 +1269,14 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; hlsl_block_add_instr(block, &load->node);
- if (!(store = hlsl_new_store_index(ctx, &row_deref, c, &load->node, 0, &instr->loc))) - return false; - hlsl_block_add_instr(block, store); + hlsl_block_add_store_index(ctx, block, &row_deref, c, &load->node, 0, &instr->loc); }
- if (!(load = hlsl_new_var_load(ctx, var, &instr->loc))) - return false; - hlsl_block_add_instr(block, &load->node); + hlsl_block_add_simple_load(ctx, block, var, &instr->loc); } else { - if (!(load = hlsl_new_load_index(ctx, &var_deref, index->idx.node, &instr->loc))) - return false; - hlsl_block_add_instr(block, &load->node); + hlsl_block_add_load_index(ctx, block, &var_deref, index->idx.node, &instr->loc); } return true; } @@ -1373,22 +1298,16 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR && src_type->e.numeric.dimx == 1) { - struct hlsl_ir_node *new_cast, *swizzle; + struct hlsl_ir_node *new_cast;
dst_scalar_type = hlsl_get_scalar_type(ctx, dst_type->e.numeric.type); /* We need to preserve the cast since it might be doing more than just * turning the scalar into a vector. */ - if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_scalar_type, &cast->node.loc))) - return false; - hlsl_block_add_instr(block, new_cast); + new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_scalar_type, &cast->node.loc);
if (dst_type->e.numeric.dimx != 1) - { - if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), - dst_type->e.numeric.dimx, new_cast, &cast->node.loc))) - return false; - hlsl_block_add_instr(block, swizzle); - } + hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), + dst_type->e.numeric.dimx, new_cast, &cast->node.loc);
return true; } @@ -1398,7 +1317,7 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s
/* Allocate a unique, ordered index to each instruction, which will be used for * copy propagation and computing liveness ranges. - * Index 0 means unused; index 1 means function entry, so start at 2. */ + * Index 0 means unused, so start at 1. */ static unsigned int index_instructions(struct hlsl_block *block, unsigned int index) { struct hlsl_ir_node *instr; @@ -1480,6 +1399,17 @@ static unsigned int index_instructions(struct hlsl_block *block, unsigned int in * * we can copy-prop the load (@7) into a constant vector {123, 456}, but we * cannot easily vectorize the stores @3 and @6. + * + * Moreover, we implement a transformation that propagates loads with a single + * non-constant index in its deref path. Consider a load of the form + * var[[a0][a1]...[i]...[an]], where ak are integral constants, and i is an + * arbitrary non-constant node. If, for all j, the following holds: + * + * var[[a0][a1]...[j]...[an]] = x[[c0*j + d0][c1*j + d1]...[cm*j + dm]], + * + * where ck, dk are constants, then we can replace the load with + * x[[c0*i + d0]...[cm*i + dm]]. This pass is implemented by + * copy_propagation_replace_with_deref(). */
struct copy_propagation_value @@ -1704,16 +1634,25 @@ static void copy_propagation_invalidate_variable_from_deref_recurse(struct hlsl_
if (path_node->type == HLSL_IR_CONSTANT) { + uint32_t index = hlsl_ir_constant(path_node)->value.u[0].u; + + /* Don't bother invalidating anything if the index is constant but + * out-of-range. + * Such indices are illegal in HLSL, but only if the code is not + * dead, and we can't always know if code is dead without copy-prop + * itself. */ + if (index >= hlsl_type_element_count(type)) + return; + copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, - depth + 1, hlsl_ir_constant(path_node)->value.u[0].u * subtype_comp_count, - writemask, time); + depth + 1, comp_start + index * subtype_comp_count, writemask, time); } else { for (i = 0; i < hlsl_type_element_count(type); ++i) { copy_propagation_invalidate_variable_from_deref_recurse(ctx, var_def, deref, subtype, - depth + 1, i * subtype_comp_count, writemask, time); + depth + 1, comp_start + i * subtype_comp_count, writemask, time); } } } @@ -1837,131 +1776,459 @@ static bool copy_propagation_replace_with_constant_vector(struct hlsl_ctx *ctx, return true; }
-static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, - struct hlsl_ir_load *load, struct copy_propagation_state *state) +static bool component_index_from_deref_path_node(struct hlsl_ir_node *path_node, + struct hlsl_type *type, unsigned int *index) { - struct hlsl_type *type = load->node.data_type; + unsigned int idx, i; + + if (path_node->type != HLSL_IR_CONSTANT) + return false; + + idx = hlsl_ir_constant(path_node)->value.u[0].u; + *index = 0;
switch (type->class) { - case HLSL_CLASS_DEPTH_STENCIL_STATE: - case HLSL_CLASS_SCALAR: case HLSL_CLASS_VECTOR: - case HLSL_CLASS_PIXEL_SHADER: - case HLSL_CLASS_RASTERIZER_STATE: - case HLSL_CLASS_SAMPLER: - case HLSL_CLASS_STRING: - case HLSL_CLASS_TEXTURE: - case HLSL_CLASS_UAV: - case HLSL_CLASS_VERTEX_SHADER: - case HLSL_CLASS_COMPUTE_SHADER: - case HLSL_CLASS_DOMAIN_SHADER: - case HLSL_CLASS_HULL_SHADER: - case HLSL_CLASS_RENDER_TARGET_VIEW: - case HLSL_CLASS_DEPTH_STENCIL_VIEW: - case HLSL_CLASS_GEOMETRY_SHADER: - case HLSL_CLASS_BLEND_STATE: - case HLSL_CLASS_STREAM_OUTPUT: - case HLSL_CLASS_NULL: + if (idx >= type->e.numeric.dimx) + return false; + *index = idx; break;
case HLSL_CLASS_MATRIX: + if (idx >= hlsl_type_major_size(type)) + return false; + if (hlsl_type_is_row_major(type)) + *index = idx * type->e.numeric.dimx; + else + *index = idx * type->e.numeric.dimy; + break; + case HLSL_CLASS_ARRAY: + if (idx >= type->e.array.elements_count) + return false; + *index = idx * hlsl_type_component_count(type->e.array.type); + break; + case HLSL_CLASS_STRUCT: - /* We can't handle complex types here. - * They should have been already split anyway by earlier passes, - * but they may not have been deleted yet. We can't rely on DCE to - * solve that problem for us, since we may be called on a partial - * block, but DCE deletes dead stores, so it needs to be able to - * see the whole program. */ - case HLSL_CLASS_ERROR: - return false; + for (i = 0; i < idx; ++i) + *index += hlsl_type_component_count(type->e.record.fields[i].type); + break;
- case HLSL_CLASS_CONSTANT_BUFFER: - case HLSL_CLASS_EFFECT_GROUP: - case HLSL_CLASS_PASS: - case HLSL_CLASS_TECHNIQUE: - case HLSL_CLASS_VOID: + default: vkd3d_unreachable(); }
- if (copy_propagation_replace_with_constant_vector(ctx, state, load, HLSL_SWIZZLE(X, Y, Z, W), &load->node)) - return true; - - if (copy_propagation_replace_with_single_instr(ctx, state, load, HLSL_SWIZZLE(X, Y, Z, W), &load->node)) - return true; - - return false; + return true; }
-static bool copy_propagation_transform_swizzle(struct hlsl_ctx *ctx, - struct hlsl_ir_swizzle *swizzle, struct copy_propagation_state *state) +static bool nonconst_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, + unsigned int *idx, unsigned int *base, unsigned int *scale, unsigned int *count) { - struct hlsl_ir_load *load; + struct hlsl_type *type = deref->var->data_type; + bool found = false; + unsigned int i;
- if (swizzle->val.node->type != HLSL_IR_LOAD) - return false; - load = hlsl_ir_load(swizzle->val.node); + *base = 0;
- if (copy_propagation_replace_with_constant_vector(ctx, state, load, swizzle->u.vector, &swizzle->node)) - return true; + for (i = 0; i < deref->path_len; ++i) + { + struct hlsl_ir_node *path_node = deref->path[i].node; + struct hlsl_type *next_type;
- if (copy_propagation_replace_with_single_instr(ctx, state, load, swizzle->u.vector, &swizzle->node)) - return true; + VKD3D_ASSERT(path_node);
- return false; + /* We should always have generated a cast to UINT. */ + VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); + + next_type = hlsl_get_element_type_from_path_index(ctx, type, path_node); + + if (path_node->type != HLSL_IR_CONSTANT) + { + if (found) + return false; + found = true; + *idx = i; + *scale = hlsl_type_component_count(next_type); + *count = hlsl_type_element_count(type); + } + else + { + unsigned int index; + + if (!component_index_from_deref_path_node(path_node, type, &index)) + return false; + *base += index; + } + + type = next_type; + } + + return found; }
-static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, - struct hlsl_deref *deref, struct copy_propagation_state *state, unsigned int time) +static struct hlsl_ir_node *new_affine_path_index(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc, + struct hlsl_block *block, struct hlsl_ir_node *index, int c, int d) { - struct copy_propagation_value *value; - struct hlsl_ir_load *load; - unsigned int start, count; - - if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count)) - return false; - VKD3D_ASSERT(count == 1); + struct hlsl_ir_node *c_node, *d_node, *ic, *idx; + bool use_uint = c >= 0 && d >= 0;
- if (!(value = copy_propagation_get_value(state, deref->var, start, time))) - return false; - VKD3D_ASSERT(value->component == 0); + if (!c) + { + VKD3D_ASSERT(d >= 0);
- /* Only HLSL_IR_LOAD can produce an object. */ - load = hlsl_ir_load(value->node); + return hlsl_block_add_uint_constant(ctx, block, d, loc); + }
- /* As we are replacing the instruction's deref (with the one in the hlsl_ir_load) and not the - * instruction itself, we won't be able to rely on the value retrieved by - * copy_propagation_get_value() for the new deref in subsequent iterations of copy propagation. - * This is because another value may be written to that deref between the hlsl_ir_load and - * this instruction. - * - * For this reason, we only replace the new deref when it corresponds to a uniform variable, - * which cannot be written to. - * - * In a valid shader, all object references must resolve statically to a single uniform object. - * If this is the case, we can expect copy propagation on regular store/loads and the other - * compilation passes to replace all hlsl_ir_loads with loads to uniform objects, so this - * implementation is complete, even with this restriction. - */ - if (!load->src.var->is_uniform) + if (use_uint) { - TRACE("Ignoring load from non-uniform object variable %s\n", load->src.var->name); - return false; + c_node = hlsl_block_add_uint_constant(ctx, block, c, loc); + d_node = hlsl_block_add_uint_constant(ctx, block, d, loc); + } + else + { + c_node = hlsl_block_add_int_constant(ctx, block, c, loc); + d_node = hlsl_block_add_int_constant(ctx, block, d, loc); + index = hlsl_block_add_cast(ctx, block, index, hlsl_get_scalar_type(ctx, HLSL_TYPE_INT), loc); }
- hlsl_cleanup_deref(deref); - hlsl_copy_deref(ctx, deref, &load->src); + ic = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, index, c_node); + idx = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, ic, d_node); + if (!use_uint) + idx = hlsl_block_add_cast(ctx, block, idx, hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc);
- return true; + return idx; }
-static bool copy_propagation_transform_resource_load(struct hlsl_ctx *ctx, - struct hlsl_ir_resource_load *load, struct copy_propagation_state *state) +static bool copy_propagation_replace_with_deref(struct hlsl_ctx *ctx, + const struct copy_propagation_state *state, const struct hlsl_ir_load *load, + uint32_t swizzle, struct hlsl_ir_node *instr) { - bool progress = false; - - progress |= copy_propagation_transform_object_load(ctx, &load->resource, state, load->node.index); + const unsigned int instr_component_count = hlsl_type_component_count(instr->data_type); + unsigned int nonconst_i = 0, base, scale, count; + struct hlsl_ir_node *index, *new_instr = NULL; + const struct hlsl_deref *deref = &load->src; + const struct hlsl_ir_var *var = deref->var; + unsigned int time = load->node.index; + struct hlsl_deref tmp_deref = {0}; + struct hlsl_ir_load *new_load; + struct hlsl_ir_var *x = NULL; + int *c = NULL, *d = NULL; + uint32_t ret_swizzle = 0; + struct hlsl_block block; + unsigned int path_len; + bool success = false; + int i, j, k; + + if (!nonconst_index_from_deref(ctx, deref, &nonconst_i, &base, &scale, &count)) + return false; + + VKD3D_ASSERT(count); + + hlsl_block_init(&block); + + index = deref->path[nonconst_i].node; + + /* Iterate over the nonconst index, and check if their values all have the form + * x[[c0*i + d0][c1*i + d1]...[cm*i + dm]], and determine the constants c, d. */ + for (i = 0; i < count; ++i) + { + unsigned int start = base + scale * i; + struct copy_propagation_value *value; + struct hlsl_ir_load *idx; + uint32_t cur_swizzle = 0; + + if (!(value = copy_propagation_get_value(state, var, + start + hlsl_swizzle_get_component(swizzle, 0), time))) + goto done; + + if (value->node->type != HLSL_IR_LOAD) + goto done; + idx = hlsl_ir_load(value->node); + + if (!x) + x = idx->src.var; + else if (x != idx->src.var) + goto done; + + if (hlsl_version_lt(ctx, 4, 0) && x->is_uniform && ctx->profile->type != VKD3D_SHADER_TYPE_VERTEX) + { + TRACE("Skipping propagating non-constant deref to SM1 uniform %s.\n", var->name); + goto done; + } + + if (i == 0) + { + path_len = idx->src.path_len; + + if (path_len) + { + if (!(c = hlsl_calloc(ctx, path_len, sizeof(c[0]))) + || !(d = hlsl_alloc(ctx, path_len * sizeof(d[0])))) + goto done; + } + + for (k = 0; k < path_len; ++k) + { + if (idx->src.path[k].node->type != HLSL_IR_CONSTANT) + goto done; + d[k] = hlsl_ir_constant(idx->src.path[k].node)->value.u[0].u; + } + + } + else if (i == 1) + { + struct hlsl_type *type = idx->src.var->data_type; + + if (idx->src.path_len != path_len) + goto done; + + /* Calculate constants c and d based on the first two path indices. */ + for (k = 0; k < path_len; ++k) + { + int ix; + + if (idx->src.path[k].node->type != HLSL_IR_CONSTANT) + goto done; + ix = hlsl_ir_constant(idx->src.path[k].node)->value.u[0].u; + c[k] = ix - d[k]; + d[k] = ix - c[k] * i; + + if (c[k] && type->class == HLSL_CLASS_STRUCT) + goto done; + + type = hlsl_get_element_type_from_path_index(ctx, type, idx->src.path[k].node); + } + } + else + { + if (idx->src.path_len != path_len) + goto done; + + /* Check that this load has the form x[[c0*i +d0][c1*i + d1]...[cm*i + dm]]. */ + for (k = 0; k < path_len; ++k) + { + if (idx->src.path[k].node->type != HLSL_IR_CONSTANT) + goto done; + if (hlsl_ir_constant(idx->src.path[k].node)->value.u[0].u != c[k] * i + d[k]) + goto done; + } + } + + hlsl_swizzle_set_component(&cur_swizzle, 0, value->component); + + for (j = 1; j < instr_component_count; ++j) + { + struct copy_propagation_value *val; + + if (!(val = copy_propagation_get_value(state, var, + start + hlsl_swizzle_get_component(swizzle, j), time))) + goto done; + if (val->node != &idx->node) + goto done; + + hlsl_swizzle_set_component(&cur_swizzle, j, val->component); + } + + if (i == 0) + ret_swizzle = cur_swizzle; + else if (ret_swizzle != cur_swizzle) + goto done; + } + + if (!hlsl_init_deref(ctx, &tmp_deref, x, path_len)) + goto done; + + for (k = 0; k < path_len; ++k) + { + hlsl_src_from_node(&tmp_deref.path[k], + new_affine_path_index(ctx, &load->node.loc, &block, index, c[k], d[k])); + } + + if (!(new_load = hlsl_new_load_index(ctx, &tmp_deref, NULL, &load->node.loc))) + goto done; + new_instr = &new_load->node; + hlsl_block_add_instr(&block, new_instr); + + if (new_instr->data_type->class == HLSL_CLASS_SCALAR || new_instr->data_type->class == HLSL_CLASS_VECTOR) + new_instr = hlsl_block_add_swizzle(ctx, &block, ret_swizzle, instr_component_count, new_instr, &instr->loc); + + if (TRACE_ON()) + { + struct vkd3d_string_buffer buffer; + + vkd3d_string_buffer_init(&buffer); + + vkd3d_string_buffer_printf(&buffer, "Load from %s[", var->name); + for (j = 0; j < deref->path_len; ++j) + { + if (j == nonconst_i) + vkd3d_string_buffer_printf(&buffer, "[i]"); + else + vkd3d_string_buffer_printf(&buffer, "[%u]", hlsl_ir_constant(deref->path[j].node)->value.u[0].u); + } + vkd3d_string_buffer_printf(&buffer, "]%s propagated as %s[", + debug_hlsl_swizzle(swizzle, instr_component_count), tmp_deref.var->name); + for (k = 0; k < path_len; ++k) + { + if (c[k]) + vkd3d_string_buffer_printf(&buffer, "[i*%d + %d]", c[k], d[k]); + else + vkd3d_string_buffer_printf(&buffer, "[%d]", d[k]); + } + vkd3d_string_buffer_printf(&buffer, "]%s (i = %p).\n", + debug_hlsl_swizzle(ret_swizzle, instr_component_count), index); + + vkd3d_string_buffer_trace(&buffer); + vkd3d_string_buffer_cleanup(&buffer); + } + + list_move_before(&instr->entry, &block.instrs); + hlsl_replace_node(instr, new_instr); + success = true; + +done: + hlsl_cleanup_deref(&tmp_deref); + hlsl_block_cleanup(&block); + vkd3d_free(c); + vkd3d_free(d); + return success; +} + +static bool copy_propagation_transform_load(struct hlsl_ctx *ctx, + struct hlsl_ir_load *load, struct copy_propagation_state *state) +{ + struct hlsl_type *type = load->node.data_type; + + switch (type->class) + { + case HLSL_CLASS_DEPTH_STENCIL_STATE: + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_PIXEL_SHADER: + case HLSL_CLASS_RASTERIZER_STATE: + case HLSL_CLASS_SAMPLER: + case HLSL_CLASS_STRING: + case HLSL_CLASS_TEXTURE: + case HLSL_CLASS_UAV: + case HLSL_CLASS_VERTEX_SHADER: + case HLSL_CLASS_COMPUTE_SHADER: + case HLSL_CLASS_DOMAIN_SHADER: + case HLSL_CLASS_HULL_SHADER: + case HLSL_CLASS_RENDER_TARGET_VIEW: + case HLSL_CLASS_DEPTH_STENCIL_VIEW: + case HLSL_CLASS_GEOMETRY_SHADER: + case HLSL_CLASS_BLEND_STATE: + case HLSL_CLASS_STREAM_OUTPUT: + case HLSL_CLASS_NULL: + break; + + case HLSL_CLASS_MATRIX: + case HLSL_CLASS_ARRAY: + case HLSL_CLASS_STRUCT: + /* We can't handle complex types here. + * They should have been already split anyway by earlier passes, + * but they may not have been deleted yet. We can't rely on DCE to + * solve that problem for us, since we may be called on a partial + * block, but DCE deletes dead stores, so it needs to be able to + * see the whole program. */ + case HLSL_CLASS_ERROR: + return false; + + case HLSL_CLASS_CONSTANT_BUFFER: + case HLSL_CLASS_EFFECT_GROUP: + case HLSL_CLASS_PASS: + case HLSL_CLASS_TECHNIQUE: + case HLSL_CLASS_VOID: + vkd3d_unreachable(); + } + + if (copy_propagation_replace_with_constant_vector(ctx, state, load, HLSL_SWIZZLE(X, Y, Z, W), &load->node)) + return true; + + if (copy_propagation_replace_with_single_instr(ctx, state, load, HLSL_SWIZZLE(X, Y, Z, W), &load->node)) + return true; + + if (copy_propagation_replace_with_deref(ctx, state, load, HLSL_SWIZZLE(X, Y, Z, W), &load->node)) + return true; + + return false; +} + +static bool copy_propagation_transform_swizzle(struct hlsl_ctx *ctx, + struct hlsl_ir_swizzle *swizzle, struct copy_propagation_state *state) +{ + struct hlsl_ir_load *load; + + if (swizzle->val.node->type != HLSL_IR_LOAD) + return false; + load = hlsl_ir_load(swizzle->val.node); + + if (copy_propagation_replace_with_constant_vector(ctx, state, load, swizzle->u.vector, &swizzle->node)) + return true; + + if (copy_propagation_replace_with_single_instr(ctx, state, load, swizzle->u.vector, &swizzle->node)) + return true; + + if (copy_propagation_replace_with_deref(ctx, state, load, swizzle->u.vector, &swizzle->node)) + return true; + + return false; +} + +static bool copy_propagation_transform_object_load(struct hlsl_ctx *ctx, + struct hlsl_deref *deref, struct copy_propagation_state *state, unsigned int time) +{ + struct copy_propagation_value *value; + struct hlsl_ir_load *load; + unsigned int start, count; + + if (!hlsl_component_index_range_from_deref(ctx, deref, &start, &count)) + return false; + VKD3D_ASSERT(count == 1); + + if (!(value = copy_propagation_get_value(state, deref->var, start, time))) + return false; + VKD3D_ASSERT(value->component == 0); + + /* A uniform object should have never been written to. */ + VKD3D_ASSERT(!deref->var->is_uniform); + + /* Only HLSL_IR_LOAD can produce an object. */ + load = hlsl_ir_load(value->node); + + /* As we are replacing the instruction's deref (with the one in the hlsl_ir_load) and not the + * instruction itself, we won't be able to rely on the value retrieved by + * copy_propagation_get_value() for the new deref in subsequent iterations of copy propagation. + * This is because another value may be written to that deref between the hlsl_ir_load and + * this instruction. + * + * For this reason, we only replace the new deref when it corresponds to a uniform variable, + * which cannot be written to. + * + * In a valid shader, all object references must resolve statically to a single uniform object. + * If this is the case, we can expect copy propagation on regular store/loads and the other + * compilation passes to replace all hlsl_ir_loads with loads to uniform objects, so this + * implementation is complete, even with this restriction. + */ + if (!load->src.var->is_uniform) + { + TRACE("Ignoring load from non-uniform object variable %s\n", load->src.var->name); + return false; + } + + hlsl_cleanup_deref(deref); + hlsl_copy_deref(ctx, deref, &load->src); + + return true; +} + +static bool copy_propagation_transform_resource_load(struct hlsl_ctx *ctx, + struct hlsl_ir_resource_load *load, struct copy_propagation_state *state) +{ + bool progress = false; + + progress |= copy_propagation_transform_object_load(ctx, &load->resource, state, load->node.index); if (load->sampler.var) progress |= copy_propagation_transform_object_load(ctx, &load->sampler, state, load->node.index); return progress; @@ -2108,126 +2375,689 @@ static bool copy_propagation_process_loop(struct hlsl_ctx *ctx, struct hlsl_ir_l { bool progress = false;
- copy_propagation_invalidate_from_block(ctx, state, &loop->body, loop->node.index); - copy_propagation_invalidate_from_block(ctx, state, &loop->iter, loop->node.index); + copy_propagation_invalidate_from_block(ctx, state, &loop->body, loop->node.index); + copy_propagation_invalidate_from_block(ctx, state, &loop->iter, loop->node.index); + + copy_propagation_push_scope(state, ctx); + progress |= copy_propagation_transform_block(ctx, &loop->body, state); + if (state->stopped) + return progress; + copy_propagation_pop_scope(state); + + return progress; +} + +static bool copy_propagation_process_switch(struct hlsl_ctx *ctx, struct hlsl_ir_switch *s, + struct copy_propagation_state *state) +{ + struct hlsl_ir_switch_case *c; + bool progress = false; + + LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) + { + copy_propagation_push_scope(state, ctx); + progress |= copy_propagation_transform_block(ctx, &c->body, state); + if (state->stopped) + return progress; + copy_propagation_pop_scope(state); + } + + LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) + { + copy_propagation_invalidate_from_block(ctx, state, &c->body, s->node.index); + } + + return progress; +} + +static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct copy_propagation_state *state) +{ + struct hlsl_ir_node *instr, *next; + bool progress = false; + + LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) + { + if (instr == state->stop) + { + state->stopped = true; + return progress; + } + + switch (instr->type) + { + case HLSL_IR_LOAD: + progress |= copy_propagation_transform_load(ctx, hlsl_ir_load(instr), state); + break; + + case HLSL_IR_RESOURCE_LOAD: + progress |= copy_propagation_transform_resource_load(ctx, hlsl_ir_resource_load(instr), state); + break; + + case HLSL_IR_RESOURCE_STORE: + progress |= copy_propagation_transform_resource_store(ctx, hlsl_ir_resource_store(instr), state); + break; + + case HLSL_IR_STORE: + copy_propagation_record_store(ctx, hlsl_ir_store(instr), state); + break; + + case HLSL_IR_SWIZZLE: + progress |= copy_propagation_transform_swizzle(ctx, hlsl_ir_swizzle(instr), state); + break; + + case HLSL_IR_IF: + progress |= copy_propagation_process_if(ctx, hlsl_ir_if(instr), state); + break; + + case HLSL_IR_LOOP: + progress |= copy_propagation_process_loop(ctx, hlsl_ir_loop(instr), state); + break; + + case HLSL_IR_SWITCH: + progress |= copy_propagation_process_switch(ctx, hlsl_ir_switch(instr), state); + break; + + case HLSL_IR_INTERLOCKED: + progress |= copy_propagation_transform_interlocked(ctx, hlsl_ir_interlocked(instr), state); + break; + + default: + break; + } + + if (state->stopped) + return progress; + } + + return progress; +} + +bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block) +{ + struct copy_propagation_state state; + bool progress; + + if (ctx->result) + return false; + + index_instructions(block, 1); + + copy_propagation_state_init(&state, ctx); + + progress = copy_propagation_transform_block(ctx, block, &state); + + copy_propagation_state_destroy(&state); + + return progress; +} + +enum validation_result +{ + DEREF_VALIDATION_OK, + DEREF_VALIDATION_OUT_OF_BOUNDS, + DEREF_VALIDATION_NOT_CONSTANT, +}; + +struct vectorize_exprs_state +{ + struct vectorizable_exprs_group + { + struct hlsl_block *block; + struct hlsl_ir_expr *exprs[4]; + uint8_t expr_count, component_count; + } *groups; + size_t count, capacity; +}; + +static bool is_same_vectorizable_source(struct hlsl_ir_node *a, struct hlsl_ir_node *b) +{ + /* TODO: We can also vectorize different constants. */ + + if (a->type == HLSL_IR_SWIZZLE) + a = hlsl_ir_swizzle(a)->val.node; + if (b->type == HLSL_IR_SWIZZLE) + b = hlsl_ir_swizzle(b)->val.node; + + return a == b; +} + +static bool is_same_vectorizable_expr(struct hlsl_ir_expr *a, struct hlsl_ir_expr *b) +{ + if (a->op != b->op) + return false; + + for (size_t j = 0; j < HLSL_MAX_OPERANDS; ++j) + { + if (!a->operands[j].node) + break; + if (!is_same_vectorizable_source(a->operands[j].node, b->operands[j].node)) + return false; + } + + return true; +} + +static void record_vectorizable_expr(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_expr *expr, struct vectorize_exprs_state *state) +{ + if (expr->node.data_type->class > HLSL_CLASS_VECTOR) + return; + + /* These are the only current ops that are not per-component. */ + if (expr->op == HLSL_OP1_COS_REDUCED || expr->op == HLSL_OP1_SIN_REDUCED + || expr->op == HLSL_OP2_DOT || expr->op == HLSL_OP3_DP2ADD) + return; + + for (size_t i = 0; i < state->count; ++i) + { + struct vectorizable_exprs_group *group = &state->groups[i]; + struct hlsl_ir_expr *other = group->exprs[0]; + + /* These are SSA instructions, which means they have the same value + * regardless of what block they're in. However, being in different + * blocks may mean that one expression or the other is not always + * executed. */ + + if (expr->node.data_type->e.numeric.dimx + group->component_count <= 4 + && group->block == block + && is_same_vectorizable_expr(expr, other)) + { + group->exprs[group->expr_count++] = expr; + group->component_count += expr->node.data_type->e.numeric.dimx; + return; + } + } + + if (!hlsl_array_reserve(ctx, (void **)&state->groups, + &state->capacity, state->count + 1, sizeof(*state->groups))) + return; + state->groups[state->count].block = block; + state->groups[state->count].exprs[0] = expr; + state->groups[state->count].expr_count = 1; + state->groups[state->count].component_count = expr->node.data_type->e.numeric.dimx; + ++state->count; +} + +static void find_vectorizable_expr_groups(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct vectorize_exprs_state *state) +{ + struct hlsl_ir_node *instr; + + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) + { + if (instr->type == HLSL_IR_EXPR) + { + record_vectorizable_expr(ctx, block, hlsl_ir_expr(instr), state); + } + else if (instr->type == HLSL_IR_IF) + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr); + + find_vectorizable_expr_groups(ctx, &iff->then_block, state); + find_vectorizable_expr_groups(ctx, &iff->else_block, state); + } + else if (instr->type == HLSL_IR_LOOP) + { + find_vectorizable_expr_groups(ctx, &hlsl_ir_loop(instr)->body, state); + } + else if (instr->type == HLSL_IR_SWITCH) + { + struct hlsl_ir_switch *s = hlsl_ir_switch(instr); + struct hlsl_ir_switch_case *c; + + LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) + find_vectorizable_expr_groups(ctx, &c->body, state); + } + } +} + +/* Combine sequences like + * + * 3: @1.x + * 4: @2.x + * 5: @3 * @4 + * 6: @1.y + * 7: @2.x + * 8: @6 * @7 + * + * into + * + * 5_1: @1.xy + * 5_2: @2.xx + * 5_3: @5_1 * @5_2 + * 5: @5_3.x + * 8: @5_3.y + * + * Each operand to an expression needs to refer to the same ultimate source + * (in this case @1 and @2 respectively), but can be a swizzle thereof. + * + * In practice the swizzles @5 and @8 can generally then be vectorized again, + * either as part of another expression, or as part of a store. + */ +static bool vectorize_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) +{ + struct vectorize_exprs_state state = {0}; + bool progress = false; + + find_vectorizable_expr_groups(ctx, block, &state); + + for (unsigned int i = 0; i < state.count; ++i) + { + struct vectorizable_exprs_group *group = &state.groups[i]; + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + uint32_t swizzles[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_ir_node *arg, *combined; + unsigned int component_count = 0; + struct hlsl_type *combined_type; + struct hlsl_block new_block; + struct hlsl_ir_expr *expr; + + if (group->expr_count == 1) + continue; + + hlsl_block_init(&new_block); + + for (unsigned int j = 0; j < group->expr_count; ++j) + { + expr = group->exprs[j]; + + for (unsigned int a = 0; a < HLSL_MAX_OPERANDS; ++a) + { + uint32_t arg_swizzle; + + if (!(arg = expr->operands[a].node)) + break; + + if (arg->type == HLSL_IR_SWIZZLE) + arg_swizzle = hlsl_ir_swizzle(arg)->u.vector; + else + arg_swizzle = HLSL_SWIZZLE(X, Y, Z, W); + + /* Mask out the invalid components. */ + arg_swizzle &= (1u << VKD3D_SHADER_SWIZZLE_SHIFT(arg->data_type->e.numeric.dimx)) - 1; + swizzles[a] |= arg_swizzle << VKD3D_SHADER_SWIZZLE_SHIFT(component_count); + } + + component_count += expr->node.data_type->e.numeric.dimx; + } + + expr = group->exprs[0]; + for (unsigned int a = 0; a < HLSL_MAX_OPERANDS; ++a) + { + if (!(arg = expr->operands[a].node)) + break; + if (arg->type == HLSL_IR_SWIZZLE) + arg = hlsl_ir_swizzle(arg)->val.node; + args[a] = hlsl_block_add_swizzle(ctx, &new_block, swizzles[a], component_count, arg, &arg->loc); + } + + combined_type = hlsl_get_vector_type(ctx, expr->node.data_type->e.numeric.type, component_count); + combined = hlsl_block_add_expr(ctx, &new_block, expr->op, args, combined_type, &expr->node.loc); + + list_move_before(&expr->node.entry, &new_block.instrs); + + TRACE("Combining %u %s instructions into %p.\n", group->expr_count, + debug_hlsl_expr_op(group->exprs[0]->op), combined); + + component_count = 0; + for (unsigned int j = 0; j < group->expr_count; ++j) + { + struct hlsl_ir_node *replacement; + + expr = group->exprs[j]; + + if (!(replacement = hlsl_new_swizzle(ctx, + HLSL_SWIZZLE(X, Y, Z, W) >> VKD3D_SHADER_SWIZZLE_SHIFT(component_count), + expr->node.data_type->e.numeric.dimx, combined, &expr->node.loc))) + goto out; + component_count += expr->node.data_type->e.numeric.dimx; + list_add_before(&expr->node.entry, &replacement->entry); + hlsl_replace_node(&expr->node, replacement); + } + + progress = true; + } + +out: + vkd3d_free(state.groups); + return progress; +} + +struct vectorize_stores_state +{ + struct vectorizable_stores_group + { + struct hlsl_block *block; + /* We handle overlapping stores, because it's not really easier not to. + * In theory, then, we could collect an arbitrary number of stores here. + * + * In practice, overlapping stores are unlikely, and of course at most + * 4 stores can appear without overlap. Therefore, for simplicity, we + * just use a fixed array of 4. + * + * Since computing the writemask requires traversing the deref, and we + * need to do that anyway, we store it here for convenience. */ + struct hlsl_ir_store *stores[4]; + unsigned int path_len; + uint8_t writemasks[4]; + uint8_t store_count; + bool dirty; + } *groups; + size_t count, capacity; +}; + +/* This must be a store to a subsection of a vector. + * In theory we can also vectorize stores to packed struct fields, + * but this requires target-specific knowledge and is probably best left + * to a VSIR pass. */ +static bool can_vectorize_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, + unsigned int *path_len, uint8_t *writemask) +{ + struct hlsl_type *type = store->lhs.var->data_type; + unsigned int i; + + if (store->rhs.node->data_type->class > HLSL_CLASS_VECTOR) + return false; + + if (type->class == HLSL_CLASS_SCALAR) + return false; + + for (i = 0; type->class != HLSL_CLASS_VECTOR && i < store->lhs.path_len; ++i) + type = hlsl_get_element_type_from_path_index(ctx, type, store->lhs.path[i].node); + + if (type->class != HLSL_CLASS_VECTOR) + return false; + + *path_len = i; + + if (i < store->lhs.path_len) + { + struct hlsl_ir_constant *c; + + /* This is a store to a scalar component of a vector, achieved via + * indexing. */ + + if (store->lhs.path[i].node->type != HLSL_IR_CONSTANT) + return false; + c = hlsl_ir_constant(store->lhs.path[i].node); + *writemask = (1u << c->value.u[0].u); + } + else + { + *writemask = store->writemask; + } + + return true; +} + +static bool derefs_are_same_vector(struct hlsl_ctx *ctx, const struct hlsl_deref *a, const struct hlsl_deref *b) +{ + struct hlsl_type *type = a->var->data_type; + + if (a->var != b->var) + return false; + + for (unsigned int i = 0; type->class != HLSL_CLASS_VECTOR && i < a->path_len && i < b->path_len; ++i) + { + if (a->path[i].node != b->path[i].node) + return false; + type = hlsl_get_element_type_from_path_index(ctx, type, a->path[i].node); + } + + return true; +} + +static void record_vectorizable_store(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct hlsl_ir_store *store, struct vectorize_stores_state *state) +{ + unsigned int path_len; + uint8_t writemask; + + if (!can_vectorize_store(ctx, store, &path_len, &writemask)) + { + /* In the case of a dynamically indexed vector, we must invalidate + * any groups that statically index the same vector. + * For the sake of expediency, we go one step further and invalidate + * any groups that store to the same variable. + * (We also don't check that that was the reason why this store isn't + * vectorizable.) + * We could be more granular, but we'll defer that until it comes + * up in practice. */ + for (size_t i = 0; i < state->count; ++i) + { + if (state->groups[i].stores[0]->lhs.var == store->lhs.var) + state->groups[i].dirty = true; + } + return; + } + + for (size_t i = 0; i < state->count; ++i) + { + struct vectorizable_stores_group *group = &state->groups[i]; + struct hlsl_ir_store *other = group->stores[0]; + + if (group->dirty) + continue; + + if (derefs_are_same_vector(ctx, &store->lhs, &other->lhs)) + { + /* Stores must be in the same CFG block. If they're not, + * they're not executed in exactly the same flow, and + * therefore can't be vectorized. */ + if (group->block == block + && is_same_vectorizable_source(store->rhs.node, other->rhs.node)) + { + if (group->store_count < ARRAY_SIZE(group->stores)) + { + group->stores[group->store_count] = store; + group->writemasks[group->store_count] = writemask; + ++group->store_count; + return; + } + } + else + { + /* A store to the same vector with a different source, or in + * a different CFG block, invalidates any earlier store. + * + * A store to a component which *contains* the vector in + * question would also invalidate, but we should have split all + * of those by the time we get here. */ + group->dirty = true; + + /* Note that we do exit this loop early if we find a store A we + * can vectorize with, but that's fine. If there was a store B + * also in the state that we can't vectorize with, it would + * already have invalidated A. */ + } + } + else + { + /* This could still be a store to the same vector, if e.g. the + * vector is part of a dynamically indexed array, or the path has + * two equivalent instructions which refer to the same component. + * [CSE may help with the latter, but we don't have it yet, + * and we shouldn't depend on it anyway.] + * For the sake of expediency, we just invalidate it if it refers + * to the same variable at all. + * As above, we could be more granular, but we'll defer that until + * it comes up in practice. */ + if (store->lhs.var == other->lhs.var) + group->dirty = true;
- copy_propagation_push_scope(state, ctx); - progress |= copy_propagation_transform_block(ctx, &loop->body, state); - if (state->stopped) - return progress; - copy_propagation_pop_scope(state); + /* As above, we don't need to worry about exiting the loop early. */ + } + }
- return progress; + if (!hlsl_array_reserve(ctx, (void **)&state->groups, + &state->capacity, state->count + 1, sizeof(*state->groups))) + return; + state->groups[state->count].block = block; + state->groups[state->count].stores[0] = store; + state->groups[state->count].path_len = path_len; + state->groups[state->count].writemasks[0] = writemask; + state->groups[state->count].store_count = 1; + state->groups[state->count].dirty = false; + ++state->count; }
-static bool copy_propagation_process_switch(struct hlsl_ctx *ctx, struct hlsl_ir_switch *s, - struct copy_propagation_state *state) +static void mark_store_groups_dirty(struct hlsl_ctx *ctx, + struct vectorize_stores_state *state, struct hlsl_ir_var *var) { - struct hlsl_ir_switch_case *c; - bool progress = false; - - LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) - { - copy_propagation_push_scope(state, ctx); - progress |= copy_propagation_transform_block(ctx, &c->body, state); - if (state->stopped) - return progress; - copy_propagation_pop_scope(state); - } - - LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) + for (unsigned int i = 0; i < state->count; ++i) { - copy_propagation_invalidate_from_block(ctx, state, &c->body, s->node.index); + if (state->groups[i].stores[0]->lhs.var == var) + state->groups[i].dirty = true; } - - return progress; }
-static bool copy_propagation_transform_block(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct copy_propagation_state *state) +static void find_vectorizable_store_groups(struct hlsl_ctx *ctx, struct hlsl_block *block, + struct vectorize_stores_state *state) { - struct hlsl_ir_node *instr, *next; - bool progress = false; + struct hlsl_ir_node *instr;
- LIST_FOR_EACH_ENTRY_SAFE(instr, next, &block->instrs, struct hlsl_ir_node, entry) + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry) { - if (instr == state->stop) + if (instr->type == HLSL_IR_STORE) { - state->stopped = true; - return progress; + record_vectorizable_store(ctx, block, hlsl_ir_store(instr), state); + } + else if (instr->type == HLSL_IR_LOAD) + { + /* By vectorizing store A with store B, we are effectively moving + * store A down to happen at the same time as store B. + * If there was a load of the same variable between the two, this + * would be incorrect. + * Therefore invalidate all stores to this variable. As above, we + * could be more granular if necessary. */ + mark_store_groups_dirty(ctx, state, hlsl_ir_load(instr)->src.var); + } + else if (instr->type == HLSL_IR_INTERLOCKED) + { + /* An interlocked operation can be used on shared memory variables, + * and it is at the same time both a store and a load, thus, we + * should also mark all stores to this variable as dirty once we + * find one.*/ + mark_store_groups_dirty(ctx, state, hlsl_ir_interlocked(instr)->dst.var); } + else if (instr->type == HLSL_IR_IF) + { + struct hlsl_ir_if *iff = hlsl_ir_if(instr);
- switch (instr->type) + find_vectorizable_store_groups(ctx, &iff->then_block, state); + find_vectorizable_store_groups(ctx, &iff->else_block, state); + } + else if (instr->type == HLSL_IR_LOOP) { - case HLSL_IR_LOAD: - progress |= copy_propagation_transform_load(ctx, hlsl_ir_load(instr), state); - break; + find_vectorizable_store_groups(ctx, &hlsl_ir_loop(instr)->body, state); + } + else if (instr->type == HLSL_IR_SWITCH) + { + struct hlsl_ir_switch *s = hlsl_ir_switch(instr); + struct hlsl_ir_switch_case *c;
- case HLSL_IR_RESOURCE_LOAD: - progress |= copy_propagation_transform_resource_load(ctx, hlsl_ir_resource_load(instr), state); - break; + LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) + find_vectorizable_store_groups(ctx, &c->body, state); + } + } +}
- case HLSL_IR_RESOURCE_STORE: - progress |= copy_propagation_transform_resource_store(ctx, hlsl_ir_resource_store(instr), state); - break; +/* Combine sequences like + * + * 2: @1.yw + * 3: @1.zy + * 4: var.xy = @2 + * 5: var.yw = @3 + * + * to + * + * 2: @1.yzy + * 5: var.xyw = @2 + * + * There are a lot of gotchas here. We need to make sure the two stores are to + * the same vector (which may be embedded in a complex variable), that they're + * always executed in the same control flow, and that there aren't any other + * stores or loads on the same vector in the middle. */ +static bool vectorize_stores(struct hlsl_ctx *ctx, struct hlsl_block *block) +{ + struct vectorize_stores_state state = {0}; + bool progress = false;
- case HLSL_IR_STORE: - copy_propagation_record_store(ctx, hlsl_ir_store(instr), state); - break; + find_vectorizable_store_groups(ctx, block, &state);
- case HLSL_IR_SWIZZLE: - progress |= copy_propagation_transform_swizzle(ctx, hlsl_ir_swizzle(instr), state); - break; + for (unsigned int i = 0; i < state.count; ++i) + { + struct vectorizable_stores_group *group = &state.groups[i]; + uint32_t new_swizzle = 0, new_writemask = 0; + struct hlsl_ir_node *new_rhs, *value; + uint32_t swizzle_components[4]; + unsigned int component_count; + struct hlsl_ir_store *store; + struct hlsl_block new_block;
- case HLSL_IR_IF: - progress |= copy_propagation_process_if(ctx, hlsl_ir_if(instr), state); - break; + if (group->store_count == 1) + continue;
- case HLSL_IR_LOOP: - progress |= copy_propagation_process_loop(ctx, hlsl_ir_loop(instr), state); - break; + hlsl_block_init(&new_block);
- case HLSL_IR_SWITCH: - progress |= copy_propagation_process_switch(ctx, hlsl_ir_switch(instr), state); - break; + /* Compute the swizzle components. */ + for (unsigned int j = 0; j < group->store_count; ++j) + { + unsigned int writemask = group->writemasks[j]; + uint32_t rhs_swizzle;
- case HLSL_IR_INTERLOCKED: - progress |= copy_propagation_transform_interlocked(ctx, hlsl_ir_interlocked(instr), state); + store = group->stores[j];
- default: - break; + if (store->rhs.node->type == HLSL_IR_SWIZZLE) + rhs_swizzle = hlsl_ir_swizzle(store->rhs.node)->u.vector; + else + rhs_swizzle = HLSL_SWIZZLE(X, Y, Z, W); + + component_count = 0; + for (unsigned int k = 0; k < 4; ++k) + { + if (writemask & (1u << k)) + swizzle_components[k] = hlsl_swizzle_get_component(rhs_swizzle, component_count++); + } + + new_writemask |= writemask; }
- if (state->stopped) - return progress; - } + /* Construct the new swizzle. */ + component_count = 0; + for (unsigned int k = 0; k < 4; ++k) + { + if (new_writemask & (1u << k)) + hlsl_swizzle_set_component(&new_swizzle, component_count++, swizzle_components[k]); + }
- return progress; -} + store = group->stores[0]; + value = store->rhs.node; + if (value->type == HLSL_IR_SWIZZLE) + value = hlsl_ir_swizzle(value)->val.node;
-bool hlsl_copy_propagation_execute(struct hlsl_ctx *ctx, struct hlsl_block *block) -{ - struct copy_propagation_state state; - bool progress; + new_rhs = hlsl_block_add_swizzle(ctx, &new_block, new_swizzle, component_count, value, &value->loc); + hlsl_block_add_store_parent(ctx, &new_block, &store->lhs, + group->path_len, new_rhs, new_writemask, &store->node.loc);
- index_instructions(block, 2); + TRACE("Combining %u stores to %s.\n", group->store_count, store->lhs.var->name);
- copy_propagation_state_init(&state, ctx); + list_move_before(&group->stores[group->store_count - 1]->node.entry, &new_block.instrs);
- progress = copy_propagation_transform_block(ctx, block, &state); + for (unsigned int j = 0; j < group->store_count; ++j) + { + list_remove(&group->stores[j]->node.entry); + hlsl_free_instr(&group->stores[j]->node); + }
- copy_propagation_state_destroy(&state); + progress = true; + }
+ vkd3d_free(state.groups); return progress; }
-enum validation_result -{ - DEREF_VALIDATION_OK, - DEREF_VALIDATION_OUT_OF_BOUNDS, - DEREF_VALIDATION_NOT_CONSTANT, -}; - static enum validation_result validate_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) { @@ -2244,8 +3074,7 @@ static enum validation_result validate_component_index_range_from_deref(struct h return DEREF_VALIDATION_NOT_CONSTANT;
/* We should always have generated a cast to UINT. */ - VKD3D_ASSERT(path_node->data_type->class == HLSL_CLASS_SCALAR - && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); + VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
idx = hlsl_ir_constant(path_node)->value.u[0].u;
@@ -2402,11 +3231,6 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins return false; }
-static bool is_vec1(const struct hlsl_type *type) -{ - return (type->class == HLSL_CLASS_SCALAR) || (type->class == HLSL_CLASS_VECTOR && type->e.numeric.dimx == 1); -} - static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { if (instr->type == HLSL_IR_EXPR) @@ -2421,7 +3245,8 @@ static bool fold_redundant_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst src_type = expr->operands[0].node->data_type;
if (hlsl_types_are_equal(src_type, dst_type) - || (src_type->e.numeric.type == dst_type->e.numeric.type && is_vec1(src_type) && is_vec1(dst_type))) + || (src_type->e.numeric.type == dst_type->e.numeric.type + && hlsl_is_vec1(src_type) && hlsl_is_vec1(dst_type))) { hlsl_replace_node(&expr->node, expr->operands[0].node); return true; @@ -2532,6 +3357,59 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return true; }
+struct stream_append_ctx +{ + struct hlsl_ir_function_decl *func; + bool created; +}; + +static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct stream_append_ctx *append_ctx = context; + struct hlsl_ir_resource_store *store; + const struct hlsl_ir_node *rhs; + const struct hlsl_type *type; + struct hlsl_ir_var *var; + struct hlsl_block block; + + if (instr->type != HLSL_IR_RESOURCE_STORE) + return false; + + store = hlsl_ir_resource_store(instr); + if (store->store_type != HLSL_RESOURCE_STREAM_APPEND) + return false; + + rhs = store->value.node; + var = store->resource.var; + type = hlsl_get_stream_output_type(var->data_type); + + if (rhs->type != HLSL_IR_LOAD) + { + hlsl_fixme(ctx, &instr->loc, "Stream append rhs is not HLSL_IR_LOAD. Broadcast may be missing."); + return false; + } + + VKD3D_ASSERT(var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); + + if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) + { + hlsl_fixme(ctx, &instr->loc, "Append to an output stream with a nonzero stream index."); + return false; + } + + hlsl_block_init(&block); + + append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), var->storage_modifiers, + &var->semantic, var->semantic.index, false, !append_ctx->created); + append_ctx->created = true; + + list_move_before(&instr->entry, &block.instrs); + hlsl_src_remove(&store->value); + + return true; + +} + static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { const struct hlsl_ir_node *rhs; @@ -2584,20 +3462,14 @@ static bool lower_narrowing_casts(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins if (src_type->class <= HLSL_CLASS_VECTOR && dst_type->class <= HLSL_CLASS_VECTOR && dst_type->e.numeric.dimx < src_type->e.numeric.dimx) { - struct hlsl_ir_node *new_cast, *swizzle; + struct hlsl_ir_node *new_cast;
dst_vector_type = hlsl_get_vector_type(ctx, dst_type->e.numeric.type, src_type->e.numeric.dimx); /* We need to preserve the cast since it might be doing more than just * narrowing the vector. */ - if (!(new_cast = hlsl_new_cast(ctx, cast->operands[0].node, dst_vector_type, &cast->node.loc))) - return false; - hlsl_block_add_instr(block, new_cast); - - if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, Y, Z, W), - dst_type->e.numeric.dimx, new_cast, &cast->node.loc))) - return false; - hlsl_block_add_instr(block, swizzle); - + new_cast = hlsl_block_add_cast(ctx, block, cast->operands[0].node, dst_vector_type, &cast->node.loc); + hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, Y, Z, W), + dst_type->e.numeric.dimx, new_cast, &cast->node.loc); return true; }
@@ -2768,16 +3640,9 @@ static bool normalize_switch_cases(struct hlsl_ctx *ctx, struct hlsl_ir_node *in } else { - struct hlsl_ir_node *jump; - if (!(def = hlsl_new_switch_case(ctx, 0, true, NULL, &s->node.loc))) return true; - if (!(jump = hlsl_new_jump(ctx, HLSL_IR_JUMP_BREAK, NULL, &s->node.loc))) - { - hlsl_free_ir_switch_case(def); - return true; - } - hlsl_block_add_instr(&def->body, jump); + hlsl_block_add_jump(ctx, &def->body, HLSL_IR_JUMP_BREAK, NULL, &s->node.loc); } list_add_tail(&s->cases, &def->entry);
@@ -2808,7 +3673,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
if (type->class == HLSL_CLASS_VECTOR && idx->type != HLSL_IR_CONSTANT) { - struct hlsl_ir_node *eq, *swizzle, *dot, *c, *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_ir_node *eq, *swizzle, *c, *operands[HLSL_MAX_OPERANDS] = {0}; unsigned int width = type->e.numeric.dimx; struct hlsl_constant_value value; struct hlsl_ir_load *vector_load; @@ -2818,9 +3683,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir return false; hlsl_block_add_instr(block, &vector_load->node);
- if (!(swizzle = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc))) - return false; - hlsl_block_add_instr(block, swizzle); + swizzle = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), width, idx, &instr->loc);
value.u[0].u = 0; value.u[1].u = 1; @@ -2832,14 +3695,9 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir
operands[0] = swizzle; operands[1] = c; - if (!(eq = hlsl_new_expr(ctx, HLSL_OP2_EQUAL, operands, - hlsl_get_vector_type(ctx, HLSL_TYPE_BOOL, width), &instr->loc))) - return false; - hlsl_block_add_instr(block, eq); - - if (!(eq = hlsl_new_cast(ctx, eq, type, &instr->loc))) - return false; - hlsl_block_add_instr(block, eq); + eq = hlsl_block_add_expr(ctx, block, HLSL_OP2_EQUAL, operands, + hlsl_get_vector_type(ctx, HLSL_TYPE_BOOL, width), &instr->loc); + eq = hlsl_block_add_cast(ctx, block, eq, type, &instr->loc);
op = HLSL_OP2_DOT; if (width == 1) @@ -2849,10 +3707,7 @@ static bool lower_nonconstant_vector_derefs(struct hlsl_ctx *ctx, struct hlsl_ir * LOGIC_OR + LOGIC_AND. */ operands[0] = &vector_load->node; operands[1] = eq; - if (!(dot = hlsl_new_expr(ctx, op, operands, instr->data_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, dot); - + hlsl_block_add_expr(ctx, block, op, operands, instr->data_type, &instr->loc); return true; }
@@ -2891,6 +3746,11 @@ static bool validate_nonconstant_vector_store_derefs(struct hlsl_ctx *ctx, struc return false; }
+static bool deref_supports_sm1_indirect_addressing(struct hlsl_ctx *ctx, const struct hlsl_deref *deref) +{ + return ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX && deref->var->is_uniform; +} + /* This pass flattens array (and row_major matrix) loads that include the indexing of a non-constant * index into multiple constant loads, where the value of only one of them ends up in the resulting * node. @@ -2901,7 +3761,7 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n struct hlsl_block *block) { struct hlsl_constant_value zero_value = {0}; - struct hlsl_ir_node *cut_index, *zero, *store; + struct hlsl_ir_node *cut_index, *zero; unsigned int i, i_cut, element_count; const struct hlsl_deref *deref; struct hlsl_type *cut_type; @@ -2917,6 +3777,9 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n if (deref->path_len == 0) return false;
+ if (deref_supports_sm1_indirect_addressing(ctx, deref)) + return false; + for (i = deref->path_len - 1; ; --i) { if (deref->path[i].node->type != HLSL_IR_CONSTANT) @@ -2944,70 +3807,44 @@ static bool lower_nonconstant_array_loads(struct hlsl_ctx *ctx, struct hlsl_ir_n return false; hlsl_block_add_instr(block, zero);
- if (!(store = hlsl_new_simple_store(ctx, var, zero))) - return false; - hlsl_block_add_instr(block, store); + hlsl_block_add_simple_store(ctx, block, var, zero);
TRACE("Lowering non-constant %s load on variable '%s'.\n", row_major ? "row_major" : "array", deref->var->name);
element_count = hlsl_type_element_count(cut_type); for (i = 0; i < element_count; ++i) { + struct hlsl_ir_node *const_i, *equals, *ternary, *specific_load, *var_load; struct hlsl_type *btype = hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL); struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_ir_node *const_i, *equals, *ternary, *var_store; - struct hlsl_ir_load *var_load, *specific_load; struct hlsl_deref deref_copy = {0};
- if (!(const_i = hlsl_new_uint_constant(ctx, i, &cut_index->loc))) - return false; - hlsl_block_add_instr(block, const_i); + const_i = hlsl_block_add_uint_constant(ctx, block, i, &cut_index->loc);
operands[0] = cut_index; operands[1] = const_i; - if (!(equals = hlsl_new_expr(ctx, HLSL_OP2_EQUAL, operands, btype, &cut_index->loc))) - return false; - hlsl_block_add_instr(block, equals); - - if (!(equals = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), - var->data_type->e.numeric.dimx, equals, &cut_index->loc))) - return false; - hlsl_block_add_instr(block, equals); + equals = hlsl_block_add_expr(ctx, block, HLSL_OP2_EQUAL, operands, btype, &cut_index->loc); + equals = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), + var->data_type->e.numeric.dimx, equals, &cut_index->loc);
- if (!(var_load = hlsl_new_var_load(ctx, var, &cut_index->loc))) - return false; - hlsl_block_add_instr(block, &var_load->node); + var_load = hlsl_block_add_simple_load(ctx, block, var, &cut_index->loc);
if (!hlsl_copy_deref(ctx, &deref_copy, deref)) return false; hlsl_src_remove(&deref_copy.path[i_cut]); hlsl_src_from_node(&deref_copy.path[i_cut], const_i); - - if (!(specific_load = hlsl_new_load_index(ctx, &deref_copy, NULL, &cut_index->loc))) - { - hlsl_cleanup_deref(&deref_copy); - return false; - } - hlsl_block_add_instr(block, &specific_load->node); - + specific_load = hlsl_block_add_load_index(ctx, block, &deref_copy, NULL, &cut_index->loc); hlsl_cleanup_deref(&deref_copy);
operands[0] = equals; - operands[1] = &specific_load->node; - operands[2] = &var_load->node; - if (!(ternary = hlsl_new_expr(ctx, HLSL_OP3_TERNARY, operands, instr->data_type, &cut_index->loc))) - return false; - hlsl_block_add_instr(block, ternary); + operands[1] = specific_load; + operands[2] = var_load; + ternary = hlsl_block_add_expr(ctx, block, HLSL_OP3_TERNARY, operands, instr->data_type, &cut_index->loc);
- if (!(var_store = hlsl_new_simple_store(ctx, var, ternary))) - return false; - hlsl_block_add_instr(block, var_store); + hlsl_block_add_simple_store(ctx, block, var, ternary); }
- if (!(load = hlsl_new_var_load(ctx, var, &instr->loc))) - return false; - hlsl_block_add_instr(block, &load->node); - + hlsl_block_add_simple_load(ctx, block, var, &instr->loc); return true; }
@@ -3278,9 +4115,37 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx) return false; }
-/* Turn CAST to int or uint as follows: +/* Turn CAST to int or uint into TRUNC + REINTERPRET */ +static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; + struct hlsl_ir_node *arg, *trunc; + struct hlsl_ir_expr *expr; + + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP1_CAST) + return false; + + arg = expr->operands[0].node; + if (!hlsl_type_is_integer(instr->data_type) || instr->data_type->e.numeric.type == HLSL_TYPE_BOOL) + return false; + if (!hlsl_type_is_floating_point(arg->data_type)) + return false; + + trunc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_TRUNC, arg, &instr->loc); + + memset(operands, 0, sizeof(operands)); + operands[0] = trunc; + hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); + + return true; +} + +/* Turn TRUNC into: * - * CAST(x) = x - FRACT(x) + extra + * TRUNC(x) = x - FRACT(x) + extra * * where * @@ -3288,27 +4153,19 @@ static bool sort_synthetic_separated_samplers_first(struct hlsl_ctx *ctx) * * where the comparisons in the extra term are performed using CMP or SLT * depending on whether this is a pixel or vertex shader, respectively. - * - * A REINTERPET (which is written as a mere MOV) is also applied to the final - * result for type consistency. */ -static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static bool lower_trunc(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }; struct hlsl_ir_node *arg, *res; struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR) return false; expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP1_CAST) + if (expr->op != HLSL_OP1_TRUNC) return false;
arg = expr->operands[0].node; - if (instr->data_type->e.numeric.type != HLSL_TYPE_INT && instr->data_type->e.numeric.type != HLSL_TYPE_UINT) - return false; - if (arg->data_type->e.numeric.type != HLSL_TYPE_FLOAT && arg->data_type->e.numeric.type != HLSL_TYPE_HALF) - return false;
if (ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) { @@ -3328,13 +4185,8 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; hlsl_block_add_instr(block, one);
- if (!(fract = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc))) - return false; - hlsl_block_add_instr(block, fract); - - if (!(neg_fract = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, fract, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg_fract); + fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); + neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc);
if (!(has_fract = hlsl_new_ternary_expr(ctx, HLSL_OP3_CMP, neg_fract, zero, one))) return false; @@ -3344,52 +4196,63 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; hlsl_block_add_instr(block, extra);
- if (!(floor = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, neg_fract))) - return false; - hlsl_block_add_instr(block, floor); - - if (!(res = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, floor, extra))) - return false; - hlsl_block_add_instr(block, res); + floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract); + res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, floor, extra); } else { struct hlsl_ir_node *neg_arg, *is_neg, *fract, *neg_fract, *has_fract, *floor;
- if (!(neg_arg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg_arg); + neg_arg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); + is_neg = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, arg, neg_arg); + fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); + neg_fract = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, fract, &instr->loc); + has_fract = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, neg_fract, fract); + floor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, neg_fract);
- if (!(is_neg = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, arg, neg_arg))) + if (!(res = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, is_neg, has_fract, floor))) return false; - hlsl_block_add_instr(block, is_neg); + hlsl_block_add_instr(block, res); + }
- if (!(fract = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc))) - return false; - hlsl_block_add_instr(block, fract); + return true; +}
- if (!(neg_fract = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, fract, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg_fract); +/* Lower modulus using: + * + * mod(x, y) = x - trunc(x / y) * y; + * + */ +static bool lower_int_modulus_sm1(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_node *div, *trunc, *mul, *neg, *operands[2], *ret; + struct hlsl_type *float_type; + struct hlsl_ir_expr *expr; + bool is_float;
- if (!(has_fract = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, neg_fract, fract))) - return false; - hlsl_block_add_instr(block, has_fract); + if (instr->type != HLSL_IR_EXPR) + return false; + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP2_MOD) + return false;
- if (!(floor = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, neg_fract))) - return false; - hlsl_block_add_instr(block, floor); + is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT + || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; + if (is_float) + return false; + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx);
- if (!(res = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, is_neg, has_fract, floor))) - return false; - hlsl_block_add_instr(block, res); + for (unsigned int i = 0; i < 2; ++i) + { + operands[i] = hlsl_block_add_cast(ctx, block, expr->operands[i].node, float_type, &instr->loc); }
- memset(operands, 0, sizeof(operands)); - operands[0] = res; - if (!(res = hlsl_new_expr(ctx, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, res); + div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, operands[0], operands[1]); + trunc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_TRUNC, div, &instr->loc); + mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, trunc, operands[1]); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul, &instr->loc); + ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, operands[0], neg); + hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc);
return true; } @@ -3397,8 +4260,10 @@ static bool lower_casts_to_int(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, /* Lower DIV to RCP + MUL. */ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *rcp, *mul; + struct hlsl_ir_node *rcp, *ret, *operands[2]; + struct hlsl_type *float_type; struct hlsl_ir_expr *expr; + bool is_float;
if (instr->type != HLSL_IR_EXPR) return false; @@ -3406,13 +4271,21 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str if (expr->op != HLSL_OP2_DIV) return false;
- if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, expr->operands[1].node, &instr->loc))) - return false; - hlsl_block_add_instr(block, rcp); + is_float = instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT + || instr->data_type->e.numeric.type == HLSL_TYPE_HALF; + float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx);
- if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, expr->operands[0].node, rcp))) - return false; - hlsl_block_add_instr(block, mul); + for (unsigned int i = 0; i < 2; ++i) + { + operands[i] = expr->operands[i].node; + if (!is_float) + operands[i] = hlsl_block_add_cast(ctx, block, operands[i], float_type, &instr->loc); + } + + rcp = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, operands[1], &instr->loc); + ret = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, operands[0], rcp); + if (!is_float) + ret = hlsl_block_add_cast(ctx, block, ret, instr->data_type, &instr->loc);
return true; } @@ -3420,8 +4293,8 @@ static bool lower_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, str /* Lower SQRT to RSQ + RCP. */ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *rsq, *rcp; struct hlsl_ir_expr *expr; + struct hlsl_ir_node *rsq;
if (instr->type != HLSL_IR_EXPR) return false; @@ -3429,20 +4302,15 @@ static bool lower_sqrt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct if (expr->op != HLSL_OP1_SQRT) return false;
- if (!(rsq = hlsl_new_unary_expr(ctx, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc))) - return false; - hlsl_block_add_instr(block, rsq); - - if (!(rcp = hlsl_new_unary_expr(ctx, HLSL_OP1_RCP, rsq, &instr->loc))) - return false; - hlsl_block_add_instr(block, rcp); + rsq = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RSQ, expr->operands[0].node, &instr->loc); + hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_RCP, rsq, &instr->loc); return true; }
/* Lower DP2 to MUL + ADD */ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg1, *arg2, *mul, *replacement, *zero, *add_x, *add_y; + struct hlsl_ir_node *arg1, *arg2, *mul, *add_x, *add_y; struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR) @@ -3459,37 +4327,22 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h { struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 };
- if (!(zero = hlsl_new_float_constant(ctx, 0.0f, &expr->node.loc))) - return false; - hlsl_block_add_instr(block, zero); - operands[0] = arg1; operands[1] = arg2; - operands[2] = zero; + operands[2] = hlsl_block_add_float_constant(ctx, block, 0.0f, &expr->node.loc);
- if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc))) - return false; + hlsl_block_add_expr(ctx, block, HLSL_OP3_DP2ADD, operands, instr->data_type, &expr->node.loc); } else { - if (!(mul = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node))) - return false; - hlsl_block_add_instr(block, mul); - - if (!(add_x = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(X, X, X, X), - instr->data_type->e.numeric.dimx, mul, &expr->node.loc))) - return false; - hlsl_block_add_instr(block, add_x); - - if (!(add_y = hlsl_new_swizzle(ctx, HLSL_SWIZZLE(Y, Y, Y, Y), - instr->data_type->e.numeric.dimx, mul, &expr->node.loc))) - return false; - hlsl_block_add_instr(block, add_y); + mul = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, expr->operands[0].node, expr->operands[1].node);
- if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, add_x, add_y))) - return false; + add_x = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(X, X, X, X), + instr->data_type->e.numeric.dimx, mul, &expr->node.loc); + add_y = hlsl_block_add_swizzle(ctx, block, HLSL_SWIZZLE(Y, Y, Y, Y), + instr->data_type->e.numeric.dimx, mul, &expr->node.loc); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, add_x, add_y); } - hlsl_block_add_instr(block, replacement);
return true; } @@ -3497,7 +4350,7 @@ static bool lower_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h /* Lower ABS to MAX */ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg, *neg, *replacement; + struct hlsl_ir_node *arg, *neg; struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR) @@ -3507,21 +4360,15 @@ static bool lower_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h if (expr->op != HLSL_OP1_ABS) return false;
- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - - if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_MAX, neg, arg))) - return false; - hlsl_block_add_instr(block, replacement); - + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, neg, arg); return true; }
/* Lower ROUND using FRC, ROUND(x) -> ((x + 0.5) - FRC(x + 0.5)). */ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg, *neg, *sum, *frc, *half, *replacement; + struct hlsl_ir_node *arg, *neg, *sum, *frc, *half; struct hlsl_type *type = instr->data_type; struct hlsl_constant_value half_value; unsigned int i, component_count; @@ -3542,29 +4389,17 @@ static bool lower_round(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct return false; hlsl_block_add_instr(block, half);
- if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg, half))) - return false; - hlsl_block_add_instr(block, sum); - - if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, sum, &instr->loc))) - return false; - hlsl_block_add_instr(block, frc); - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, frc, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - - if (!(replacement = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, sum, neg))) - return false; - hlsl_block_add_instr(block, replacement); - + sum = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg, half); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, sum, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, sum, neg); return true; }
/* Lower CEIL to FRC */ static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg, *neg, *sum, *frc; + struct hlsl_ir_node *arg, *neg, *frc; struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR) @@ -3575,25 +4410,16 @@ static bool lower_ceil(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct if (expr->op != HLSL_OP1_CEIL) return false;
- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - - if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, neg, &instr->loc))) - return false; - hlsl_block_add_instr(block, frc); - - if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, frc, arg))) - return false; - hlsl_block_add_instr(block, sum); - + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, neg, &instr->loc); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, frc, arg); return true; }
/* Lower FLOOR to FRC */ static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg, *neg, *sum, *frc; + struct hlsl_ir_node *arg, *neg, *frc; struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR) @@ -3604,18 +4430,9 @@ static bool lower_floor(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct if (expr->op != HLSL_OP1_FLOOR) return false;
- if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, arg, &instr->loc))) - return false; - hlsl_block_add_instr(block, frc); - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, frc, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - - if (!(sum = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, neg, arg))) - return false; - hlsl_block_add_instr(block, sum); - + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, arg, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, frc, &instr->loc); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, neg, arg); return true; }
@@ -3667,33 +4484,26 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct if (!(mad = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, arg, reciprocal_two_pi, half))) return false; hlsl_block_add_instr(block, mad); - if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, mad, &instr->loc))) - return false; - hlsl_block_add_instr(block, frc); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mad, &instr->loc); if (!(reduced = hlsl_new_ternary_expr(ctx, HLSL_OP3_MAD, frc, two_pi, neg_pi))) return false; hlsl_block_add_instr(block, reduced);
if (type->e.numeric.dimx == 1) { - if (!(sincos = hlsl_new_unary_expr(ctx, op, reduced, &instr->loc))) - return false; - hlsl_block_add_instr(block, sincos); + sincos = hlsl_block_add_unary_expr(ctx, block, op, reduced, &instr->loc); } else { struct hlsl_ir_node *comps[4] = {0}; struct hlsl_ir_var *var; struct hlsl_deref var_deref; - struct hlsl_ir_load *var_load;
for (i = 0; i < type->e.numeric.dimx; ++i) { uint32_t s = hlsl_swizzle_from_writemask(1 << i);
- if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, reduced, &instr->loc))) - return false; - hlsl_block_add_instr(block, comps[i]); + comps[i] = hlsl_block_add_swizzle(ctx, block, s, 1, reduced, &instr->loc); }
if (!(var = hlsl_new_synthetic_var(ctx, "sincos", type, &instr->loc))) @@ -3702,20 +4512,11 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
for (i = 0; i < type->e.numeric.dimx; ++i) { - struct hlsl_block store_block; - - if (!(sincos = hlsl_new_unary_expr(ctx, op, comps[i], &instr->loc))) - return false; - hlsl_block_add_instr(block, sincos); - - if (!hlsl_new_store_component(ctx, &store_block, &var_deref, i, sincos)) - return false; - hlsl_block_add_block(block, &store_block); + sincos = hlsl_block_add_unary_expr(ctx, block, op, comps[i], &instr->loc); + hlsl_block_add_store_component(ctx, block, &var_deref, i, sincos); }
- if (!(var_load = hlsl_new_load_index(ctx, &var_deref, NULL, &instr->loc))) - return false; - hlsl_block_add_instr(block, &var_load->node); + hlsl_block_add_load_index(ctx, block, &var_deref, NULL, &instr->loc); }
return true; @@ -3723,8 +4524,8 @@ static bool lower_trig(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct
static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { + struct hlsl_ir_node *arg, *arg_cast, *neg, *one, *sub; struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; - struct hlsl_ir_node *arg, *arg_cast, *neg, *one, *sub, *res; struct hlsl_constant_value one_value; struct hlsl_type *float_type; struct hlsl_ir_expr *expr; @@ -3741,13 +4542,9 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st /* If this is happens, it means we failed to cast the argument to boolean somewhere. */ VKD3D_ASSERT(arg->data_type->e.numeric.type == HLSL_TYPE_BOOL);
- if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &arg->loc))) - return false; - hlsl_block_add_instr(block, arg_cast); + arg_cast = hlsl_block_add_cast(ctx, block, arg, float_type, &arg->loc);
- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg_cast, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg_cast, &instr->loc);
one_value.u[0].f = 1.0; one_value.u[1].f = 1.0; @@ -3757,24 +4554,19 @@ static bool lower_logic_not(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, st return false; hlsl_block_add_instr(block, one);
- if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, one, neg))) - return false; - hlsl_block_add_instr(block, sub); + sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg);
memset(operands, 0, sizeof(operands)); operands[0] = sub; - if (!(res = hlsl_new_expr(ctx, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, res); - + hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); return true; }
/* Lower TERNARY to CMP for SM1. */ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = { 0 }, *replacement; struct hlsl_ir_node *cond, *first, *second, *float_cond, *neg; + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; struct hlsl_ir_expr *expr; struct hlsl_type *type;
@@ -3799,23 +4591,14 @@ static bool lower_ternary(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
type = hlsl_get_numeric_type(ctx, instr->data_type->class, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx, instr->data_type->e.numeric.dimy); - - if (!(float_cond = hlsl_new_cast(ctx, cond, type, &instr->loc))) - return false; - hlsl_block_add_instr(block, float_cond); - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, float_cond, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); + float_cond = hlsl_block_add_cast(ctx, block, cond, type, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, float_cond, &instr->loc);
memset(operands, 0, sizeof(operands)); operands[0] = neg; operands[1] = second; operands[2] = first; - if (!(replacement = hlsl_new_expr(ctx, HLSL_OP3_CMP, operands, first->data_type, &instr->loc))) - return false; - - hlsl_block_add_instr(block, replacement); + hlsl_block_add_expr(ctx, block, HLSL_OP3_CMP, operands, first->data_type, &instr->loc); return true; }
@@ -3867,7 +4650,7 @@ static bool lower_resource_load_bias(struct hlsl_ctx *ctx, struct hlsl_ir_node * static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg1, *arg1_cast, *arg2, *arg2_cast, *slt, *res, *ret; + struct hlsl_ir_node *arg1, *arg1_cast, *arg2, *arg2_cast, *slt, *res; struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; struct hlsl_type *float_type; struct hlsl_ir_expr *expr; @@ -3884,13 +4667,8 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node arg2 = expr->operands[1].node; float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx);
- if (!(arg1_cast = hlsl_new_cast(ctx, arg1, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, arg1_cast); - - if (!(arg2_cast = hlsl_new_cast(ctx, arg2, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, arg2_cast); + arg1_cast = hlsl_block_add_cast(ctx, block, arg1, float_type, &instr->loc); + arg2_cast = hlsl_block_add_cast(ctx, block, arg2, float_type, &instr->loc);
switch (expr->op) { @@ -3899,36 +4677,21 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node { struct hlsl_ir_node *neg, *sub, *abs, *abs_neg;
- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2_cast, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - - if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg1_cast, neg))) - return false; - hlsl_block_add_instr(block, sub); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2_cast, &instr->loc); + sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg1_cast, neg);
if (ctx->profile->major_version >= 3) { - if (!(abs = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, sub, &instr->loc))) - return false; - hlsl_block_add_instr(block, abs); + abs = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, sub, &instr->loc); } else { /* Use MUL as a precarious ABS. */ - if (!(abs = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, sub, sub))) - return false; - hlsl_block_add_instr(block, abs); + abs = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, sub, sub); }
- if (!(abs_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, abs, &instr->loc))) - return false; - hlsl_block_add_instr(block, abs_neg); - - if (!(slt = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, abs_neg, abs))) - return false; - hlsl_block_add_instr(block, slt); - + abs_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, abs, &instr->loc); + slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, abs_neg, abs); negate = (expr->op == HLSL_OP2_EQUAL); break; } @@ -3936,10 +4699,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node case HLSL_OP2_GEQUAL: case HLSL_OP2_LESS: { - if (!(slt = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, arg1_cast, arg2_cast))) - return false; - hlsl_block_add_instr(block, slt); - + slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, arg1_cast, arg2_cast); negate = (expr->op == HLSL_OP2_GEQUAL); break; } @@ -3961,13 +4721,8 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node return false; hlsl_block_add_instr(block, one);
- if (!(slt_neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, slt, &instr->loc))) - return false; - hlsl_block_add_instr(block, slt_neg); - - if (!(res = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, one, slt_neg))) - return false; - hlsl_block_add_instr(block, res); + slt_neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); + res = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, slt_neg); } else { @@ -3978,10 +4733,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node * and casts to BOOL have already been lowered to "!= 0". */ memset(operands, 0, sizeof(operands)); operands[0] = res; - if (!(ret = hlsl_new_expr(ctx, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, ret); - + hlsl_block_add_expr(ctx, block, HLSL_OP1_REINTERPRET, operands, instr->data_type, &instr->loc); return true; }
@@ -4010,21 +4762,10 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h arg2 = expr->operands[1].node; float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx);
- if (!(arg1_cast = hlsl_new_cast(ctx, arg1, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, arg1_cast); - - if (!(arg2_cast = hlsl_new_cast(ctx, arg2, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, arg2_cast); - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2_cast, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - - if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, arg1_cast, neg))) - return false; - hlsl_block_add_instr(block, sub); + arg1_cast = hlsl_block_add_cast(ctx, block, arg1, float_type, &instr->loc); + arg2_cast = hlsl_block_add_cast(ctx, block, arg2, float_type, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2_cast, &instr->loc); + sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, arg1_cast, neg);
memset(&zero_value, 0, sizeof(zero_value)); if (!(zero = hlsl_new_constant(ctx, float_type, &zero_value, &instr->loc))) @@ -4056,7 +4797,7 @@ static bool lower_slt(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h */ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *args[3], *args_cast[3], *slt, *neg_slt, *sub, *zero, *one, *mul1, *mul2, *add; + struct hlsl_ir_node *args[3], *args_cast[3], *slt, *neg_slt, *sub, *zero, *one, *mul1, *mul2; struct hlsl_constant_value zero_value, one_value; struct hlsl_type *float_type; struct hlsl_ir_expr *expr; @@ -4073,10 +4814,7 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h for (i = 0; i < 3; ++i) { args[i] = expr->operands[i].node; - - if (!(args_cast[i] = hlsl_new_cast(ctx, args[i], float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, args_cast[i]); + args_cast[i] = hlsl_block_add_cast(ctx, block, args[i], float_type, &instr->loc); }
memset(&zero_value, 0, sizeof(zero_value)); @@ -4092,30 +4830,12 @@ static bool lower_cmp(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct h return false; hlsl_block_add_instr(block, one);
- if (!(slt = hlsl_new_binary_expr(ctx, HLSL_OP2_SLT, args_cast[0], zero))) - return false; - hlsl_block_add_instr(block, slt); - - if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, args_cast[2], slt))) - return false; - hlsl_block_add_instr(block, mul1); - - if (!(neg_slt = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, slt, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg_slt); - - if (!(sub = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, one, neg_slt))) - return false; - hlsl_block_add_instr(block, sub); - - if (!(mul2 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, args_cast[1], sub))) - return false; - hlsl_block_add_instr(block, mul2); - - if (!(add = hlsl_new_binary_expr(ctx, HLSL_OP2_ADD, mul1, mul2))) - return false; - hlsl_block_add_instr(block, add); - + slt = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_SLT, args_cast[0], zero); + mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[2], slt); + neg_slt = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, slt, &instr->loc); + sub = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, one, neg_slt); + mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, args_cast[1], sub); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, mul1, mul2); return true; }
@@ -4145,10 +4865,8 @@ static bool lower_casts_to_bool(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; hlsl_block_add_instr(block, zero);
- if (!(neq = hlsl_new_binary_expr(ctx, HLSL_OP2_NEQUAL, expr->operands[0].node, zero))) - return false; + neq = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_NEQUAL, expr->operands[0].node, zero); neq->data_type = expr->node.data_type; - hlsl_block_add_instr(block, neq);
return true; } @@ -4158,7 +4876,6 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc { struct hlsl_type *cond_type = condition->data_type; struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS]; - struct hlsl_ir_node *cond;
VKD3D_ASSERT(hlsl_types_are_equal(if_true->data_type, if_false->data_type));
@@ -4166,23 +4883,16 @@ struct hlsl_ir_node *hlsl_add_conditional(struct hlsl_ctx *ctx, struct hlsl_bloc { cond_type = hlsl_get_numeric_type(ctx, cond_type->class, HLSL_TYPE_BOOL, cond_type->e.numeric.dimx, cond_type->e.numeric.dimy); - - if (!(condition = hlsl_new_cast(ctx, condition, cond_type, &condition->loc))) - return NULL; - hlsl_block_add_instr(instrs, condition); + condition = hlsl_block_add_cast(ctx, instrs, condition, cond_type, &condition->loc); }
operands[0] = condition; operands[1] = if_true; operands[2] = if_false; - if (!(cond = hlsl_new_expr(ctx, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc))) - return false; - hlsl_block_add_instr(instrs, cond); - - return cond; + return hlsl_block_add_expr(ctx, instrs, HLSL_OP3_TERNARY, operands, if_true->data_type, &condition->loc); }
-static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static bool lower_int_division_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *xor, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; struct hlsl_type *type = instr->data_type, *utype; @@ -4203,9 +4913,7 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; utype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy);
- if (!(xor = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_XOR, arg1, arg2))) - return false; - hlsl_block_add_instr(block, xor); + xor = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_XOR, arg1, arg2);
for (i = 0; i < type->e.numeric.dimx; ++i) high_bit_value.u[i].u = 0x80000000; @@ -4213,42 +4921,18 @@ static bool lower_int_division(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; hlsl_block_add_instr(block, high_bit);
- if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, xor, high_bit))) - return false; - hlsl_block_add_instr(block, and); - - if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc))) - return false; - hlsl_block_add_instr(block, abs1); - - if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) - return false; - hlsl_block_add_instr(block, cast1); - - if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc))) - return false; - hlsl_block_add_instr(block, abs2); - - if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) - return false; - hlsl_block_add_instr(block, cast2); - - if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, cast1, cast2))) - return false; - hlsl_block_add_instr(block, div); - - if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) - return false; - hlsl_block_add_instr(block, cast3); - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - + and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, xor, high_bit); + abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); + cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); + abs2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg2, &instr->loc); + cast2 = hlsl_block_add_cast(ctx, block, abs2, utype, &instr->loc); + div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, cast1, cast2); + cast3 = hlsl_block_add_cast(ctx, block, div, type, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, cast3, &instr->loc); return hlsl_add_conditional(ctx, block, and, neg, cast3); }
-static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +static bool lower_int_modulus_sm4(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_ir_node *arg1, *arg2, *and, *abs1, *abs2, *div, *neg, *cast1, *cast2, *cast3, *high_bit; struct hlsl_type *type = instr->data_type, *utype; @@ -4275,45 +4959,21 @@ static bool lower_int_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return false; hlsl_block_add_instr(block, high_bit);
- if (!(and = hlsl_new_binary_expr(ctx, HLSL_OP2_BIT_AND, arg1, high_bit))) - return false; - hlsl_block_add_instr(block, and); - - if (!(abs1 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg1, &instr->loc))) - return false; - hlsl_block_add_instr(block, abs1); - - if (!(cast1 = hlsl_new_cast(ctx, abs1, utype, &instr->loc))) - return false; - hlsl_block_add_instr(block, cast1); - - if (!(abs2 = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, arg2, &instr->loc))) - return false; - hlsl_block_add_instr(block, abs2); - - if (!(cast2 = hlsl_new_cast(ctx, abs2, utype, &instr->loc))) - return false; - hlsl_block_add_instr(block, cast2); - - if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_MOD, cast1, cast2))) - return false; - hlsl_block_add_instr(block, div); - - if (!(cast3 = hlsl_new_cast(ctx, div, type, &instr->loc))) - return false; - hlsl_block_add_instr(block, cast3); - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, cast3, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - + and = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_BIT_AND, arg1, high_bit); + abs1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg1, &instr->loc); + cast1 = hlsl_block_add_cast(ctx, block, abs1, utype, &instr->loc); + abs2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_ABS, arg2, &instr->loc); + cast2 = hlsl_block_add_cast(ctx, block, abs2, utype, &instr->loc); + div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MOD, cast1, cast2); + cast3 = hlsl_block_add_cast(ctx, block, div, type, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, cast3, &instr->loc); return hlsl_add_conditional(ctx, block, and, neg, cast3); }
static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { struct hlsl_type *type = instr->data_type; - struct hlsl_ir_node *arg, *neg, *max; + struct hlsl_ir_node *arg, *neg; struct hlsl_ir_expr *expr;
if (instr->type != HLSL_IR_EXPR) @@ -4329,14 +4989,8 @@ static bool lower_int_abs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
arg = expr->operands[0].node;
- if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg); - - if (!(max = hlsl_new_binary_expr(ctx, HLSL_OP2_MAX, arg, neg))) - return false; - hlsl_block_add_instr(block, max); - + neg = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg, &instr->loc); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MAX, arg, neg); return true; }
@@ -4355,8 +5009,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru if (expr->op != HLSL_OP2_DOT) return false;
- if (type->e.numeric.type == HLSL_TYPE_INT || type->e.numeric.type == HLSL_TYPE_UINT - || type->e.numeric.type == HLSL_TYPE_BOOL) + if (hlsl_type_is_integer(type)) { arg1 = expr->operands[0].node; arg2 = expr->operands[1].node; @@ -4364,26 +5017,18 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru dimx = arg1->data_type->e.numeric.dimx; is_bool = type->e.numeric.type == HLSL_TYPE_BOOL;
- if (!(mult = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2))) - return false; - hlsl_block_add_instr(block, mult); + mult = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_AND : HLSL_OP2_MUL, arg1, arg2);
for (i = 0; i < dimx; ++i) { uint32_t s = hlsl_swizzle_from_writemask(1 << i);
- if (!(comps[i] = hlsl_new_swizzle(ctx, s, 1, mult, &instr->loc))) - return false; - hlsl_block_add_instr(block, comps[i]); + comps[i] = hlsl_block_add_swizzle(ctx, block, s, 1, mult, &instr->loc); }
res = comps[0]; for (i = 1; i < dimx; ++i) - { - if (!(res = hlsl_new_binary_expr(ctx, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]))) - return false; - hlsl_block_add_instr(block, res); - } + res = hlsl_block_add_binary_expr(ctx, block, is_bool ? HLSL_OP2_LOGIC_OR : HLSL_OP2_ADD, res, comps[i]);
return true; } @@ -4393,7 +5038,7 @@ static bool lower_int_dot(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, stru
static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) { - struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one, *mul3; + struct hlsl_ir_node *arg1, *arg2, *mul1, *neg1, *ge, *neg2, *div, *mul2, *frc, *cond, *one; struct hlsl_type *type = instr->data_type, *btype; struct hlsl_constant_value one_value; struct hlsl_ir_expr *expr; @@ -4412,25 +5057,14 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; btype = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy);
- if (!(mul1 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, arg2, arg1))) - return false; - hlsl_block_add_instr(block, mul1); - - if (!(neg1 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, mul1, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg1); + mul1 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, arg2, arg1); + neg1 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, mul1, &instr->loc);
- if (!(ge = hlsl_new_binary_expr(ctx, HLSL_OP2_GEQUAL, mul1, neg1))) - return false; + ge = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_GEQUAL, mul1, neg1); ge->data_type = btype; - hlsl_block_add_instr(block, ge); - - if (!(neg2 = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, arg2, &instr->loc))) - return false; - hlsl_block_add_instr(block, neg2);
- if (!(cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2))) - return false; + neg2 = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_NEG, arg2, &instr->loc); + cond = hlsl_add_conditional(ctx, block, ge, arg2, neg2);
for (i = 0; i < type->e.numeric.dimx; ++i) one_value.u[i].f = 1.0f; @@ -4438,82 +5072,13 @@ static bool lower_float_modulus(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; hlsl_block_add_instr(block, one);
- if (!(div = hlsl_new_binary_expr(ctx, HLSL_OP2_DIV, one, cond))) - return false; - hlsl_block_add_instr(block, div); - - if (!(mul2 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, div, arg1))) - return false; - hlsl_block_add_instr(block, mul2); - - if (!(frc = hlsl_new_unary_expr(ctx, HLSL_OP1_FRACT, mul2, &instr->loc))) - return false; - hlsl_block_add_instr(block, frc); - - if (!(mul3 = hlsl_new_binary_expr(ctx, HLSL_OP2_MUL, frc, cond))) - return false; - hlsl_block_add_instr(block, mul3); - + div = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_DIV, one, cond); + mul2 = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, div, arg1); + frc = hlsl_block_add_unary_expr(ctx, block, HLSL_OP1_FRACT, mul2, &instr->loc); + hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, frc, cond); return true; }
-static bool lower_nonfloat_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) -{ - struct hlsl_ir_expr *expr; - - if (instr->type != HLSL_IR_EXPR) - return false; - expr = hlsl_ir_expr(instr); - if (expr->op == HLSL_OP1_CAST || instr->data_type->e.numeric.type == HLSL_TYPE_FLOAT) - return false; - - switch (expr->op) - { - case HLSL_OP1_ABS: - case HLSL_OP1_NEG: - case HLSL_OP2_ADD: - case HLSL_OP2_DIV: - case HLSL_OP2_LOGIC_AND: - case HLSL_OP2_LOGIC_OR: - case HLSL_OP2_MAX: - case HLSL_OP2_MIN: - case HLSL_OP2_MUL: - { - struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_ir_node *arg, *arg_cast, *float_expr, *ret; - struct hlsl_type *float_type; - unsigned int i; - - for (i = 0; i < HLSL_MAX_OPERANDS; ++i) - { - arg = expr->operands[i].node; - if (!arg) - continue; - - float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, arg->data_type->e.numeric.dimx); - if (!(arg_cast = hlsl_new_cast(ctx, arg, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, arg_cast); - - operands[i] = arg_cast; - } - - float_type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, instr->data_type->e.numeric.dimx); - if (!(float_expr = hlsl_new_expr(ctx, expr->op, operands, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, float_expr); - - if (!(ret = hlsl_new_cast(ctx, float_expr, instr->data_type, &instr->loc))) - return false; - hlsl_block_add_instr(block, ret); - - return true; - } - default: - return false; - } -} - static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_node *zero, *bool_false, *or, *cmp, *load; @@ -4541,9 +5106,7 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, operands[1] = zero; cmp_type = hlsl_get_numeric_type(ctx, arg_type->class, HLSL_TYPE_BOOL, arg_type->e.numeric.dimx, arg_type->e.numeric.dimy); - if (!(cmp = hlsl_new_expr(ctx, HLSL_OP2_LESS, operands, cmp_type, &instr->loc))) - return false; - hlsl_block_add_instr(&block, cmp); + cmp = hlsl_block_add_expr(ctx, &block, HLSL_OP2_LESS, operands, cmp_type, &instr->loc);
if (!(bool_false = hlsl_new_constant(ctx, hlsl_get_scalar_type(ctx, HLSL_TYPE_BOOL), &zero_value, &instr->loc))) return false; @@ -4554,12 +5117,8 @@ static bool lower_discard_neg(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, count = hlsl_type_component_count(cmp_type); for (i = 0; i < count; ++i) { - if (!(load = hlsl_add_load_component(ctx, &block, cmp, i, &instr->loc))) - return false; - - if (!(or = hlsl_new_binary_expr(ctx, HLSL_OP2_LOGIC_OR, or, load))) - return NULL; - hlsl_block_add_instr(&block, or); + load = hlsl_add_load_component(ctx, &block, cmp, i, &instr->loc); + or = hlsl_block_add_binary_expr(ctx, &block, HLSL_OP2_LOGIC_OR, or, load); }
list_move_tail(&instr->entry, &block.instrs); @@ -4588,17 +5147,9 @@ static bool lower_discard_nz(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, v
hlsl_block_init(&block);
- if (!(cond_cast = hlsl_new_cast(ctx, cond, float_type, &instr->loc))) - return false; - hlsl_block_add_instr(&block, cond_cast); - - if (!(abs = hlsl_new_unary_expr(ctx, HLSL_OP1_ABS, cond_cast, &instr->loc))) - return false; - hlsl_block_add_instr(&block, abs); - - if (!(neg = hlsl_new_unary_expr(ctx, HLSL_OP1_NEG, abs, &instr->loc))) - return false; - hlsl_block_add_instr(&block, neg); + cond_cast = hlsl_block_add_cast(ctx, &block, cond, float_type, &instr->loc); + abs = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_ABS, cond_cast, &instr->loc); + neg = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_NEG, abs, &instr->loc);
list_move_tail(&instr->entry, &block.instrs); hlsl_src_remove(&jump->condition); @@ -4634,6 +5185,9 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) struct hlsl_ir_store *store = hlsl_ir_store(instr); struct hlsl_ir_var *var = store->lhs.var;
+ if (var->is_output_semantic) + break; + if (var->last_read < instr->index) { list_remove(&instr->entry); @@ -4645,11 +5199,12 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context)
case HLSL_IR_CALL: case HLSL_IR_IF: + case HLSL_IR_INTERLOCKED: case HLSL_IR_JUMP: case HLSL_IR_LOOP: case HLSL_IR_RESOURCE_STORE: case HLSL_IR_SWITCH: - case HLSL_IR_INTERLOCKED: + case HLSL_IR_SYNC: break; case HLSL_IR_STATEBLOCK_CONSTANT: /* Stateblock constants should not appear in the shader program. */ @@ -4709,6 +5264,8 @@ static char get_regset_name(enum hlsl_regset regset) return 't'; case HLSL_REGSET_UAVS: return 'u'; + case HLSL_REGSET_STREAM_OUTPUTS: + return 'm'; case HLSL_REGSET_NUMERIC: vkd3d_unreachable(); } @@ -4877,8 +5434,10 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop var = store->resource.var; var->last_read = max(var->last_read, last_read); deref_mark_last_read(&store->resource, last_read); - store->coords.node->last_read = last_read; - store->value.node->last_read = last_read; + if (store->coords.node) + store->coords.node->last_read = last_read; + if (store->value.node) + store->value.node->last_read = last_read; break; } case HLSL_IR_SWIZZLE: @@ -4929,6 +5488,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop } case HLSL_IR_CONSTANT: case HLSL_IR_STRING_CONSTANT: + case HLSL_IR_SYNC: break; case HLSL_IR_COMPILE: case HLSL_IR_SAMPLER_STATE: @@ -4938,20 +5498,15 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop } }
-static void init_var_liveness(struct hlsl_ir_var *var) -{ - if (var->is_uniform || var->is_input_semantic) - var->first_write = 1; - else if (var->is_output_semantic) - var->last_read = UINT_MAX; -} - static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { struct hlsl_scope *scope; struct hlsl_ir_var *var;
- index_instructions(&entry_func->body, 2); + if (ctx->result) + return; + + index_instructions(&entry_func->body, 1);
LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { @@ -4959,12 +5514,6 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl var->first_write = var->last_read = 0; }
- LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) - init_var_liveness(var); - - LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) - init_var_liveness(var); - compute_liveness_recurse(&entry_func->body, 0, 0); }
@@ -5001,7 +5550,7 @@ struct register_allocator
/* Indexable temps are allocated separately and always keep their index regardless of their * lifetime. */ - size_t indexable_count; + uint32_t indexable_count;
/* Total number of registers allocated so far. Used to declare sm4 temp count. */ uint32_t reg_count; @@ -5269,8 +5818,7 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) struct hlsl_type *type; unsigned int index;
- if (!hlsl_regset_index_from_deref(ctx, deref, regset, &index)) - return; + hlsl_regset_index_from_deref(ctx, deref, regset, &index);
if (regset <= HLSL_REGSET_LAST_OBJECT) { @@ -5281,7 +5829,6 @@ static void register_deref_usage(struct hlsl_ctx *ctx, struct hlsl_deref *deref) { type = hlsl_deref_get_type(ctx, deref);
- hlsl_regset_index_from_deref(ctx, deref, regset, &index); required_bind_count = align(index + type->reg_size[regset], 4) / 4; var->bind_count[regset] = max(var->bind_count[regset], required_bind_count); } @@ -5475,10 +6022,37 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, break; }
- default: - break; + default: + break; + } + } +} + +static bool find_constant(struct hlsl_ctx *ctx, const float *f, unsigned int count, struct hlsl_reg *ret) +{ + struct hlsl_constant_defs *defs = &ctx->constant_defs; + + for (size_t i = 0; i < defs->count; ++i) + { + const struct hlsl_constant_register *reg = &defs->regs[i]; + + for (size_t j = 0; j <= 4 - count; ++j) + { + unsigned int writemask = ((1u << count) - 1) << j; + + if ((reg->allocated_mask & writemask) == writemask + && !memcmp(f, ®->value.f[j], count * sizeof(float))) + { + ret->id = reg->index; + ret->allocation_size = 1; + ret->writemask = writemask; + ret->allocated = true; + return true; + } } } + + return false; }
static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, float f, @@ -5494,6 +6068,7 @@ static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, if (reg->index == (component_index / 4)) { reg->value.f[component_index % 4] = f; + reg->allocated_mask |= (1u << (component_index % 4)); return; } } @@ -5504,6 +6079,7 @@ static void record_constant(struct hlsl_ctx *ctx, unsigned int component_index, memset(reg, 0, sizeof(*reg)); reg->index = component_index / 4; reg->value.f[component_index % 4] = f; + reg->allocated_mask = (1u << (component_index % 4)); reg->loc = *loc; }
@@ -5520,49 +6096,57 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, { struct hlsl_ir_constant *constant = hlsl_ir_constant(instr); const struct hlsl_type *type = instr->data_type; - unsigned int x, i; - - constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); - TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); + float f[4] = {0};
VKD3D_ASSERT(hlsl_is_numeric_type(type)); VKD3D_ASSERT(type->e.numeric.dimy == 1); - VKD3D_ASSERT(constant->reg.writemask);
- for (x = 0, i = 0; x < 4; ++x) + for (unsigned int i = 0; i < type->e.numeric.dimx; ++i) { const union hlsl_constant_value_component *value; - float f = 0;
- if (!(constant->reg.writemask & (1u << x))) - continue; - value = &constant->value.u[i++]; + value = &constant->value.u[i];
switch (type->e.numeric.type) { case HLSL_TYPE_BOOL: - f = !!value->u; + f[i] = !!value->u; break;
case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: - f = value->f; + f[i] = value->f; break;
case HLSL_TYPE_INT: - f = value->i; + f[i] = value->i; break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: - f = value->u; + f[i] = value->u; break;
case HLSL_TYPE_DOUBLE: FIXME("Double constant.\n"); return; } + } + + if (find_constant(ctx, f, type->e.numeric.dimx, &constant->reg)) + { + TRACE("Reusing already allocated constant %s for @%u.\n", + debug_register('c', constant->reg, type), instr->index); + break; + }
- record_constant(ctx, constant->reg.id * 4 + x, f, &constant->node.loc); + constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); + TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); + + for (unsigned int x = 0, i = 0; x < 4; ++x) + { + if ((constant->reg.writemask & (1u << x))) + record_constant(ctx, constant->reg.id * 4 + x, f[i++], &constant->node.loc); }
break; @@ -5765,15 +6349,12 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun /* ps_1_* outputs are special and go in temp register 0. */ if (ctx->profile->major_version == 1 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) { - size_t i; - - for (i = 0; i < entry_func->parameters.count; ++i) + LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) { - var = entry_func->parameters.vars[i]; if (var->is_output_semantic) { record_allocation(ctx, &allocator, 0, VKD3DSP_WRITEMASK_ALL, - var->first_write, var->last_read, 0, false); + var->first_write, UINT_MAX, 0, false); break; } } @@ -5782,6 +6363,13 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun allocate_temp_registers_recurse(ctx, &entry_func->body, &allocator); vkd3d_free(allocator.allocations);
+ if (allocator.indexable_count) + TRACE("Declaration of function "%s" required %u temp registers, and %u indexable temps.\n", + entry_func->func->name, allocator.reg_count, allocator.indexable_count); + else + TRACE("Declaration of function "%s" required %u temp registers.\n", + entry_func->func->name, allocator.reg_count); + return allocator.reg_count; }
@@ -5803,6 +6391,11 @@ static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hl {HLSL_STORAGE_CENTROID | HLSL_STORAGE_LINEAR, VKD3DSIM_LINEAR_CENTROID}, };
+ if (hlsl_type_is_primitive_array(type)) + type = type->e.array.type; + + VKD3D_ASSERT(hlsl_is_numeric_type(type)); + if ((storage_modifiers & HLSL_STORAGE_NOINTERPOLATION) || base_type_get_semantic_equivalent(type->e.numeric.type) == HLSL_TYPE_UINT) return VKD3DSIM_CONSTANT; @@ -5829,7 +6422,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var [VKD3D_SHADER_TYPE_COMPUTE] = "Compute", };
- bool is_patch = hlsl_type_is_patch_array(var->data_type); + bool is_primitive = hlsl_type_is_primitive_array(var->data_type); enum vkd3d_shader_register_type type; struct vkd3d_shader_version version; bool special_interpolation = false; @@ -5853,7 +6446,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var return;
builtin = sm1_register_from_semantic_name(&version, - var->semantic.name, var->semantic.index, output, &type, ®); + var->semantic.name, var->semantic.index, output, NULL, &type, ®); if (!builtin && !sm1_usage_from_semantic_name(var->semantic.name, var->semantic.index, &usage, &usage_idx)) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, @@ -5870,7 +6463,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var bool has_idx;
if (!sm4_sysval_semantic_from_semantic_name(&semantic, &version, ctx->semantic_compat_mapping, ctx->domain, - var->semantic.name, var->semantic.index, output, ctx->is_patch_constant_func, is_patch)) + var->semantic.name, var->semantic.index, output, ctx->is_patch_constant_func, is_primitive)) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "Invalid semantic '%s'.", var->semantic.name); @@ -5892,7 +6485,9 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var || semantic == VKD3D_SHADER_SV_PRIMITIVE_ID) vip_allocation = true;
- if (semantic == VKD3D_SHADER_SV_IS_FRONT_FACE || semantic == VKD3D_SHADER_SV_SAMPLE_INDEX) + if (semantic == VKD3D_SHADER_SV_IS_FRONT_FACE || semantic == VKD3D_SHADER_SV_SAMPLE_INDEX + || (version.type == VKD3D_SHADER_TYPE_DOMAIN && !output && !is_primitive) + || (ctx->is_patch_constant_func && output)) special_interpolation = true; }
@@ -5903,7 +6498,7 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var } else { - unsigned int component_count = is_patch + unsigned int component_count = is_primitive ? var->data_type->e.array.type->e.numeric.dimx : var->data_type->e.numeric.dimx; int mode = (ctx->profile->major_version < 4) ? 0 : sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); @@ -5920,14 +6515,17 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var } }
-static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) +static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, + uint32_t *output_reg_count) { - struct register_allocator in_patch_allocator = {0}, patch_constant_out_patch_allocator = {0}; + struct register_allocator in_prim_allocator = {0}, patch_constant_out_patch_allocator = {0}; struct register_allocator input_allocator = {0}, output_allocator = {0}; bool is_vertex_shader = ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX; bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; struct hlsl_ir_var *var;
+ in_prim_allocator.prioritize_smaller_writemasks = true; + patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; input_allocator.prioritize_smaller_writemasks = true; output_allocator.prioritize_smaller_writemasks = true;
@@ -5935,7 +6533,7 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun { if (var->is_input_semantic) { - if (hlsl_type_is_patch_array(var->data_type)) + if (hlsl_type_is_primitive_array(var->data_type)) { bool is_patch_constant_output_patch = ctx->is_patch_constant_func && var->data_type->e.array.array_type == HLSL_ARRAY_PATCH_OUTPUT; @@ -5944,7 +6542,7 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun allocate_semantic_register(ctx, var, &patch_constant_out_patch_allocator, false, !is_vertex_shader); else - allocate_semantic_register(ctx, var, &in_patch_allocator, false, + allocate_semantic_register(ctx, var, &in_prim_allocator, false, !is_vertex_shader); } else @@ -5955,6 +6553,10 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader); }
+ *output_reg_count = output_allocator.reg_count; + + vkd3d_free(in_prim_allocator.allocations); + vkd3d_free(patch_constant_out_patch_allocator.allocations); vkd3d_free(input_allocator.allocations); vkd3d_free(output_allocator.allocations); } @@ -6356,11 +6958,33 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl } }
+static void allocate_stream_outputs(struct hlsl_ctx *ctx) +{ + struct hlsl_ir_var *var; + uint32_t index = 0; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) + continue; + + /* We should have ensured that all stream output objects are single-element. */ + VKD3D_ASSERT(var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS] == 1); + + var->regs[HLSL_REGSET_STREAM_OUTPUTS].space = 0; + var->regs[HLSL_REGSET_STREAM_OUTPUTS].index = index; + var->regs[HLSL_REGSET_STREAM_OUTPUTS].id = index; + var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated = true; + + ++index; + } +} + bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *start, unsigned int *count) { struct hlsl_type *type = deref->var->data_type; - unsigned int i, k; + unsigned int i;
*start = 0; *count = 0; @@ -6368,49 +6992,18 @@ bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hl for (i = 0; i < deref->path_len; ++i) { struct hlsl_ir_node *path_node = deref->path[i].node; - unsigned int idx = 0; + unsigned int index;
VKD3D_ASSERT(path_node); if (path_node->type != HLSL_IR_CONSTANT) return false;
/* We should always have generated a cast to UINT. */ - VKD3D_ASSERT(path_node->data_type->class == HLSL_CLASS_SCALAR - && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); - - idx = hlsl_ir_constant(path_node)->value.u[0].u; - - switch (type->class) - { - case HLSL_CLASS_VECTOR: - if (idx >= type->e.numeric.dimx) - return false; - *start += idx; - break; - - case HLSL_CLASS_MATRIX: - if (idx >= hlsl_type_major_size(type)) - return false; - if (hlsl_type_is_row_major(type)) - *start += idx * type->e.numeric.dimx; - else - *start += idx * type->e.numeric.dimy; - break; - - case HLSL_CLASS_ARRAY: - if (idx >= type->e.array.elements_count) - return false; - *start += idx * hlsl_type_component_count(type->e.array.type); - break; - - case HLSL_CLASS_STRUCT: - for (k = 0; k < idx; ++k) - *start += hlsl_type_component_count(type->e.record.fields[k].type); - break; + VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
- default: - vkd3d_unreachable(); - } + if (!component_index_from_deref_path_node(path_node, type, &index)) + return false; + *start += index;
type = hlsl_get_element_type_from_path_index(ctx, type, path_node); } @@ -6439,8 +7032,7 @@ bool hlsl_regset_index_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref if (path_node->type == HLSL_IR_CONSTANT) { /* We should always have generated a cast to UINT. */ - VKD3D_ASSERT(path_node->data_type->class == HLSL_CLASS_SCALAR - && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT); + VKD3D_ASSERT(hlsl_is_vec1(path_node->data_type) && path_node->data_type->e.numeric.type == HLSL_TYPE_UINT);
idx = hlsl_ir_constant(path_node)->value.u[0].u;
@@ -6502,14 +7094,13 @@ bool hlsl_offset_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref
*offset = deref->const_offset;
- if (hlsl_type_is_patch_array(deref->var->data_type)) + if (hlsl_type_is_primitive_array(deref->var->data_type)) return false;
if (offset_node) { /* We should always have generated a cast to UINT. */ - VKD3D_ASSERT(offset_node->data_type->class == HLSL_CLASS_SCALAR - && offset_node->data_type->e.numeric.type == HLSL_TYPE_UINT); + VKD3D_ASSERT(hlsl_is_vec1(offset_node->data_type) && offset_node->data_type->e.numeric.type == HLSL_TYPE_UINT); VKD3D_ASSERT(offset_node->type != HLSL_IR_CONSTANT); return false; } @@ -6544,11 +7135,14 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere { const struct hlsl_ir_var *var = deref->var; struct hlsl_reg ret = var->regs[HLSL_REGSET_NUMERIC]; - unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref); + unsigned int offset = 0;
VKD3D_ASSERT(deref->data_type); VKD3D_ASSERT(hlsl_is_numeric_type(deref->data_type));
+ if (!hlsl_type_is_primitive_array(deref->var->data_type)) + offset = hlsl_offset_from_deref_safe(ctx, deref); + ret.index += offset / 4; ret.id += offset / 4;
@@ -6559,6 +7153,35 @@ struct hlsl_reg hlsl_reg_from_deref(struct hlsl_ctx *ctx, const struct hlsl_dere return ret; }
+static bool get_integral_argument_value(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr, + unsigned int i, int *value) +{ + const struct hlsl_ir_node *instr = attr->args[i].node; + const struct hlsl_type *type = instr->data_type; + + if (type->class != HLSL_CLASS_SCALAR + || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT)) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Unexpected type for argument %u of [%s]: expected int or uint, but got %s.", + i, attr->name, string->buffer); + hlsl_release_string_buffer(ctx, string); + return false; + } + + if (instr->type != HLSL_IR_CONSTANT) + { + hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [%s] initializer.", attr->name); + return false; + } + + *value = hlsl_ir_constant(instr)->value.u[0].i; + return true; +} + static const char *get_string_argument_value(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr, unsigned int i) { const struct hlsl_ir_node *instr = attr->args[i].node; @@ -6581,6 +7204,7 @@ static const char *get_string_argument_value(struct hlsl_ctx *ctx, const struct
static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) { + static const unsigned int limits[3] = {1024, 1024, 64}; unsigned int i;
ctx->found_numthreads = 1; @@ -6594,37 +7218,21 @@ static void parse_numthreads_attribute(struct hlsl_ctx *ctx, const struct hlsl_a
for (i = 0; i < attr->args_count; ++i) { - const struct hlsl_ir_node *instr = attr->args[i].node; - const struct hlsl_type *type = instr->data_type; - const struct hlsl_ir_constant *constant; - - if (type->class != HLSL_CLASS_SCALAR - || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT)) - { - struct vkd3d_string_buffer *string; + int value;
- if ((string = hlsl_type_to_string(ctx, type))) - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument %u of [numthreads]: expected int or uint, but got %s.", - i, string->buffer); - hlsl_release_string_buffer(ctx, string); - break; - } - - if (instr->type != HLSL_IR_CONSTANT) - { - hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [numthreads] initializer."); - break; - } - constant = hlsl_ir_constant(instr); + if (!get_integral_argument_value(ctx, attr, i, &value)) + return;
- if ((type->e.numeric.type == HLSL_TYPE_INT && constant->value.u[0].i <= 0) - || (type->e.numeric.type == HLSL_TYPE_UINT && !constant->value.u[0].u)) - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT, - "Thread count must be a positive integer."); + if (value < 1 || value > limits[i]) + hlsl_error(ctx, &attr->args[i].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT, + "Dimension %u of the thread count must be between 1 and %u.", i, limits[i]);
- ctx->thread_count[i] = constant->value.u[0].u; + ctx->thread_count[i] = value; } + + if (ctx->thread_count[0] * ctx->thread_count[1] * ctx->thread_count[2] > 1024) + hlsl_error(ctx, &attr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_THREAD_COUNT, + "Product of thread count parameters cannot exceed 1024."); }
static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) @@ -6655,9 +7263,7 @@ static void parse_domain_attribute(struct hlsl_ctx *ctx, const struct hlsl_attri
static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) { - const struct hlsl_ir_node *instr; - const struct hlsl_type *type; - const struct hlsl_ir_constant *constant; + int value;
if (attr->args_count != 1) { @@ -6666,35 +7272,14 @@ static void parse_outputcontrolpoints_attribute(struct hlsl_ctx *ctx, const stru return; }
- instr = attr->args[0].node; - type = instr->data_type; - - if (type->class != HLSL_CLASS_SCALAR - || (type->e.numeric.type != HLSL_TYPE_INT && type->e.numeric.type != HLSL_TYPE_UINT)) - { - struct vkd3d_string_buffer *string; - - if ((string = hlsl_type_to_string(ctx, type))) - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Wrong type for argument 0 of [outputcontrolpoints]: expected int or uint, but got %s.", - string->buffer); - hlsl_release_string_buffer(ctx, string); - return; - } - - if (instr->type != HLSL_IR_CONSTANT) - { - hlsl_fixme(ctx, &instr->loc, "Non-constant expression in [outputcontrolpoints] initializer."); + if (!get_integral_argument_value(ctx, attr, 0, &value)) return; - } - constant = hlsl_ir_constant(instr);
- if ((type->e.numeric.type == HLSL_TYPE_INT && constant->value.u[0].i < 0) - || constant->value.u[0].u > 32) - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, + if (value < 0 || value > 32) + hlsl_error(ctx, &attr->args[0].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, "Output control point count must be between 0 and 32.");
- ctx->output_control_point_count = constant->value.u[0].u; + ctx->output_control_point_count = value; }
static void parse_outputtopology_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) @@ -6788,6 +7373,27 @@ static void parse_patchconstantfunc_attribute(struct hlsl_ctx *ctx, const struct "Patch constant function "%s" is not defined.", name); }
+static void parse_maxvertexcount_attribute(struct hlsl_ctx *ctx, const struct hlsl_attribute *attr) +{ + int value; + + if (attr->args_count != 1) + { + hlsl_error(ctx, &attr->loc, VKD3D_SHADER_ERROR_HLSL_WRONG_PARAMETER_COUNT, + "Expected 1 parameter for [maxvertexcount] attribute, but got %u.", attr->args_count); + return; + } + + if (!get_integral_argument_value(ctx, attr, 0, &value)) + return; + + if (value < 1 || value > 1024) + hlsl_error(ctx, &attr->args[0].node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, + "Max vertex count must be between 1 and 1024."); + + ctx->max_vertex_count = value; +} + static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) { const struct hlsl_profile_info *profile = ctx->profile; @@ -6812,6 +7418,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir parse_patchconstantfunc_attribute(ctx, attr); else if (!strcmp(attr->name, "earlydepthstencil") && profile->type == VKD3D_SHADER_TYPE_PIXEL) entry_func->early_depth_test = true; + else if (!strcmp(attr->name, "maxvertexcount") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + parse_maxvertexcount_attribute(ctx, attr); else hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Ignoring unknown attribute "%s".", entry_func->attrs[i]->name); @@ -6884,7 +7492,71 @@ static void validate_hull_shader_attributes(struct hlsl_ctx *ctx, const struct h } }
-static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) +static enum vkd3d_primitive_type get_primitive_type(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) +{ + uint32_t prim_modifier = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK; + enum vkd3d_primitive_type prim_type = VKD3D_PT_UNDEFINED; + + if (prim_modifier) + { + unsigned int count = var->data_type->e.array.elements_count; + unsigned int expected_count; + + VKD3D_ASSERT(!(prim_modifier & (prim_modifier - 1))); + + switch (prim_modifier) + { + case HLSL_PRIMITIVE_POINT: + prim_type = VKD3D_PT_POINTLIST; + expected_count = 1; + break; + + case HLSL_PRIMITIVE_LINE: + prim_type = VKD3D_PT_LINELIST; + expected_count = 2; + break; + + case HLSL_PRIMITIVE_TRIANGLE: + prim_type = VKD3D_PT_TRIANGLELIST; + expected_count = 3; + break; + + case HLSL_PRIMITIVE_LINEADJ: + prim_type = VKD3D_PT_LINELIST_ADJ; + expected_count = 4; + break; + + case HLSL_PRIMITIVE_TRIANGLEADJ: + prim_type = VKD3D_PT_TRIANGLELIST_ADJ; + expected_count = 6; + break; + + default: + vkd3d_unreachable(); + } + + if (count != expected_count) + { + struct vkd3d_string_buffer *string; + + if ((string = hlsl_modifiers_to_string(ctx, prim_modifier))) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, + "Control point count %u does not match the expect count %u for the %s input primitive type.", + count, expected_count, string->buffer); + hlsl_release_string_buffer(ctx, string); + } + } + + /* Patch types take precedence over primitive modifiers. */ + if (hlsl_type_is_patch_array(var->data_type)) + prim_type = VKD3D_PT_PATCH; + + VKD3D_ASSERT(prim_type != VKD3D_PT_UNDEFINED); + return prim_type; +} + + +static void validate_and_record_prim_type(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) { unsigned int control_point_count = var->data_type->e.array.elements_count; enum hlsl_array_type array_type = var->data_type->e.array.array_type; @@ -6902,7 +7574,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ return; } } - else + else if (array_type == HLSL_ARRAY_PATCH_OUTPUT) { if (!ctx->is_patch_constant_func && profile->type != VKD3D_SHADER_TYPE_DOMAIN) { @@ -6913,6 +7585,30 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ } }
+ if ((var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK) && profile->type != VKD3D_SHADER_TYPE_GEOMETRY) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "Input primitive parameters can only be used in geometry shaders."); + return; + } + + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + { + enum vkd3d_primitive_type prim_type = get_primitive_type(ctx, var); + + if (ctx->input_primitive_type == VKD3D_PT_UNDEFINED) + { + ctx->input_primitive_type = prim_type; + } + else if (ctx->input_primitive_type != prim_type) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Input primitive type does not match the previously declared type."); + hlsl_note(ctx, &ctx->input_primitive_param->loc, VKD3D_SHADER_LOG_ERROR, + "The input primitive was previously declared here."); + } + } + if (control_point_count > 32) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, @@ -6925,7 +7621,7 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_ { if (control_point_count != ctx->output_control_point_count) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, - "Output control point count %u does not match the count %u specified in the control point function.", + "Output control point count %u does not match the count %u declared in the control point function.", control_point_count, ctx->output_control_point_count);
if (!hlsl_types_are_equal(control_point_type, ctx->output_control_point_type)) @@ -6937,22 +7633,126 @@ static void validate_and_record_patch_type(struct hlsl_ctx *ctx, struct hlsl_ir_
if (ctx->input_control_point_count != UINT_MAX) { - VKD3D_ASSERT(ctx->is_patch_constant_func); + VKD3D_ASSERT(profile->type == VKD3D_SHADER_TYPE_GEOMETRY || ctx->is_patch_constant_func);
if (control_point_count != ctx->input_control_point_count) + { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, - "Input control point count %u does not match the count %u specified in the control point function.", + "Input control point count %u does not match the count %u declared previously.", control_point_count, ctx->input_control_point_count); + hlsl_note(ctx, &ctx->input_primitive_param->loc, VKD3D_SHADER_LOG_ERROR, + "The input primitive was previously declared here."); + }
- if (!hlsl_types_are_equal(control_point_type, ctx->input_control_point_type)) + if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY + && !hlsl_types_are_equal(control_point_type, ctx->input_control_point_type)) + { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Input control point type does not match the input type specified in the control point function."); + "Input control point type does not match the input type declared previously."); + hlsl_note(ctx, &ctx->input_primitive_param->loc, VKD3D_SHADER_LOG_ERROR, + "The input primitive was previously declared here."); + }
return; }
ctx->input_control_point_count = control_point_count; ctx->input_control_point_type = control_point_type; + ctx->input_primitive_param = var; +} + +static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) +{ + static const enum vkd3d_primitive_type prim_types[] = + { + [HLSL_STREAM_OUTPUT_POINT_STREAM] = VKD3D_PT_POINTLIST, + [HLSL_STREAM_OUTPUT_LINE_STREAM] = VKD3D_PT_LINESTRIP, + [HLSL_STREAM_OUTPUT_TRIANGLE_STREAM] = VKD3D_PT_TRIANGLESTRIP, + }; + + bool reported_non_point_multistream = false, reported_nonzero_index = false, reported_invalid_index = false; + enum hlsl_so_object_type so_type; + const struct hlsl_type *type; + struct hlsl_ir_var *var; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) + continue; + + type = hlsl_get_stream_output_type(var->data_type); + so_type = type->e.so.so_type; + + VKD3D_ASSERT(so_type < ARRAY_SIZE(prim_types)); + + if (ctx->output_topology_type == VKD3D_PT_UNDEFINED) + { + ctx->output_topology_type = prim_types[so_type]; + } + else + { + if ((so_type != HLSL_STREAM_OUTPUT_POINT_STREAM || ctx->output_topology_type != VKD3D_PT_POINTLIST) + && !reported_non_point_multistream) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Multiple output streams are only allowed with PointStream objects."); + reported_non_point_multistream = true; + } + } + + if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index && hlsl_version_lt(ctx, 5, 0) && !reported_nonzero_index) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "Multiple output streams are only supported in shader model 5.0 or higher."); + reported_nonzero_index = true; + } + + if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index >= VKD3D_MAX_STREAM_COUNT && !reported_invalid_index) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SIZE, + "Output stream index %u exceeds the maximum index %u.", + var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, VKD3D_MAX_STREAM_COUNT - 1); + reported_invalid_index = true; + } + } + + /* TODO: check that maxvertexcount * outputdatasize <= 1024. */ +} + +static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, + uint32_t output_reg_count) +{ + unsigned int max_output_size, comp_count = 0; + unsigned int *reg_comp_count; + struct hlsl_ir_var *var; + uint32_t id; + + if (ctx->result) + return; + + if (!(reg_comp_count = hlsl_calloc(ctx, output_reg_count, sizeof(*reg_comp_count)))) + return; + + LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->is_output_semantic) + continue; + + VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated); + id = var->regs[HLSL_REGSET_NUMERIC].id; + reg_comp_count[id] = max(reg_comp_count[id], vkd3d_log2i(var->regs[HLSL_REGSET_NUMERIC].writemask) + 1); + } + + for (id = 0; id < output_reg_count; ++id) + comp_count += reg_comp_count[id]; + + max_output_size = ctx->max_vertex_count * comp_count; + if (max_output_size > 1024) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, + "Max vertex count (%u) * output data component count (%u) = %u, which is greater than 1024.", + ctx->max_vertex_count, comp_count, max_output_size); + + vkd3d_free(reg_comp_count); }
static void remove_unreachable_code(struct hlsl_ctx *ctx, struct hlsl_block *body) @@ -7016,6 +7816,40 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) lower_ir(ctx, lower_index_loads, body); }
+ +static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) +{ + bool progress, any_progress = false; + + do + { + 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, hlsl_fold_constant_identities, block, NULL); + progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); + + any_progress |= progress; + } while (progress); + + return any_progress; +} + +static void hlsl_run_folding_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) +{ + bool progress; + + hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); + do + { + progress = simplify_exprs(ctx, body); + progress |= hlsl_copy_propagation_execute(ctx, body); + progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); + progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); + progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); + } while (progress); + hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL); +} + void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body) { bool progress; @@ -7035,32 +7869,24 @@ void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body)
lower_ir(ctx, lower_narrowing_casts, body); lower_ir(ctx, lower_int_dot, body); - lower_ir(ctx, lower_int_division, body); - lower_ir(ctx, lower_int_modulus, body); + if (hlsl_version_ge(ctx, 4, 0)) + { + lower_ir(ctx, lower_int_modulus_sm4, body); + lower_ir(ctx, lower_int_division_sm4, body); + } lower_ir(ctx, lower_int_abs, body); lower_ir(ctx, lower_casts_to_bool, body); lower_ir(ctx, lower_float_modulus, body); - hlsl_transform_ir(ctx, fold_redundant_casts, body, NULL);
- do - { - progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, body, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, body, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, body, NULL); - progress |= hlsl_copy_propagation_execute(ctx, body); - progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); - progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); - progress |= hlsl_transform_ir(ctx, remove_trivial_conditional_branches, body, NULL); - } while (progress); + hlsl_run_folding_passes(ctx, body); }
static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_program *program, struct shader_signature *signature, bool output, struct hlsl_ir_var *var) { enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_VOID; + bool is_primitive = hlsl_type_is_primitive_array(var->data_type); enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; - bool is_patch = hlsl_type_is_patch_array(var->data_type); unsigned int register_index, mask, use_mask; const char *name = var->semantic.name; enum vkd3d_shader_register_type type; @@ -7073,7 +7899,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog bool has_idx, ret;
ret = sm4_sysval_semantic_from_semantic_name(&sysval, &program->shader_version, ctx->semantic_compat_mapping, - ctx->domain, var->semantic.name, var->semantic.index, output, ctx->is_patch_constant_func, is_patch); + ctx->domain, var->semantic.name, var->semantic.index, output, ctx->is_patch_constant_func, is_primitive); VKD3D_ASSERT(ret); if (sysval == ~0u) return; @@ -7109,6 +7935,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog break;
case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: component_type = VKD3D_SHADER_COMPONENT_UINT; break; @@ -7134,7 +7961,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog return;
if (!sm1_register_from_semantic_name(&program->shader_version, - var->semantic.name, var->semantic.index, output, &type, ®ister_index)) + var->semantic.name, var->semantic.index, output, &sysval, &type, ®ister_index)) { enum vkd3d_decl_usage usage; unsigned int usage_idx; @@ -7151,6 +7978,8 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog if (program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX && output && usage == VKD3D_DECL_USAGE_POSITION) sysval = VKD3D_SHADER_SV_POSITION; + else + sysval = VKD3D_SHADER_SV_NONE; }
mask = (1 << var->data_type->e.numeric.dimx) - 1; @@ -7197,7 +8026,28 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog element->mask = mask; element->used_mask = use_mask; if (program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL && !output) - element->interpolation_mode = VKD3DSIM_LINEAR; + { + if (program->shader_version.major >= 4) + element->interpolation_mode = sm4_get_interpolation_mode(var->data_type, var->storage_modifiers); + else + element->interpolation_mode = VKD3DSIM_LINEAR; + } + + switch (var->data_type->e.numeric.type) + { + case HLSL_TYPE_BOOL: + case HLSL_TYPE_DOUBLE: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE; + break; + + case HLSL_TYPE_MIN16UINT: + element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_UINT_16; + break; + } }
static void generate_vsir_signature(struct hlsl_ctx *ctx, @@ -7265,6 +8115,7 @@ static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, return VKD3D_DATA_INT; case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: return VKD3D_DATA_UINT; } } @@ -7416,7 +8267,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, static enum vkd3d_shader_register_type sm4_get_semantic_register_type(enum vkd3d_shader_type shader_type, bool is_patch_constant_func, const struct hlsl_ir_var *var) { - if (hlsl_type_is_patch_array(var->data_type)) + if (hlsl_type_is_primitive_array(var->data_type)) { VKD3D_ASSERT(var->is_input_semantic);
@@ -7636,7 +8487,7 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p } else { - unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref) + var->buffer_offset; + unsigned int offset = deref->const_offset + var->buffer_offset;
VKD3D_ASSERT(data_type->class <= HLSL_CLASS_VECTOR); reg->type = VKD3DSPR_CONSTBUFFER; @@ -7654,19 +8505,27 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p reg->idx[1].offset = offset / 4; reg->idx_count = 2; } + + if (deref->rel_offset.node) + { + if (!(reg->idx[reg->idx_count - 1].rel_addr = sm4_generate_vsir_new_idx_src(ctx, + program, deref->rel_offset.node))) + return false; + } + *writemask = ((1u << data_type->e.numeric.dimx) - 1) << (offset & 3); } } else if (var->is_input_semantic) { - bool is_patch = hlsl_type_is_patch_array(var->data_type); + bool is_primitive = hlsl_type_is_primitive_array(var->data_type); bool has_idx;
if (sm4_register_from_semantic_name(version, var->semantic.name, false, ®->type, &has_idx)) { unsigned int offset = hlsl_offset_from_deref_safe(ctx, deref);
- VKD3D_ASSERT(!is_patch); + VKD3D_ASSERT(!is_primitive);
if (has_idx) { @@ -7688,12 +8547,12 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p
reg->type = sm4_get_semantic_register_type(version->type, ctx->is_patch_constant_func, var); reg->dimension = VSIR_DIMENSION_VEC4; - reg->idx[is_patch ? 1 : 0].offset = hlsl_reg.id; - reg->idx_count = is_patch ? 2 : 1; + reg->idx[is_primitive ? 1 : 0].offset = hlsl_reg.id; + reg->idx_count = is_primitive ? 2 : 1; *writemask = hlsl_reg.writemask; }
- if (is_patch) + if (is_primitive) { reg->idx[0].offset = deref->const_offset / 4; if (deref->rel_offset.node) @@ -7750,7 +8609,8 @@ static bool sm4_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, st
if (!sm4_generate_vsir_reg_from_deref(ctx, program, &src_param->reg, &writemask, deref)) return false; - src_param->swizzle = generate_vsir_get_src_swizzle(writemask, dst_writemask); + if (src_param->reg.dimension != VSIR_DIMENSION_NONE) + src_param->swizzle = generate_vsir_get_src_swizzle(writemask, dst_writemask); return true; }
@@ -7780,7 +8640,6 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_constant *constant) { struct hlsl_ir_node *instr = &constant->node; - struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins;
@@ -7792,13 +8651,11 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx,
src_param = &ins->src[0]; vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = constant->reg.id; src_param->swizzle = generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask);
- dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); - dst_param->reg.idx[0].offset = instr->reg.id; - dst_param->write_mask = instr->reg.writemask; + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); }
static void sm4_generate_vsir_rasterizer_sample_count(struct hlsl_ctx *ctx, @@ -7885,11 +8742,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx dst_param = &ins->dst[0]; vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); dst_param->reg.idx[0].offset = instr->reg.id; + dst_param->reg.dimension = VSIR_DIMENSION_VEC4; dst_param->write_mask = 1u << i;
src_param = &ins->src[0]; vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); src_param->reg.idx[0].offset = operand->reg.id; + src_param->reg.dimension = VSIR_DIMENSION_VEC4; c = vsir_swizzle_get_component(src_swizzle, i); src_param->swizzle = vsir_swizzle_from_writemask(1u << c); } @@ -7901,7 +8760,6 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi { struct hlsl_ir_node *operand = expr->operands[0].node; struct hlsl_ir_node *instr = &expr->node; - struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; unsigned int src_count = 0; @@ -7912,25 +8770,20 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SINCOS, 1, src_count))) return;
- dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); - dst_param->reg.idx[0].offset = instr->reg.id; - dst_param->write_mask = instr->reg.writemask; - - src_param = &ins->src[0]; - vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); - src_param->reg.idx[0].offset = operand->reg.id; - src_param->swizzle = generate_vsir_get_src_swizzle(operand->reg.writemask, VKD3DSP_WRITEMASK_ALL); + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); + vsir_src_from_hlsl_node(&ins->src[0], ctx, operand, VKD3DSP_WRITEMASK_ALL);
if (ctx->profile->major_version < 3) { src_param = &ins->src[1]; vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = ctx->d3dsincosconst1.id; src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
- src_param = &ins->src[1]; + src_param = &ins->src[2]; vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = ctx->d3dsincosconst2.id; src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; } @@ -7957,6 +8810,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: /* Integrals are internally represented as floats, so no change is necessary.*/ @@ -7978,8 +8832,9 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: - switch(src_type->e.numeric.type) + switch (src_type->e.numeric.type) { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: @@ -7989,6 +8844,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, break;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); @@ -8004,13 +8860,8 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - if (ctx->double_as_float_alias) - { - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); - return true; - } - hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "The 'double' type is not supported for the %s profile.", ctx->profile->name); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + return true; break;
default: @@ -8033,12 +8884,15 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr struct hlsl_ir_expr *expr) { struct hlsl_ir_node *instr = &expr->node; + struct hlsl_type *type = instr->data_type; + + if (!hlsl_is_numeric_type(type)) + goto err;
- if (expr->op != HLSL_OP1_REINTERPRET && expr->op != HLSL_OP1_CAST - && instr->data_type->e.numeric.type != HLSL_TYPE_FLOAT) + if (type->e.numeric.type == HLSL_TYPE_DOUBLE && !ctx->double_as_float_alias) { - /* These need to be lowered. */ - hlsl_fixme(ctx, &instr->loc, "SM1 non-float expression."); + hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "The 'double' type is not supported for the %s profile.", ctx->profile->name); return false; }
@@ -8053,30 +8907,44 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr
case HLSL_OP1_COS_REDUCED: VKD3D_ASSERT(expr->node.reg.writemask == VKD3DSP_WRITEMASK_0); + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_sincos(ctx, program, expr); break;
case HLSL_OP1_DSX: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true); break;
case HLSL_OP1_DSY: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true); break;
case HLSL_OP1_EXP2: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_EXP); break;
case HLSL_OP1_LOG2: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_LOG); break;
case HLSL_OP1_NEG: + if (type->e.numeric.type == HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true); break;
case HLSL_OP1_RCP: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RCP); break;
@@ -8085,23 +8953,33 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break;
case HLSL_OP1_RSQ: + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RSQ); break;
case HLSL_OP1_SAT: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true); break;
case HLSL_OP1_SIN_REDUCED: VKD3D_ASSERT(expr->node.reg.writemask == VKD3DSP_WRITEMASK_1); + if (!hlsl_type_is_floating_point(type)) + goto err; sm1_generate_vsir_instr_expr_sincos(ctx, program, expr); break;
case HLSL_OP2_ADD: + if (type->e.numeric.type == HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true); break;
case HLSL_OP2_DOT: + if (!hlsl_type_is_floating_point(type)) + goto err; switch (expr->operands[0].node->data_type->e.numeric.dimx) { case 3: @@ -8135,35 +9013,49 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break;
case HLSL_OP2_LOGIC_AND: + if (type->e.numeric.type != HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); break;
case HLSL_OP2_LOGIC_OR: + if (type->e.numeric.type != HLSL_TYPE_BOOL) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); break;
case HLSL_OP2_SLT: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SLT, 0, 0, true); break;
case HLSL_OP3_CMP: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_CMP, 0, 0, true); break;
case HLSL_OP3_DP2ADD: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2ADD, 0, 0, false); break;
case HLSL_OP3_MAD: + if (!hlsl_type_is_floating_point(type)) + goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true); break;
default: - hlsl_fixme(ctx, &instr->loc, "SM1 "%s" expression.", debug_hlsl_expr_op(expr->op)); - return false; + goto err; } - return true; + +err: + hlsl_fixme(ctx, &instr->loc, "SM1 %s expression of type %s.", debug_hlsl_expr_op(expr->op), instr->data_type->name); + return false; }
static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, @@ -8193,7 +9085,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, register_index = 0; } else if (!sm1_register_from_semantic_name(&version, semantic_name, - deref->var->semantic.index, true, &type, ®ister_index)) + deref->var->semantic.index, true, NULL, &type, ®ister_index)) { VKD3D_ASSERT(reg.allocated); type = VKD3DSPR_OUTPUT; @@ -8213,19 +9105,68 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, else VKD3D_ASSERT(reg.allocated);
- vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); + if (type == VKD3DSPR_DEPTHOUT) + { + vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); + dst_param->reg.dimension = VSIR_DIMENSION_SCALAR; + } + else + { + vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); + dst_param->reg.idx[0].offset = register_index; + dst_param->reg.dimension = VSIR_DIMENSION_VEC4; + } dst_param->write_mask = writemask; - dst_param->reg.idx[0].offset = register_index;
if (deref->rel_offset.node) hlsl_fixme(ctx, loc, "Translate relative addressing on dst register for vsir."); }
+static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx, + struct vsir_program *program, struct hlsl_ir_node *instr) +{ + enum vkd3d_shader_opcode opcode = hlsl_version_ge(ctx, 2, 0) ? VKD3DSIH_MOVA : VKD3DSIH_MOV; + struct vkd3d_shader_dst_param *dst_param; + struct vkd3d_shader_instruction *ins; + + VKD3D_ASSERT(instr->reg.allocated); + + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 1))) + return; + + dst_param = &ins->dst[0]; + vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); + dst_param->write_mask = VKD3DSP_WRITEMASK_0; + + VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); + VKD3D_ASSERT(instr->data_type->e.numeric.dimx == 1); + vsir_src_from_hlsl_node(&ins->src[0], ctx, instr, VKD3DSP_WRITEMASK_ALL); +} + +static struct vkd3d_shader_src_param *sm1_generate_vsir_new_address_src(struct hlsl_ctx *ctx, + struct vsir_program *program) +{ + struct vkd3d_shader_src_param *idx_src; + + if (!(idx_src = vsir_program_get_src_params(program, 1))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return NULL; + } + + memset(idx_src, 0, sizeof(*idx_src)); + vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); + idx_src->reg.dimension = VSIR_DIMENSION_VEC4; + idx_src->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + return idx_src; +} + static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, - struct vkd3d_shader_src_param *src_param, struct hlsl_deref *deref, - unsigned int dst_writemask, const struct vkd3d_shader_location *loc) + struct vsir_program *program, struct vkd3d_shader_src_param *src_param, + struct hlsl_deref *deref, uint32_t dst_writemask, const struct vkd3d_shader_location *loc) { enum vkd3d_shader_register_type type = VKD3DSPR_TEMP; + struct vkd3d_shader_src_param *src_rel_addr = NULL; struct vkd3d_shader_version version; uint32_t register_index; unsigned int writemask; @@ -8243,12 +9184,26 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, } else if (deref->var->is_uniform) { + unsigned int offset = deref->const_offset; + type = VKD3DSPR_CONST; + register_index = deref->var->regs[HLSL_REGSET_NUMERIC].id + offset / 4;
- reg = hlsl_reg_from_deref(ctx, deref); - register_index = reg.id; - writemask = reg.writemask; - VKD3D_ASSERT(reg.allocated); + writemask = 0xf & (0xf << (offset % 4)); + if (deref->var->regs[HLSL_REGSET_NUMERIC].writemask) + writemask = hlsl_combine_writemasks(deref->var->regs[HLSL_REGSET_NUMERIC].writemask, writemask); + + if (deref->rel_offset.node) + { + VKD3D_ASSERT(deref_supports_sm1_indirect_addressing(ctx, deref)); + + if (!(src_rel_addr = sm1_generate_vsir_new_address_src(ctx, program))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } + } + VKD3D_ASSERT(deref->var->regs[HLSL_REGSET_NUMERIC].allocated); } else if (deref->var->is_input_semantic) { @@ -8256,7 +9211,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, version.minor = ctx->profile->minor_version; version.type = ctx->profile->type; if (sm1_register_from_semantic_name(&version, deref->var->semantic.name, - deref->var->semantic.index, false, &type, ®ister_index)) + deref->var->semantic.index, false, NULL, &type, ®ister_index)) { writemask = (1 << deref->var->data_type->e.numeric.dimx) - 1; } @@ -8280,32 +9235,30 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, }
vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = register_index; + src_param->reg.idx[0].rel_addr = src_rel_addr; src_param->swizzle = generate_vsir_get_src_swizzle(writemask, dst_writemask); - - if (deref->rel_offset.node) - hlsl_fixme(ctx, loc, "Translate relative addressing on src register for vsir."); }
static void sm1_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_load *load) { struct hlsl_ir_node *instr = &load->node; - struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins;
VKD3D_ASSERT(instr->reg.allocated);
+ if (load->src.rel_offset.node) + sm1_generate_vsir_instr_mova(ctx, program, load->src.rel_offset.node); + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) return;
- dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); - dst_param->reg.idx[0].offset = instr->reg.id; - dst_param->write_mask = instr->reg.writemask; + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
- sm1_generate_vsir_init_src_param_from_deref(ctx, &ins->src[0], &load->src, dst_param->write_mask, - &ins->location); + sm1_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[0], + &load->src, ins->dst[0].write_mask, &ins->location); }
static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, @@ -8315,7 +9268,6 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, struct hlsl_ir_node *ddx = load->ddx.node; struct hlsl_ir_node *ddy = load->ddy.node; struct hlsl_ir_node *instr = &load->node; - struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; enum vkd3d_shader_opcode opcode; @@ -8354,15 +9306,12 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, return; ins->flags = flags;
- dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); - dst_param->reg.idx[0].offset = instr->reg.id; - dst_param->write_mask = instr->reg.writemask; + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
src_param = &ins->src[0]; vsir_src_from_hlsl_node(src_param, ctx, coords, VKD3DSP_WRITEMASK_ALL);
- sm1_generate_vsir_init_src_param_from_deref(ctx, &ins->src[1], &load->resource, + sm1_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[1], &load->resource, VKD3DSP_WRITEMASK_ALL, &ins->location);
if (load->load_type == HLSL_RESOURCE_SAMPLE_GRAD) @@ -8379,7 +9328,6 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_swizzle *swizzle_instr) { struct hlsl_ir_node *instr = &swizzle_instr->node, *val = swizzle_instr->val.node; - struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; uint32_t swizzle; @@ -8389,11 +9337,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx, if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) return;
- dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); - dst_param->reg.idx[0].offset = instr->reg.id; - dst_param->reg.dimension = VSIR_DIMENSION_VEC4; - dst_param->write_mask = instr->reg.writemask; + vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
swizzle = hlsl_swizzle_from_writemask(val->reg.writemask); swizzle = hlsl_combine_swizzles(swizzle, swizzle_instr->u.vector, instr->data_type->e.numeric.dimx); @@ -8429,18 +9373,14 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx, { struct hlsl_ir_node *condition = jump->condition.node; struct hlsl_ir_node *instr = &jump->node; - struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins;
if (jump->type == HLSL_IR_JUMP_DISCARD_NEG) { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 1, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 0, 1))) return;
- dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); - dst_param->reg.idx[0].offset = condition->reg.id; - dst_param->write_mask = condition->reg.writemask; + vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL); } else { @@ -8561,6 +9501,10 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl return; }
+ program->temp_count = allocate_temp_registers(ctx, entry_func); + if (ctx->result) + return; + generate_vsir_signature(ctx, program, entry_func);
hlsl_block_init(&block); @@ -8650,6 +9594,10 @@ D3DXPARAMETER_TYPE hlsl_sm1_base_type(const struct hlsl_type *type, bool is_comb case HLSL_TYPE_INT: case HLSL_TYPE_UINT: return D3DXPT_INT; + /* Minimum-precision types are not supported until 46, but at + * that point they do the same thing, and return sm4 types. */ + case HLSL_TYPE_MIN16UINT: + return 0x39; } break;
@@ -8934,6 +9882,7 @@ static void write_sm1_uniforms(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffe uni.f = var->default_values[k].number.i; break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: uni.f = var->default_values[k].number.u; @@ -8977,7 +9926,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs const struct hlsl_ir_var *var, struct hlsl_block *block, const struct vkd3d_shader_location *loc) { const struct vkd3d_shader_version *version = &program->shader_version; - const bool is_patch = hlsl_type_is_patch_array(var->data_type); + const bool is_primitive = hlsl_type_is_primitive_array(var->data_type); const bool output = var->is_output_semantic; enum vkd3d_shader_sysval_semantic semantic; struct vkd3d_shader_dst_param *dst_param; @@ -8989,7 +9938,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs bool has_idx;
sm4_sysval_semantic_from_semantic_name(&semantic, version, ctx->semantic_compat_mapping, ctx->domain, - var->semantic.name, var->semantic.index, output, ctx->is_patch_constant_func, is_patch); + var->semantic.name, var->semantic.index, output, ctx->is_patch_constant_func, is_primitive); if (semantic == ~0u) semantic = VKD3D_SHADER_SV_NONE;
@@ -9002,9 +9951,17 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT; break;
+ case VKD3D_SHADER_SV_PRIMITIVE_ID: + if (version->type == VKD3D_SHADER_TYPE_PIXEL) + opcode = VKD3DSIH_DCL_INPUT_PS_SGV; + else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY) + opcode = VKD3DSIH_DCL_INPUT; + else + opcode = VKD3DSIH_DCL_INPUT_SGV; + break; + case VKD3D_SHADER_SV_INSTANCE_ID: case VKD3D_SHADER_SV_IS_FRONT_FACE: - case VKD3D_SHADER_SV_PRIMITIVE_ID: case VKD3D_SHADER_SV_SAMPLE_INDEX: case VKD3D_SHADER_SV_VERTEX_ID: opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) @@ -9014,7 +9971,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs default: if (version->type == VKD3D_SHADER_TYPE_PIXEL) opcode = VKD3DSIH_DCL_INPUT_PS_SIV; - else if (is_patch) + else if (is_primitive && version->type != VKD3D_SHADER_TYPE_GEOMETRY) opcode = VKD3DSIH_DCL_INPUT; else opcode = VKD3DSIH_DCL_INPUT_SIV; @@ -9024,7 +9981,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs else { if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL - || version->type == VKD3D_SHADER_TYPE_HULL) + || (version->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)) opcode = VKD3DSIH_DCL_OUTPUT; else opcode = VKD3DSIH_DCL_OUTPUT_SIV; @@ -9055,7 +10012,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs } else if (opcode == VKD3DSIH_DCL_INPUT || opcode == VKD3DSIH_DCL_INPUT_PS) { - VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || is_patch); + VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || is_primitive || version->type == VKD3D_SHADER_TYPE_GEOMETRY); dst_param = &ins->declaration.dst; } else @@ -9066,7 +10023,7 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs dst_param = &ins->declaration.register_semantic.reg; }
- if (is_patch) + if (is_primitive) { VKD3D_ASSERT(has_idx); vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 2); @@ -9127,13 +10084,6 @@ static bool type_is_float(const struct hlsl_type *type) return type->e.numeric.type == HLSL_TYPE_FLOAT || type->e.numeric.type == HLSL_TYPE_HALF; }
-static bool type_is_integer(const struct hlsl_type *type) -{ - return type->e.numeric.type == HLSL_TYPE_BOOL - || type->e.numeric.type == HLSL_TYPE_INT - || type->e.numeric.type == HLSL_TYPE_UINT; -} - static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_program *program, const struct hlsl_ir_expr *expr, uint32_t bits) { @@ -9188,6 +10138,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ITOF, 0, 0, true); return true;
+ case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UTOF, 0, 0, true); return true; @@ -9211,6 +10162,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); return true; @@ -9225,6 +10177,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, } break;
+ case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: switch (src_type->e.numeric.type) { @@ -9234,6 +10187,7 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); return true; @@ -9263,8 +10217,8 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, static void sm4_generate_vsir_expr_with_two_destinations(struct hlsl_ctx *ctx, struct vsir_program *program, enum vkd3d_shader_opcode opcode, const struct hlsl_ir_expr *expr, unsigned int dst_idx) { - struct vkd3d_shader_dst_param *dst_param, *null_param; const struct hlsl_ir_node *instr = &expr->node; + struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins; unsigned int i, src_count;
@@ -9282,9 +10236,7 @@ static void sm4_generate_vsir_expr_with_two_destinations(struct hlsl_ctx *ctx, s dst_param = &ins->dst[dst_idx]; vsir_dst_from_hlsl_node(dst_param, ctx, instr);
- null_param = &ins->dst[1 - dst_idx]; - vsir_dst_param_init(null_param, VKD3DSPR_NULL, VKD3D_DATA_FLOAT, 0); - null_param->reg.dimension = VSIR_DIMENSION_NONE; + vsir_dst_param_init_null(&ins->dst[1 - dst_idx]);
for (i = 0; i < src_count; ++i) vsir_src_from_hlsl_node(&ins->src[i], ctx, expr->operands[i].node, dst_param->write_mask); @@ -9339,7 +10291,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_OP1_BIT_NOT: - VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); return true;
@@ -9431,6 +10383,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INEG, 0, 0, true); return true; @@ -9498,6 +10451,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IADD, 0, 0, true); return true; @@ -9508,17 +10462,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, }
case HLSL_OP2_BIT_AND: - VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true); return true;
case HLSL_OP2_BIT_OR: - VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true); return true;
case HLSL_OP2_BIT_XOR: - VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_XOR, 0, 0, true); return true;
@@ -9529,6 +10483,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DIV, 0, 0, true); return true;
+ case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 0); return true; @@ -9577,6 +10532,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IEQ, 0, 0, true); return true; @@ -9601,6 +10557,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UGE, 0, 0, true); return true; @@ -9625,6 +10582,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ULT, 0, 0, true); return true; @@ -9646,7 +10604,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_OP2_LSHIFT: - VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ISHL, 0, 0, true); return true; @@ -9659,6 +10617,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAD, 0, 0, true); return true; @@ -9679,6 +10638,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAX, 0, 0, true); return true;
+ case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMAX, 0, 0, true); return true; @@ -9699,6 +10659,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMIN, 0, 0, true); return true;
+ case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMIN, 0, 0, true); return true; @@ -9711,6 +10672,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_OP2_MOD: switch (dst_type->e.numeric.type) { + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 1); return true; @@ -9728,6 +10690,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, return true;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: /* Using IMUL instead of UMUL because we're taking the low * bits, and the native compiler generates IMUL. */ @@ -9750,6 +10713,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INE, 0, 0, true); return true; @@ -9761,7 +10725,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, }
case HLSL_OP2_RSHIFT: - VKD3D_ASSERT(type_is_integer(dst_type)); + VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3DSIH_ISHR : VKD3DSIH_USHR, 0, 0, true); @@ -9866,6 +10830,24 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, struct vkd3d_shader_instruction *ins; unsigned int writemask;
+ if (store->store_type != HLSL_RESOURCE_STORE) + { + enum vkd3d_shader_opcode opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND + ? VKD3DSIH_EMIT : VKD3DSIH_CUT; + + VKD3D_ASSERT(!store->value.node && !store->coords.node); + VKD3D_ASSERT(store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); + + if (store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) + { + hlsl_fixme(ctx, &instr->loc, "Stream output operation with a nonzero stream index."); + return false; + } + + ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); + return !!ins; + } + if (!store->resource.var->is_uniform) { hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); @@ -10408,6 +11390,19 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx, } }
+static bool sm4_generate_vsir_instr_sync(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct hlsl_ir_sync *sync) +{ + const struct hlsl_ir_node *instr = &sync->node; + struct vkd3d_shader_instruction *ins; + + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SYNC, 0, 0))) + return false; + ins->flags = sync->sync_flags; + + return true; +} + static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *block, struct vsir_program *program);
static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_if *iff) @@ -10558,6 +11553,10 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo sm4_generate_vsir_instr_interlocked(ctx, program, hlsl_ir_interlocked(instr)); break;
+ case HLSL_IR_SYNC: + sm4_generate_vsir_instr_sync(ctx, program, hlsl_ir_sync(instr)); + break; + default: break; } @@ -10846,6 +11845,7 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, const struct vkd3d_shader_version *version = &program->shader_version; struct extern_resource *extern_resources; unsigned int extern_resources_count, i; + struct hlsl_ir_var *var;
extern_resources = sm4_get_extern_resources(ctx, &extern_resources_count);
@@ -10866,6 +11866,25 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx,
sm4_free_extern_resources(extern_resources, extern_resources_count);
+ LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) + { + const struct hlsl_type *type = var->data_type; + + if (hlsl_type_is_primitive_array(type)) + type = var->data_type->e.array.type; + + /* Note that it doesn't matter if the semantic is unused or doesn't + * generate a signature element (e.g. SV_DispatchThreadID). */ + if ((var->is_input_semantic || var->is_output_semantic) + && (type->is_minimum_precision || hlsl_type_is_minimum_precision(type))) + { + program->global_flags |= VKD3DSGF_ENABLE_MINIMUM_PRECISION; + break; + } + } + /* FIXME: We also need to check for minimum-precision uniforms and local + * variable arithmetic. */ + if (entry_func->early_depth_test && vkd3d_shader_ver_ge(version, 5, 0)) program->global_flags |= VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; } @@ -10994,6 +12013,7 @@ static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_ return VKD3D_DATA_INT;
case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: return VKD3D_DATA_UINT; } @@ -11153,6 +12173,13 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl ? 0 : ctx->input_control_point_count; program->tess_domain = ctx->domain; } + else if (version.type == VKD3D_SHADER_TYPE_GEOMETRY) + { + program->input_control_point_count = ctx->input_control_point_count; + program->input_primitive = ctx->input_primitive_type; + program->output_topology = ctx->output_topology_type; + program->vertices_out_count = ctx->max_vertex_count; + }
LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { @@ -11288,6 +12315,7 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) break;
case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: return D3D_RETURN_TYPE_UINT; } @@ -11373,6 +12401,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) return D3D_SVT_INT; case HLSL_TYPE_UINT: return D3D_SVT_UINT; + case HLSL_TYPE_MIN16UINT: + return D3D_SVT_MIN16UINT; }
vkd3d_unreachable(); @@ -11696,16 +12726,13 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd static bool loop_unrolling_generate_const_bool_store(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, bool val, struct hlsl_block *block, struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *const_node, *store; + struct hlsl_ir_node *const_node;
if (!(const_node = hlsl_new_bool_constant(ctx, val, loc))) return false; hlsl_block_add_instr(block, const_node);
- if (!(store = hlsl_new_simple_store(ctx, var, const_node))) - return false; - hlsl_block_add_instr(block, store); - + hlsl_block_add_simple_store(ctx, block, var, const_node); return true; }
@@ -11759,19 +12786,13 @@ static bool loop_unrolling_remove_jumps_visit(struct hlsl_ctx *ctx, struct hlsl_ static struct hlsl_ir_if *loop_unrolling_generate_var_check(struct hlsl_ctx *ctx, struct hlsl_block *dst, struct hlsl_ir_var *var, struct vkd3d_shader_location *loc) { - struct hlsl_ir_node *cond, *iff; + struct hlsl_ir_node *cond, *load, *iff; struct hlsl_block then_block; - struct hlsl_ir_load *load;
hlsl_block_init(&then_block);
- if (!(load = hlsl_new_var_load(ctx, var, loc))) - return NULL; - hlsl_block_add_instr(dst, &load->node); - - if (!(cond = hlsl_new_unary_expr(ctx, HLSL_OP1_LOGIC_NOT, &load->node, loc))) - return NULL; - hlsl_block_add_instr(dst, cond); + load = hlsl_block_add_simple_load(ctx, dst, var, loc); + cond = hlsl_block_add_unary_expr(ctx, dst, HLSL_OP1_LOGIC_NOT, load, loc);
if (!(iff = hlsl_new_if(ctx, cond, &then_block, NULL, loc))) return NULL; @@ -11850,9 +12871,7 @@ static void loop_unrolling_simplify(struct hlsl_ctx *ctx, struct hlsl_block *blo copy_propagation_pop_scope(state); copy_propagation_push_scope(state, ctx);
- progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); - progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); + progress = simplify_exprs(ctx, block);
current_index = index_instructions(block, *index); progress |= copy_propagation_transform_block(ctx, block, state); @@ -12113,10 +13132,9 @@ static void loop_unrolling_execute(struct hlsl_ctx *ctx, struct hlsl_block *bloc
static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { - struct hlsl_ir_node *call, *rhs, *store; struct hlsl_ir_function_decl *func; + struct hlsl_ir_node *call, *rhs; unsigned int component_count; - struct hlsl_ir_load *load; struct hlsl_ir_expr *expr; struct hlsl_ir_var *lhs; char *body; @@ -12179,28 +13197,21 @@ static bool lower_f16tof32(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru return false;
lhs = func->parameters.vars[0]; - - if (!(store = hlsl_new_simple_store(ctx, lhs, rhs))) - return false; - hlsl_block_add_instr(block, store); + hlsl_block_add_simple_store(ctx, block, lhs, rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc))) return false; hlsl_block_add_instr(block, call);
- if (!(load = hlsl_new_var_load(ctx, func->return_var, &node->loc))) - return false; - hlsl_block_add_instr(block, &load->node); - + hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); return true; }
static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { - struct hlsl_ir_node *call, *rhs, *store; struct hlsl_ir_function_decl *func; + struct hlsl_ir_node *call, *rhs; unsigned int component_count; - struct hlsl_ir_load *load; struct hlsl_ir_expr *expr; struct hlsl_ir_var *lhs; char *body; @@ -12251,30 +13262,22 @@ static bool lower_f32tof16(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, stru return false;
lhs = func->parameters.vars[0]; - - if (!(store = hlsl_new_simple_store(ctx, lhs, rhs))) - return false; - hlsl_block_add_instr(block, store); + hlsl_block_add_simple_store(ctx, block, lhs, rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc))) return false; hlsl_block_add_instr(block, call);
- if (!(load = hlsl_new_var_load(ctx, func->return_var, &node->loc))) - return false; - hlsl_block_add_instr(block, &load->node); - + hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); return true; }
static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct hlsl_block *block) { - struct hlsl_ir_node *call, *rhs, *store; struct hlsl_ir_function_decl *func; + struct hlsl_ir_node *call, *rhs; unsigned int component_count; - struct hlsl_ir_load *load; struct hlsl_ir_expr *expr; - struct hlsl_ir_var *lhs; const char *template; char *body;
@@ -12327,7 +13330,7 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct template = template_sm2; else if (hlsl_version_lt(ctx, 4, 0)) template = template_sm3; - else if (type_is_integer(rhs->data_type)) + else if (hlsl_type_is_integer(rhs->data_type)) template = template_int; else template = template_sm4; @@ -12339,20 +13342,13 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct if (!(func = hlsl_compile_internal_function(ctx, "isinf", body))) return false;
- lhs = func->parameters.vars[0]; - - if (!(store = hlsl_new_simple_store(ctx, lhs, rhs))) - return false; - hlsl_block_add_instr(block, store); + hlsl_block_add_simple_store(ctx, block, func->parameters.vars[0], rhs);
if (!(call = hlsl_new_call(ctx, func, &node->loc))) return false; hlsl_block_add_instr(block, call);
- if (!(load = hlsl_new_var_load(ctx, func->return_var, &node->loc))) - return false; - hlsl_block_add_instr(block, &load->node); - + hlsl_block_add_simple_load(ctx, block, func->return_var, &node->loc); return true; }
@@ -12364,8 +13360,11 @@ static void process_entry_function(struct hlsl_ctx *ctx, struct hlsl_block static_initializers, global_uniforms; struct hlsl_block *const body = &entry_func->body; struct recursive_call_ctx recursive_call_ctx; + struct stream_append_ctx stream_append_ctx; + uint32_t output_reg_count; struct hlsl_ir_var *var; unsigned int i; + bool progress;
ctx->is_patch_constant_func = entry_func == ctx->patch_constant_func;
@@ -12418,41 +13417,59 @@ static void process_entry_function(struct hlsl_ctx *ctx, else prepend_uniform_copy(ctx, body, var); } - else if (hlsl_type_is_patch_array(var->data_type)) + else if (hlsl_type_is_primitive_array(var->data_type)) { - if (var->data_type->e.array.array_type == HLSL_ARRAY_PATCH_INPUT) + if (var->storage_modifiers & HLSL_STORAGE_OUT) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Input primitive parameter "%s" is declared as "out".", var->name); + + if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY) { - if (input_patch) + enum hlsl_array_type array_type = var->data_type->e.array.array_type; + + if (array_type == HLSL_ARRAY_PATCH_INPUT) { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH, - "Found multiple InputPatch parameters."); - hlsl_note(ctx, &input_patch->loc, VKD3D_SHADER_LOG_ERROR, - "The InputPatch parameter was previously declared here."); - continue; + if (input_patch) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH, + "Found multiple InputPatch parameters."); + hlsl_note(ctx, &input_patch->loc, VKD3D_SHADER_LOG_ERROR, + "The InputPatch parameter was previously declared here."); + continue; + } + input_patch = var; } - input_patch = var; - } - else - { - if (output_patch) + else if (array_type == HLSL_ARRAY_PATCH_OUTPUT) { - hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH, - "Found multiple OutputPatch parameters."); - hlsl_note(ctx, &output_patch->loc, VKD3D_SHADER_LOG_ERROR, - "The OutputPatch parameter was previously declared here."); - continue; + if (output_patch) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH, + "Found multiple OutputPatch parameters."); + hlsl_note(ctx, &output_patch->loc, VKD3D_SHADER_LOG_ERROR, + "The OutputPatch parameter was previously declared here."); + continue; + } + output_patch = var; } - output_patch = var; }
- validate_and_record_patch_type(ctx, var); - if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + validate_and_record_prim_type(ctx, var); + prepend_input_var_copy(ctx, entry_func, var); + } + else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) + { + if (profile->type != VKD3D_SHADER_TYPE_GEOMETRY) { - hlsl_fixme(ctx, &var->loc, "InputPatch/OutputPatch parameters in geometry shaders."); + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "Stream output parameters can only be used in geometry shaders."); continue; }
- prepend_input_var_copy(ctx, entry_func, var); + if (!(var->storage_modifiers & HLSL_STORAGE_IN) || !(var->storage_modifiers & HLSL_STORAGE_OUT)) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Stream output parameter "%s" must be declared as "inout".", var->name); + + prepend_uniform_copy(ctx, body, var); } else { @@ -12465,12 +13482,24 @@ static void process_entry_function(struct hlsl_ctx *ctx, }
if (var->storage_modifiers & HLSL_STORAGE_IN) + { + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && !var->semantic.name) + { + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE, + "Input parameter "%s" is missing a primitive type.", var->name); + continue; + } + prepend_input_var_copy(ctx, entry_func, var); + } if (var->storage_modifiers & HLSL_STORAGE_OUT) { if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Output parameters are not supported in hull shader control point functions."); + else if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, + "Output parameters are not allowed in geometry shaders."); else append_output_var_copy(ctx, entry_func, var); } @@ -12478,7 +13507,11 @@ static void process_entry_function(struct hlsl_ctx *ctx, } if (entry_func->return_var) { - if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT && !entry_func->return_var->semantic.name) + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "Geometry shaders cannot return values."); + else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT + && !entry_func->return_var->semantic.name) hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, "Entry point "%s" is missing a return value semantic.", entry_func->func->name);
@@ -12493,6 +13526,10 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function."); }
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && ctx->input_primitive_type == VKD3D_PT_UNDEFINED) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE, + "Entry point "%s" is missing an input primitive parameter.", entry_func->func->name); + if (hlsl_version_ge(ctx, 4, 0)) { hlsl_transform_ir(ctx, lower_discard_neg, body, NULL); @@ -12503,6 +13540,9 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL); }
+ compute_liveness(ctx, entry_func); + transform_derefs(ctx, divert_written_uniform_derefs_to_temp, &entry_func->body); + loop_unrolling_execute(ctx, body); hlsl_run_const_passes(ctx, body);
@@ -12517,6 +13557,17 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_transform_ir(ctx, lower_separate_samples, body, NULL);
hlsl_transform_ir(ctx, validate_dereferences, body, NULL); + + do + { + progress = vectorize_exprs(ctx, body); + compute_liveness(ctx, entry_func); + progress |= hlsl_transform_ir(ctx, dce, body, NULL); + progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); + progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); + progress |= vectorize_stores(ctx, body); + } while (progress); + hlsl_transform_ir(ctx, track_object_components_sampler_dim, body, NULL);
if (hlsl_version_ge(ctx, 4, 0)) @@ -12532,19 +13583,29 @@ static void process_entry_function(struct hlsl_ctx *ctx, else sort_synthetic_separated_samplers_first(ctx);
+ if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + { + allocate_stream_outputs(ctx); + validate_and_record_stream_outputs(ctx); + + memset(&stream_append_ctx, 0, sizeof(stream_append_ctx)); + stream_append_ctx.func = entry_func; + hlsl_transform_ir(ctx, lower_stream_appends, body, &stream_append_ctx); + } + if (profile->major_version < 4) { while (lower_ir(ctx, lower_nonconstant_array_loads, body));
lower_ir(ctx, lower_ternary, body); - - lower_ir(ctx, lower_nonfloat_exprs, body); + lower_ir(ctx, lower_int_modulus_sm1, body); + lower_ir(ctx, lower_division, body); /* Constants casted to float must be folded, and new casts to bool also need to be lowered. */ hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL); lower_ir(ctx, lower_casts_to_bool, body);
lower_ir(ctx, lower_casts_to_int, body); - lower_ir(ctx, lower_division, body); + lower_ir(ctx, lower_trunc, body); lower_ir(ctx, lower_sqrt, body); lower_ir(ctx, lower_dot, body); lower_ir(ctx, lower_round, body); @@ -12566,13 +13627,15 @@ static void process_entry_function(struct hlsl_ctx *ctx,
lower_ir(ctx, validate_nonconstant_vector_store_derefs, body);
+ hlsl_run_folding_passes(ctx, body); + do compute_liveness(ctx, entry_func); while (hlsl_transform_ir(ctx, dce, body, NULL));
/* TODO: move forward, remove when no longer needed */ transform_derefs(ctx, replace_deref_path_with_offset, body); - while (hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, body, NULL)); + simplify_exprs(ctx, body); transform_derefs(ctx, clean_constant_deref_offset_srcs, body);
do @@ -12586,7 +13649,10 @@ static void process_entry_function(struct hlsl_ctx *ctx,
allocate_register_reservations(ctx, &ctx->extern_vars); allocate_register_reservations(ctx, &entry_func->extern_vars); - allocate_semantic_registers(ctx, entry_func); + allocate_semantic_registers(ctx, entry_func, &output_reg_count); + + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + validate_max_output_size(ctx, entry_func, output_reg_count); }
int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, @@ -12608,6 +13674,9 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry else if (profile->type == VKD3D_SHADER_TYPE_DOMAIN && ctx->domain == VKD3D_TESSELLATOR_DOMAIN_INVALID) hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, "Entry point "%s" is missing a [domain] attribute.", entry_func->func->name); + else if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && !ctx->max_vertex_count) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, + "Entry point "%s" is missing a [maxvertexcount] attribute.", entry_func->func->name);
hlsl_block_init(&global_uniform_block);
@@ -12633,7 +13702,6 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry if (profile->major_version < 4) { mark_indexable_vars(ctx, entry_func); - allocate_temp_registers(ctx, entry_func); allocate_const_registers(ctx, entry_func); sort_uniforms_by_bind_count(ctx, HLSL_REGSET_SAMPLERS); allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c index 538f0f46854..d339a06e6c7 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -51,13 +51,11 @@ static bool fold_abs(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, dst->u[k].i = abs(src->value.u[k].i); break;
+ case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: - dst->u[k].u = src->value.u[k].u; - break; - - default: - FIXME("Fold abs() for type %s.\n", debug_hlsl_type(ctx, dst_type)); - return false; + /* Should not occur. */ + vkd3d_unreachable(); } } return true; @@ -126,6 +124,7 @@ static bool fold_bit_not(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, switch (type) { case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: dst->u[k].u = ~src->value.u[k].u; @@ -175,6 +174,7 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, break;
case HLSL_TYPE_UINT: + case HLSL_TYPE_MIN16UINT: u = src->value.u[k].u; i = src->value.u[k].u; f = src->value.u[k].u; @@ -205,6 +205,7 @@ static bool fold_cast(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, break;
case HLSL_TYPE_UINT: + case HLSL_TYPE_MIN16UINT: dst->u[k].u = u; break;
@@ -395,6 +396,7 @@ static bool fold_neg(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, break;
case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: dst->u[k].u = -src->value.u[k].u; break; @@ -612,6 +614,7 @@ static bool fold_add(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons /* Handling HLSL_TYPE_INT through the unsigned field to avoid * undefined behavior with signed integers in C. */ 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; break; @@ -638,6 +641,7 @@ static bool fold_and(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons switch (type) { case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: dst->u[k].u = src1->value.u[k].u & src2->value.u[k].u; @@ -665,6 +669,7 @@ static bool fold_or(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const switch (type) { case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: dst->u[k].u = src1->value.u[k].u | src2->value.u[k].u; @@ -692,6 +697,7 @@ static bool fold_bit_xor(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, switch (type) { 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; break; @@ -813,6 +819,7 @@ static bool fold_div(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons dst->u[k].i = src1->value.u[k].i / src2->value.u[k].i; break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: if (src2->value.u[k].u == 0) { @@ -855,6 +862,7 @@ static bool fold_equal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, co case HLSL_TYPE_INT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: dst->u[k].u = src1->value.u[k].u == src2->value.u[k].u; break; } @@ -891,6 +899,7 @@ static bool fold_gequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c
case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: dst->u[k].u = src1->value.u[k].u >= src2->value.u[k].u; break; } @@ -927,6 +936,7 @@ static bool fold_less(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, con
case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: dst->u[k].u = src1->value.u[k].u < src2->value.u[k].u; break; } @@ -951,6 +961,7 @@ static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c switch (src1->node.data_type->e.numeric.type) { case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: dst->u[k].u = src1->value.u[k].u << shift; break; @@ -989,6 +1000,7 @@ static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons dst->u[k].i = max(src1->value.u[k].i, src2->value.u[k].i); break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: dst->u[k].u = max(src1->value.u[k].u, src2->value.u[k].u); break; @@ -1027,6 +1039,7 @@ static bool fold_min(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons dst->u[k].i = min(src1->value.u[k].i, src2->value.u[k].i); break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: dst->u[k].u = min(src1->value.u[k].u, src2->value.u[k].u); break; @@ -1065,6 +1078,7 @@ static bool fold_mod(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons dst->u[k].i = src1->value.u[k].i % src2->value.u[k].i; break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: if (src2->value.u[k].u == 0) { @@ -1105,6 +1119,7 @@ static bool fold_mul(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons 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; break; @@ -1141,6 +1156,7 @@ static bool fold_nequal(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c case HLSL_TYPE_INT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: dst->u[k].u = src1->value.u[k].u != src2->value.u[k].u; break; } @@ -1183,6 +1199,7 @@ static bool fold_rshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c dst->u[k].i = src1->value.u[k].i >> shift; break;
+ case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: dst->u[k].u = src1->value.u[k].u >> shift; break; @@ -1399,6 +1416,7 @@ static bool constant_is_zero(struct hlsl_ir_constant *const_arg) 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; @@ -1429,6 +1447,7 @@ static bool constant_is_one(struct hlsl_ir_constant *const_arg)
case HLSL_TYPE_UINT: case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: if (const_arg->value.u[k].u != 1) return false; break; @@ -1524,7 +1543,7 @@ static bool is_op_associative(enum hlsl_ir_expr_op op, enum hlsl_base_type type) { case HLSL_OP2_ADD: case HLSL_OP2_MUL: - return type == HLSL_TYPE_INT || type == HLSL_TYPE_UINT; + return hlsl_base_type_is_integer(type);
case HLSL_OP2_BIT_AND: case HLSL_OP2_BIT_OR: @@ -1574,7 +1593,7 @@ static bool is_op_left_distributive(enum hlsl_ir_expr_op opl, enum hlsl_ir_expr_
case HLSL_OP2_DOT: case HLSL_OP2_MUL: - return opr == HLSL_OP2_ADD && (type == HLSL_TYPE_INT || type == HLSL_TYPE_UINT); + return opr == HLSL_OP2_ADD && hlsl_base_type_is_integer(type);
case HLSL_OP2_MAX: return opr == HLSL_OP2_MIN; @@ -1593,7 +1612,6 @@ static struct hlsl_ir_node *collect_exprs(struct hlsl_ctx *ctx, struct hlsl_bloc { enum hlsl_base_type type = instr->data_type->e.numeric.type; struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; - struct hlsl_ir_node *ab, *res; struct hlsl_ir_expr *e1, *e2; enum hlsl_ir_expr_op opl;
@@ -1610,17 +1628,9 @@ static struct hlsl_ir_node *collect_exprs(struct hlsl_ctx *ctx, struct hlsl_bloc if (e1->operands[1].node->type != HLSL_IR_CONSTANT || e2->operands[1].node->type != HLSL_IR_CONSTANT) return NULL;
- if (!(ab = hlsl_new_binary_expr(ctx, opr, e1->operands[1].node, e2->operands[1].node))) - return NULL; - hlsl_block_add_instr(block, ab); - operands[0] = e1->operands[0].node; - operands[1] = ab; - - if (!(res = hlsl_new_expr(ctx, opl, operands, instr->data_type, &instr->loc))) - return NULL; - hlsl_block_add_instr(block, res); - return res; + operands[1] = hlsl_block_add_binary_expr(ctx, block, opr, e1->operands[1].node, e2->operands[1].node); + return hlsl_block_add_expr(ctx, block, opl, operands, instr->data_type, &instr->loc); }
bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -1677,26 +1687,14 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst if (arg2->type == HLSL_IR_CONSTANT) { /* (x OP a) OP b -> x OP (a OP b) */ - struct hlsl_ir_node *ab; - - if (!(ab = hlsl_new_binary_expr(ctx, op, e1->operands[1].node, arg2))) - goto fail; - hlsl_block_add_instr(&block, ab); - arg1 = e1->operands[0].node; - arg2 = ab; + arg2 = hlsl_block_add_binary_expr(ctx, &block, op, e1->operands[1].node, arg2); progress = true; } else if (is_op_commutative(op)) { /* (x OP a) OP y -> (x OP y) OP a */ - struct hlsl_ir_node *xy; - - if (!(xy = hlsl_new_binary_expr(ctx, op, e1->operands[0].node, arg2))) - goto fail; - hlsl_block_add_instr(&block, xy); - - arg1 = xy; + arg1 = hlsl_block_add_binary_expr(ctx, &block, op, e1->operands[0].node, arg2); arg2 = e1->operands[1].node; progress = true; } @@ -1706,18 +1704,13 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst && e2->operands[0].node->type != HLSL_IR_CONSTANT && e2->operands[1].node->type == HLSL_IR_CONSTANT) { /* x OP (y OP a) -> (x OP y) OP a */ - struct hlsl_ir_node *xy; - - if (!(xy = hlsl_new_binary_expr(ctx, op, arg1, e2->operands[0].node))) - goto fail; - hlsl_block_add_instr(&block, xy); - - arg1 = xy; + arg1 = hlsl_block_add_binary_expr(ctx, &block, op, arg1, e2->operands[0].node); arg2 = e2->operands[1].node; progress = true; }
- if (!progress && e1 && (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[1].node, arg2))) + if (!progress && e1 && e1->op == op + && (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[1].node, arg2))) { /* (y OPR (x OPL a)) OPR (x OPL b) -> y OPR (x OPL (a OPR b)) */ arg1 = e1->operands[0].node; @@ -1725,7 +1718,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst progress = true; }
- if (!progress && is_op_commutative(op) && e1 + if (!progress && is_op_commutative(op) && e1 && e1->op == op && (tmp = collect_exprs(ctx, &block, instr, op, e1->operands[0].node, arg2))) { /* ((x OPL a) OPR y) OPR (x OPL b) -> (x OPL (a OPR b)) OPR y */ @@ -1734,7 +1727,8 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst progress = true; }
- if (!progress && e2 && (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[0].node))) + if (!progress && e2 && e2->op == op + && (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[0].node))) { /* (x OPL a) OPR ((x OPL b) OPR y) -> (x OPL (a OPR b)) OPR y */ arg1 = tmp; @@ -1742,7 +1736,7 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst progress = true; }
- if (!progress && is_op_commutative(op) && e2 + if (!progress && is_op_commutative(op) && e2 && e2->op == op && (tmp = collect_exprs(ctx, &block, instr, op, arg1, e2->operands[1].node))) { /* (x OPL a) OPR (y OPR (x OPL b)) -> (x OPL (a OPR b)) OPR y */ @@ -1757,19 +1751,13 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {arg1, arg2}; struct hlsl_ir_node *res;
- if (!(res = hlsl_new_expr(ctx, op, operands, instr->data_type, &instr->loc))) - goto fail; - hlsl_block_add_instr(&block, res); + res = hlsl_block_add_expr(ctx, &block, op, operands, instr->data_type, &instr->loc);
list_move_before(&instr->entry, &block.instrs); hlsl_replace_node(instr, res); }
return progress; - -fail: - hlsl_block_cleanup(&block); - return false; }
bool hlsl_fold_constant_swizzles(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index b608fae21ac..7466f7a2da1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -116,6 +116,7 @@ void vsir_program_cleanup(struct vsir_program *program) shader_signature_cleanup(&program->input_signature); shader_signature_cleanup(&program->output_signature); shader_signature_cleanup(&program->patch_constant_signature); + vkd3d_shader_free_scan_descriptor_info1(&program->descriptors); }
const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( @@ -311,6 +312,13 @@ static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3 dst->write_mask = e->mask; }
+void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) +{ + vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + dst->reg.dimension = VSIR_DIMENSION_NONE; + dst->write_mask = 0; +} + static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) { vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); @@ -469,6 +477,80 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d return false; }
+static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *program, + struct vsir_transformation_context *ctx) +{ + struct vkd3d_shader_instruction *ins, *ins2; + unsigned int tmp_idx = ~0u; + unsigned int i, k, r; + + for (i = 0; i < program->instructions.count; ++i) + { + ins = &program->instructions.elements[i]; + + if (ins->opcode == VKD3DSIH_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR) + { + if (tmp_idx == ~0u) + tmp_idx = program->temp_count++; + + ins->opcode = VKD3DSIH_FTOU; + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + ins->dst[0].reg.idx[0].offset = tmp_idx; + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + } + else if (ins->opcode == VKD3DSIH_MOVA) + { + if (tmp_idx == ~0u) + tmp_idx = program->temp_count++; + + if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + ins = &program->instructions.elements[i]; + ins2 = &program->instructions.elements[i + 1]; + + ins->opcode = VKD3DSIH_ROUND_NE; + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + ins->dst[0].reg.idx[0].offset = tmp_idx; + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + + if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VKD3DSIH_FTOU, 1, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + ins2->dst[0].reg.idx[0].offset = tmp_idx; + ins2->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins2->dst[0].write_mask = ins->dst[0].write_mask; + + vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + ins2->src[0].reg.idx[0].offset = tmp_idx; + ins2->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins2->src[0].swizzle = vsir_swizzle_from_writemask(ins2->dst[0].write_mask); + } + + for (k = 0; k < ins->src_count; ++k) + { + struct vkd3d_shader_src_param *src = &ins->src[k]; + + for (r = 0; r < src->reg.idx_count; ++r) + { + struct vkd3d_shader_src_param *rel = src->reg.idx[r].rel_addr; + + if (rel && rel->reg.type == VKD3DSPR_ADDR) + { + if (tmp_idx == ~0u) + tmp_idx = program->temp_count++; + + vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + rel->reg.idx[0].offset = tmp_idx; + rel->reg.dimension = VSIR_DIMENSION_VEC4; + } + } + } + } + + return VKD3D_OK; +} + static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx, struct vkd3d_shader_message_context *message_context) @@ -481,6 +563,7 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program,
if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; + ifc = &instructions->elements[pos];
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; @@ -534,11 +617,12 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; + texkill = &instructions->elements[pos];
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++;
- /* tmp = ins->dst[0] < 0 */ + /* tmp = ins->src[0] < 0 */
ins = &instructions->elements[pos + 1]; if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2)) @@ -549,7 +633,7 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program ins->dst[0].reg.idx[0].offset = *tmp_idx; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
- ins->src[0].reg = texkill->dst[0].reg; + ins->src[0].reg = texkill->src[0].reg; ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; @@ -620,6 +704,7 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro
if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; + mad = &instructions->elements[pos];
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; @@ -664,6 +749,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog
if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; + sincos = &instructions->elements[pos];
ins = &instructions->elements[pos + 1];
@@ -684,7 +770,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog } else { - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(&ins->dst[0]); }
if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) @@ -694,7 +780,7 @@ static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *prog } else { - vsir_dst_param_init(&ins->dst[1], VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(&ins->dst[1]); }
/* Make the original instruction no-op */ @@ -716,6 +802,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program,
if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; + tex = &instructions->elements[pos];
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; @@ -775,12 +862,14 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, } else if (tex->flags == VKD3DSI_TEXLD_BIAS) { + enum vkd3d_shader_swizzle_component w = vsir_swizzle_get_component(srcs[0].swizzle, 3); + tex->opcode = VKD3DSIH_SAMPLE_B; tex->src = srcs; tex->src_count = 4;
srcs[3] = tex->src[0]; - srcs[3].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); + srcs[3].swizzle = vkd3d_shader_create_swizzle(w, w, w, w); } else { @@ -1127,6 +1216,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra if (!shader_instruction_array_insert_at(&program->instructions, i, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; ins = &program->instructions.elements[i]; + vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = 0; @@ -1218,7 +1308,7 @@ static void remove_unread_output_components(const struct shader_signature *signa if (ins->dst_count == 1) vkd3d_shader_instruction_make_nop(ins); else - vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init_null(dst); } }
@@ -1345,7 +1435,6 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program loc = ins->location; if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[i];
for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) @@ -1732,8 +1821,20 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i return VKD3D_OK; }
+struct io_normaliser_register_data +{ + struct + { + uint8_t register_count; + uint32_t mask; + uint32_t used_mask; + } component[VKD3D_VEC4_SIZE]; +}; + + struct io_normaliser { + struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_instruction_array instructions; enum vkd3d_shader_type shader_type; uint8_t major; @@ -1751,9 +1852,9 @@ struct io_normaliser struct vkd3d_shader_dst_param *input_dcl_params[MAX_REG_OUTPUT]; struct vkd3d_shader_dst_param *output_dcl_params[MAX_REG_OUTPUT]; struct vkd3d_shader_dst_param *pc_dcl_params[MAX_REG_OUTPUT]; - uint8_t input_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE]; - uint8_t output_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE]; - uint8_t pc_range_map[MAX_REG_OUTPUT][VKD3D_VEC4_SIZE]; + struct io_normaliser_register_data input_range_map[MAX_REG_OUTPUT]; + struct io_normaliser_register_data output_range_map[MAX_REG_OUTPUT]; + struct io_normaliser_register_data pc_range_map[MAX_REG_OUTPUT];
bool use_vocp; }; @@ -1794,36 +1895,44 @@ struct signature_element *vsir_signature_find_element_for_reg(const struct shade return NULL; }
-static unsigned int range_map_get_register_count(uint8_t range_map[][VKD3D_VEC4_SIZE], +static unsigned int range_map_get_register_count(struct io_normaliser_register_data range_map[], unsigned int register_idx, uint32_t write_mask) { - return range_map[register_idx][vsir_write_mask_get_component_idx(write_mask)]; + return range_map[register_idx].component[vsir_write_mask_get_component_idx(write_mask)].register_count; }
-static void range_map_set_register_range(uint8_t range_map[][VKD3D_VEC4_SIZE], unsigned int register_idx, - unsigned int register_count, uint32_t write_mask, bool is_dcl_indexrange) +static enum vkd3d_result range_map_set_register_range(struct io_normaliser *normaliser, + struct io_normaliser_register_data range_map[], unsigned int register_idx, + unsigned int register_count, uint32_t mask, uint32_t used_mask, bool is_dcl_indexrange) { unsigned int i, j, r, c, component_idx, component_count;
- VKD3D_ASSERT(write_mask <= VKD3DSP_WRITEMASK_ALL); - component_idx = vsir_write_mask_get_component_idx(write_mask); - component_count = vsir_write_mask_component_count(write_mask); + VKD3D_ASSERT(mask <= VKD3DSP_WRITEMASK_ALL); + component_idx = vsir_write_mask_get_component_idx(mask); + component_count = vsir_write_mask_component_count(mask);
VKD3D_ASSERT(register_idx < MAX_REG_OUTPUT && MAX_REG_OUTPUT - register_idx >= register_count);
- if (range_map[register_idx][component_idx] > register_count && is_dcl_indexrange) + if (range_map[register_idx].component[component_idx].register_count > register_count && is_dcl_indexrange) { - /* Validated in the TPF reader. */ - VKD3D_ASSERT(range_map[register_idx][component_idx] != UINT8_MAX); - return; + if (range_map[register_idx].component[component_idx].register_count == UINT8_MAX) + { + WARN("Conflicting index ranges.\n"); + vkd3d_shader_error(normaliser->message_context, NULL, + VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, "Conflicting index ranges."); + return VKD3D_ERROR_INVALID_SHADER; + } + return VKD3D_OK; } - if (range_map[register_idx][component_idx] == register_count) + if (range_map[register_idx].component[component_idx].register_count == register_count) { /* Already done. This happens when fxc splits a register declaration by * component(s). The dcl_indexrange instructions are split too. */ - return; + return VKD3D_OK; } - range_map[register_idx][component_idx] = register_count; + range_map[register_idx].component[component_idx].register_count = register_count; + range_map[register_idx].component[component_idx].mask = mask; + range_map[register_idx].component[component_idx].used_mask = used_mask;
for (i = 0; i < register_count; ++i) { @@ -1834,21 +1943,31 @@ static void range_map_set_register_range(uint8_t range_map[][VKD3D_VEC4_SIZE], u /* A synthetic patch constant range which overlaps an existing range can start upstream of it * for fork/join phase instancing, but ranges declared by dcl_indexrange should not overlap. * The latter is validated in the TPF reader. */ - VKD3D_ASSERT(!range_map[r][c] || !is_dcl_indexrange); - range_map[r][c] = UINT8_MAX; + if (range_map[r].component[c].register_count && is_dcl_indexrange) + { + WARN("Conflicting index ranges.\n"); + vkd3d_shader_error(normaliser->message_context, NULL, + VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, "Conflicting index ranges."); + return VKD3D_ERROR_INVALID_SHADER; + } + range_map[r].component[c].register_count = UINT8_MAX; + range_map[r].component[c].mask = mask; + range_map[r].component[c].used_mask = used_mask; } } + + return VKD3D_OK; }
-static void io_normaliser_add_index_range(struct io_normaliser *normaliser, +static enum vkd3d_result io_normaliser_add_index_range(struct io_normaliser *normaliser, const struct vkd3d_shader_instruction *ins) { const struct vkd3d_shader_index_range *range = &ins->declaration.index_range; const struct vkd3d_shader_register *reg = &range->dst.reg; + struct io_normaliser_register_data *range_map; const struct shader_signature *signature; - uint8_t (*range_map)[VKD3D_VEC4_SIZE]; - struct signature_element *element; - unsigned int reg_idx, write_mask; + uint32_t mask, used_mask; + unsigned int reg_idx, i;
switch (reg->type) { @@ -1879,9 +1998,21 @@ static void io_normaliser_add_index_range(struct io_normaliser *normaliser, }
reg_idx = reg->idx[reg->idx_count - 1].offset; - write_mask = range->dst.write_mask; - element = vsir_signature_find_element_for_reg(signature, reg_idx, write_mask); - range_map_set_register_range(range_map, reg_idx, range->register_count, element->mask, true); + mask = range->dst.write_mask; + used_mask = 0; + + for (i = 0; i < range->register_count; ++i) + { + struct signature_element *element; + + if ((element = vsir_signature_find_element_for_reg(signature, reg_idx + i, mask))) + { + mask |= element->mask; + used_mask |= element->used_mask; + } + } + + return range_map_set_register_range(normaliser, range_map, reg_idx, range->register_count, mask, used_mask, true); }
static int signature_element_mask_compare(const void *a, const void *b) @@ -1908,33 +2039,42 @@ static bool sysval_semantics_should_merge(const struct signature_element *e, con }
/* Merge tess factor sysvals because they are an array in SPIR-V. */ -static void shader_signature_map_patch_constant_index_ranges(struct shader_signature *s, - uint8_t range_map[][VKD3D_VEC4_SIZE]) +static enum vkd3d_result shader_signature_map_patch_constant_index_ranges(struct io_normaliser *normaliser, + struct shader_signature *s, struct io_normaliser_register_data range_map[]) { - struct signature_element *e, *f; unsigned int i, j, register_count; + struct signature_element *e, *f; + enum vkd3d_result ret;
qsort(s->elements, s->element_count, sizeof(s->elements[0]), signature_element_mask_compare);
for (i = 0; i < s->element_count; i += register_count) { + uint32_t used_mask; + e = &s->elements[i]; register_count = 1;
if (!e->sysval_semantic) continue;
+ used_mask = e->used_mask; for (j = i + 1; j < s->element_count; ++j, ++register_count) { f = &s->elements[j]; if (f->register_index != e->register_index + register_count || !sysval_semantics_should_merge(e, f)) break; + used_mask |= f->used_mask; } if (register_count < 2) continue;
- range_map_set_register_range(range_map, e->register_index, register_count, e->mask, false); + if ((ret = range_map_set_register_range(normaliser, range_map, + e->register_index, register_count, e->mask, used_mask, false)) < 0) + return ret; } + + return VKD3D_OK; }
static int signature_element_register_compare(const void *a, const void *b) @@ -1977,62 +2117,19 @@ static int signature_element_index_compare(const void *a, const void *b) return vkd3d_u32_compare(e->sort_index, f->sort_index); }
-static unsigned int signature_element_range_expand_mask(struct signature_element *e, unsigned int register_count, - uint8_t range_map[][VKD3D_VEC4_SIZE]) -{ - unsigned int i, j, component_idx, component_count, merged_write_mask = e->mask; - - /* dcl_indexrange instructions can declare a subset of the full mask, and the masks of - * the elements within the range may differ. TPF's handling of arrayed inputs with - * dcl_indexrange is really just a hack. Here we create a mask which covers all element - * masks, and check for collisions with other ranges. */ - - for (i = 1; i < register_count; ++i) - merged_write_mask |= e[i].mask; - - if (merged_write_mask == e->mask) - return merged_write_mask; - - /* Reaching this point is very rare to begin with, and collisions are even rarer or - * impossible. If the latter shows up, the fallback in shader_signature_find_element_for_reg() - * may be sufficient. */ - - component_idx = vsir_write_mask_get_component_idx(e->mask); - component_count = vsir_write_mask_component_count(e->mask); - - for (i = e->register_index; i < e->register_index + register_count; ++i) - { - for (j = 0; j < component_idx; ++j) - if (range_map[i][j]) - break; - for (j = component_idx + component_count; j < VKD3D_VEC4_SIZE; ++j) - if (range_map[i][j]) - break; - } - - if (i == register_count) - { - WARN("Expanding mask %#x to %#x for %s, base reg %u, count %u.\n", e->mask, merged_write_mask, - e->semantic_name, e->register_index, register_count); - return merged_write_mask; - } - - WARN("Cannot expand mask %#x to %#x for %s, base reg %u, count %u.\n", e->mask, merged_write_mask, - e->semantic_name, e->register_index, register_count); - return e->mask; -} - -static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map[][VKD3D_VEC4_SIZE], +static enum vkd3d_result shader_signature_merge(struct io_normaliser *normaliser, + struct shader_signature *s, struct io_normaliser_register_data range_map[], bool is_patch_constant) { unsigned int i, j, element_count, new_count, register_count; struct signature_element *elements; + enum vkd3d_result ret = VKD3D_OK; struct signature_element *e, *f; bool used;
element_count = s->element_count; if (!(elements = vkd3d_malloc(element_count * sizeof(*elements)))) - return false; + return VKD3D_ERROR_OUT_OF_MEMORY; if (element_count) memcpy(elements, s->elements, element_count * sizeof(*elements));
@@ -2091,42 +2188,49 @@ static bool shader_signature_merge(struct shader_signature *s, uint8_t range_map s->elements = elements; s->element_count = element_count;
- if (is_patch_constant) - shader_signature_map_patch_constant_index_ranges(s, range_map); + if (is_patch_constant + && (ret = shader_signature_map_patch_constant_index_ranges(normaliser, s, range_map)) < 0) + goto out;
- for (i = 0, new_count = 0; i < element_count; i += register_count, elements[new_count++] = *e) + for (i = 0, new_count = 0; i < element_count; ++i) { e = &elements[i]; register_count = 1;
if (e->register_index >= MAX_REG_OUTPUT) + { + elements[new_count++] = *e; continue; + }
register_count = range_map_get_register_count(range_map, e->register_index, e->mask); - VKD3D_ASSERT(register_count != UINT8_MAX); - register_count += !register_count;
- if (register_count > 1) + if (register_count == UINT8_MAX) { - TRACE("Merging %s, base reg %u, count %u.\n", e->semantic_name, e->register_index, register_count); - e->register_count = register_count; - e->mask = signature_element_range_expand_mask(e, register_count, range_map); + TRACE("Register %u mask %#x semantic %s%u has already been merged, dropping it.\n", + e->register_index, e->mask, e->semantic_name, e->semantic_index); + vkd3d_free((void *)e->semantic_name); + continue; + }
- for (j = 1; j < register_count; ++j) - { - f = &elements[i + j]; - vkd3d_free((void *)f->semantic_name); - } + if (register_count > 0) + { + TRACE("Register %u mask %#x semantic %s%u is used as merge destination.\n", + e->register_index, e->mask, e->semantic_name, e->semantic_index); + e->register_count = register_count; + e->mask = range_map[e->register_index].component[vsir_write_mask_get_component_idx(e->mask)].mask; + e->used_mask = range_map[e->register_index].component[vsir_write_mask_get_component_idx(e->mask)].used_mask; } + + elements[new_count++] = *e; } - element_count = new_count; + s->element_count = new_count;
+out: /* Restoring the original order is required for sensible trace output. */ - qsort(elements, element_count, sizeof(elements[0]), signature_element_index_compare); + qsort(s->elements, s->element_count, sizeof(elements[0]), signature_element_index_compare);
- s->element_count = element_count; - - return true; + return ret; }
static unsigned int shader_register_normalise_arrayed_addressing(struct vkd3d_shader_register *reg, @@ -2342,8 +2446,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, struct vsir_transformation_context *ctx) { - struct io_normaliser normaliser = {program->instructions}; + struct io_normaliser normaliser = {ctx->message_context, program->instructions}; struct vkd3d_shader_instruction *ins; + enum vkd3d_result ret; unsigned int i;
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO); @@ -2365,7 +2470,8 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program normaliser.output_control_point_count = ins->declaration.count; break; case VKD3DSIH_DCL_INDEX_RANGE: - io_normaliser_add_index_range(&normaliser, ins); + if ((ret = io_normaliser_add_index_range(&normaliser, ins)) < 0) + return ret; vkd3d_shader_instruction_make_nop(ins); break; case VKD3DSIH_HS_CONTROL_POINT_PHASE: @@ -2378,12 +2484,14 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program } }
- if (!shader_signature_merge(&program->input_signature, normaliser.input_range_map, false) - || !shader_signature_merge(&program->output_signature, normaliser.output_range_map, false) - || !shader_signature_merge(&program->patch_constant_signature, normaliser.pc_range_map, true)) + if ((ret = shader_signature_merge(&normaliser, &program->input_signature, normaliser.input_range_map, false)) < 0 + || (ret = shader_signature_merge(&normaliser, &program->output_signature, + normaliser.output_range_map, false)) < 0 + || (ret = shader_signature_merge(&normaliser, &program->patch_constant_signature, + normaliser.pc_range_map, true)) < 0) { program->instructions = normaliser.instructions; - return VKD3D_ERROR_OUT_OF_MEMORY; + return ret; }
normaliser.phase = VKD3DSIH_INVALID; @@ -2410,7 +2518,8 @@ struct flat_constants_normaliser };
static bool get_flat_constant_register_type(const struct vkd3d_shader_register *reg, - enum vkd3d_shader_d3dbc_constant_register *set, uint32_t *index) + enum vkd3d_shader_d3dbc_constant_register *set, uint32_t *index, + struct vkd3d_shader_src_param **rel_addr) { static const struct { @@ -2430,12 +2539,8 @@ static bool get_flat_constant_register_type(const struct vkd3d_shader_register * { if (reg->type == regs[i].type) { - if (reg->idx[0].rel_addr) - { - FIXME("Unhandled relative address.\n"); - return false; - } - + if (rel_addr) + *rel_addr = reg->idx[0].rel_addr; *set = regs[i].set; *index = reg->idx[0].offset; return true; @@ -2449,10 +2554,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par const struct flat_constants_normaliser *normaliser) { enum vkd3d_shader_d3dbc_constant_register set; + struct vkd3d_shader_src_param *rel_addr; uint32_t index; size_t i, j;
- if (!get_flat_constant_register_type(¶m->reg, &set, &index)) + if (!get_flat_constant_register_type(¶m->reg, &set, &index, &rel_addr)) return;
for (i = 0; i < normaliser->def_count; ++i) @@ -2470,8 +2576,11 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par
param->reg.type = VKD3DSPR_CONSTBUFFER; param->reg.idx[0].offset = set; /* register ID */ + param->reg.idx[0].rel_addr = NULL; param->reg.idx[1].offset = set; /* register index */ + param->reg.idx[1].rel_addr = NULL; param->reg.idx[2].offset = index; /* buffer index */ + param->reg.idx[2].rel_addr = rel_addr; param->reg.idx_count = 3; }
@@ -2498,7 +2607,7 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr
def = &normaliser.defs[normaliser.def_count++];
- get_flat_constant_register_type((struct vkd3d_shader_register *)&ins->dst[0].reg, &def->set, &def->index); + get_flat_constant_register_type(&ins->dst[0].reg, &def->set, &def->index, NULL); for (j = 0; j < 4; ++j) def->value[j] = ins->src[0].reg.u.immconst_u32[j];
@@ -6021,6 +6130,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_instruction_array *instructions = &program->instructions; + const struct vkd3d_shader_location loc = ret->location; static const struct vkd3d_shader_location no_loc; size_t pos = ret - instructions->elements; struct vkd3d_shader_instruction *ins; @@ -6045,9 +6155,10 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr { if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; + ret = NULL; ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_DISCARD, 0, 1); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1); ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; src_param_init_const_uint(&ins->src[0], 0);
@@ -6057,20 +6168,20 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr
if (!shader_instruction_array_insert_at(&program->instructions, pos, 3)) return VKD3D_ERROR_OUT_OF_MEMORY; - + ret = NULL; ins = &program->instructions.elements[pos];
switch (ref->data_type) { case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32: - vsir_instruction_init_with_params(program, ins, &ret->location, opcodes[compare_func].float_opcode, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].float_opcode, 1, 2); src_param_init_temp_float(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_FLOAT); break;
case VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32: - vsir_instruction_init_with_params(program, ins, &ret->location, opcodes[compare_func].uint_opcode, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].uint_opcode, 1, 2); src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_UINT); @@ -6091,14 +6202,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
++ins; - vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_DISCARD, 0, 1); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1); ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; src_param_init_ssa_bool(&ins->src[0], program->ssa_count);
++program->ssa_count;
++ins; - vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = colour_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; @@ -6199,13 +6310,14 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos) { struct vkd3d_shader_instruction_array *instructions = &program->instructions; + const struct vkd3d_shader_location loc = ret->location; size_t pos = ret - instructions->elements; struct vkd3d_shader_instruction *ins; unsigned int output_idx = 0;
if (!shader_instruction_array_insert_at(&program->instructions, pos, vkd3d_popcount(mask) + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - + ret = NULL; ins = &program->instructions.elements[pos];
for (unsigned int i = 0; i < 8; ++i) @@ -6213,7 +6325,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog if (!(mask & (1u << i))) continue;
- vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_DP4, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DP4, 1, 2); src_param_init_temp_float4(&ins->src[0], position_temp); src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VKD3D_DATA_FLOAT); ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; @@ -6231,7 +6343,7 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog ++ins; }
- vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = position_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; @@ -6388,15 +6500,16 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr const struct vkd3d_shader_instruction *ret, size_t *ret_pos) { struct vkd3d_shader_instruction_array *instructions = &program->instructions; + 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, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - + ret = NULL; ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT); @@ -6525,9 +6638,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter)) return VKD3D_ERROR_OUT_OF_MEMORY; + ins = &program->instructions.elements[i + 1];
loc = &program->instructions.elements[i].location; - ins = &program->instructions.elements[i + 1];
if (min_parameter) { @@ -6725,7 +6838,6 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr { if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[insert_pos];
vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); @@ -6799,6 +6911,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro */ if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) return VKD3D_ERROR_OUT_OF_MEMORY; + ret = NULL; + *ret_pos = pos + 4;
ssa_temp = program->ssa_count++; @@ -6829,6 +6943,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro */ if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) return VKD3D_ERROR_OUT_OF_MEMORY; + ret = NULL; + *ret_pos = pos + 4;
ssa_temp = program->ssa_count++; @@ -6859,6 +6975,8 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro */ if (!shader_instruction_array_insert_at(&program->instructions, pos, 5)) return VKD3D_ERROR_OUT_OF_MEMORY; + ret = NULL; + *ret_pos = pos + 5;
ssa_temp = program->ssa_count++; @@ -7037,16 +7155,18 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr { const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; struct vkd3d_shader_instruction_array *instructions = &program->instructions; + 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)) return VKD3D_ERROR_OUT_OF_MEMORY; + ret = NULL;
ins = &program->instructions.elements[pos];
/* Write the fog output. */ - vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, fog_signature_idx, 0x1); src_param_init_temp_float4(&ins->src[0], temp); if (source == VKD3D_SHADER_FOG_SOURCE_Z) @@ -7056,7 +7176,7 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr ++ins;
/* Write the position or specular output. */ - vsir_instruction_init_with_params(program, ins, &ret->location, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); dst_param_init_output(&ins->dst[0], vkd3d_data_type_from_component_type(e->component_type), source_signature_idx, e->mask); src_param_init_temp_float4(&ins->src[0], temp); @@ -7691,6 +7811,54 @@ static void vsir_validate_label_register(struct validation_context *ctx, reg->idx[0].offset, ctx->program->block_count); }
+static void vsir_validate_descriptor_indices(struct validation_context *ctx, + const struct vkd3d_shader_register *reg, enum vkd3d_shader_descriptor_type type, const char *name) +{ + const struct vkd3d_shader_descriptor_info1 *descriptor; + + if (reg->idx[0].rel_addr) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, + "Non-NULL indirect address for the ID of a register of type "%s".", name); + + if (!ctx->program->has_descriptor_info) + return; + + if (!(descriptor = vkd3d_shader_find_descriptor(&ctx->program->descriptors, type, reg->idx[0].offset))) + { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, + "No matching descriptor found for register %s%u.", name, reg->idx[0].offset); + return; + } + + if (!reg->idx[1].rel_addr && (reg->idx[1].offset < descriptor->register_index + || reg->idx[1].offset - descriptor->register_index >= descriptor->count)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, + "Register index %u doesn't belong to the range [%u, %u] for register %s%u.", + reg->idx[1].offset, descriptor->register_index, + descriptor->register_index + descriptor->count - 1, name, reg->idx[0].offset); +} + +static void vsir_validate_constbuffer_register(struct validation_context *ctx, + const struct vkd3d_shader_register *reg) +{ + if (reg->precision != VKD3D_SHADER_REGISTER_PRECISION_DEFAULT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, + "Invalid precision %#x for a CONSTBUFFER register.", reg->precision); + + if (reg->dimension != VSIR_DIMENSION_VEC4) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, + "Invalid dimension %#x for a CONSTBUFFER register.", reg->dimension); + + if (reg->idx_count != 3) + { + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, + "Invalid index count %u for a CONSTBUFFER register.", reg->idx_count); + return; + } + + vsir_validate_descriptor_indices(ctx, reg, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, "cb"); +} + static void vsir_validate_sampler_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { @@ -7714,9 +7882,7 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, return; }
- if (reg->idx[0].rel_addr) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, - "Non-NULL relative address for the descriptor index of a SAMPLER register."); + vsir_validate_descriptor_indices(ctx, reg, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, "s"); }
static void vsir_validate_resource_register(struct validation_context *ctx, @@ -7741,9 +7907,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx, return; }
- if (reg->idx[0].rel_addr) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, - "Non-NULL relative address for the descriptor index of a RESOURCE register."); + vsir_validate_descriptor_indices(ctx, reg, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, "t"); }
static void vsir_validate_uav_register(struct validation_context *ctx, @@ -7773,9 +7937,7 @@ static void vsir_validate_uav_register(struct validation_context *ctx, return; }
- if (reg->idx[0].rel_addr) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX, - "Non-NULL relative address for the descriptor index of a UAV register."); + vsir_validate_descriptor_indices(ctx, reg, VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, "u"); }
static void vsir_validate_ssa_register(struct validation_context *ctx, @@ -7928,6 +8090,10 @@ static void vsir_validate_register(struct validation_context *ctx, vsir_validate_register_without_indices(ctx, reg); break;
+ case VKD3DSPR_CONSTBUFFER: + vsir_validate_constbuffer_register(ctx, reg); + break; + case VKD3DSPR_PRIMID: vsir_validate_register_without_indices(ctx, reg); break; @@ -8095,6 +8261,14 @@ static void vsir_validate_dst_param(struct validation_context *ctx, switch (dst->reg.type) { case VKD3DSPR_SSA: + if (dst->reg.dimension == VSIR_DIMENSION_VEC4 + && dst->write_mask != VKD3DSP_WRITEMASK_0 + && dst->write_mask != (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1) + && dst->write_mask != (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2) + && dst->write_mask != VKD3DSP_WRITEMASK_ALL) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK, + "SSA register has invalid write mask %#x.", dst->write_mask); + if (dst->reg.idx[0].offset < ctx->program->ssa_count) { struct validation_context_ssa_data *data = &ctx->ssas[dst->reg.idx[0].offset]; @@ -8115,6 +8289,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx,
case VKD3DSPR_IMMCONST: case VKD3DSPR_IMMCONST64: + case VKD3DSPR_CONSTBUFFER: + case VKD3DSPR_IMMCONSTBUFFER: case VKD3DSPR_SAMPLER: case VKD3DSPR_RESOURCE: validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, @@ -8187,8 +8363,11 @@ static void vsir_validate_src_param(struct validation_context *ctx, break;
case VKD3DSPR_NULL: + case VKD3DSPR_DEPTHOUT: + case VKD3DSPR_DEPTHOUTGE: + case VKD3DSPR_DEPTHOUTLE: validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE, - "Invalid NULL register used as source parameter."); + "Invalid register of type %#x used as source parameter.", src->reg.type); break;
case VKD3DSPR_INPUT: @@ -8505,10 +8684,13 @@ static void vsir_validate_signature_element(struct validation_context *ctx, { case VKD3D_SHADER_COMPONENT_INT: case VKD3D_SHADER_COMPONENT_UINT: + case VKD3D_SHADER_COMPONENT_INT16: + case VKD3D_SHADER_COMPONENT_UINT16: integer_type = true; break;
case VKD3D_SHADER_COMPONENT_FLOAT: + case VKD3D_SHADER_COMPONENT_FLOAT16: break;
default: @@ -8684,6 +8866,45 @@ static void vsir_validate_signature(struct validation_context *ctx, const struct } }
+static void vsir_validate_descriptors(struct validation_context *ctx) +{ + const struct vkd3d_shader_scan_descriptor_info1 *descriptors = &ctx->program->descriptors; + unsigned int i; + + for (i = 0; i < descriptors->descriptor_count; ++i) + { + const struct vkd3d_shader_descriptor_info1 *descriptor = &descriptors->descriptors[i]; + + if (descriptor->type >= VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE, + "Descriptor %u has invalid type %#x.", i, descriptor->type); + + if (descriptor->resource_type >= VKD3D_SHADER_RESOURCE_TYPE_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE, + "Descriptor %u has invalid resource type %#x.", i, descriptor->resource_type); + else if ((descriptor->resource_type == VKD3D_SHADER_RESOURCE_NONE) + != (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE, + "Descriptor %u has invalid resource type %#x for descriptor type %#x.", + i, descriptor->resource_type, descriptor->type); + + if (descriptor->resource_data_type >= VKD3D_DATA_COUNT) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Descriptor %u has invalid resource data type %#x.", i, descriptor->resource_data_type); + else if ((descriptor->resource_data_type == VKD3D_DATA_UNUSED) + != (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Descriptor %u has invalid resource data type %#x for descriptor type %#x.", + i, descriptor->resource_data_type, descriptor->type); + + if (!descriptor->count || (descriptor->count > UINT_MAX - descriptor->register_index + && descriptor->count != UINT_MAX)) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT, + "Descriptor %u has invalid descriptor count %u starting at index %u.", + i, descriptor->count, descriptor->register_index); + } +} + static const char *name_from_cf_type(enum vsir_control_flow_type type) { switch (type) @@ -9650,6 +9871,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c } }
+ vsir_validate_descriptors(&ctx); + if (!(ctx.temps = vkd3d_calloc(ctx.program->temp_count, sizeof(*ctx.temps)))) goto fail;
@@ -9776,6 +9999,9 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t if (program->shader_version.major <= 2) vsir_transform(&ctx, vsir_program_ensure_diffuse);
+ if (program->shader_version.major < 4) + vsir_transform(&ctx, vsir_program_normalize_addr); + if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) vsir_transform(&ctx, vsir_program_remap_output_signature);
diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index e783128e236..4f37468af86 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -18,6 +18,13 @@
#include "vkd3d_shader_private.h"
+enum msl_data_type +{ + MSL_DATA_FLOAT, + MSL_DATA_UINT, + MSL_DATA_UNION, +}; + struct msl_src { struct vkd3d_string_buffer *str; @@ -44,7 +51,14 @@ struct msl_generator bool write_depth;
const struct vkd3d_shader_interface_info *interface_info; - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info; +}; + +struct msl_resource_type_info +{ + size_t read_coord_size; + bool array; + bool lod; + const char *type_suffix; };
static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen, @@ -58,6 +72,30 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen gen->failed = true; }
+static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3d_shader_resource_type t) +{ + static const struct msl_resource_type_info info[] = + { + [VKD3D_SHADER_RESOURCE_NONE] = {0, false, false, "none"}, + [VKD3D_SHADER_RESOURCE_BUFFER] = {1, false, false, "_buffer"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, false, false, "1d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, false, true, "2d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, false, false, "2d_ms"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, false, true, "3d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, false, true, "cube"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, true, false, "1d_array"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, true, true, "2d_array"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, true, false, "2d_ms_array"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, true, true, "cube_array"}, + }; + + if (!t || t >= ARRAY_SIZE(info)) + return NULL; + + return &info[t]; +} + + static const char *msl_get_prefix(enum vkd3d_shader_type type) { switch (type) @@ -84,6 +122,30 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in vkd3d_string_buffer_printf(buffer, "%*s", 4 * indent, ""); }
+static void msl_print_resource_datatype(struct msl_generator *gen, + struct vkd3d_string_buffer *buffer, enum vkd3d_data_type data_type) +{ + switch (data_type) + { + case VKD3D_DATA_FLOAT: + case VKD3D_DATA_UNORM: + case VKD3D_DATA_SNORM: + vkd3d_string_buffer_printf(buffer, "float"); + break; + case VKD3D_DATA_INT: + vkd3d_string_buffer_printf(buffer, "int"); + break; + case VKD3D_DATA_UINT: + vkd3d_string_buffer_printf(buffer, "uint"); + break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource datatype %#x.", data_type); + vkd3d_string_buffer_printf(buffer, "<unrecognised resource datatype %#x>", data_type); + break; + } +} + static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, enum vkd3d_data_type data_type) { @@ -107,15 +169,119 @@ static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, } }
-static void msl_print_register_name(struct vkd3d_string_buffer *buffer, +static bool msl_check_shader_visibility(const struct msl_generator *gen, + enum vkd3d_shader_visibility visibility) +{ + enum vkd3d_shader_type t = gen->program->shader_version.type; + + switch (visibility) + { + case VKD3D_SHADER_VISIBILITY_ALL: + return true; + case VKD3D_SHADER_VISIBILITY_VERTEX: + return t == VKD3D_SHADER_TYPE_VERTEX; + case VKD3D_SHADER_VISIBILITY_HULL: + return t == VKD3D_SHADER_TYPE_HULL; + case VKD3D_SHADER_VISIBILITY_DOMAIN: + return t == VKD3D_SHADER_TYPE_DOMAIN; + case VKD3D_SHADER_VISIBILITY_GEOMETRY: + return t == VKD3D_SHADER_TYPE_GEOMETRY; + case VKD3D_SHADER_VISIBILITY_PIXEL: + return t == VKD3D_SHADER_TYPE_PIXEL; + case VKD3D_SHADER_VISIBILITY_COMPUTE: + return t == VKD3D_SHADER_TYPE_COMPUTE; + default: + WARN("Invalid shader visibility %#x.\n", visibility); + return false; + } +} + +static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx) +{ + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + unsigned int i; + + if (!interface_info) + return NULL; + + for (i = 0; i < interface_info->binding_count; ++i) + { + const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; + + if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) + continue; + if (binding->register_space != register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) + continue; + + return &binding->binding; + } + + return NULL; +} + +static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) +{ + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + enum vkd3d_shader_binding_flag resource_type_flag; + unsigned int i; + + if (!interface_info) + return NULL; + + resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER + ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; + + for (i = 0; i < interface_info->binding_count; ++i) + { + const struct vkd3d_shader_resource_binding *binding = &interface_info->bindings[i]; + + if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SRV) + continue; + if (binding->register_space != register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + if (!(binding->flags & resource_type_flag)) + continue; + + return &binding->binding; + } + + return NULL; +} + +static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].buf<vkd3d_vec4>()", binding); +} + +static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, + const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].tex<texture%s<", + binding, resource_type_info->type_suffix); + msl_print_resource_datatype(gen, buffer, resource_data_type); + vkd3d_string_buffer_printf(buffer, ">>()"); +} + +static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, const struct vkd3d_shader_register *reg) { switch (reg->type) { case VKD3DSPR_TEMP: vkd3d_string_buffer_printf(buffer, "r[%u]", reg->idx[0].offset); - msl_print_register_datatype(buffer, gen, reg->data_type); - break; + return MSL_DATA_UNION;
case VKD3DSPR_INPUT: if (reg->idx_count != 1) @@ -123,18 +289,17 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled input register index count %u.", reg->idx_count); vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); - break; + return MSL_DATA_UNION; } if (reg->idx[0].rel_addr) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled input register indirect addressing."); vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); - break; + return MSL_DATA_UNION; } vkd3d_string_buffer_printf(buffer, "v[%u]", reg->idx[0].offset); - msl_print_register_datatype(buffer, gen, reg->data_type); - break; + return MSL_DATA_UNION;
case VKD3DSPR_OUTPUT: if (reg->idx_count != 1) @@ -142,18 +307,17 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled output register index count %u.", reg->idx_count); vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); - break; + return MSL_DATA_UNION; } if (reg->idx[0].rel_addr) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled output register indirect addressing."); vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); - break; + return MSL_DATA_UNION; } vkd3d_string_buffer_printf(buffer, "o[%u]", reg->idx[0].offset); - msl_print_register_datatype(buffer, gen, reg->data_type); - break; + return MSL_DATA_UNION;
case VKD3DSPR_DEPTHOUT: if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) @@ -161,89 +325,64 @@ static void msl_print_register_name(struct vkd3d_string_buffer *buffer, "Internal compiler error: Unhandled depth output in shader type #%x.", gen->program->shader_version.type); vkd3d_string_buffer_printf(buffer, "o_depth"); - break; + return MSL_DATA_FLOAT;
case VKD3DSPR_IMMCONST: switch (reg->dimension) { case VSIR_DIMENSION_SCALAR: - switch (reg->data_type) - { - case VKD3D_DATA_INT: - vkd3d_string_buffer_printf(buffer, "as_type<int>(%#xu)", reg->u.immconst_u32[0]); - break; - case VKD3D_DATA_UINT: - vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); - break; - case VKD3D_DATA_FLOAT: - vkd3d_string_buffer_printf(buffer, "as_type<float>(%#xu)", reg->u.immconst_u32[0]); - break; - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled immconst datatype %#x.", reg->data_type); - vkd3d_string_buffer_printf(buffer, "<unrecognised immconst datatype %#x>", reg->data_type); - break; - } - break; + vkd3d_string_buffer_printf(buffer, "%#xu", reg->u.immconst_u32[0]); + return MSL_DATA_UINT;
case VSIR_DIMENSION_VEC4: - switch (reg->data_type) - { - case VKD3D_DATA_INT: - vkd3d_string_buffer_printf(buffer, "as_type<int4>(uint4(%#xu, %#xu, %#xu, %#xu))", - reg->u.immconst_u32[0], reg->u.immconst_u32[1], - reg->u.immconst_u32[2], reg->u.immconst_u32[3]); - break; - case VKD3D_DATA_UINT: - vkd3d_string_buffer_printf(buffer, "uint4(%#xu, %#xu, %#xu, %#xu)", - reg->u.immconst_u32[0], reg->u.immconst_u32[1], - reg->u.immconst_u32[2], reg->u.immconst_u32[3]); - break; - case VKD3D_DATA_FLOAT: - vkd3d_string_buffer_printf(buffer, "as_type<float4>(uint4(%#xu, %#xu, %#xu, %#xu))", - reg->u.immconst_u32[0], reg->u.immconst_u32[1], - reg->u.immconst_u32[2], reg->u.immconst_u32[3]); - break; - default: - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled immconst datatype %#x.", reg->data_type); - vkd3d_string_buffer_printf(buffer, "<unrecognised immconst datatype %#x>", reg->data_type); - break; - } - break; + vkd3d_string_buffer_printf(buffer, "uint4(%#xu, %#xu, %#xu, %#xu)", + reg->u.immconst_u32[0], reg->u.immconst_u32[1], + reg->u.immconst_u32[2], reg->u.immconst_u32[3]); + return MSL_DATA_UINT;
default: vkd3d_string_buffer_printf(buffer, "<unhandled_dimension %#x>", reg->dimension); msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled dimension %#x.", reg->dimension); - break; + return MSL_DATA_UINT; } - break;
case VKD3DSPR_CONSTBUFFER: - if (reg->idx_count != 3) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled constant buffer register index count %u.", reg->idx_count); - vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); - break; - } - if (reg->idx[0].rel_addr || reg->idx[2].rel_addr) { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled constant buffer register indirect addressing."); - vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); - break; + const struct vkd3d_shader_descriptor_binding *binding; + + if (reg->idx_count != 3) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register index count %u.", + reg->idx_count); + vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); + return MSL_DATA_UNION; + } + if (reg->idx[0].rel_addr || reg->idx[1].rel_addr || reg->idx[2].rel_addr) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled constant buffer register indirect addressing."); + vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); + return MSL_DATA_UNION; + } + if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "Cannot finding binding for CBV register %u.", reg->idx[0].offset); + vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); + return MSL_DATA_UNION; + } + msl_print_cbv_name(buffer, binding->binding); + vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset); + return MSL_DATA_UNION; } - vkd3d_string_buffer_printf(buffer, "descriptors.cb_%u[%u]", reg->idx[0].offset, reg->idx[2].offset); - msl_print_register_datatype(buffer, gen, reg->data_type); - break;
default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); vkd3d_string_buffer_printf(buffer, "<unrecognised register %#x>", reg->type); - break; + return MSL_DATA_UINT; } }
@@ -278,24 +417,64 @@ static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cach vkd3d_string_buffer_release(cache, src->str); }
-static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, - const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) +static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_generator *gen, const char *src, + enum vkd3d_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) +{ + bool write_cast = false; + + if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) + dst_data_type = VKD3D_DATA_FLOAT; + + switch (src_data_type) + { + case MSL_DATA_FLOAT: + write_cast = dst_data_type != VKD3D_DATA_FLOAT; + break; + + case MSL_DATA_UINT: + write_cast = dst_data_type != VKD3D_DATA_UINT; + break; + + case MSL_DATA_UNION: + break; + } + + if (write_cast) + { + vkd3d_string_buffer_printf(dst, "as_type<"); + msl_print_resource_datatype(gen, dst, dst_data_type); + vkd3d_string_buffer_printf(dst, "%s>(", dimension == VSIR_DIMENSION_VEC4 ? "4" : ""); + } + + vkd3d_string_buffer_printf(dst, "%s", src); + + if (write_cast) + vkd3d_string_buffer_printf(dst, ")"); + + if (src_data_type == MSL_DATA_UNION) + msl_print_register_datatype(dst, gen, dst_data_type); +} + +static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, + const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) { const struct vkd3d_shader_register *reg = &vsir_src->reg; - struct vkd3d_string_buffer *str; + struct vkd3d_string_buffer *register_name, *str; + enum msl_data_type src_data_type;
- msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); + register_name = vkd3d_string_buffer_get(&gen->string_buffers);
if (reg->non_uniform) msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled 'non-uniform' modifier.");
if (!vsir_src->modifiers) - str = msl_src->str; + str = buffer; else str = vkd3d_string_buffer_get(&gen->string_buffers);
- msl_print_register_name(str, gen, reg); + src_data_type = msl_print_register_name(register_name, gen, reg); + msl_print_bitcast(str, gen, register_name->buffer, data_type, src_data_type, reg->dimension); if (reg->dimension == VSIR_DIMENSION_VEC4) msl_print_swizzle(str, vsir_src->swizzle, mask);
@@ -304,23 +483,30 @@ static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, case VKD3DSPSM_NONE: break; case VKD3DSPSM_NEG: - vkd3d_string_buffer_printf(msl_src->str, "-%s", str->buffer); + vkd3d_string_buffer_printf(buffer, "-%s", str->buffer); break; case VKD3DSPSM_ABS: - vkd3d_string_buffer_printf(msl_src->str, "abs(%s)", str->buffer); + vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); break; default: - vkd3d_string_buffer_printf(msl_src->str, "<unhandled modifier %#x>(%s)", + vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)", vsir_src->modifiers, str->buffer); msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled source modifier(s) %#x.", vsir_src->modifiers); break; }
- if (str != msl_src->str) + if (str != buffer) vkd3d_string_buffer_release(&gen->string_buffers, str); }
+static void msl_src_init(struct msl_src *msl_src, struct msl_generator *gen, + const struct vkd3d_shader_src_param *vsir_src, uint32_t mask) +{ + msl_src->str = vkd3d_string_buffer_get(&gen->string_buffers); + msl_print_src_with_type(msl_src->str, gen, vsir_src, mask, vsir_src->reg.data_type); +} + static void msl_dst_cleanup(struct msl_dst *dst, struct vkd3d_string_buffer_cache *cache) { vkd3d_string_buffer_release(cache, dst->mask); @@ -331,6 +517,7 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_dst_param *vsir_dst) { uint32_t write_mask = vsir_dst->write_mask; + enum msl_data_type dst_data_type;
if (ins->flags & VKD3DSI_PRECISE_XYZW) msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -343,7 +530,9 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, msl_dst->register_name = vkd3d_string_buffer_get(&gen->string_buffers); msl_dst->mask = vkd3d_string_buffer_get(&gen->string_buffers);
- msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg); + dst_data_type = msl_print_register_name(msl_dst->register_name, gen, &vsir_dst->reg); + if (dst_data_type == MSL_DATA_UNION) + msl_print_register_datatype(msl_dst->mask, gen, vsir_dst->reg.data_type); if (vsir_dst->reg.dimension == VSIR_DIMENSION_VEC4) msl_print_write_mask(msl_dst->mask, write_mask);
@@ -530,6 +719,89 @@ static void msl_else(struct msl_generator *gen) msl_begin_block(gen); }
+static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + 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; + struct vkd3d_string_buffer *read; + enum vkd3d_data_type data_type; + uint32_t coord_mask; + struct msl_dst dst; + + if (vkd3d_shader_instruction_has_texel_offset(ins)) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled texel fetch offset."); + + if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Descriptor indexing is not supported."); + + resource_id = ins->src[1].reg.idx[0].offset; + resource_idx = ins->src[1].reg.idx[1].offset; + if ((descriptor = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) + { + resource_type = descriptor->resource_type; + resource_space = descriptor->register_space; + data_type = descriptor->resource_data_type; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + data_type = VKD3D_DATA_FLOAT; + } + + if ((resource_type_info = msl_get_resource_type_info(resource_type))) + { + coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); + coord_mask = vkd3d_write_mask_from_component_count(2); + } + + if (!(binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "Cannot finding binding for SRV register %u index %u space %u.", + resource_id, resource_idx, resource_space); + return; + } + + msl_dst_init(&dst, gen, ins, &ins->dst[0]); + read = vkd3d_string_buffer_get(&gen->string_buffers); + + vkd3d_string_buffer_printf(read, "as_type<uint4>("); + msl_print_srv_name(read, gen, binding->binding, resource_type_info, data_type); + vkd3d_string_buffer_printf(read, ".read("); + msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); + if (resource_type_info->array) + { + vkd3d_string_buffer_printf(read, ", "); + msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); + } + if (resource_type_info->lod) + { + vkd3d_string_buffer_printf(read, ", "); + msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); + } + vkd3d_string_buffer_printf(read, "))"); + msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); + + msl_print_assignment(gen, &dst, "%s", read->buffer); + + vkd3d_string_buffer_release(&gen->string_buffers, read); + msl_dst_cleanup(&dst, &gen->string_buffers); +} + static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) { struct msl_src src; @@ -671,6 +943,9 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d case VKD3DSIH_UTOF: msl_cast(gen, ins, "float"); break; + case VKD3DSIH_LD: + msl_ld(gen, ins); + break; case VKD3DSIH_LOG: msl_intrinsic(gen, ins, "log2"); break; @@ -716,144 +991,6 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d } }
-static bool msl_check_shader_visibility(const struct msl_generator *gen, - enum vkd3d_shader_visibility visibility) -{ - enum vkd3d_shader_type t = gen->program->shader_version.type; - - switch (visibility) - { - case VKD3D_SHADER_VISIBILITY_ALL: - return true; - case VKD3D_SHADER_VISIBILITY_VERTEX: - return t == VKD3D_SHADER_TYPE_VERTEX; - case VKD3D_SHADER_VISIBILITY_HULL: - return t == VKD3D_SHADER_TYPE_HULL; - case VKD3D_SHADER_VISIBILITY_DOMAIN: - return t == VKD3D_SHADER_TYPE_DOMAIN; - case VKD3D_SHADER_VISIBILITY_GEOMETRY: - return t == VKD3D_SHADER_TYPE_GEOMETRY; - case VKD3D_SHADER_VISIBILITY_PIXEL: - return t == VKD3D_SHADER_TYPE_PIXEL; - case VKD3D_SHADER_VISIBILITY_COMPUTE: - return t == VKD3D_SHADER_TYPE_COMPUTE; - default: - WARN("Invalid shader visibility %#x.\n", visibility); - return false; - } -} - -static bool msl_get_cbv_binding(const struct msl_generator *gen, - unsigned int register_space, unsigned int register_idx, unsigned int *binding_idx) -{ - const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; - const struct vkd3d_shader_resource_binding *binding; - unsigned int i; - - if (!interface_info) - return false; - - for (i = 0; i < interface_info->binding_count; ++i) - { - binding = &interface_info->bindings[i]; - - if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_CBV) - continue; - if (binding->register_space != register_space) - continue; - if (binding->register_index != register_idx) - continue; - if (!msl_check_shader_visibility(gen, binding->shader_visibility)) - continue; - if (!(binding->flags & VKD3D_SHADER_BINDING_FLAG_BUFFER)) - continue; - *binding_idx = i; - return true; - } - - return false; -} - -static void msl_generate_cbv_declaration(struct msl_generator *gen, - const struct vkd3d_shader_descriptor_info1 *cbv) -{ - const struct vkd3d_shader_descriptor_binding *binding; - struct vkd3d_string_buffer *buffer = gen->buffer; - unsigned int binding_idx; - size_t size; - - if (cbv->count != 1) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Constant buffer %u has unsupported descriptor array size %u.", cbv->register_id, cbv->count); - return; - } - - if (!msl_get_cbv_binding(gen, cbv->register_space, cbv->register_index, &binding_idx)) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "No descriptor binding specified for constant buffer %u.", cbv->register_id); - return; - } - - binding = &gen->interface_info->bindings[binding_idx].binding; - - if (binding->set != 0) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Unsupported binding set %u specified for constant buffer %u.", binding->set, cbv->register_id); - return; - } - - if (binding->count != 1) - { - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Unsupported binding count %u specified for constant buffer %u.", binding->count, cbv->register_id); - return; - } - - size = align(cbv->buffer_size, VKD3D_VEC4_SIZE * sizeof(uint32_t)); - size /= VKD3D_VEC4_SIZE * sizeof(uint32_t); - - vkd3d_string_buffer_printf(buffer, - "constant vkd3d_vec4 *cb_%u [[id(%u)]];", cbv->register_id, binding->binding); -}; - -static void msl_generate_descriptor_struct_declarations(struct msl_generator *gen) -{ - const struct vkd3d_shader_scan_descriptor_info1 *info = gen->descriptor_info; - const struct vkd3d_shader_descriptor_info1 *descriptor; - struct vkd3d_string_buffer *buffer = gen->buffer; - unsigned int i; - - if (!info->descriptor_count) - return; - - vkd3d_string_buffer_printf(buffer, "struct vkd3d_%s_descriptors\n{\n", gen->prefix); - - for (i = 0; i < info->descriptor_count; ++i) - { - descriptor = &info->descriptors[i]; - - msl_print_indent(buffer, 1); - switch (descriptor->type) - { - case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: - msl_generate_cbv_declaration(gen, descriptor); - break; - - default: - vkd3d_string_buffer_printf(buffer, "/* <unhandled descriptor type %#x> */", descriptor->type); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled descriptor type %#x.", descriptor->type); - break; - } - vkd3d_string_buffer_printf(buffer, "\n"); - } - - vkd3d_string_buffer_printf(buffer, "};\n\n"); -} - static void msl_generate_input_struct_declarations(struct msl_generator *gen) { const struct shader_signature *signature = &gen->program->input_signature; @@ -1171,12 +1308,12 @@ static void msl_generate_entrypoint(struct msl_generator *gen)
vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix);
- if (gen->descriptor_info->descriptor_count) + if (gen->program->descriptors.descriptor_count) { msl_print_indent(gen->buffer, 2); /* TODO: Configurable argument buffer binding location. */ vkd3d_string_buffer_printf(gen->buffer, - "constant vkd3d_%s_descriptors& descriptors [[buffer(0)]],\n", gen->prefix); + "constant descriptor *descriptors [[buffer(0)]],\n"); }
msl_print_indent(gen->buffer, 2); @@ -1195,7 +1332,7 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix); if (gen->write_depth) vkd3d_string_buffer_printf(gen->buffer, ", shader_out_depth"); - if (gen->descriptor_info->descriptor_count) + if (gen->program->descriptors.descriptor_count) vkd3d_string_buffer_printf(gen->buffer, ", descriptors"); vkd3d_string_buffer_printf(gen->buffer, ");\n");
@@ -1212,7 +1349,8 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n");
vkd3d_string_buffer_printf(gen->buffer, "/* Generated by %s. */\n\n", vkd3d_shader_get_version(NULL, NULL)); - vkd3d_string_buffer_printf(gen->buffer, "#include <metal_common>\n\n"); + vkd3d_string_buffer_printf(gen->buffer, "#include <metal_common>\n"); + vkd3d_string_buffer_printf(gen->buffer, "#include <metal_texture>\n\n"); vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n");
if (gen->program->global_flags) @@ -1224,7 +1362,28 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n"); vkd3d_string_buffer_printf(gen->buffer, " float4 f;\n};\n\n");
- msl_generate_descriptor_struct_declarations(gen); + if (gen->program->descriptors.descriptor_count > 0) + { + vkd3d_string_buffer_printf(gen->buffer, + "struct descriptor\n" + "{\n" + " const device void *ptr;\n" + "\n" + " template<typename T>\n" + " constant T &tex() constant\n" + " {\n" + " return reinterpret_cast<constant T &>(this->ptr);\n" + " }\n" + "\n" + " template<typename T>\n" + " const device T * constant &buf() constant\n" + " {\n" + " return reinterpret_cast<const device T * constant &>(this->ptr);\n" + " }\n" + "};\n" + "\n"); + } + msl_generate_input_struct_declarations(gen); msl_generate_output_struct_declarations(gen);
@@ -1234,8 +1393,8 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader gen->prefix); if (gen->write_depth) vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); - if (gen->descriptor_info->descriptor_count) - vkd3d_string_buffer_printf(gen->buffer, ", constant vkd3d_%s_descriptors& descriptors", gen->prefix); + if (gen->program->descriptors.descriptor_count) + vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); vkd3d_string_buffer_printf(gen->buffer, ")\n{\n");
++gen->indent; @@ -1276,7 +1435,6 @@ static void msl_generator_cleanup(struct msl_generator *gen)
static int msl_generator_init(struct msl_generator *gen, struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, struct vkd3d_shader_message_context *message_context) { enum vkd3d_shader_type type = program->shader_version.type; @@ -1294,16 +1452,14 @@ static int msl_generator_init(struct msl_generator *gen, struct vsir_program *pr { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled shader type %#x.", type); - return VKD3D_ERROR_INVALID_SHADER; + gen->prefix = "unknown"; } gen->interface_info = vkd3d_find_struct(compile_info->next, INTERFACE_INFO); - gen->descriptor_info = descriptor_info;
return VKD3D_OK; }
int msl_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { @@ -1314,8 +1470,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, return ret;
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info);
- if ((ret = msl_generator_init(&generator, program, compile_info, descriptor_info, message_context)) < 0) + if ((ret = msl_generator_init(&generator, program, compile_info, message_context)) < 0) return ret; ret = msl_generator_generate(&generator, out); msl_generator_cleanup(&generator); diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.y b/libs/vkd3d/libs/vkd3d-shader/preproc.y index c6be17bd230..95987831faa 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.y +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.y @@ -178,6 +178,16 @@ static int default_open_include(const char *filename, bool local, if (S_ISREG(st.st_mode)) size = st.st_size;
+ if (!size) + { + fclose(f); + + out->code = NULL; + out->size = 0; + + return VKD3D_OK; + } + if (!(data = vkd3d_malloc(size))) { fclose(f); diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index db7ebab742d..1f967c22406 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -18,6 +18,7 @@ */
#include "vkd3d_shader_private.h" +#include "spirv_grammar.h" #include "wine/rbtree.h"
#include <stdarg.h> @@ -37,7 +38,7 @@ #define VKD3D_SPIRV_VERSION_1_0 0x00010000 #define VKD3D_SPIRV_VERSION_1_3 0x00010300 #define VKD3D_SPIRV_GENERATOR_ID 18 -#define VKD3D_SPIRV_GENERATOR_VERSION 15 +#define VKD3D_SPIRV_GENERATOR_VERSION 16 #define VKD3D_SPIRV_GENERATOR_MAGIC vkd3d_make_u32(VKD3D_SPIRV_GENERATOR_VERSION, VKD3D_SPIRV_GENERATOR_ID) #ifndef VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER # define VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER 0 @@ -60,6 +61,8 @@ #define VKD3D_SPIRV_INSTRUCTION_OP_SHIFT 0u #define VKD3D_SPIRV_INSTRUCTION_OP_MASK (0xffffu << VKD3D_SPIRV_INSTRUCTION_OP_SHIFT)
+#define VKD3D_SPIRV_INDENT 15 + #ifdef HAVE_SPIRV_TOOLS # include "spirv-tools/libspirv.h"
@@ -211,6 +214,10 @@ struct spirv_colours { const char *reset; const char *comment; + const char *literal; + const char *enumerant; + const char *opcode; + const char *id; };
struct spirv_parser @@ -240,6 +247,16 @@ static void VKD3D_PRINTF_FUNC(3, 4) spirv_parser_error(struct spirv_parser *pars parser->failed = true; }
+static void VKD3D_PRINTF_FUNC(3, 4) spirv_parser_warning(struct spirv_parser *parser, + enum vkd3d_shader_error error, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vkd3d_shader_vwarning(parser->message_context, &parser->location, error, format, args); + va_end(args); +} + static uint32_t spirv_parser_read_u32(struct spirv_parser *parser) { if (parser->pos >= parser->size) @@ -290,6 +307,91 @@ static void spirv_parser_print_generator(struct spirv_parser *parser, uint32_t m spirv_parser_print_comment(parser, "Generator: Unknown (%#x); %u", id, version); }
+static void spirv_parser_print_immediate_word(struct spirv_parser *parser, + struct vkd3d_string_buffer *buffer, const char *prefix, uint32_t w, const char *suffix) +{ + vkd3d_string_buffer_printf(buffer, "%s!%s0x%08x%s%s", + prefix, parser->colours.literal, w, parser->colours.reset, suffix); +} + +static void spirv_parser_print_id(struct spirv_parser *parser, + struct vkd3d_string_buffer *buffer, const char *prefix, uint32_t id, const char *suffix) +{ + vkd3d_string_buffer_printf(buffer, "%s%%%s%u%s%s", + prefix, parser->colours.id, id, parser->colours.reset, suffix); +} + +static void spirv_parser_print_uint_literal(struct spirv_parser *parser, + struct vkd3d_string_buffer *buffer, const char *prefix, uint32_t i, const char *suffix) +{ + vkd3d_string_buffer_printf(buffer, "%s%s%u%s%s", + prefix, parser->colours.literal, i, parser->colours.reset, suffix); +} + +static void spirv_parser_print_enumerant(struct spirv_parser *parser, + struct vkd3d_string_buffer *buffer, const char *prefix, const char *name, const char *suffix) +{ + vkd3d_string_buffer_printf(buffer, "%s%s%s%s%s", + prefix, parser->colours.enumerant, name, parser->colours.reset, suffix); +} + +static void spirv_parser_print_opcode(struct spirv_parser *parser, + struct vkd3d_string_buffer *buffer, const char *name) +{ + vkd3d_string_buffer_printf(buffer, "%s%s%s", parser->colours.opcode, name, parser->colours.reset); +} + +static void spirv_parser_print_instruction_offset(struct spirv_parser *parser, + struct vkd3d_string_buffer *buffer, const char *prefix, size_t offset, const char *suffix) +{ + vkd3d_string_buffer_printf(parser->text, "%s%s; 0x%08zx%s%s", prefix, + parser->colours.comment, offset * sizeof(uint32_t), parser->colours.reset, suffix); +} + +static void spirv_parser_print_string_literal(struct spirv_parser *parser, struct vkd3d_string_buffer *buffer, + const char *prefix, const char *s, size_t len, const char *suffix) +{ + vkd3d_string_buffer_printf(buffer, "%s"%s", prefix, parser->colours.literal); + vkd3d_string_buffer_print_string_escaped(buffer, s, len); + vkd3d_string_buffer_printf(buffer, "%s"%s", parser->colours.reset, suffix); +} + +static const struct spirv_parser_enumerant *spirv_parser_get_enumerant( + const struct spirv_parser_operand_type_info *info, uint32_t value) +{ + const struct spirv_parser_enumerant *e; + size_t i; + + for (i = 0; i < info->enumerant_count; ++i) + { + if ((e = &info->enumerants[i])->value == value) + return e; + } + + return NULL; +} + +static const struct spirv_parser_operand_type_info *spirv_parser_get_operand_type_info(enum spirv_parser_operand_type t) +{ + if (t >= ARRAY_SIZE(spirv_parser_operand_type_info)) + return NULL; + return &spirv_parser_operand_type_info[t]; +} + +static int spirv_parser_opcode_info_compare(const void *key, const void *element) +{ + const struct spirv_parser_opcode_info *e = element; + const uint16_t *op = key; + + return vkd3d_u32_compare(*op, e->op); +} + +static const struct spirv_parser_opcode_info *spirv_parser_get_opcode_info(uint16_t op) +{ + return bsearch(&op, spirv_parser_opcode_info, ARRAY_SIZE(spirv_parser_opcode_info), + sizeof(*spirv_parser_opcode_info), spirv_parser_opcode_info_compare); +} + static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser) { uint32_t magic, version, generator, bound, schema; @@ -324,7 +426,7 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser)
major = (version & VKD3D_SPIRV_VERSION_MAJOR_MASK) >> VKD3D_SPIRV_VERSION_MAJOR_SHIFT; minor = (version & VKD3D_SPIRV_VERSION_MINOR_MASK) >> VKD3D_SPIRV_VERSION_MINOR_SHIFT; - if (major != 1 || minor > 0) + if (major != 1 || minor > 6) { spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unable to parse SPIR-V version %u.%u.", major, minor); @@ -357,36 +459,260 @@ static enum vkd3d_result spirv_parser_read_header(struct spirv_parser *parser) return VKD3D_OK; }
+static bool spirv_parser_parse_string_literal(struct spirv_parser *parser, + struct vkd3d_string_buffer *buffer, size_t end) +{ + const char *s = (const char *)&parser->code[parser->pos]; + size_t len, max_len; + + max_len = (end - parser->pos) * sizeof(uint32_t); + len = strnlen(s, max_len); + if (len == max_len) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Insufficient words remaining while parsing string literal."); + return false; + } + + spirv_parser_print_string_literal(parser, buffer, " ", s, len, ""); + parser->pos += (len / sizeof(uint32_t)) + 1; + + return true; +} + +static uint32_t lowest_set(uint32_t v) +{ + return v & -v; +} + +static bool spirv_parser_parse_operand(struct spirv_parser *parser, struct vkd3d_string_buffer *buffer, + const char *opcode_name, enum spirv_parser_operand_type type, size_t end, uint32_t *result_id) +{ + const struct spirv_parser_operand_type_info *info; + const struct spirv_parser_enumerant *e; + uint32_t word, tmp, v, i, j; + + if (parser->pos >= end) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Insufficient words remaining while parsing operands for instruction "%s".", opcode_name); + return false; + } + + if (!(info = spirv_parser_get_operand_type_info(type))) + { + ERR("Invalid operand type %#x.\n", type); + return false; + } + + if (info->category == SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM) + { + if (!(word = spirv_parser_read_u32(parser))) + { + if (!(e = spirv_parser_get_enumerant(info, word))) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled enumeration value %#x.", word); + return false; + } + spirv_parser_print_enumerant(parser, buffer, " ", e->name, ""); + + for (j = 0; j < e->parameter_count; ++j) + { + if (!spirv_parser_parse_operand(parser, buffer, opcode_name, e->parameters[j], end, result_id)) + return false; + } + + return true; + } + + for (i = 0, tmp = word; tmp; ++i, tmp ^= v) + { + v = lowest_set(tmp); + if (!(e = spirv_parser_get_enumerant(info, v))) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled enumeration value %#x.", v); + return false; + } + spirv_parser_print_enumerant(parser, buffer, i ? " | " : " ", e->name, ""); + } + + for (i = 0, tmp = word; tmp; ++i, tmp ^= v) + { + v = lowest_set(tmp); + if (!(e = spirv_parser_get_enumerant(info, v))) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled enumeration value %#x.", v); + return false; + } + + for (j = 0; j < e->parameter_count; ++j) + { + if (!spirv_parser_parse_operand(parser, buffer, opcode_name, e->parameters[j], end, result_id)) + return false; + } + } + + return true; + } + + if (info->category == SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM) + { + word = spirv_parser_read_u32(parser); + if (!(e = spirv_parser_get_enumerant(info, word))) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled "%s" enumeration value %#x.", info->name, word); + return false; + } + spirv_parser_print_enumerant(parser, buffer, " ", e->name, ""); + + for (i = 0; i < e->parameter_count; ++i) + { + if (!spirv_parser_parse_operand(parser, buffer, opcode_name, e->parameters[i], end, result_id)) + return false; + } + + return true; + } + + switch (type) + { + case SPIRV_PARSER_OPERAND_TYPE_ID_REF: + case SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE: + spirv_parser_print_id(parser, buffer, " ", spirv_parser_read_u32(parser), ""); + return true; + + case SPIRV_PARSER_OPERAND_TYPE_ID_RESULT: + if (*result_id) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Instruction has multiple results."); + return false; + } + *result_id = spirv_parser_read_u32(parser); + return true; + + case SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER: + spirv_parser_print_uint_literal(parser, buffer, " ", spirv_parser_read_u32(parser), ""); + return true; + + case SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING: + return spirv_parser_parse_string_literal(parser, buffer, end); + + default: + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled operand type "%s".", info->name); + return false; + } +} + +static void spirv_parser_parse_raw_instruction(struct spirv_parser *parser, uint16_t count) +{ + size_t pos = parser->pos; + size_t i; + + if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT) + vkd3d_string_buffer_printf(parser->text, "%*s", VKD3D_SPIRV_INDENT, ""); + for (i = 0; i < count; ++i) + { + spirv_parser_print_immediate_word(parser, parser->text, i ? " " : "", spirv_parser_read_u32(parser), ""); + } + if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS) + spirv_parser_print_instruction_offset(parser, parser->text, " ", pos, ""); + vkd3d_string_buffer_printf(parser->text, "\n"); +} + static enum vkd3d_result spirv_parser_parse_instruction(struct spirv_parser *parser) { - struct vkd3d_string_buffer *buffer; - uint16_t op, count; - unsigned int i; - uint32_t word; + const struct spirv_parser_instruction_operand *operand; + struct vkd3d_string_buffer *operands, *result_name; + const struct spirv_parser_opcode_info *info; + uint32_t result_id, word; + uint16_t op, count, rem; + size_t end, pos, i;
+ pos = parser->pos; word = spirv_parser_read_u32(parser); count = (word & VKD3D_SPIRV_INSTRUCTION_WORD_COUNT_MASK) >> VKD3D_SPIRV_INSTRUCTION_WORD_COUNT_SHIFT; op = (word & VKD3D_SPIRV_INSTRUCTION_OP_MASK) >> VKD3D_SPIRV_INSTRUCTION_OP_SHIFT;
- if (!count) + if (!count || count > parser->size - pos) { spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_INVALID_SHADER, "Invalid word count %u.", count); return VKD3D_ERROR_INVALID_SHADER; }
- --count; - buffer = vkd3d_string_buffer_get(&parser->string_buffers); - for (i = 0; i < count; ++i) + if (!(info = spirv_parser_get_opcode_info(op))) { - word = spirv_parser_read_u32(parser); - vkd3d_string_buffer_printf(buffer, " 0x%08x", word); + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unrecognised instruction %#x.", op); + goto raw; } - spirv_parser_print_comment(parser, "<unrecognised instruction %#x>%s", op, buffer->buffer); - vkd3d_string_buffer_release(&parser->string_buffers, buffer);
- spirv_parser_error(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, - "Unrecognised instruction %#x.", op); + operands = vkd3d_string_buffer_get(&parser->string_buffers); + + result_id = 0; + for (i = 0, end = pos + count; i < info->operand_count; ++i) + { + operand = &info->operands[i]; + + do + { + if (parser->pos >= end && (operand->quantifier == '?' || operand->quantifier == '*')) + break; + + if (!spirv_parser_parse_operand(parser, operands, info->name, operand->type, end, &result_id)) + { + vkd3d_string_buffer_release(&parser->string_buffers, operands); + goto raw; + } + } while (operand->quantifier == '*' && parser->pos < end); + } + + if ((rem = end - parser->pos)) + { + spirv_parser_warning(parser, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "%u word(s) remaining after parsing all operands for instruction "%s"", rem, info->name); + for (i = 0; i < rem; ++i) + { + spirv_parser_print_immediate_word(parser, operands, " ", spirv_parser_read_u32(parser), ""); + } + } + + if (result_id) + { + int max_indent = 0; + + if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT) + max_indent = VKD3D_SPIRV_INDENT - 4; + result_name = vkd3d_string_buffer_get(&parser->string_buffers); + vkd3d_string_buffer_printf(result_name, "%u", result_id); + vkd3d_string_buffer_printf(parser->text, "%*s%%%s%s%s = ", + result_name->content_size > max_indent ? 0 : max_indent - (int)result_name->content_size, "", + parser->colours.id, result_name->buffer, parser->colours.reset); + vkd3d_string_buffer_release(&parser->string_buffers, result_name); + } + else if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT) + { + vkd3d_string_buffer_printf(parser->text, "%*s", VKD3D_SPIRV_INDENT, ""); + } + spirv_parser_print_opcode(parser, parser->text, info->name); + vkd3d_string_buffer_printf(parser->text, "%s", operands->buffer); + if (parser->formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_OFFSETS) + spirv_parser_print_instruction_offset(parser, parser->text, " ", pos, ""); + vkd3d_string_buffer_printf(parser->text, "\n"); + + vkd3d_string_buffer_release(&parser->string_buffers, operands); + + return VKD3D_OK; + +raw: + parser->pos = pos; + spirv_parser_parse_raw_instruction(parser, count);
return VKD3D_OK; } @@ -441,11 +767,19 @@ static enum vkd3d_result spirv_parser_init(struct spirv_parser *parser, const st { .reset = "", .comment = "", + .literal = "", + .enumerant = "", + .opcode = "", + .id = "", }; static const struct spirv_colours colours = { .reset = "\x1b[m", .comment = "\x1b[36m", + .literal = "\x1b[95m", + .enumerant = "\x1b[93m", + .opcode = "\x1b[96;1m", + .id = "\x1b[96m", };
memset(parser, 0, sizeof(*parser)); @@ -829,16 +1163,16 @@ static unsigned int vkd3d_spirv_string_word_count(const char *str) static void vkd3d_spirv_build_string(struct vkd3d_spirv_stream *stream, const char *str, unsigned int word_count) { - unsigned int word_idx, i; - const char *ptr = str; + uint32_t *ptr;
- for (word_idx = 0; word_idx < word_count; ++word_idx) - { - uint32_t word = 0; - for (i = 0; i < sizeof(uint32_t) && *ptr; ++i) - word |= (uint32_t)*ptr++ << (8 * i); - vkd3d_spirv_build_word(stream, word); - } + if (!vkd3d_array_reserve((void **)&stream->words, &stream->capacity, + stream->word_count + word_count, sizeof(*stream->words))) + return; + + ptr = &stream->words[stream->word_count]; + ptr[word_count - 1] = 0; + memcpy(ptr, str, strlen(str)); + stream->word_count += word_count; }
typedef uint32_t (*vkd3d_spirv_build_pfn)(struct vkd3d_spirv_builder *builder); @@ -2757,9 +3091,6 @@ struct spirv_compiler } *spirv_parameter_info;
bool prolog_emitted; - struct shader_signature input_signature; - struct shader_signature output_signature; - struct shader_signature patch_constant_signature; const struct vkd3d_shader_transform_feedback_info *xfb_info; struct vkd3d_shader_output_info { @@ -2774,7 +3105,6 @@ struct spirv_compiler
uint32_t binding_idx;
- const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info; unsigned int input_control_point_count; unsigned int output_control_point_count;
@@ -2852,10 +3182,6 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler)
vkd3d_string_buffer_cache_cleanup(&compiler->string_buffers);
- shader_signature_cleanup(&compiler->input_signature); - shader_signature_cleanup(&compiler->output_signature); - shader_signature_cleanup(&compiler->patch_constant_signature); - vkd3d_free(compiler->ssa_register_info); vkd3d_free(compiler->block_label_ids);
@@ -2864,7 +3190,6 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler)
static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, - const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, struct vkd3d_shader_message_context *message_context, uint64_t config_flags) { const struct vkd3d_shader_interface_info *shader_interface; @@ -2880,6 +3205,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p compiler->message_context = message_context; compiler->location.source_name = compile_info->source_name; compiler->config_flags = config_flags; + compiler->program = program;
if ((target_info = vkd3d_find_struct(compile_info->next, SPIRV_TARGET_INFO))) { @@ -3006,8 +3332,6 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p else if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY) compiler->emit_point_size = compiler->xfb_info && compiler->xfb_info->element_count;
- compiler->scan_descriptor_info = scan_descriptor_info; - compiler->phase = VKD3DSIH_INVALID;
vkd3d_string_buffer_cache_init(&compiler->string_buffers); @@ -3375,7 +3699,8 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, "Vectors of bool type are not supported."); return vkd3d_spirv_get_op_undef(builder, type_id); default: - FIXME("Unhandled component_type %#x.\n", component_type); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_TYPE, + "Unhandled component_type %#x.", component_type); return vkd3d_spirv_get_op_undef(builder, type_id); }
@@ -5450,7 +5775,7 @@ static unsigned int shader_signature_next_location(const struct shader_signature return max_row; }
-static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, +static void spirv_compiler_emit_input(struct spirv_compiler *compiler, enum vkd3d_shader_register_type reg_type, unsigned int element_idx) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -5461,17 +5786,15 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, const struct vkd3d_spirv_builtin *builtin; enum vkd3d_shader_sysval_semantic sysval; uint32_t write_mask, reg_write_mask; - struct vkd3d_symbol *symbol = NULL; uint32_t val_id, input_id, var_id; uint32_t type_id, float_type_id; struct vkd3d_symbol reg_symbol; SpvStorageClass storage_class; - struct rb_entry *entry = NULL; bool use_private_var = false; unsigned int array_sizes[2];
shader_signature = reg_type == VKD3DSPR_PATCHCONST - ? &compiler->patch_constant_signature : &compiler->input_signature; + ? &compiler->program->patch_constant_signature : &compiler->program->input_signature;
signature_element = &shader_signature->elements[element_idx]; sysval = signature_element->sysval_semantic; @@ -5481,6 +5804,9 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, if (compiler->shader_type == VKD3D_SHADER_TYPE_DOMAIN && reg_type != VKD3DSPR_PATCHCONST) sysval = VKD3D_SHADER_SV_NONE;
+ if (!signature_element->used_mask) + return; + builtin = get_spirv_builtin_for_sysval(compiler, sysval);
array_sizes[0] = signature_element->register_count; @@ -5521,7 +5847,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
vkd3d_symbol_make_io(®_symbol, reg_type, element_idx);
- if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) + if (rb_get(&compiler->symbol_table, ®_symbol)) { /* Except for vicp there should be one declaration per signature element. Sources of * duplicate declarations are: a single register split into multiple declarations having @@ -5529,8 +5855,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, * being repeated in another (i.e. vcp/vocp), which should have been deleted. */ if (reg_type != VKD3DSPR_INPUT || !is_in_fork_or_join_phase(compiler)) FIXME("Duplicate input definition found.\n"); - symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); - return symbol->id; + return; }
if (builtin) @@ -5549,7 +5874,7 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler, if (reg_type == VKD3DSPR_PATCHCONST) { vkd3d_spirv_build_op_decorate(builder, input_id, SpvDecorationPatch, NULL, 0); - location += shader_signature_next_location(&compiler->input_signature); + location += shader_signature_next_location(&compiler->program->input_signature); } vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationLocation, location); if (component_idx) @@ -5602,8 +5927,6 @@ static uint32_t spirv_compiler_emit_input(struct spirv_compiler *compiler,
spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask, val_id); } - - return input_id; }
static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler, @@ -5683,7 +6006,7 @@ static void calculate_clip_or_cull_distance_mask(const struct signature_element /* Emits arrayed SPIR-V built-in variables. */ static void spirv_compiler_emit_shader_signature_outputs(struct spirv_compiler *compiler) { - const struct shader_signature *output_signature = &compiler->output_signature; + const struct shader_signature *output_signature = &compiler->program->output_signature; uint32_t clip_distance_mask = 0, clip_distance_id = 0; uint32_t cull_distance_mask = 0, cull_distance_id = 0; const struct vkd3d_spirv_builtin *builtin; @@ -5793,7 +6116,8 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler,
is_patch_constant = (reg_type == VKD3DSPR_PATCHCONST);
- shader_signature = is_patch_constant ? &compiler->patch_constant_signature : &compiler->output_signature; + shader_signature = is_patch_constant ? &compiler->program->patch_constant_signature + : &compiler->program->output_signature;
signature_element = &shader_signature->elements[element_idx]; sysval = signature_element->sysval_semantic; @@ -5867,7 +6191,7 @@ static void spirv_compiler_emit_output(struct spirv_compiler *compiler, unsigned int location = signature_element->target_location;
if (is_patch_constant) - location += shader_signature_next_location(&compiler->output_signature); + location += shader_signature_next_location(&compiler->program->output_signature); else if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL && signature_element->sysval_semantic == VKD3D_SHADER_SV_TARGET) location = signature_element->semantic_index; @@ -6057,7 +6381,8 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler *
is_patch_constant = is_in_fork_or_join_phase(compiler);
- signature = is_patch_constant ? &compiler->patch_constant_signature : &compiler->output_signature; + signature = is_patch_constant ? &compiler->program->patch_constant_signature + : &compiler->program->output_signature;
function_id = compiler->epilogue_function_id;
@@ -6401,7 +6726,7 @@ static const struct vkd3d_shader_descriptor_info1 *spirv_compiler_get_descriptor struct spirv_compiler *compiler, enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register_range *range) { - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info = compiler->scan_descriptor_info; + const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info = &compiler->program->descriptors; unsigned int register_last = (range->last == ~0u) ? range->first : range->last; const struct vkd3d_shader_descriptor_info1 *d; unsigned int i; @@ -6797,7 +7122,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp return; }
- sampled_type = vkd3d_component_type_from_resource_data_type(descriptor->resource_data_type); + sampled_type = vkd3d_component_type_from_data_type(descriptor->resource_data_type);
if (!is_uav && spirv_compiler_has_combined_sampler_for_resource(compiler, range)) { @@ -6904,6 +7229,13 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler const SpvStorageClass storage_class = SpvStorageClassWorkgroup; struct vkd3d_symbol reg_symbol;
+ if (zero_init && !(compiler->features & VKD3D_SHADER_COMPILE_OPTION_FEATURE_ZERO_INITIALIZE_WORKGROUP_MEMORY)) + { + WARN("Unsupported zero-initialized workgroup memory.\n"); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_UNSUPPORTED_FEATURE, + "The target environment does not support zero-initialized workgroup memory."); + } + /* Alignment is supported only in the Kernel execution model. */ if (alignment) TRACE("Ignoring alignment %u.\n", alignment); @@ -10772,20 +11104,20 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) { struct vkd3d_shader_dst_param dst;
- for (unsigned int i = 0; i < compiler->input_signature.element_count; ++i) + for (unsigned int i = 0; i < compiler->program->input_signature.element_count; ++i) spirv_compiler_emit_input(compiler, VKD3DSPR_INPUT, i);
- for (unsigned int i = 0; i < compiler->output_signature.element_count; ++i) + for (unsigned int i = 0; i < compiler->program->output_signature.element_count; ++i) { /* PS outputs other than TARGET have dedicated registers and therefore * go through spirv_compiler_emit_dcl_output() for now. */ if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL - && compiler->output_signature.elements[i].sysval_semantic != VKD3D_SHADER_SV_TARGET) + && compiler->program->output_signature.elements[i].sysval_semantic != VKD3D_SHADER_SV_TARGET) continue; spirv_compiler_emit_output(compiler, VKD3DSPR_OUTPUT, i); }
- for (unsigned int i = 0; i < compiler->patch_constant_signature.element_count; ++i) + for (unsigned int i = 0; i < compiler->program->patch_constant_signature.element_count; ++i) { if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) spirv_compiler_emit_output(compiler, VKD3DSPR_PATCHCONST, i); @@ -10821,11 +11153,12 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *compiler) { + const struct vkd3d_shader_scan_descriptor_info1 *descriptors = &compiler->program->descriptors; unsigned int i;
- for (i = 0; i < compiler->scan_descriptor_info->descriptor_count; ++i) + for (i = 0; i < descriptors->descriptor_count; ++i) { - const struct vkd3d_shader_descriptor_info1 *descriptor = &compiler->scan_descriptor_info->descriptors[i]; + const struct vkd3d_shader_descriptor_info1 *descriptor = &descriptors->descriptors[i]; struct vkd3d_shader_register_range range;
range.first = descriptor->register_index; @@ -10856,23 +11189,18 @@ static void spirv_compiler_emit_descriptor_declarations(struct spirv_compiler *c } }
-static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct vsir_program *program, +static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *spirv) { const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vsir_program *program = compiler->program; struct vkd3d_shader_instruction_array instructions; enum vkd3d_shader_spirv_environment environment; enum vkd3d_result result = VKD3D_OK; unsigned int i, max_element_count;
- if ((result = vsir_program_transform(program, compiler->config_flags, - compile_info, compiler->message_context)) < 0) - return result; - - VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); - max_element_count = max(program->output_signature.element_count, program->patch_constant_signature.element_count); if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info)))) return VKD3D_ERROR_OUT_OF_MEMORY; @@ -10919,17 +11247,8 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count)) return VKD3D_ERROR_OUT_OF_MEMORY;
- compiler->program = program; - instructions = program->instructions; - memset(&program->instructions, 0, sizeof(program->instructions)); - - compiler->input_signature = program->input_signature; - compiler->output_signature = program->output_signature; - compiler->patch_constant_signature = program->patch_constant_signature; - memset(&program->input_signature, 0, sizeof(program->input_signature)); - memset(&program->output_signature, 0, sizeof(program->output_signature)); - memset(&program->patch_constant_signature, 0, sizeof(program->patch_constant_signature)); + compiler->use_vocp = program->use_vocp; compiler->block_names = program->block_names; compiler->block_name_count = program->block_name_count; @@ -10949,8 +11268,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct result = spirv_compiler_handle_instruction(compiler, &instructions.elements[i]); }
- shader_instruction_array_destroy(&instructions); - if (result < 0) return result;
@@ -11032,21 +11349,26 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, struct }
int spirv_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { struct spirv_compiler *spirv_compiler; int ret;
+ if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) + return ret; + + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); + VKD3D_ASSERT(program->has_descriptor_info); + if (!(spirv_compiler = spirv_compiler_create(program, compile_info, - scan_descriptor_info, message_context, config_flags))) + message_context, config_flags))) { ERR("Failed to create SPIR-V compiler.\n"); return VKD3D_ERROR; }
- ret = spirv_compiler_generate_spirv(spirv_compiler, program, compile_info, out); + ret = spirv_compiler_generate_spirv(spirv_compiler, compile_info, out);
spirv_compiler_destroy(spirv_compiler); return ret; diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 82302aac666..29b03871e05 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -714,6 +714,22 @@ input_primitive_type_table[] = [VKD3D_SM4_INPUT_PT_TRIANGLEADJ] = {6, VKD3D_PT_TRIANGLELIST_ADJ}, };
+static const enum vkd3d_sm4_input_primitive_type sm4_input_primitive_type_table[] = +{ + [VKD3D_PT_POINTLIST] = VKD3D_SM4_INPUT_PT_POINT, + [VKD3D_PT_LINELIST] = VKD3D_SM4_INPUT_PT_LINE, + [VKD3D_PT_TRIANGLELIST] = VKD3D_SM4_INPUT_PT_TRIANGLE, + [VKD3D_PT_LINELIST_ADJ] = VKD3D_SM4_INPUT_PT_LINEADJ, + [VKD3D_PT_TRIANGLELIST_ADJ] = VKD3D_SM4_INPUT_PT_TRIANGLEADJ, +}; + +static const enum vkd3d_sm4_output_primitive_type sm4_output_primitive_type_table[] = +{ + [VKD3D_PT_POINTLIST] = VKD3D_SM4_OUTPUT_PT_POINTLIST, + [VKD3D_PT_LINESTRIP] = VKD3D_SM4_OUTPUT_PT_LINESTRIP, + [VKD3D_PT_TRIANGLESTRIP] = VKD3D_SM4_OUTPUT_PT_TRIANGLESTRIP, +}; + static const enum vkd3d_shader_resource_type resource_type_table[] = { /* 0 */ VKD3D_SHADER_RESOURCE_NONE, @@ -1051,7 +1067,8 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins register_idx, register_count, write_mask, e->sysval_semantic); return; } - if ((io_masks[register_idx + i] & write_mask) != write_mask) + if ((io_masks[register_idx + i] & write_mask) != write_mask + && (io_masks[register_idx + i] & write_mask) != 0) { WARN("No matching declaration for index range base %u, count %u, mask %#x.\n", register_idx, register_count, write_mask); @@ -1076,6 +1093,8 @@ 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; }
static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -1103,6 +1122,8 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction
if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED) FIXME("Unhandled input primitive type %#x.\n", primitive_type); + + program->input_primitive = ins->declaration.primitive_type.type; }
static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -1113,6 +1134,8 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i ins->declaration.count = *tokens; if (opcode == VKD3D_SM4_OP_DCL_TEMPS) program->temp_count = max(program->temp_count, *tokens); + else if (opcode == VKD3D_SM4_OP_DCL_VERTICES_OUT) + program->vertices_out_count = *tokens; }
static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -1720,7 +1743,7 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) {VKD3D_SM5_RT_LOCAL_THREAD_ID, VKD3DSPR_LOCALTHREADID, VKD3D_SM4_SWIZZLE_VEC4}, {VKD3D_SM5_RT_COVERAGE, VKD3DSPR_COVERAGE, VKD3D_SM4_SWIZZLE_VEC4}, {VKD3D_SM5_RT_LOCAL_THREAD_INDEX, VKD3DSPR_LOCALTHREADINDEX,VKD3D_SM4_SWIZZLE_VEC4}, - {VKD3D_SM5_RT_GS_INSTANCE_ID, VKD3DSPR_GSINSTID, VKD3D_SM4_SWIZZLE_VEC4}, + {VKD3D_SM5_RT_GS_INSTANCE_ID, VKD3DSPR_GSINSTID, VKD3D_SM4_SWIZZLE_SCALAR}, {VKD3D_SM5_RT_DEPTHOUT_GREATER_EQUAL, VKD3DSPR_DEPTHOUTGE, VKD3D_SM4_SWIZZLE_VEC4}, {VKD3D_SM5_RT_DEPTHOUT_LESS_EQUAL, VKD3DSPR_DEPTHOUTLE, VKD3D_SM4_SWIZZLE_VEC4}, {VKD3D_SM5_RT_OUTPUT_STENCIL_REF, VKD3DSPR_OUTSTENCILREF, VKD3D_SM4_SWIZZLE_VEC4}, @@ -2990,6 +3013,7 @@ bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, {"sv_primitiveid", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3DSPR_PRIMID, false},
{"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3DSPR_PRIMID, false}, + {"sv_gsinstanceid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3DSPR_GSINSTID, false},
{"sv_outputcontrolpointid", false, VKD3D_SHADER_TYPE_HULL, VKD3DSPR_OUTPOINTID, false}, {"sv_primitiveid", false, VKD3D_SHADER_TYPE_HULL, VKD3DSPR_PRIMID, false}, @@ -3070,7 +3094,8 @@ static bool get_insidetessfactor_sysval_semantic(enum vkd3d_shader_sysval_semant
bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *sysval_semantic, const struct vkd3d_shader_version *version, bool semantic_compat_mapping, enum vkd3d_tessellator_domain domain, - const char *semantic_name, unsigned int semantic_idx, bool output, bool is_patch_constant_func, bool is_patch) + const char *semantic_name, unsigned int semantic_idx, bool output, + bool is_patch_constant_func, bool is_primitive) { unsigned int i;
@@ -3091,12 +3116,15 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s {"sv_domainlocation", false, VKD3D_SHADER_TYPE_DOMAIN, ~0u}, {"sv_position", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, {"sv_primitiveid", false, VKD3D_SHADER_TYPE_DOMAIN, ~0u}, + {"sv_rendertargetarrayindex", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE}, + {"sv_viewportarrayindex", false, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_NONE},
{"sv_position", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_POSITION}, + {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, + {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_DOMAIN, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX},
- {"position", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, - {"sv_position", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, {"sv_primitiveid", false, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_PRIMITIVE_ID}, + {"sv_gsinstanceid", false, VKD3D_SHADER_TYPE_GEOMETRY, ~0u},
{"position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, {"sv_position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, @@ -3107,6 +3135,8 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s {"sv_primitiveid", false, VKD3D_SHADER_TYPE_HULL, ~0u},
{"sv_position", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_POSITION}, + {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, + {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_HULL, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX},
{"position", false, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_SV_POSITION}, {"sv_position", false, VKD3D_SHADER_TYPE_PIXEL, VKD3D_SHADER_SV_POSITION}, @@ -3133,13 +3163,17 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s }; bool has_sv_prefix = !ascii_strncasecmp(semantic_name, "sv_", 3);
- if (is_patch) + if (is_primitive) { VKD3D_ASSERT(!output);
if (!ascii_strcasecmp(semantic_name, "sv_position") || (semantic_compat_mapping && !ascii_strcasecmp(semantic_name, "position"))) *sysval_semantic = VKD3D_SHADER_SV_POSITION; + else if (!ascii_strcasecmp(semantic_name, "sv_rendertargetarrayindex")) + *sysval_semantic = VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX; + else if (!ascii_strcasecmp(semantic_name, "sv_viewportarrayindex")) + *sysval_semantic = VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX; else if (has_sv_prefix) return false; else @@ -3155,11 +3189,6 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s return get_tessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); if (!ascii_strcasecmp(semantic_name, "sv_insidetessfactor")) return get_insidetessfactor_sysval_semantic(sysval_semantic, domain, semantic_idx); - if (!ascii_strcasecmp(semantic_name, "sv_position")) - { - *sysval_semantic = VKD3D_SHADER_SV_NONE; - return true; - } } else { @@ -3190,13 +3219,18 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s && (semantic_compat_mapping || has_sv_prefix) && version->type == semantics[i].shader_type) { - *sysval_semantic = semantics[i].semantic; + if (is_patch_constant_func && output && semantics[i].semantic != ~0u) + *sysval_semantic = VKD3D_SHADER_SV_NONE; + else + *sysval_semantic = semantics[i].semantic; return true; } }
if (has_sv_prefix) return false; + if (!output && version->type == VKD3D_SHADER_TYPE_GEOMETRY) + return false;
*sysval_semantic = VKD3D_SHADER_SV_NONE; return true; @@ -3228,6 +3262,7 @@ static int signature_element_pointer_compare(const void *x, const void *y)
static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_signature *signature, uint32_t tag) { + bool has_minimum_precision = tpf->program->global_flags & VKD3DSGF_ENABLE_MINIMUM_PRECISION; bool output = tag == TAG_OSGN || (tag == TAG_PCSG && tpf->program->shader_version.type == VKD3D_SHADER_TYPE_HULL); const struct signature_element **sorted_elements; @@ -3256,12 +3291,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si if (sysval >= VKD3D_SHADER_SV_TARGET) sysval = VKD3D_SHADER_SV_NONE;
+ if (has_minimum_precision) + put_u32(&buffer, 0); /* FIXME: stream index */ put_u32(&buffer, 0); /* name */ put_u32(&buffer, element->semantic_index); put_u32(&buffer, sysval); put_u32(&buffer, element->component_type); put_u32(&buffer, element->register_index); put_u32(&buffer, vkd3d_make_u16(element->mask, used_mask)); + if (has_minimum_precision) + put_u32(&buffer, element->min_precision); }
for (i = 0; i < signature->element_count; ++i) @@ -3270,9 +3309,21 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si size_t string_offset;
string_offset = put_string(&buffer, element->semantic_name); - set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset); + if (has_minimum_precision) + set_u32(&buffer, (2 + i * 8 + 1) * sizeof(uint32_t), string_offset); + else + set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset); }
+ if (has_minimum_precision) + { + if (tag == TAG_ISGN) + tag = TAG_ISG1; + else if (tag == TAG_OSGN || tag == TAG_OSG5) + tag = TAG_OSG1; + else if (tag == TAG_PCSG) + tag = TAG_PSG1; + } add_section(tpf, tag, &buffer); vkd3d_free(sorted_elements); } @@ -3444,12 +3495,16 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc unsigned int j) { unsigned int addressing = sm4_get_index_addressing_from_reg(reg, j); + const struct vkd3d_shader_register_index *idx = ®->idx[j]; struct vkd3d_bytecode_buffer *buffer = tpf->buffer; unsigned int k;
+ if (!addressing || (addressing & VKD3D_SM4_ADDRESSING_OFFSET)) + put_u32(buffer, idx->offset); + if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) { - const struct vkd3d_shader_src_param *idx_src = reg->idx[j].rel_addr; + const struct vkd3d_shader_src_param *idx_src = idx->rel_addr; uint32_t idx_src_token;
VKD3D_ASSERT(idx_src); @@ -3464,10 +3519,6 @@ static void sm4_write_register_index(const struct tpf_compiler *tpf, const struc VKD3D_ASSERT(!idx_src->reg.idx[k].rel_addr); } } - else - { - put_u32(tpf->buffer, reg->idx[j].offset); - } }
static void sm4_write_dst_register(const struct tpf_compiler *tpf, const struct vkd3d_shader_dst_param *dst) @@ -3771,6 +3822,25 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s write_sm4_instruction(tpf, &instr); }
+static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type) +{ + unsigned int i, k, type = 0; + + for (k = 0; k < 4; ++k) + { + for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i) + { + if (resource_data_type[k] == data_type_table[i]) + { + type |= i << (4 * k); + break; + } + } + } + + return type; +} + static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource; @@ -3778,7 +3848,6 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s const struct vkd3d_shader_version *version = &tpf->program->shader_version; const struct vkd3d_sm4_opcode_info *info; struct sm4_instruction instr = {0}; - unsigned int i, k; bool uav;
info = get_info_from_vsir_opcode(&tpf->lookup, ins->opcode); @@ -3793,18 +3862,11 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s instr.dsts[0] = semantic->resource.reg; instr.dst_count = 1;
- for (k = 0; k < 4; ++k) + if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED) { - for (i = ARRAY_SIZE(data_type_table) - 1; i < ARRAY_SIZE(data_type_table); --i) - { - if (semantic->resource_data_type[k] == data_type_table[i]) - { - instr.idx[0] |= i << (4 * k); - break; - } - } + instr.idx[0] = pack_resource_data_type(semantic->resource_data_type); + instr.idx_count = 1; } - instr.idx_count = 1;
if (vkd3d_shader_ver_ge(version, 5, 1)) { @@ -3813,8 +3875,7 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last; instr.dsts[0].reg.idx_count = 3;
- instr.idx[1] = semantic->resource.range.space; - instr.idx_count = 2; + instr.idx[instr.idx_count++] = semantic->resource.range.space; } else { @@ -3912,6 +3973,57 @@ static void tpf_write_dcl_tessellator_output_primitive(const struct tpf_compiler write_sm4_instruction(tpf, &instr); }
+static void tpf_write_dcl_input_primitive(const struct tpf_compiler *tpf, enum vkd3d_primitive_type input_primitive, + unsigned int patch_vertex_count) +{ + enum vkd3d_sm4_input_primitive_type sm4_input_primitive; + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, + }; + + if (input_primitive == VKD3D_PT_PATCH) + { + VKD3D_ASSERT(patch_vertex_count >= 1 && patch_vertex_count <= 32); + sm4_input_primitive = VKD3D_SM5_INPUT_PT_PATCH1 + patch_vertex_count - 1; + } + else + { + VKD3D_ASSERT(input_primitive < ARRAY_SIZE(sm4_input_primitive_type_table)); + sm4_input_primitive = sm4_input_primitive_type_table[input_primitive]; + } + + instr.extra_bits = sm4_input_primitive << VKD3D_SM4_PRIMITIVE_TYPE_SHIFT; + + write_sm4_instruction(tpf, &instr); +} + +static void tpf_write_dcl_output_topology(const struct tpf_compiler *tpf, enum vkd3d_primitive_type output_topology) +{ + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, + }; + + VKD3D_ASSERT(output_topology < ARRAY_SIZE(sm4_output_primitive_type_table)); + instr.extra_bits = sm4_output_primitive_type_table[output_topology] << VKD3D_SM4_PRIMITIVE_TYPE_SHIFT; + + write_sm4_instruction(tpf, &instr); +} + +static void tpf_write_dcl_vertices_out(const struct tpf_compiler *tpf, unsigned int count) +{ + struct sm4_instruction instr = + { + .opcode = VKD3D_SM4_OP_DCL_VERTICES_OUT, + + .idx = {count}, + .idx_count = 1, + }; + + write_sm4_instruction(tpf, &instr); +} + static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { struct sm4_instruction_modifier *modifier; @@ -4053,6 +4165,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VKD3DSIH_BREAK: case VKD3DSIH_CASE: case VKD3DSIH_CONTINUE: + case VKD3DSIH_CUT: case VKD3DSIH_DEFAULT: case VKD3DSIH_DISCARD: case VKD3DSIH_DIV: @@ -4066,6 +4179,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VKD3DSIH_DSY_COARSE: case VKD3DSIH_DSY_FINE: case VKD3DSIH_ELSE: + case VKD3DSIH_EMIT: case VKD3DSIH_ENDIF: case VKD3DSIH_ENDLOOP: case VKD3DSIH_ENDSWITCH: @@ -4101,6 +4215,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VKD3DSIH_IMM_ATOMIC_UMIN: case VKD3DSIH_IMM_ATOMIC_OR: case VKD3DSIH_IMM_ATOMIC_XOR: + case VKD3DSIH_SYNC: case VKD3DSIH_IMUL: case VKD3DSIH_INE: case VKD3DSIH_INEG: @@ -4215,6 +4330,13 @@ static void tpf_write_shdr(struct tpf_compiler *tpf) tpf_write_dcl_input_control_point_count(tpf, program->input_control_point_count); tpf_write_dcl_tessellator_domain(tpf, program->tess_domain); } + else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY) + { + tpf_write_dcl_input_primitive(tpf, program->input_primitive, program->input_control_point_count); + if (program->output_topology != VKD3D_PT_UNDEFINED) + tpf_write_dcl_output_topology(tpf, program->output_topology); + tpf_write_dcl_vertices_out(tpf, program->vertices_out_count); + }
tpf_write_program(tpf, program);
@@ -4233,6 +4355,9 @@ static void tpf_write_sfi0(struct tpf_compiler *tpf) if (tpf->program->features.rovs) *flags |= DXBC_SFI0_REQUIRES_ROVS;
+ if (tpf->program->global_flags & VKD3DSGF_ENABLE_MINIMUM_PRECISION) + *flags |= DXBC_SFI0_REQUIRES_MINIMUM_PRECISION; + /* FIXME: We also emit code that should require UAVS_AT_EVERY_STAGE, * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 021691bb3a1..f56608940db 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -161,6 +161,60 @@ int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d) return ret; }
+static char get_escape_char(char c) +{ + switch (c) + { + case '"': + case '\': + return c; + case '\t': + return 't'; + case '\n': + return 'n'; + case '\v': + return 'v'; + case '\f': + return 'f'; + case '\r': + return 'r'; + default: + return 0; + } +} + +int vkd3d_string_buffer_print_string_escaped(struct vkd3d_string_buffer *buffer, const char *s, size_t len) +{ + size_t content_size, start, i; + int ret; + char c; + + content_size = buffer->content_size; + for (i = 0, start = 0; i < len; ++i) + { + if ((c = get_escape_char(s[i]))) + { + if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s\%c", (int)(i - start), &s[start], c)) < 0) + goto fail; + start = i + 1; + } + else if (!isprint(s[i])) + { + if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s\%03o", + (int)(i - start), &s[start], (uint8_t)s[i])) < 0) + goto fail; + start = i + 1; + } + } + if ((ret = vkd3d_string_buffer_printf(buffer, "%.*s", (int)(len - start), &s[start])) < 0) + goto fail; + return ret; + +fail: + buffer->content_size = content_size; + return ret; +} + void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) { vkd3d_shader_trace_text_(buffer->buffer, buffer->content_size, function); @@ -454,8 +508,15 @@ struct shader_dump_data const char *target_suffix; };
+enum shader_dump_type +{ + SHADER_DUMP_TYPE_SOURCE, + SHADER_DUMP_TYPE_PREPROC, + SHADER_DUMP_TYPE_TARGET, +}; + static void vkd3d_shader_dump_shader(const struct shader_dump_data *dump_data, - const void *data, size_t size, bool source) + const void *data, size_t size, enum shader_dump_type type) { static const char hexadecimal_digits[] = "0123456789abcdef"; const uint8_t *checksum = dump_data->checksum; @@ -480,8 +541,10 @@ static void vkd3d_shader_dump_shader(const struct shader_dump_data *dump_data, if (dump_data->profile) pos += snprintf(filename + pos, ARRAY_SIZE(filename) - pos, "-%s", dump_data->profile);
- if (source) + if (type == SHADER_DUMP_TYPE_SOURCE) pos += snprintf(filename + pos, ARRAY_SIZE(filename) - pos, "-source.%s", dump_data->source_suffix); + else if (type == SHADER_DUMP_TYPE_PREPROC) + pos += snprintf(filename + pos, ARRAY_SIZE(filename) - pos, "-preproc.%s", dump_data->source_suffix); else pos += snprintf(filename + pos, ARRAY_SIZE(filename) - pos, "-target.%s", dump_data->target_suffix);
@@ -737,12 +800,20 @@ void vkd3d_shader_free_messages(char *messages) static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_signature *signature, const struct shader_signature *src) { - unsigned int i; + struct vkd3d_shader_signature_element *d; + const struct signature_element *e; + size_t count, i, j;
- signature->element_count = src->element_count; + for (i = 0, count = 0; i < src->element_count; ++i) + { + e = &src->elements[i]; + count += e->register_count; + } + + signature->element_count = count; if (!src->elements) { - VKD3D_ASSERT(!signature->element_count); + VKD3D_ASSERT(!count); signature->elements = NULL; return true; } @@ -750,30 +821,25 @@ static bool vkd3d_shader_signature_from_shader_signature(struct vkd3d_shader_sig if (!(signature->elements = vkd3d_calloc(signature->element_count, sizeof(*signature->elements)))) return false;
- for (i = 0; i < signature->element_count; ++i) + for (i = 0, d = signature->elements; i < src->element_count; ++i) { - struct vkd3d_shader_signature_element *d = &signature->elements[i]; - struct signature_element *e = &src->elements[i]; - - if (!(d->semantic_name = vkd3d_strdup(e->semantic_name))) + for (j = 0, e = &src->elements[i]; j < e->register_count; ++j) { - for (unsigned int j = 0; j < i; ++j) + if (!(d->semantic_name = vkd3d_strdup(e->semantic_name))) { - vkd3d_free((void *)signature->elements[j].semantic_name); + vkd3d_shader_free_shader_signature(signature); + return false; } - vkd3d_free(signature->elements); - return false; + d->semantic_index = e->semantic_index + j; + d->stream_index = e->stream_index; + d->sysval_semantic = e->sysval_semantic; + d->component_type = e->component_type; + d->register_index = e->register_index + j; + d->mask = e->mask; + d->used_mask = e->used_mask; + d->min_precision = e->min_precision; + ++d; } - d->semantic_index = e->semantic_index; - d->stream_index = e->stream_index; - d->sysval_semantic = e->sysval_semantic; - d->component_type = e->component_type; - d->register_index = e->register_index; - if (e->register_count > 1) - FIXME("Arrayed elements are not supported yet.\n"); - d->mask = e->mask; - d->used_mask = e->used_mask; - d->min_precision = e->min_precision; }
return true; @@ -995,7 +1061,7 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, - enum vkd3d_shader_resource_data_type resource_data_type) + enum vkd3d_data_type resource_data_type) { struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; struct vkd3d_shader_descriptor_info1 *d; @@ -1031,7 +1097,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc struct vkd3d_shader_descriptor_info1 *d;
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, - &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) + &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) return; d->buffer_size = cb->size; } @@ -1043,7 +1109,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte struct vkd3d_shader_descriptor_info1 *d;
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, - &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT))) + &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED))) return;
if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) @@ -1054,12 +1120,12 @@ static void vkd3d_shader_scan_combined_sampler_declaration( struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) { vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, - &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_SHADER_RESOURCE_DATA_UINT); + &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED); vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, - &semantic->resource.range, semantic->resource_type, VKD3D_SHADER_RESOURCE_DATA_FLOAT); + &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT); }
-static const struct vkd3d_shader_descriptor_info1 *find_descriptor( +const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( const struct vkd3d_shader_scan_descriptor_info1 *info, enum vkd3d_shader_descriptor_type type, unsigned int register_id) { @@ -1113,11 +1179,11 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co if (dynamic_resource || dynamic_sampler) return;
- if ((d = find_descriptor(context->scan_descriptor_info, + if ((d = vkd3d_shader_find_descriptor(context->scan_descriptor_info, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource->idx[0].offset))) resource_space = d->register_space;
- if (sampler && (d = find_descriptor(context->scan_descriptor_info, + if (sampler && (d = vkd3d_shader_find_descriptor(context->scan_descriptor_info, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler->idx[0].offset))) sampler_space = d->register_space; } @@ -1146,8 +1212,8 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co
static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, - enum vkd3d_shader_resource_data_type resource_data_type, - unsigned int sample_count, unsigned int structure_stride, bool raw, uint32_t flags) + enum vkd3d_data_type resource_data_type, unsigned int sample_count, + unsigned int structure_stride, bool raw, uint32_t flags) { struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_descriptor_type type; @@ -1171,59 +1237,16 @@ static void vkd3d_shader_scan_typed_resource_declaration(struct vkd3d_shader_sca const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_semantic *semantic = &instruction->declaration.semantic; - enum vkd3d_shader_resource_data_type resource_data_type;
- if (semantic->resource_data_type[0] != semantic->resource_data_type[1] || - semantic->resource_data_type[0] != semantic->resource_data_type[2] || - semantic->resource_data_type[0] != semantic->resource_data_type[3]) - FIXME("Resource data types are different (%d, %d, %d, %d).\n", - semantic->resource_data_type[0], - semantic->resource_data_type[1], - semantic->resource_data_type[2], - semantic->resource_data_type[3]); + if (semantic->resource_data_type[0] != semantic->resource_data_type[1] + || semantic->resource_data_type[0] != semantic->resource_data_type[2] + || semantic->resource_data_type[0] != semantic->resource_data_type[3]) + FIXME("Resource data types are different (%#x, %#x, %#x, %#x).\n", + semantic->resource_data_type[0], semantic->resource_data_type[1], + semantic->resource_data_type[2], semantic->resource_data_type[3]);
- switch (semantic->resource_data_type[0]) - { - case VKD3D_DATA_UNORM: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UNORM; - break; - case VKD3D_DATA_SNORM: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_SNORM; - break; - case VKD3D_DATA_INT: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_INT; - break; - case VKD3D_DATA_UINT: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UINT; - break; - case VKD3D_DATA_FLOAT: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; - break; - case VKD3D_DATA_MIXED: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_MIXED; - break; - case VKD3D_DATA_DOUBLE: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_DOUBLE; - break; - case VKD3D_DATA_CONTINUED: - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_CONTINUED; - break; - default: - ERR("Invalid resource data type %#x.\n", semantic->resource_data_type[0]); - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; - break; - } - - if (context->api_version < VKD3D_SHADER_API_VERSION_1_3 - && resource_data_type >= VKD3D_SHADER_RESOURCE_DATA_MIXED) - { - ERR("Invalid resource data type %#x for API version %#x.\n", - semantic->resource_data_type[0], context->api_version); - resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; - } - - vkd3d_shader_scan_resource_declaration(context, &semantic->resource, - semantic->resource_type, resource_data_type, semantic->sample_count, 0, false, instruction->flags); + vkd3d_shader_scan_resource_declaration(context, &semantic->resource, semantic->resource_type, + semantic->resource_data_type[0], semantic->sample_count, 0, false, instruction->flags); }
static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *context, @@ -1259,12 +1282,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte case VKD3DSIH_DCL_RESOURCE_RAW: case VKD3DSIH_DCL_UAV_RAW: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, 0, true, instruction->flags); + VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags); break; case VKD3DSIH_DCL_RESOURCE_STRUCTURED: case VKD3DSIH_DCL_UAV_STRUCTURED: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT, 0, + VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, instruction->declaration.structured_resource.byte_stride, false, instruction->flags); break; case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: @@ -1475,8 +1498,36 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_OK; }
-static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descriptor_info *info, - const struct vkd3d_shader_scan_descriptor_info1 *info1) +static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vkd3d_data_type data_type) +{ + switch (data_type) + { + case VKD3D_DATA_UNORM: + return VKD3D_SHADER_RESOURCE_DATA_UNORM; + case VKD3D_DATA_SNORM: + return VKD3D_SHADER_RESOURCE_DATA_SNORM; + case VKD3D_DATA_INT: + return VKD3D_SHADER_RESOURCE_DATA_INT; + case VKD3D_DATA_UINT: + return VKD3D_SHADER_RESOURCE_DATA_UINT; + case VKD3D_DATA_FLOAT: + return VKD3D_SHADER_RESOURCE_DATA_FLOAT; + case VKD3D_DATA_MIXED: + return VKD3D_SHADER_RESOURCE_DATA_MIXED; + case VKD3D_DATA_DOUBLE: + return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; + case VKD3D_DATA_CONTINUED: + return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; + case VKD3D_DATA_UNUSED: + return VKD3D_SHADER_RESOURCE_DATA_NONE; + default: + ERR("Invalid resource data type %#x.\n", data_type); + return VKD3D_SHADER_RESOURCE_DATA_FLOAT; + } +} + +static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_context *context, + struct vkd3d_shader_scan_descriptor_info *info, const struct vkd3d_shader_scan_descriptor_info1 *info1) { unsigned int i;
@@ -1492,16 +1543,28 @@ static enum vkd3d_result convert_descriptor_info(struct vkd3d_shader_scan_descri dst->register_space = src->register_space; dst->register_index = src->register_index; dst->resource_type = src->resource_type; - dst->resource_data_type = src->resource_data_type; + dst->resource_data_type = vkd3d_resource_data_type_from_data_type(src->resource_data_type); dst->flags = src->flags; dst->count = src->count; + + if (context->api_version <= VKD3D_SHADER_API_VERSION_1_15 + && dst->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) + dst->resource_data_type = VKD3D_SHADER_RESOURCE_DATA_UINT; + + if (context->api_version < VKD3D_SHADER_API_VERSION_1_3 + && dst->resource_data_type >= VKD3D_SHADER_RESOURCE_DATA_MIXED) + { + ERR("Invalid resource data type %#x for API version %#x.\n", + src->resource_data_type, context->api_version); + dst->resource_data_type = VKD3D_SHADER_RESOURCE_DATA_FLOAT; + } } info->descriptor_count = info1->descriptor_count;
return VKD3D_OK; }
-static void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info) +void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info) { TRACE("scan_descriptor_info %p.\n", scan_descriptor_info);
@@ -1509,12 +1572,10 @@ static void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_des }
static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_message_context *message_context, - struct vkd3d_shader_scan_descriptor_info1 *descriptor_info1) + struct vkd3d_shader_message_context *message_context, bool add_descriptor_info) { 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_descriptor_info1 local_descriptor_info1 = {0}; struct vkd3d_shader_scan_descriptor_info *descriptor_info; struct vkd3d_shader_scan_signature_info *signature_info; struct vkd3d_shader_instruction *instruction; @@ -1523,29 +1584,25 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh unsigned int i;
descriptor_info = vkd3d_find_struct(compile_info->next, SCAN_DESCRIPTOR_INFO); - if (descriptor_info1) - { - descriptor_info1->descriptors = NULL; - descriptor_info1->descriptor_count = 0; - } - else if (descriptor_info) - { - descriptor_info1 = &local_descriptor_info1; - } + if (descriptor_info) + add_descriptor_info = true; + signature_info = vkd3d_find_struct(compile_info->next, SCAN_SIGNATURE_INFO);
if ((combined_sampler_info = vkd3d_find_struct(compile_info->next, SCAN_COMBINED_RESOURCE_SAMPLER_INFO))) { combined_sampler_info->combined_samplers = NULL; combined_sampler_info->combined_sampler_count = 0; - if (!descriptor_info1) - descriptor_info1 = &local_descriptor_info1; + add_descriptor_info = true; }
tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO);
vkd3d_shader_scan_context_init(&context, &program->shader_version, compile_info, - descriptor_info1, combined_sampler_info, message_context); + add_descriptor_info ? &program->descriptors : NULL, combined_sampler_info, message_context); + + if (add_descriptor_info) + program->has_descriptor_info = true;
if (TRACE_ON()) vsir_program_trace(program); @@ -1567,7 +1624,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh if (size) { if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, - &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_SHADER_RESOURCE_DATA_UINT))) + &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) d->buffer_size = size * 16; } } @@ -1585,7 +1642,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh }
if (!ret && descriptor_info) - ret = convert_descriptor_info(descriptor_info, descriptor_info1); + ret = convert_descriptor_info(&context, descriptor_info, &program->descriptors);
if (!ret && tessellation_info) { @@ -1599,15 +1656,10 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh vkd3d_shader_free_scan_combined_resource_sampler_info(combined_sampler_info); if (descriptor_info) vkd3d_shader_free_scan_descriptor_info(descriptor_info); - if (descriptor_info1) - vkd3d_shader_free_scan_descriptor_info1(descriptor_info1); if (signature_info) vkd3d_shader_free_scan_signature_info(signature_info); } - else - { - vkd3d_shader_free_scan_descriptor_info1(&local_descriptor_info1); - } + vkd3d_shader_scan_context_cleanup(&context); return ret; } @@ -1631,7 +1683,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
fill_shader_dump_data(compile_info, &dump_data); - vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, true); + vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE);
if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) { @@ -1645,7 +1697,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) { - ret = vsir_program_scan(&program, compile_info, &message_context, NULL); + ret = vsir_program_scan(&program, compile_info, &message_context, false); vsir_program_cleanup(&program); } } @@ -1662,7 +1714,6 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; - struct vkd3d_shader_scan_descriptor_info1 scan_descriptor_info; struct vkd3d_shader_compile_info scan_info; int ret;
@@ -1678,28 +1729,24 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, combined_sampler_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_COMBINED_RESOURCE_SAMPLER_INFO; combined_sampler_info.next = scan_info.next; scan_info.next = &combined_sampler_info; - if ((ret = vsir_program_scan(program, &scan_info, message_context, &scan_descriptor_info)) < 0) + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) return ret; - ret = glsl_compile(program, config_flags, &scan_descriptor_info, + ret = glsl_compile(program, config_flags, &combined_sampler_info, compile_info, out, message_context); vkd3d_shader_free_scan_combined_resource_sampler_info(&combined_sampler_info); - vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info); break;
case VKD3D_SHADER_TARGET_SPIRV_BINARY: case VKD3D_SHADER_TARGET_SPIRV_TEXT: - if ((ret = vsir_program_scan(program, &scan_info, message_context, &scan_descriptor_info)) < 0) + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) return ret; - ret = spirv_compile(program, config_flags, &scan_descriptor_info, - compile_info, out, message_context); - vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info); + ret = spirv_compile(program, config_flags, compile_info, out, message_context); break;
case VKD3D_SHADER_TARGET_MSL: - if ((ret = vsir_program_scan(program, &scan_info, message_context, &scan_descriptor_info)) < 0) + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) return ret; - ret = msl_compile(program, config_flags, &scan_descriptor_info, compile_info, out, message_context); - vkd3d_shader_free_scan_descriptor_info1(&scan_descriptor_info); + ret = msl_compile(program, config_flags, compile_info, out, message_context); break;
default: @@ -1711,7 +1758,8 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, }
static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) + const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out, + struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_code preprocessed; int ret; @@ -1719,6 +1767,8 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context))) return ret;
+ vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC); + ret = hlsl_compile_shader(&preprocessed, compile_info, out, message_context);
vkd3d_shader_free_shader_code(&preprocessed); @@ -1745,11 +1795,11 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, vkd3d_shader_message_context_init(&message_context, compile_info->log_level);
fill_shader_dump_data(compile_info, &dump_data); - vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, true); + vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE);
if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) { - ret = compile_hlsl(compile_info, out, &message_context); + ret = compile_hlsl(compile_info, &dump_data, out, &message_context); } else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX) { @@ -1768,7 +1818,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, }
if (ret >= 0) - vkd3d_shader_dump_shader(&dump_data, out->code, out->size, false); + vkd3d_shader_dump_shader(&dump_data, out->code, out->size, SHADER_DUMP_TYPE_TARGET);
vkd3d_shader_message_context_trace_messages(&message_context); if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) @@ -1961,9 +2011,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns VKD3D_SHADER_SOURCE_DXBC_TPF, VKD3D_SHADER_SOURCE_HLSL, VKD3D_SHADER_SOURCE_D3D_BYTECODE, -#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL VKD3D_SHADER_SOURCE_DXBC_DXIL, -#endif VKD3D_SHADER_SOURCE_FX, };
@@ -1996,6 +2044,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_SPIRV_BINARY, #if defined(HAVE_SPIRV_TOOLS) || defined(VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER) VKD3D_SHADER_TARGET_SPIRV_TEXT, +#endif +#ifdef VKD3D_SHADER_UNSUPPORTED_GLSL + VKD3D_SHADER_TARGET_GLSL, #endif VKD3D_SHADER_TARGET_D3D_ASM, VKD3D_SHADER_TARGET_D3D_BYTECODE, @@ -2012,7 +2063,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_D3D_ASM, };
-#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL static const enum vkd3d_shader_target_type dxbc_dxil_types[] = { VKD3D_SHADER_TARGET_SPIRV_BINARY, @@ -2021,7 +2071,6 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( # endif VKD3D_SHADER_TARGET_D3D_ASM, }; -#endif
static const enum vkd3d_shader_target_type fx_types[] = { @@ -2044,11 +2093,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( *count = ARRAY_SIZE(d3dbc_types); return d3dbc_types;
-#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL case VKD3D_SHADER_SOURCE_DXBC_DXIL: *count = ARRAY_SIZE(dxbc_dxil_types); return dxbc_dxil_types; -#endif
case VKD3D_SHADER_SOURCE_FX: *count = ARRAY_SIZE(fx_types); diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 03643acff3c..3b4fb626fcc 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -59,8 +59,10 @@ #define VKD3D_VEC4_SIZE 4 #define VKD3D_DVEC2_SIZE 2
-#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_UINT64 + 1) +#define VKD3D_SHADER_COMPONENT_TYPE_COUNT (VKD3D_SHADER_COMPONENT_INT16 + 1) #define VKD3D_SHADER_MINIMUM_PRECISION_COUNT (VKD3D_SHADER_MINIMUM_PRECISION_UINT_16 + 1) +#define VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT (VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER + 1) +#define VKD3D_SHADER_RESOURCE_TYPE_COUNT (VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY + 1)
#define VKD3D_MAX_STREAM_COUNT 4
@@ -74,6 +76,8 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE = 6, VKD3D_SHADER_ERROR_DXBC_OUT_OF_MEMORY = 7, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE = 8, + VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE = 9, + VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE = 10,
VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF = 1000, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_RANGE = 1001, @@ -167,6 +171,9 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_MISPLACED_SAMPLER_STATE = 5039, VKD3D_SHADER_ERROR_HLSL_AMBIGUOUS_CALL = 5040, VKD3D_SHADER_ERROR_HLSL_DUPLICATE_PATCH = 5041, + VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT = 5042, + VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE = 5043, + VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT = 5044,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, @@ -252,15 +259,21 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC = 9021, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE = 9022, VKD3D_SHADER_ERROR_VSIR_INVALID_RANGE = 9023, + VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE = 9024, + VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE = 9025, + VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT = 9026,
VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300,
VKD3D_SHADER_ERROR_MSL_INTERNAL = 10000, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND = 10001, + VKD3D_SHADER_ERROR_MSL_UNSUPPORTED = 10002,
VKD3D_SHADER_ERROR_FX_NOT_IMPLEMENTED = 11000, VKD3D_SHADER_ERROR_FX_INVALID_VERSION = 11001, VKD3D_SHADER_ERROR_FX_INVALID_DATA = 11002, + VKD3D_SHADER_ERROR_FX_INVALID_SIZE = 11003, + VKD3D_SHADER_ERROR_FX_OUT_OF_MEMORY = 11004, };
enum vkd3d_shader_opcode @@ -998,6 +1011,7 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader enum vkd3d_data_type data_type, unsigned int idx_count); void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int idx_count); +void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst); void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id);
struct vkd3d_shader_index_range @@ -1415,6 +1429,33 @@ enum vsir_normalisation_level VSIR_NORMALISED_SM6, };
+struct vkd3d_shader_descriptor_info1 +{ + enum vkd3d_shader_descriptor_type type; + unsigned int register_space; + unsigned int register_index; + unsigned int register_id; + enum vkd3d_shader_resource_type resource_type; + enum vkd3d_data_type resource_data_type; + unsigned int flags; + unsigned int sample_count; + unsigned int buffer_size; + unsigned int structure_stride; + unsigned int count; + uint32_t uav_flags; +}; + +struct vkd3d_shader_scan_descriptor_info1 +{ + struct vkd3d_shader_descriptor_info1 *descriptors; + unsigned int descriptor_count; +}; + +const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( + const struct vkd3d_shader_scan_descriptor_info1 *info, + enum vkd3d_shader_descriptor_type type, unsigned int register_id); +void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info); + struct vsir_program { struct vkd3d_shader_version shader_version; @@ -1424,6 +1465,9 @@ struct vsir_program struct shader_signature output_signature; struct shader_signature patch_constant_signature;
+ struct vkd3d_shader_scan_descriptor_info1 descriptors; + bool has_descriptor_info; + unsigned int parameter_count; const struct vkd3d_shader_parameter1 *parameters; bool free_parameters; @@ -1445,6 +1489,9 @@ struct vsir_program enum vkd3d_tessellator_domain tess_domain; enum vkd3d_shader_tessellator_partitioning tess_partitioning; enum vkd3d_shader_tessellator_output_primitive tess_output_primitive; + enum vkd3d_primitive_type input_primitive, output_topology; + unsigned int vertices_out_count; + uint32_t io_dcls[VKD3D_BITMAP_SIZE(VKD3DSPR_COUNT)];
struct vsir_features features; @@ -1501,28 +1548,6 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
-struct vkd3d_shader_descriptor_info1 -{ - enum vkd3d_shader_descriptor_type type; - unsigned int register_space; - unsigned int register_index; - unsigned int register_id; - enum vkd3d_shader_resource_type resource_type; - enum vkd3d_shader_resource_data_type resource_data_type; - unsigned int flags; - unsigned int sample_count; - unsigned int buffer_size; - unsigned int structure_stride; - unsigned int count; - uint32_t uav_flags; -}; - -struct vkd3d_shader_scan_descriptor_info1 -{ - struct vkd3d_shader_descriptor_info1 *descriptors; - unsigned int descriptor_count; -}; - void vsir_program_trace(const struct vsir_program *program);
const char *shader_get_type_prefix(enum vkd3d_shader_type type); @@ -1544,6 +1569,8 @@ enum vsir_asm_flags VSIR_ASM_FLAG_NONE = 0, VSIR_ASM_FLAG_DUMP_TYPES = 0x1, VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2, + VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4, + VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, };
enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, @@ -1558,6 +1585,7 @@ void vkd3d_string_buffer_clear(struct vkd3d_string_buffer *buffer); void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t size); int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f); int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d); +int vkd3d_string_buffer_print_string_escaped(struct vkd3d_string_buffer *buffer, const char *s, size_t len); int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format, ...) VKD3D_PRINTF_FUNC(2, 3); void vkd3d_string_buffer_release(struct vkd3d_string_buffer_cache *list, struct vkd3d_string_buffer *buffer); #define vkd3d_string_buffer_trace(buffer) \ @@ -1634,7 +1662,8 @@ void vkd3d_shader_trace_text_(const char *text, size_t size, const char *functio vkd3d_shader_trace_text_(text, size, __FUNCTION__)
bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, - unsigned int semantic_index, bool output, enum vkd3d_shader_register_type *type, unsigned int *reg); + unsigned int semantic_index, bool output, enum vkd3d_shader_sysval_semantic *sysval, + enum vkd3d_shader_register_type *type, unsigned int *reg); bool sm1_usage_from_semantic_name(const char *semantic_name, uint32_t semantic_index, enum vkd3d_decl_usage *usage, uint32_t *usage_idx); bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, @@ -1642,7 +1671,8 @@ bool sm4_register_from_semantic_name(const struct vkd3d_shader_version *version, bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg); bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *sysval_semantic, const struct vkd3d_shader_version *version, bool semantic_compat_mapping, enum vkd3d_tessellator_domain domain, - const char *semantic_name, unsigned int semantic_idx, bool output, bool is_patch_constant_func, bool is_patch); + const char *semantic_name, unsigned int semantic_idx, bool output, + bool is_patch_constant_func, bool is_primitive);
int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, struct vkd3d_shader_message_context *message_context, struct vsir_program *program); @@ -1665,7 +1695,6 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
int glsl_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, const struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); @@ -1673,12 +1702,10 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, #define SPIRV_MAX_SRC_COUNT 6
int spirv_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_scan_descriptor_info1 *scan_descriptor_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
int msl_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_scan_descriptor_info1 *descriptor_info, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
@@ -1747,30 +1774,6 @@ static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( } }
-static inline enum vkd3d_shader_component_type vkd3d_component_type_from_resource_data_type( - enum vkd3d_shader_resource_data_type data_type) -{ - switch (data_type) - { - case VKD3D_SHADER_RESOURCE_DATA_FLOAT: - case VKD3D_SHADER_RESOURCE_DATA_UNORM: - case VKD3D_SHADER_RESOURCE_DATA_SNORM: - return VKD3D_SHADER_COMPONENT_FLOAT; - case VKD3D_SHADER_RESOURCE_DATA_UINT: - return VKD3D_SHADER_COMPONENT_UINT; - case VKD3D_SHADER_RESOURCE_DATA_INT: - return VKD3D_SHADER_COMPONENT_INT; - case VKD3D_SHADER_RESOURCE_DATA_DOUBLE: - case VKD3D_SHADER_RESOURCE_DATA_CONTINUED: - return VKD3D_SHADER_COMPONENT_DOUBLE; - default: - FIXME("Unhandled data type %#x.\n", data_type); - /* fall-through */ - case VKD3D_SHADER_RESOURCE_DATA_MIXED: - return VKD3D_SHADER_COMPONENT_UINT; - } -} - 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; diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c index 62dd5f69f77..f2b18b665f8 100644 --- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c @@ -269,7 +269,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_15; + option->value = VKD3D_SHADER_API_VERSION_1_16;
compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; compile_info.next = &preprocess_info; @@ -433,7 +433,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_15}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, };
TRACE("data %p, size %"PRIuPTR", filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", @@ -979,7 +979,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_15}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, };
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 ce0c3b9128f..e487ed0b9ad 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -31,6 +31,43 @@ static void d3d12_command_queue_submit_locked(struct d3d12_command_queue *queue) static HRESULT d3d12_command_queue_flush_ops(struct d3d12_command_queue *queue, bool *flushed_any); static HRESULT d3d12_command_queue_flush_ops_locked(struct d3d12_command_queue *queue, bool *flushed_any);
+static void vkd3d_null_event_signal(struct vkd3d_null_event *e) +{ + vkd3d_mutex_lock(&e->mutex); + e->signalled = true; + vkd3d_cond_signal(&e->cond); + vkd3d_mutex_unlock(&e->mutex); +} + +void vkd3d_null_event_wait(struct vkd3d_null_event *e) +{ + vkd3d_mutex_lock(&e->mutex); + while (!e->signalled) + vkd3d_cond_wait(&e->cond, &e->mutex); + e->signalled = false; + vkd3d_mutex_unlock(&e->mutex); +} + +void vkd3d_null_event_cleanup(struct vkd3d_null_event *e) +{ + vkd3d_cond_destroy(&e->cond); + vkd3d_mutex_destroy(&e->mutex); +} + +void vkd3d_null_event_init(struct vkd3d_null_event *e) +{ + vkd3d_mutex_init(&e->mutex); + vkd3d_cond_init(&e->cond); + e->signalled = false; +} + +HRESULT vkd3d_signal_null_event(HANDLE h) +{ + vkd3d_null_event_signal(h); + + return S_OK; +} + HRESULT vkd3d_queue_create(struct d3d12_device *device, uint32_t family_index, const VkQueueFamilyProperties *properties, struct vkd3d_queue **queue) { @@ -753,8 +790,6 @@ static HRESULT d3d12_fence_add_vk_semaphore(struct d3d12_fence *fence, VkSemapho
static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence) { - struct d3d12_device *device = fence->device; - bool signal_null_event_cond = false; unsigned int i, j;
for (i = 0, j = 0; i < fence->event_count; ++i) @@ -763,28 +798,16 @@ static void d3d12_fence_signal_external_events_locked(struct d3d12_fence *fence)
if (current->value <= fence->value) { - if (current->event) - { - device->signal_event(current->event); - } - else - { - *current->latch = true; - signal_null_event_cond = true; - } - } - else - { - if (i != j) - fence->events[j] = *current; - ++j; + current->signal(current->event); + continue; } + + if (i != j) + fence->events[j] = *current; + ++j; }
fence->event_count = j; - - if (signal_null_event_cond) - vkd3d_cond_broadcast(&fence->null_event_cond); }
static HRESULT d3d12_fence_signal(struct d3d12_fence *fence, uint64_t value, VkFence vk_fence, bool on_cpu) @@ -978,7 +1001,6 @@ static void d3d12_fence_decref(struct d3d12_fence *fence) vkd3d_free(fence->events); vkd3d_free(fence->semaphores); vkd3d_mutex_destroy(&fence->mutex); - vkd3d_cond_destroy(&fence->null_event_cond); vkd3d_free(fence);
d3d12_device_release(device); @@ -1047,12 +1069,30 @@ static UINT64 STDMETHODCALLTYPE d3d12_fence_GetCompletedValue(ID3D12Fence1 *ifac return completed_value; }
+bool d3d12_fence_add_waiting_event(struct d3d12_fence *fence, + HANDLE event, PFN_vkd3d_signal_event signal, uint64_t value) +{ + struct vkd3d_waiting_event *e; + + if (!vkd3d_array_reserve((void **)&fence->events, &fence->events_size, + fence->event_count + 1, sizeof(*fence->events))) + return false; + + e = &fence->events[fence->event_count++]; + e->event = event; + e->signal = signal; + e->value = value; + + return true; +} + static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence1 *iface, UINT64 value, HANDLE event) { struct d3d12_fence *fence = impl_from_ID3D12Fence1(iface); + struct vkd3d_null_event null_event; + PFN_vkd3d_signal_event signal; unsigned int i; - bool latch = false;
TRACE("iface %p, value %#"PRIx64", event %p.\n", iface, value, event);
@@ -1078,30 +1118,29 @@ static HRESULT STDMETHODCALLTYPE d3d12_fence_SetEventOnCompletion(ID3D12Fence1 * } }
- if (!vkd3d_array_reserve((void **)&fence->events, &fence->events_size, - fence->event_count + 1, sizeof(*fence->events))) + signal = fence->device->signal_event; + if (!event) + { + vkd3d_null_event_init(&null_event); + event = &null_event; + signal = vkd3d_signal_null_event; + } + + if (!d3d12_fence_add_waiting_event(fence, event, signal, value)) { WARN("Failed to add event.\n"); vkd3d_mutex_unlock(&fence->mutex); return E_OUTOFMEMORY; }
- fence->events[fence->event_count].value = value; - fence->events[fence->event_count].event = event; - fence->events[fence->event_count].latch = &latch; - ++fence->event_count; + vkd3d_mutex_unlock(&fence->mutex);
- /* If event is NULL, we need to block until the fence value completes. - * Implement this in a uniform way where we pretend we have a dummy event. - * A NULL fence->events[].event means that we should set latch to true - * and signal a condition variable instead of calling external signal_event callback. */ - if (!event) + if (event == &null_event) { - while (!latch) - vkd3d_cond_wait(&fence->null_event_cond, &fence->mutex); + vkd3d_null_event_wait(&null_event); + vkd3d_null_event_cleanup(&null_event); }
- vkd3d_mutex_unlock(&fence->mutex); return S_OK; }
@@ -1159,7 +1198,7 @@ static const struct ID3D12Fence1Vtbl d3d12_fence_vtbl = d3d12_fence_GetCreationFlags, };
-static struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface) +struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface) { ID3D12Fence1 *iface1;
@@ -1185,8 +1224,6 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
vkd3d_mutex_init(&fence->mutex);
- vkd3d_cond_init(&fence->null_event_cond); - if ((fence->flags = flags)) FIXME("Ignoring flags %#x.\n", flags);
@@ -1201,8 +1238,8 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device * &fence->timeline_semaphore)) < 0) { WARN("Failed to create timeline semaphore, vr %d.\n", vr); - hr = hresult_from_vk_result(vr); - goto fail_destroy_null_cond; + vkd3d_mutex_destroy(&fence->mutex); + return hresult_from_vk_result(vr); }
fence->semaphores = NULL; @@ -1213,20 +1250,14 @@ static HRESULT d3d12_fence_init(struct d3d12_fence *fence, struct d3d12_device *
if (FAILED(hr = vkd3d_private_store_init(&fence->private_store))) { - goto fail_destroy_timeline_semaphore; + VK_CALL(vkDestroySemaphore(device->vk_device, fence->timeline_semaphore, NULL)); + vkd3d_mutex_destroy(&fence->mutex); + return hr; }
d3d12_device_add_ref(fence->device = device);
return S_OK; - -fail_destroy_timeline_semaphore: - VK_CALL(vkDestroySemaphore(device->vk_device, fence->timeline_semaphore, NULL)); -fail_destroy_null_cond: - vkd3d_cond_destroy(&fence->null_event_cond); - vkd3d_mutex_destroy(&fence->mutex); - - return hr; }
HRESULT d3d12_fence_create(struct d3d12_device *device, @@ -1499,7 +1530,7 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct VkDescriptorPoolCreateInfo pool_desc; VkDevice vk_device = device->vk_device; - VkDescriptorPoolSize vk_pool_sizes[2]; + VkDescriptorPoolSize vk_pool_sizes[4]; unsigned int pool_size, pool_limit; VkDescriptorPool vk_pool; VkResult vr; @@ -1530,21 +1561,43 @@ static VkDescriptorPool d3d12_command_allocator_allocate_descriptor_pool( } descriptor_count = pool_size;
- vk_pool_sizes[0].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, true); - vk_pool_sizes[0].descriptorCount = descriptor_count; - - vk_pool_sizes[1].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, false); - vk_pool_sizes[1].descriptorCount = descriptor_count; - pool_desc.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; pool_desc.pNext = NULL; pool_desc.flags = 0; pool_desc.maxSets = 512; - pool_desc.poolSizeCount = 1; - if (vk_pool_sizes[1].type != vk_pool_sizes[0].type) - ++pool_desc.poolSizeCount; pool_desc.pPoolSizes = vk_pool_sizes;
+ if (allocator->device->use_vk_heaps) + { + /* SRV root descriptors. */ + vk_pool_sizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER; + vk_pool_sizes[0].descriptorCount = descriptor_count; + + /* UAV root descriptors and UAV counters. */ + vk_pool_sizes[1].type = VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER; + vk_pool_sizes[1].descriptorCount = descriptor_count; + + /* CBV root descriptors. */ + vk_pool_sizes[2].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + vk_pool_sizes[2].descriptorCount = descriptor_count; + + /* Static samplers. */ + vk_pool_sizes[3].type = VK_DESCRIPTOR_TYPE_SAMPLER; + vk_pool_sizes[3].descriptorCount = descriptor_count; + + pool_desc.poolSizeCount = 4; + } + else + { + vk_pool_sizes[0].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, true); + vk_pool_sizes[0].descriptorCount = descriptor_count; + + vk_pool_sizes[1].type = vk_descriptor_type_from_vkd3d_descriptor_type(descriptor_type, false); + vk_pool_sizes[1].descriptorCount = descriptor_count; + + pool_desc.poolSizeCount = 1 + (vk_pool_sizes[0].type != vk_pool_sizes[1].type); + } + if ((vr = VK_CALL(vkCreateDescriptorPool(vk_device, &pool_desc, NULL, &vk_pool))) < 0) { ERR("Failed to create descriptor pool, vr %d.\n", vr); @@ -1578,6 +1631,10 @@ static VkDescriptorSet d3d12_command_allocator_allocate_descriptor_set(struct d3 VkDescriptorSet vk_descriptor_set; VkResult vr;
+ /* With Vulkan heaps we use just one descriptor pool. */ + if (device->use_vk_heaps) + descriptor_type = 0; + if (!allocator->vk_descriptor_pools[descriptor_type]) allocator->vk_descriptor_pools[descriptor_type] = d3d12_command_allocator_allocate_descriptor_pool(allocator, descriptor_type, descriptor_count, unbounded); @@ -2222,7 +2279,7 @@ static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, if (!stencil_state || (stencil_state & D3D12_RESOURCE_STATE_DEPTH_WRITE)) *image_layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; else - *image_layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL; + *image_layout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL_KHR; } return true;
@@ -2256,7 +2313,7 @@ static bool vk_barrier_parameters_from_d3d12_resource_state(unsigned int state, { if (stencil_state & D3D12_RESOURCE_STATE_DEPTH_WRITE) { - *image_layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL; + *image_layout = VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL_KHR; *access_mask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; } else diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c index b51e2963efa..b2636fd5585 100644 --- a/libs/vkd3d/libs/vkd3d/device.c +++ b/libs/vkd3d/libs/vkd3d/device.c @@ -73,6 +73,7 @@ static const struct vkd3d_optional_extension_info optional_instance_extensions[] static const char * const required_device_extensions[] = { VK_KHR_MAINTENANCE1_EXTENSION_NAME, + VK_KHR_MAINTENANCE2_EXTENSION_NAME, VK_KHR_SHADER_DRAW_PARAMETERS_EXTENSION_NAME, };
@@ -91,12 +92,12 @@ static const struct vkd3d_optional_extension_info optional_device_extensions[] = VK_EXTENSION(KHR_DRAW_INDIRECT_COUNT, KHR_draw_indirect_count), VK_EXTENSION(KHR_GET_MEMORY_REQUIREMENTS_2, KHR_get_memory_requirements2), VK_EXTENSION(KHR_IMAGE_FORMAT_LIST, KHR_image_format_list), - VK_EXTENSION(KHR_MAINTENANCE2, KHR_maintenance2), VK_EXTENSION(KHR_MAINTENANCE3, KHR_maintenance3), VK_EXTENSION(KHR_PORTABILITY_SUBSET, KHR_portability_subset), VK_EXTENSION(KHR_PUSH_DESCRIPTOR, KHR_push_descriptor), VK_EXTENSION(KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE, KHR_sampler_mirror_clamp_to_edge), VK_EXTENSION(KHR_TIMELINE_SEMAPHORE, KHR_timeline_semaphore), + VK_EXTENSION(KHR_ZERO_INITIALIZE_WORKGROUP_MEMORY, KHR_zero_initialize_workgroup_memory), /* EXT extensions */ VK_EXTENSION(EXT_4444_FORMATS, EXT_4444_formats), VK_EXTENSION(EXT_CALIBRATED_TIMESTAMPS, EXT_calibrated_timestamps), @@ -520,7 +521,26 @@ static VkBool32 VKAPI_PTR vkd3d_debug_report_callback(VkDebugReportFlagsEXT flag VkDebugReportObjectTypeEXT object_type, uint64_t object, size_t location, int32_t message_code, const char *layer_prefix, const char *message, void *user_data) { - FIXME("%s\n", debugstr_a(message)); + while (*message) + { + const char *end = strchr(message, '\n'); + size_t len; + + if (end) + len = end - message; + else + len = strlen(message); + + len = min(len, 256); + + FIXME("%s\n", debugstr_an(message, len)); + + message += len; + + if (*message == '\n') + ++message; + } + return VK_FALSE; }
@@ -835,6 +855,7 @@ struct vkd3d_physical_device_info VkPhysicalDeviceTimelineSemaphoreFeaturesKHR timeline_semaphore_features; VkPhysicalDeviceMutableDescriptorTypeFeaturesEXT mutable_features; VkPhysicalDevice4444FormatsFeaturesEXT formats4444_features; + VkPhysicalDeviceZeroInitializeWorkgroupMemoryFeaturesKHR zero_initialize_workgroup_memory_features;
VkPhysicalDeviceFeatures2 features2; }; @@ -870,6 +891,8 @@ static void vkd3d_chain_physical_device_info_structures(struct vkd3d_physical_de vk_prepend_struct(&info->features2, &info->mutable_features); if (vulkan_info->EXT_4444_formats) vk_prepend_struct(&info->features2, &info->formats4444_features); + if (vulkan_info->KHR_zero_initialize_workgroup_memory) + vk_prepend_struct(&info->features2, &info->zero_initialize_workgroup_memory_features);
info->properties2.pNext = NULL;
@@ -908,6 +931,7 @@ static void vkd3d_physical_device_info_init(struct vkd3d_physical_device_info *i info->timeline_semaphore_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES_KHR; info->mutable_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MUTABLE_DESCRIPTOR_TYPE_FEATURES_EXT; info->formats4444_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_4444_FORMATS_FEATURES_EXT; + info->zero_initialize_workgroup_memory_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ZERO_INITIALIZE_WORKGROUP_MEMORY_FEATURES_KHR;
info->properties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2; info->maintenance3_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES; @@ -1418,6 +1442,9 @@ static void vkd3d_init_feature_level(struct vkd3d_vulkan_info *vk_info, else if (!vk_info->vertex_attrib_zero_divisor) WARN("Vertex attribute instance rate zero divisor is not supported.\n");
+ if (!vk_info->KHR_zero_initialize_workgroup_memory) + WARN("Shader zero initialize workgroup memory is not supported.\n"); + #undef CHECK_MIN_REQUIREMENT #undef CHECK_MAX_REQUIREMENT #undef CHECK_FEATURE @@ -1834,6 +1861,8 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device, vulkan_info->EXT_mutable_descriptor_type = false; if (!physical_device_info->timeline_semaphore_features.timelineSemaphore) vulkan_info->KHR_timeline_semaphore = false; + if (!physical_device_info->zero_initialize_workgroup_memory_features.shaderZeroInitializeWorkgroupMemory) + vulkan_info->KHR_zero_initialize_workgroup_memory = false;
physical_device_info->formats4444_features.formatA4B4G4R4 = VK_FALSE;
@@ -3610,11 +3639,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device9
TRACE("Request shader model %#x.\n", data->HighestShaderModel);
-#ifdef VKD3D_SHADER_UNSUPPORTED_DXIL data->HighestShaderModel = min(data->HighestShaderModel, D3D_SHADER_MODEL_6_0); -#else - data->HighestShaderModel = min(data->HighestShaderModel, D3D_SHADER_MODEL_5_1); -#endif
TRACE("Shader model %#x.\n", data->HighestShaderModel); return S_OK; @@ -4876,14 +4901,131 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CreatePipelineLibrary(ID3D12Device return DXGI_ERROR_UNSUPPORTED; }
+struct waiting_event_semaphore +{ + HANDLE event; + PFN_vkd3d_signal_event signal; + uint32_t value; +}; + +static HRESULT waiting_event_semaphore_signal(HANDLE h) +{ + struct waiting_event_semaphore *s = h; + + if (vkd3d_atomic_decrement_u32(&s->value)) + return S_OK; + + if (s->event) + s->signal(s->event); + vkd3d_free(s); + + return S_OK; +} + +static HRESULT waiting_event_semaphore_signal_first(HANDLE h) +{ + struct waiting_event_semaphore *s = h; + HANDLE event; + + if ((event = vkd3d_atomic_exchange_ptr(&s->event, NULL))) + s->signal(event); + + return waiting_event_semaphore_signal(h); +} + +static bool waiting_event_semaphore_cancel(struct waiting_event_semaphore *s) +{ + bool ret; + + ret = !vkd3d_atomic_exchange_ptr(&s->event, NULL); + waiting_event_semaphore_signal(s); + + return ret; +} + static HRESULT STDMETHODCALLTYPE d3d12_device_SetEventOnMultipleFenceCompletion(ID3D12Device9 *iface, ID3D12Fence *const *fences, const UINT64 *values, UINT fence_count, D3D12_MULTIPLE_FENCE_WAIT_FLAGS flags, HANDLE event) { - FIXME("iface %p, fences %p, values %p, fence_count %u, flags %#x, event %p stub!\n", + struct d3d12_device *device = impl_from_ID3D12Device9(iface); + struct vkd3d_null_event null_event; + struct waiting_event_semaphore *s; + PFN_vkd3d_signal_event signal; + struct d3d12_fence *fence; + HRESULT hr = S_OK; + unsigned int i; + + TRACE("iface %p, fences %p, values %p, fence_count %u, flags %#x, event %p.\n", iface, fences, values, fence_count, flags, event);
- return E_NOTIMPL; + if (flags & ~D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY) + { + FIXME("Unhandled flags %#x.\n", flags & ~D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY); + return E_NOTIMPL; + } + + if (!fence_count) + return E_INVALIDARG; + + if (fence_count == 1) + return ID3D12Fence_SetEventOnCompletion(fences[0], values[0], event); + + if (!(s = vkd3d_malloc(sizeof(*s)))) + { + WARN("Failed to allocate semaphore memory.\n"); + return E_OUTOFMEMORY; + } + + signal = device->signal_event; + if (!event) + { + vkd3d_null_event_init(&null_event); + event = &null_event; + signal = vkd3d_signal_null_event; + } + s->event = event; + s->signal = signal; + s->value = fence_count; + + if (flags & D3D12_MULTIPLE_FENCE_WAIT_FLAG_ANY) + signal = waiting_event_semaphore_signal_first; + else + signal = waiting_event_semaphore_signal; + + for (i = 0; i < fence_count; ++i) + { + fence = unsafe_impl_from_ID3D12Fence(fences[i]); + + vkd3d_mutex_lock(&fence->mutex); + + if (values[i] <= fence->value) + { + vkd3d_mutex_unlock(&fence->mutex); + signal(s); + continue; + } + + if (!d3d12_fence_add_waiting_event(fence, s, signal, values[i])) + { + WARN("Failed to add event.\n"); + /* If the event was already signalled, we don't need to fail here. + * Note that cancel() will also return "true" for any subsequent + * cancel() calls; that's fine, because we already failed in that + * case. */ + if (!waiting_event_semaphore_cancel(s)) + hr = E_OUTOFMEMORY; + } + + vkd3d_mutex_unlock(&fence->mutex); + } + + if (event == &null_event) + { + vkd3d_null_event_wait(&null_event); + vkd3d_null_event_cleanup(&null_event); + } + + return hr; }
static HRESULT STDMETHODCALLTYPE d3d12_device_SetResidencyPriority(ID3D12Device9 *iface, diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c index eab97715944..cb184986f2a 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -3094,7 +3094,7 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, uint32_t magic, VkIm if (vk_image) { view_desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; - view_desc.pNext = NULL; + view_desc.pNext = &usage_desc; view_desc.flags = 0; view_desc.image = vk_image; view_desc.viewType = desc->view_type; @@ -3107,13 +3107,11 @@ bool vkd3d_create_texture_view(struct d3d12_device *device, uint32_t magic, VkIm view_desc.subresourceRange.levelCount = desc->miplevel_count; view_desc.subresourceRange.baseArrayLayer = desc->layer_idx; view_desc.subresourceRange.layerCount = desc->layer_count; - if (device->vk_info.KHR_maintenance2) - { - usage_desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO; - usage_desc.pNext = NULL; - usage_desc.usage = desc->usage; - view_desc.pNext = &usage_desc; - } + + usage_desc.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO; + usage_desc.pNext = NULL; + usage_desc.usage = desc->usage; + if ((vr = VK_CALL(vkCreateImageView(device->vk_device, &view_desc, NULL, &vk_view))) < 0) { WARN("Failed to create Vulkan image view, vr %d.\n", vr); diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c index aa08dc985bd..819185796c0 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c @@ -754,8 +754,11 @@ struct vkd3d_descriptor_set_context unsigned int uav_counter_index; unsigned int push_constant_index;
- struct vk_binding_array *push_descriptor_set; + struct vk_binding_array *root_descriptor_set; + struct vk_binding_array *static_samplers_descriptor_set; bool push_descriptor; + bool static_samplers; + bool use_vk_heaps; };
static void descriptor_set_context_cleanup(struct vkd3d_descriptor_set_context *context) @@ -806,13 +809,59 @@ static struct vk_binding_array *d3d12_root_signature_vk_binding_array_for_type( { struct vk_binding_array *array, **current;
+ /* There are a few different ways we can reach this point: + * * If we are using virtual heaps we want to allocate descriptors to sets + * depending on their descriptor type, in order to minimize waste when + * recycling descriptor pools. + * + With the exception of root descriptors when we are using push + * descriptors: the push descriptors must be in a separate set, so we + * keep one specifically for them. + * * If we are using Vulkan heaps then all the root table descriptors don't + * even reach here, because they are managed by the D3D12 descriptor + * heap. Thus we only have to deal with root descriptors and static + * samplers. + * + If we're using push descriptors then again we have to dedicate a set + * for them, so static samplers will and up in their own set too. + * + If we're not using push descriptors then we can use the same set and + * save one. In this case we don't care too much about minimizing + * wasted descriptors, because few descriptors can end up here anyway. + */ + if (context->push_descriptor) { - if (!context->push_descriptor_set) - context->push_descriptor_set = d3d12_root_signature_append_vk_binding_array(root_signature, - descriptor_type, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context); + /* The descriptor type is irrelevant here, it will never be used. */ + if (!context->root_descriptor_set) + context->root_descriptor_set = d3d12_root_signature_append_vk_binding_array(root_signature, + 0, VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR, context); + + return context->root_descriptor_set; + } + + if (context->use_vk_heaps) + { + if (context->static_samplers) + { + if (!context->static_samplers_descriptor_set) + { + if (!context->push_descriptor && context->root_descriptor_set) + context->static_samplers_descriptor_set = context->root_descriptor_set; + else + /* The descriptor type is irrelevant here, it will never be used. */ + context->static_samplers_descriptor_set = d3d12_root_signature_append_vk_binding_array( + root_signature, 0, 0, context); + } + + return context->static_samplers_descriptor_set; + } + else + { + /* The descriptor type is irrelevant here, it will never be used. */ + if (!context->root_descriptor_set) + context->root_descriptor_set = d3d12_root_signature_append_vk_binding_array( + root_signature, 0, 0, context);
- return context->push_descriptor_set; + return context->root_descriptor_set; + } }
current = context->current_binding_array; @@ -1638,17 +1687,22 @@ static HRESULT d3d12_root_signature_init(struct d3d12_root_signature *root_signa sizeof(*root_signature->static_samplers)))) goto fail;
+ context.use_vk_heaps = use_vk_heaps; context.push_descriptor = vk_info->KHR_push_descriptor; if (FAILED(hr = d3d12_root_signature_init_root_descriptors(root_signature, desc, &context))) goto fail; - root_signature->main_set = !!context.push_descriptor_set; + root_signature->main_set = context.root_descriptor_set && context.push_descriptor; context.push_descriptor = false;
if (FAILED(hr = d3d12_root_signature_init_push_constants(root_signature, desc, root_signature->push_constant_ranges, &root_signature->push_constant_range_count))) goto fail; + + context.static_samplers = true; if (FAILED(hr = d3d12_root_signature_init_static_samplers(root_signature, device, desc, &context))) goto fail; + context.static_samplers = false; + context.push_constant_index = 0; if (FAILED(hr = d3d12_root_signature_init_root_descriptor_tables(root_signature, desc, &info, &context))) goto fail; @@ -2316,6 +2370,8 @@ static unsigned int feature_flags_compile_option(const struct d3d12_device *devi flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_FLOAT64; if (device->feature_options1.WaveOps) flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_WAVE_OPS; + if (device->vk_info.KHR_zero_initialize_workgroup_memory) + flags |= VKD3D_SHADER_COMPILE_OPTION_FEATURE_ZERO_INITIALIZE_WORKGROUP_MEMORY;
return flags; } @@ -2333,7 +2389,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_15}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, {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)}, @@ -2388,7 +2444,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_15}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, };
@@ -3146,13 +3202,13 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s struct vkd3d_shader_spirv_target_info *stage_target_info; uint32_t aligned_offsets[D3D12_VS_INPUT_REGISTER_COUNT]; struct vkd3d_shader_descriptor_offset_info offset_info; + struct vkd3d_shader_scan_signature_info signature_info; struct vkd3d_shader_parameter ps_shader_parameters[1]; struct vkd3d_shader_transform_feedback_info xfb_info; struct vkd3d_shader_spirv_target_info ps_target_info; struct vkd3d_shader_interface_info shader_interface; struct vkd3d_shader_spirv_target_info target_info; - const struct d3d12_root_signature *root_signature; - struct vkd3d_shader_signature input_signature; + struct d3d12_root_signature *root_signature; bool have_attachment, is_dsv_format_unknown; VkShaderStageFlagBits xfb_stage = 0; VkSampleCountFlagBits sample_count; @@ -3163,7 +3219,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s size_t rt_count; uint32_t mask; HRESULT hr; - int ret;
static const DWORD default_ps_code[] = { @@ -3196,7 +3251,8 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s memset(&state->uav_counters, 0, sizeof(state->uav_counters)); graphics->stage_count = 0;
- memset(&input_signature, 0, sizeof(input_signature)); + memset(&signature_info, 0, sizeof(signature_info)); + signature_info.type = VKD3D_SHADER_STRUCTURE_TYPE_SCAN_SIGNATURE_INFO;
for (i = desc->rtv_formats.NumRenderTargets; i < ARRAY_SIZE(desc->rtv_formats.RTFormats); ++i) { @@ -3207,10 +3263,25 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s } }
+ state->implicit_root_signature = NULL; if (!(root_signature = unsafe_impl_from_ID3D12RootSignature(desc->root_signature))) { - WARN("Root signature is NULL.\n"); - return E_INVALIDARG; + TRACE("Root signature is NULL, looking for an embedded signature in the vertex shader.\n"); + if (FAILED(hr = d3d12_root_signature_create(device, + desc->vs.pShaderBytecode, desc->vs.BytecodeLength, &root_signature)) + && FAILED(hr = d3d12_root_signature_create(device, + desc->ps.pShaderBytecode, desc->ps.BytecodeLength, &root_signature)) + && FAILED(hr = d3d12_root_signature_create(device, + desc->ds.pShaderBytecode, desc->ds.BytecodeLength, &root_signature)) + && FAILED(hr = d3d12_root_signature_create(device, + desc->hs.pShaderBytecode, desc->hs.BytecodeLength, &root_signature)) + && FAILED(hr = d3d12_root_signature_create(device, + desc->gs.pShaderBytecode, desc->gs.BytecodeLength, &root_signature))) + { + WARN("Failed to find an embedded root signature, hr %s.\n", debugstr_hresult(hr)); + goto fail; + } + state->implicit_root_signature = &root_signature->ID3D12RootSignature_iface; }
sample_count = vk_samples_from_dxgi_sample_desc(&desc->sample_desc); @@ -3425,7 +3496,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s for (i = 0; i < ARRAY_SIZE(shader_stages); ++i) { const D3D12_SHADER_BYTECODE *b = (const void *)((uintptr_t)desc + shader_stages[i].offset); - const struct vkd3d_shader_code dxbc = {b->pShaderBytecode, b->BytecodeLength};
if (!b->pShaderBytecode) continue; @@ -3439,14 +3509,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s stage_target_info = &target_info; switch (shader_stages[i].stage) { - case VK_SHADER_STAGE_VERTEX_BIT: - if ((ret = vkd3d_shader_parse_input_signature(&dxbc, &input_signature, NULL)) < 0) - { - hr = hresult_from_vkd3d_result(ret); - goto fail; - } - break; - case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT: case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT: if (desc->primitive_topology_type != D3D12_PRIMITIVE_TOPOLOGY_TYPE_PATCH) @@ -3457,6 +3519,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s } break;
+ case VK_SHADER_STAGE_VERTEX_BIT: case VK_SHADER_STAGE_GEOMETRY_BIT: break;
@@ -3478,11 +3541,14 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s ps_target_info.next = NULL; target_info.next = NULL; offset_info.next = NULL; + signature_info.next = NULL; if (shader_stages[i].stage == xfb_stage) vkd3d_prepend_struct(&shader_interface, &xfb_info); vkd3d_prepend_struct(&shader_interface, stage_target_info); if (root_signature->descriptor_offsets) vkd3d_prepend_struct(&shader_interface, &offset_info); + if (shader_stages[i].stage == VK_SHADER_STAGE_VERTEX_BIT) + vkd3d_prepend_struct(&shader_interface, &signature_info);
if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count], shader_stages[i].stage, b, &shader_interface))) @@ -3533,7 +3599,7 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s goto fail; }
- if (!(signature_element = vkd3d_shader_find_signature_element(&input_signature, + if (!(signature_element = vkd3d_shader_find_signature_element(&signature_info.input, e->SemanticName, e->SemanticIndex, 0))) { WARN("Unused input element %u.\n", i); @@ -3660,19 +3726,21 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s if (FAILED(hr = vkd3d_private_store_init(&state->private_store))) goto fail;
- vkd3d_shader_free_shader_signature(&input_signature); + vkd3d_shader_free_scan_signature_info(&signature_info); state->vk_bind_point = VK_PIPELINE_BIND_POINT_GRAPHICS; - state->implicit_root_signature = NULL; d3d12_device_add_ref(state->device = device);
return S_OK;
fail: + if (state->implicit_root_signature) + ID3D12RootSignature_Release(state->implicit_root_signature); + for (i = 0; i < graphics->stage_count; ++i) { VK_CALL(vkDestroyShaderModule(device->vk_device, state->u.graphics.stages[i].module, NULL)); } - vkd3d_shader_free_shader_signature(&input_signature); + vkd3d_shader_free_scan_signature_info(&signature_info);
d3d12_pipeline_uav_counter_state_cleanup(&state->uav_counters, device);
@@ -4067,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_15}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, };
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h index fd1fbb1679a..7e54738b19e 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -127,12 +127,12 @@ struct vkd3d_vulkan_info bool KHR_draw_indirect_count; bool KHR_get_memory_requirements2; bool KHR_image_format_list; - bool KHR_maintenance2; bool KHR_maintenance3; bool KHR_portability_subset; bool KHR_push_descriptor; bool KHR_sampler_mirror_clamp_to_edge; bool KHR_timeline_semaphore; + bool KHR_zero_initialize_workgroup_memory; /* EXT device extensions */ bool EXT_4444_formats; bool EXT_calibrated_timestamps; @@ -357,6 +357,18 @@ HRESULT vkd3d_set_private_data(struct vkd3d_private_store *store, const GUID *tag, unsigned int data_size, const void *data); HRESULT vkd3d_set_private_data_interface(struct vkd3d_private_store *store, const GUID *tag, const IUnknown *object);
+struct vkd3d_null_event +{ + struct vkd3d_mutex mutex; + struct vkd3d_cond cond; + bool signalled; +}; + +void vkd3d_null_event_cleanup(struct vkd3d_null_event *e); +void vkd3d_null_event_init(struct vkd3d_null_event *e); +void vkd3d_null_event_wait(struct vkd3d_null_event *e); +HRESULT vkd3d_signal_null_event(HANDLE h); + struct vkd3d_signaled_semaphore { uint64_t value; @@ -385,13 +397,12 @@ struct d3d12_fence uint64_t value; uint64_t max_pending_value; struct vkd3d_mutex mutex; - struct vkd3d_cond null_event_cond;
struct vkd3d_waiting_event { - uint64_t value; HANDLE event; - bool *latch; + PFN_vkd3d_signal_event signal; + uint64_t value; } *events; size_t events_size; size_t event_count; @@ -411,8 +422,11 @@ struct d3d12_fence struct vkd3d_private_store private_store; };
+bool d3d12_fence_add_waiting_event(struct d3d12_fence *fence, + HANDLE event, PFN_vkd3d_signal_event signal, uint64_t value); HRESULT d3d12_fence_create(struct d3d12_device *device, uint64_t initial_value, D3D12_FENCE_FLAGS flags, struct d3d12_fence **fence); +struct d3d12_fence *unsafe_impl_from_ID3D12Fence(ID3D12Fence *iface);
VkResult vkd3d_create_timeline_semaphore(const struct d3d12_device *device, uint64_t initial_value, VkSemaphore *timeline_semaphore);
This merge request was approved by Matteo Bruni.