From 7efbc5c239296a3dbe3d03f4b79aa2009ec41ac0 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Tue, 25 Nov 2025 12:56:39 +1100 Subject: [PATCH] Updated vkd3d to e9d08df0108e1a6b7dd67b37f3ed2e35f98100d1. --- libs/vkd3d/Makefile.in | 4 +- libs/vkd3d/include/private/spirv_grammar.h | 561 +-------- libs/vkd3d/include/private/vkd3d_common.h | 9 +- libs/vkd3d/include/private/vkd3d_version.h | 2 +- libs/vkd3d/include/vkd3d_shader.h | 19 + libs/vkd3d/libs/vkd3d-common/blob.c | 1 + libs/vkd3d/libs/vkd3d-shader/dxil.c | 1114 +++++++++-------- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 39 +- libs/vkd3d/libs/vkd3d-shader/ir.c | 96 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 1 + .../libs/vkd3d-shader/vkd3d_shader_main.c | 1 + .../libs/vkd3d-shader/vkd3d_shader_private.h | 4 + libs/vkd3d/libs/vkd3d/command.c | 143 ++- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 14 + 14 files changed, 927 insertions(+), 1081 deletions(-) diff --git a/libs/vkd3d/Makefile.in b/libs/vkd3d/Makefile.in index 9ad9ed850b6..868f4582380 100644 --- a/libs/vkd3d/Makefile.in +++ b/libs/vkd3d/Makefile.in @@ -7,7 +7,6 @@ EXTRADEFS = \ -DLIBVKD3D_UTILS_SOURCE SOURCES = \ - config.h \ libs/vkd3d-common/blob.c \ libs/vkd3d-common/debug.c \ libs/vkd3d-common/error.c \ @@ -40,4 +39,5 @@ SOURCES = \ libs/vkd3d/resource.c \ libs/vkd3d/state.c \ libs/vkd3d/utils.c \ - libs/vkd3d/vkd3d_main.c + libs/vkd3d/vkd3d_main.c \ + config.h diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h index 34cadd9bd58..2aac5a6558c 100644 --- a/libs/vkd3d/include/private/spirv_grammar.h +++ b/libs/vkd3d/include/private/spirv_grammar.h @@ -43,12 +43,10 @@ enum spirv_parser_operand_type SPIRV_PARSER_OPERAND_TYPE_ADDRESSING_MODEL, SPIRV_PARSER_OPERAND_TYPE_BUILT_IN, SPIRV_PARSER_OPERAND_TYPE_CAPABILITY, - SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, - SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT, SPIRV_PARSER_OPERAND_TYPE_DECORATION, SPIRV_PARSER_OPERAND_TYPE_DIM, SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE, @@ -84,7 +82,6 @@ enum spirv_parser_operand_type SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, SPIRV_PARSER_OPERAND_TYPE_LOAD_CACHE_CONTROL, SPIRV_PARSER_OPERAND_TYPE_LOOP_CONTROL, - SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, SPIRV_PARSER_OPERAND_TYPE_MEMORY_MODEL, SPIRV_PARSER_OPERAND_TYPE_MEMORY_SEMANTICS, @@ -149,7 +146,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_BUILT_IN] = { - "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 126, + "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 116, (struct spirv_parser_enumerant[]) { {0, "Position"}, @@ -210,9 +207,6 @@ spirv_parser_operand_type_info[] = {0x1156, "DeviceIndex"}, {0x1158, "ViewIndex"}, {0x115c, "ShadingRateKHR"}, - {0x118c, "TileOffsetQCOM"}, - {0x118d, "TileDimensionQCOM"}, - {0x118e, "TileApronSizeQCOM"}, {0x1380, "BaryCoordNoPerspAMD"}, {0x1381, "BaryCoordNoPerspCentroidAMD"}, {0x1382, "BaryCoordNoPerspSampleAMD"}, @@ -264,25 +258,18 @@ spirv_parser_operand_type_info[] = {0x14e0, "HitMicroTriangleVertexBarycentricsNV"}, {0x14e7, "IncomingRayFlagsKHR"}, {0x14e8, "RayGeometryIndexKHR"}, - {0x14ef, "HitIsSphereNV"}, - {0x14f0, "HitIsLSSNV"}, - {0x14f1, "HitSpherePositionNV"}, {0x14fe, "WarpsPerSMNV"}, {0x14ff, "SMCountNV"}, {0x1500, "WarpIDNV"}, {0x1501, "SMIDNV"}, - {0x1514, "HitLSSPositionsNV"}, {0x151d, "HitKindFrontFacingMicroTriangleNV"}, {0x151e, "HitKindBackFacingMicroTriangleNV"}, - {0x152c, "HitSphereRadiusNV"}, - {0x152d, "HitLSSRadiiNV"}, - {0x153c, "ClusterIDNV"}, {0x1785, "CullMaskKHR"}, } }, [SPIRV_PARSER_OPERAND_TYPE_CAPABILITY] = { - "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 261, + "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 245, (struct spirv_parser_enumerant[]) { {0, "Matrix"}, @@ -393,7 +380,6 @@ spirv_parser_operand_type_info[] = {0x1184, "TextureSampleWeightedQCOM"}, {0x1185, "TextureBoxFilterQCOM"}, {0x1186, "TextureBlockMatchQCOM"}, - {0x118f, "TileShadingQCOM"}, {0x1192, "TextureBlockMatch2QCOM"}, {0x1390, "Float16ImageAMD"}, {0x1391, "ImageGatherBiasLodAMD"}, @@ -404,9 +390,6 @@ spirv_parser_operand_type_info[] = {0x13bf, "ShaderClockKHR"}, {0x13cb, "ShaderEnqueueAMDX"}, {0x13df, "QuadControlKHR"}, - {0x13fc, "BFloat16TypeKHR"}, - {0x13fd, "BFloat16DotProductKHR"}, - {0x13fe, "BFloat16CooperativeMatrixKHR"}, {0x1481, "SampleMaskOverrideCoverageNV"}, {0x1483, "GeometryShaderPassthroughNV"}, {0x1486, "ShaderViewportIndexLayerEXT"}, @@ -452,19 +435,14 @@ spirv_parser_operand_type_info[] = {0x1507, "ShaderInvocationReorderNV"}, {0x150e, "BindlessTextureNV"}, {0x150f, "RayQueryPositionFetchKHR"}, - {0x1512, "CooperativeVectorNV"}, {0x151c, "AtomicFloat16VectorNV"}, {0x1521, "RayTracingDisplacementMicromapNV"}, {0x1526, "RawAccessChainsNV"}, - {0x152a, "RayTracingSpheresGeometryNV"}, - {0x152b, "RayTracingLinearSweptSpheresGeometryNV"}, {0x1536, "CooperativeMatrixReductionsNV"}, {0x1537, "CooperativeMatrixConversionsNV"}, {0x1538, "CooperativeMatrixPerElementOperationsNV"}, {0x1539, "CooperativeMatrixTensorAddressingNV"}, {0x153a, "CooperativeMatrixBlockLoadsNV"}, - {0x153b, "CooperativeVectorTrainingNV"}, - {0x153d, "RayTracingClusterAccelerationStructureNV"}, {0x153f, "TensorAddressingNV"}, {0x15c0, "SubgroupShuffleINTEL"}, {0x15c1, "SubgroupBufferBlockIOINTEL"}, @@ -529,47 +507,18 @@ spirv_parser_operand_type_info[] = {0x1800, "ArithmeticFenceEXT"}, {0x1806, "FPGAClusterAttributesV2INTEL"}, {0x1811, "FPGAKernelAttributesv2INTEL"}, - {0x1812, "TaskSequenceINTEL"}, {0x1819, "FPMaxErrorINTEL"}, {0x181b, "FPGALatencyControlINTEL"}, {0x181e, "FPGAArgumentInterfacesINTEL"}, {0x182b, "GlobalVariableHostAccessINTEL"}, {0x182d, "GlobalVariableFPGADecorationsINTEL"}, {0x184c, "SubgroupBufferPrefetchINTEL"}, - {0x1854, "Subgroup2DBlockIOINTEL"}, - {0x1855, "Subgroup2DBlockTransformINTEL"}, - {0x1856, "Subgroup2DBlockTransposeINTEL"}, - {0x185c, "SubgroupMatrixMultiplyAccumulateINTEL"}, - {0x1861, "TernaryBitwiseFunctionINTEL"}, {0x1900, "GroupUniformArithmeticKHR"}, - {0x1919, "TensorFloat32RoundingINTEL"}, {0x191b, "MaskedGatherScatterINTEL"}, {0x1929, "CacheControlsINTEL"}, {0x193c, "RegisterLimitsINTEL"}, } }, - [SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE] = - { - "ComponentType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 15, - (struct spirv_parser_enumerant[]) - { - {0, "Float16NV"}, - {0x1, "Float32NV"}, - {0x2, "Float64NV"}, - {0x3, "SignedInt8NV"}, - {0x4, "SignedInt16NV"}, - {0x5, "SignedInt32NV"}, - {0x6, "SignedInt64NV"}, - {0x7, "UnsignedInt8NV"}, - {0x8, "UnsignedInt16NV"}, - {0x9, "UnsignedInt32NV"}, - {0xa, "UnsignedInt64NV"}, - {0x3ba247f8, "SignedInt8PackedNV"}, - {0x3ba247f9, "UnsignedInt8PackedNV"}, - {0x3ba247fa, "FloatE4M3NV"}, - {0x3ba247fb, "FloatE5M2NV"}, - } - }, [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT] = { "CooperativeMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, @@ -614,17 +563,6 @@ spirv_parser_operand_type_info[] = {0x2, "MatrixAccumulatorKHR"}, } }, - [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT] = - { - "CooperativeVectorMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, - (struct spirv_parser_enumerant[]) - { - {0, "RowMajorNV"}, - {0x1, "ColumnMajorNV"}, - {0x2, "InferencingOptimalNV"}, - {0x3, "TrainingOptimalNV"}, - } - }, [SPIRV_PARSER_OPERAND_TYPE_DECORATION] = { "Decoration", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 142, @@ -1240,7 +1178,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE] = { - "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 96, + "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 94, (struct spirv_parser_enumerant[]) { { @@ -1389,16 +1327,6 @@ spirv_parser_operand_type_info[] = SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, } }, - {0x1189, "NonCoherentTileAttachmentReadQCOM"}, - { - 0x118a, "TileShadingRateQCOM", 3, - (enum spirv_parser_operand_type[]) - { - SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, - SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, - SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, - } - }, {0x1399, "EarlyAndLateFragmentTestsAMD"}, {0x13a3, "StencilRefReplacingEXT"}, {0x13cd, "CoalescingAMDX"}, @@ -1628,11 +1556,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_FPENCODING] = { - "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 1, - (struct spirv_parser_enumerant[]) - { - {0, "BFloat16KHR"}, - } + "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM }, [SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE] = { @@ -1757,7 +1681,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE] = { - "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 26, + "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 20, (struct spirv_parser_enumerant[]) { {0, "SnormInt8"}, @@ -1777,15 +1701,9 @@ spirv_parser_operand_type_info[] = {0xe, "Float"}, {0xf, "UnormInt24"}, {0x10, "UnormInt101010_2"}, - {0x11, "UnormInt10X6EXT"}, {0x13, "UnsignedIntRaw10EXT"}, {0x14, "UnsignedIntRaw12EXT"}, {0x15, "UnormInt2_101010EXT"}, - {0x16, "UnsignedInt10X6EXT"}, - {0x17, "UnsignedInt12X4EXT"}, - {0x18, "UnsignedInt14X2EXT"}, - {0x19, "UnormInt12X4EXT"}, - {0x1a, "UnormInt14X2EXT"}, } }, [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_ORDER] = @@ -2146,28 +2064,6 @@ spirv_parser_operand_type_info[] = }, } }, - [SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS] = - { - "MatrixMultiplyAccumulateOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 15, - (struct spirv_parser_enumerant[]) - { - {0, "None"}, - {0x1, "MatrixASignedComponentsINTEL"}, - {0x2, "MatrixBSignedComponentsINTEL"}, - {0x4, "MatrixCBFloat16INTEL"}, - {0x8, "MatrixResultBFloat16INTEL"}, - {0x10, "MatrixAPackedInt8INTEL"}, - {0x20, "MatrixBPackedInt8INTEL"}, - {0x40, "MatrixAPackedInt4INTEL"}, - {0x80, "MatrixBPackedInt4INTEL"}, - {0x100, "MatrixATF32INTEL"}, - {0x200, "MatrixBTF32INTEL"}, - {0x400, "MatrixAPackedFloat16INTEL"}, - {0x800, "MatrixBPackedFloat16INTEL"}, - {0x1000, "MatrixAPackedBFloat16INTEL"}, - {0x2000, "MatrixBPackedBFloat16INTEL"}, - } - }, [SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS] = { "MemoryAccess", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 9, @@ -2405,7 +2301,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE] = { - "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 14, + "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 13, (struct spirv_parser_enumerant[]) { {0, "Unknown"}, @@ -2421,12 +2317,11 @@ spirv_parser_operand_type_info[] = {0xa, "WGSL"}, {0xb, "Slang"}, {0xc, "Zig"}, - {0xd, "Rust"}, } }, [SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS] = { - "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 28, + "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 27, (struct spirv_parser_enumerant[]) { {0, "UniformConstant"}, @@ -2443,7 +2338,6 @@ spirv_parser_operand_type_info[] = {0xb, "Image"}, {0xc, "StorageBuffer"}, {0x104c, "TileImageEXT"}, - {0x118b, "TileAttachmentQCOM"}, {0x13cc, "NodePayloadAMDX"}, {0x14d0, "CallableDataKHR"}, {0x14d1, "IncomingCallableDataKHR"}, @@ -6996,78 +6890,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_IMAGE_OPERANDS, '?'}, } }, - { - 0x14a8, "OpTypeCooperativeVectorNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x14a9, "OpCooperativeVectorMatrixMulNV", 13, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, - {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, - } - }, - { - 0x14aa, "OpCooperativeVectorOuterProductAccumulateNV", 7, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, - } - }, - { - 0x14ab, "OpCooperativeVectorReduceSumAccumulateNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x14ac, "OpCooperativeVectorMatrixMulAddNV", 16, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, - {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, - } - }, { 0x14ad, "OpCooperativeMatrixConvertNV", 3, (struct spirv_parser_instruction_operand[]) @@ -7138,27 +6960,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x14b6, "OpCooperativeVectorLoadNV", 5, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, - } - }, - { - 0x14b7, "OpCooperativeVectorStoreNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, - } - }, { 0x14d6, "OpReportIntersectionKHR", 4, (struct spirv_parser_instruction_operand[]) @@ -7249,25 +7050,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x14e1, "OpRayQueryGetClusterIdNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x14e2, "OpHitObjectGetClusterIdNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x14ee, "OpTypeCooperativeMatrixNV", 5, (struct spirv_parser_instruction_operand[]) @@ -7580,130 +7362,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, '?'}, } }, - { - 0x1533, "OpRayQueryGetIntersectionSpherePositionNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1534, "OpRayQueryGetIntersectionSphereRadiusNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1535, "OpRayQueryGetIntersectionLSSPositionsNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1536, "OpRayQueryGetIntersectionLSSRadiiNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1537, "OpRayQueryGetIntersectionLSSHitValueNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1538, "OpHitObjectGetSpherePositionNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1539, "OpHitObjectGetSphereRadiusNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153a, "OpHitObjectGetLSSPositionsNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153b, "OpHitObjectGetLSSRadiiNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153c, "OpHitObjectIsSphereHitNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153d, "OpHitObjectIsLSSHitNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153e, "OpRayQueryIsSphereHitNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153f, "OpRayQueryIsLSSHitNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x15c3, "OpSubgroupShuffleINTEL", 4, (struct spirv_parser_instruction_operand[]) @@ -7962,9 +7620,10 @@ spirv_parser_opcode_info[] = } }, { - 0x15e9, "OpAsmTargetINTEL", 2, + 0x15e9, "OpAsmTargetINTEL", 3, (struct spirv_parser_instruction_operand[]) { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, } @@ -9237,7 +8896,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 8, + 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -9248,6 +8907,7 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, } }, { @@ -9279,7 +8939,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16d3, "OpArbitraryFloatCastToIntINTEL", 8, + 0x16d3, "OpArbitraryFloatCastToIntINTEL", 7, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -9289,7 +8949,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, } }, { @@ -9803,7 +9462,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16fa, "OpArbitraryFloatPowNINTEL", 10, + 0x16fa, "OpArbitraryFloatPowNINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -9815,7 +9474,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, } }, { @@ -9851,12 +9509,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1723, "OpFixedSqrtINTEL", 8, + 0x1723, "OpFixedSqrtINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9865,12 +9524,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1724, "OpFixedRecipINTEL", 8, + 0x1724, "OpFixedRecipINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9879,12 +9539,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1725, "OpFixedRsqrtINTEL", 8, + 0x1725, "OpFixedRsqrtINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9893,12 +9554,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1726, "OpFixedSinINTEL", 8, + 0x1726, "OpFixedSinINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9907,12 +9569,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1727, "OpFixedCosINTEL", 8, + 0x1727, "OpFixedCosINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9921,12 +9584,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1728, "OpFixedSinCosINTEL", 8, + 0x1728, "OpFixedSinCosINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9935,12 +9599,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1729, "OpFixedSinPiINTEL", 8, + 0x1729, "OpFixedSinPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9949,12 +9614,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172a, "OpFixedCosPiINTEL", 8, + 0x172a, "OpFixedCosPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9963,12 +9629,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172b, "OpFixedSinCosPiINTEL", 8, + 0x172b, "OpFixedSinCosPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9977,12 +9644,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172c, "OpFixedLogINTEL", 8, + 0x172c, "OpFixedLogINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9991,12 +9659,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172d, "OpFixedExpINTEL", 8, + 0x172d, "OpFixedExpINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -10043,12 +9712,13 @@ spirv_parser_opcode_info[] = } }, { - 0x173d, "OpFPGARegINTEL", 3, + 0x173d, "OpFPGARegINTEL", 4, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, { @@ -10311,50 +9981,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x1813, "OpTaskSequenceCreateINTEL", 7, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - } - }, - { - 0x1814, "OpTaskSequenceAsyncINTEL", 2, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, - } - }, - { - 0x1815, "OpTaskSequenceGetINTEL", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1816, "OpTaskSequenceReleaseINTEL", 1, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1837, "OpTypeTaskSequenceINTEL", 1, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - } - }, { 0x184d, "OpSubgroupBlockPrefetchINTEL", 3, (struct spirv_parser_instruction_operand[]) @@ -10364,110 +9990,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, } }, - { - 0x1857, "OpSubgroup2DBlockLoadINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1858, "OpSubgroup2DBlockLoadTransformINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1859, "OpSubgroup2DBlockLoadTransposeINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x185a, "OpSubgroup2DBlockPrefetchINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x185b, "OpSubgroup2DBlockStoreINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x185d, "OpSubgroupMatrixMultiplyAccumulateINTEL", 7, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, '?'}, - } - }, - { - 0x1862, "OpBitwiseFunctionINTEL", 6, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x1901, "OpGroupIMulKHR", 5, (struct spirv_parser_instruction_operand[]) @@ -10556,15 +10078,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x191a, "OpRoundFToTF32INTEL", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x191c, "OpMaskedGatherINTEL", 6, (struct spirv_parser_instruction_operand[]) diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h index 7ee11b54396..60d1665cc85 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -285,7 +285,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) { #ifdef _MSC_VER return __popcnt(v); -#elif defined(__MINGW32__) +#elif defined(HAVE_BUILTIN_POPCOUNT) return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; @@ -349,12 +349,7 @@ static inline unsigned int vkd3d_log2i(unsigned int x) static inline unsigned int vkd3d_ctz(uint32_t v) { -#ifdef _WIN32 - ULONG result; - if (_BitScanForward(&result, v)) - return (unsigned int)result; - return 32; -#elif defined(HAVE_BUILTIN_CTZ) +#ifdef HAVE_BUILTIN_CTZ return __builtin_ctz(v); #else unsigned int c = 31; diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h index 0edc4428022..687751d6a5f 100644 --- a/libs/vkd3d/include/private/vkd3d_version.h +++ b/libs/vkd3d/include/private/vkd3d_version.h @@ -1 +1 @@ -#define VKD3D_VCS_ID " (Wine bundled)" +#define VKD3D_VCS_ID " (git a8ca1f95)" diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index 352c222f27d..cc6cf4001a7 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -1039,6 +1039,25 @@ enum vkd3d_shader_parameter_name VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_3, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_4, VKD3D_SHADER_PARAMETER_NAME_BUMP_LUMINANCE_OFFSET_5, + /** + * A mask of projected textures. + * + * When this parameter is provided to a shader model 1.0-1.3 pixel shader, + * for each nonzero bit of this mask, the corresponding texture will be + * projected. That is, it will have its coordinates divided by their W + * component before sampling. + * + * The default value is zero, i.e. no textures are projected. + * + * The data type for this parameter must be + * VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32. + * + * Only VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT is supported in this + * version of vkd3d-shader. + * + * \since 1.19 + */ + VKD3D_SHADER_PARAMETER_NAME_PROJECTED_TEXTURE_MASK, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_PARAMETER_NAME), }; diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c index f60ef7db769..c2c6ad67804 100644 --- a/libs/vkd3d/libs/vkd3d-common/blob.c +++ b/libs/vkd3d/libs/vkd3d-common/blob.c @@ -20,6 +20,7 @@ #define WIDL_C_INLINE_WRAPPERS #endif #define COBJMACROS + #define CONST_VTABLE #include "vkd3d.h" #include "vkd3d_blob.h" diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index 9f25ae8334b..2d1187fd7e5 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -176,6 +176,11 @@ enum bitcode_value_symtab_code VST_CODE_BBENTRY = 2, }; +enum bitcode_paramattr_group_code +{ + PARAMATTR_GRP_CODE_ENTRY = 3, +}; + enum bitcode_linkage { LINKAGE_EXTERNAL = 0, @@ -596,10 +601,20 @@ struct sm6_pointer_info enum bitcode_address_space addr_space; }; +enum dxil_well_known_structs +{ + WELL_KNOWN_NONE = 0, + WELL_KNOWN_HANDLE, + WELL_KNOWN_DIMENSIONS, + WELL_KNOWN_SPLITDOUBLE, + WELL_KNOWN_FOURI32, +}; + struct sm6_struct_info { const char *name; unsigned int elem_count; + enum dxil_well_known_structs well_known; const struct sm6_type *elem_types[]; }; @@ -748,67 +763,15 @@ struct sm6_symbol struct incoming_value { - const struct sm6_block *block; - struct vkd3d_shader_register reg; -}; - -struct sm6_phi -{ - struct sm6_value value; - struct incoming_value *incoming; - size_t incoming_capacity; - size_t incoming_count; -}; - -enum sm6_block_terminator_type -{ - TERMINATOR_UNCOND_BR, - TERMINATOR_COND_BR, - TERMINATOR_SWITCH, - TERMINATOR_RET, -}; - -struct terminator_case -{ - const struct sm6_block *block; - uint64_t value; - bool is_default; -}; - -struct sm6_block_terminator -{ - struct vkd3d_shader_register conditional_reg; - enum sm6_block_terminator_type type; - const struct sm6_block *true_block; - const struct sm6_block *false_block; - struct terminator_case *cases; - unsigned int case_count; -}; - -struct sm6_block -{ - struct vkd3d_shader_instruction *instructions; - size_t instruction_capacity; - size_t instruction_count; - - /* A nonzero id. */ - unsigned int id; - - struct sm6_phi *phi; - size_t phi_capacity; - size_t phi_count; - - struct sm6_block_terminator terminator; + unsigned int block_idx; + const struct sm6_value *src; }; struct sm6_function { const struct sm6_value *declaration; - - struct sm6_block **blocks; - size_t block_capacity; + struct vkd3d_shader_instruction_array instructions; size_t block_count; - size_t value_count; }; @@ -895,6 +858,38 @@ struct sm6_descriptor_info enum vsir_data_type reg_data_type; }; +enum dxil_attribute_kind +{ + ATTRIBUTE_WELL_KNOWN = 0, + ATTRIBUTE_WELL_KNOWN_WITH_INTEGER_VALUE = 1, + ATTRIBUTE_STRING = 3, + ATTRIBUTE_STRING_WITH_STRING_VALUE = 4, +}; + +struct dxil_attribute +{ + enum dxil_attribute_kind kind; + union + { + uint64_t well_known; + const char *string; + } key; + union + { + uint64_t numeric; + const char *string; + } value; +}; + +struct dxil_attribute_group +{ + unsigned int group_id; + unsigned int parameter_idx; + struct dxil_attribute *attributes; + size_t attribute_count; + size_t attribute_capacity; +}; + struct sm6_parser { const uint32_t *ptr, *start, *end; @@ -948,6 +943,9 @@ struct sm6_parser size_t cur_max_value; unsigned int ssa_next_id; + struct dxil_attribute_group *attribute_groups; + size_t attribute_group_count; + struct vkd3d_shader_parser p; }; @@ -1630,6 +1628,50 @@ static char *dxil_record_to_string(const struct dxil_record *record, unsigned in return str; } +static char *dxil_record_to_zero_terminated_string(const struct dxil_record *record, + unsigned int *offset, struct sm6_parser *dxil) +{ + size_t str_len = 0, str_capacity = 0; + char *str = NULL; + unsigned int i; + + VKD3D_ASSERT(*offset < record->operand_count); + + for (i = *offset; i < record->operand_count; ++i) + { + if (record->operands[i] > UCHAR_MAX) + { + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_STRING, + "Operand value %"PRIu64" is not a valid string character.", record->operands[i]); + vkd3d_free(str); + return NULL; + } + + if (!vkd3d_array_reserve((void **)&str, &str_capacity, str_len + 1, sizeof(*str))) + { + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Out of memory allocating a string of length %zu.", str_len + 1); + vkd3d_free(str); + return NULL; + } + + if (!(str[str_len++] = record->operands[i])) + break; + } + + if (i == record->operand_count) + { + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_STRING, + "String is not zero-terminated."); + vkd3d_free(str); + return NULL; + } + + *offset = i + 1; + + return str; +} + static bool dxil_record_validate_operand_min_count(const struct dxil_record *record, unsigned int min_count, struct sm6_parser *sm6) { @@ -1660,6 +1702,8 @@ static bool dxil_record_validate_operand_count(const struct dxil_record *record, return dxil_record_validate_operand_min_count(record, min_count, sm6); } +static void dxil_recognise_well_known_struct(struct sm6_parser *dxil, struct sm6_struct_info *info); + static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6) { const struct dxil_record *record; @@ -1875,11 +1919,14 @@ static enum vkd3d_result sm6_parser_type_table_init(struct sm6_parser *sm6) break; } - if (!strcmp(struct_name, "dx.types.Handle")) - sm6->handle_type = type; - type->u.struc->name = struct_name; struct_name = NULL; + + dxil_recognise_well_known_struct(sm6, type->u.struc); + + if (type->u.struc->well_known == WELL_KNOWN_HANDLE) + sm6->handle_type = type; + break; case TYPE_CODE_STRUCT_NAME: @@ -2034,7 +2081,7 @@ static inline bool sm6_type_is_function_pointer(const struct sm6_type *type) static inline bool sm6_type_is_handle(const struct sm6_type *type) { - return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Handle"); + return sm6_type_is_struct(type) && type->u.struc->well_known == WELL_KNOWN_HANDLE; } static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type *type, @@ -2055,6 +2102,79 @@ static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type return NULL; } +static void dxil_recognise_well_known_struct(struct sm6_parser *dxil, struct sm6_struct_info *info) +{ + unsigned int i; + + info->well_known = WELL_KNOWN_NONE; + + if (!info->name) + return; + + if (!strcmp(info->name, "dx.types.Dimensions")) + { + if (info->elem_count != 4) + goto error; + for (i = 0; i < 4; ++i) + { + if (!sm6_type_is_i32(info->elem_types[i])) + goto error; + } + info->well_known = WELL_KNOWN_DIMENSIONS; + + return; + } + + if (!strcmp(info->name, "dx.types.fouri32")) + { + if (info->elem_count != 4) + goto error; + for (i = 0; i < 4; ++i) + { + if (!sm6_type_is_i32(info->elem_types[i])) + goto error; + } + info->well_known = WELL_KNOWN_FOURI32; + + return; + } + + if (!strcmp(info->name, "dx.types.Handle")) + { + if (info->elem_count != 1) + goto error; + if (!sm6_type_is_pointer(info->elem_types[0])) + goto error; + if (!sm6_type_is_i8(info->elem_types[0]->u.pointer.type)) + goto error; + if (info->elem_types[0]->u.pointer.addr_space != ADDRESS_SPACE_DEFAULT) + goto error; + info->well_known = WELL_KNOWN_HANDLE; + + return; + } + + if (!strcmp(info->name, "dx.types.splitdouble")) + { + if (info->elem_count != 2) + goto error; + for (i = 0; i < 2; ++i) + { + if (!sm6_type_is_i32(info->elem_types[i])) + goto error; + } + info->well_known = WELL_KNOWN_SPLITDOUBLE; + + return; + } + + return; + +error: + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "Structure type `%s' has unexpected fields.", info->name); +} + static const struct sm6_type *sm6_type_get_cmpxchg_result_struct(struct sm6_parser *sm6) { const struct sm6_type *type; @@ -2890,27 +3010,24 @@ static size_t sm6_parser_compute_max_value_count(struct sm6_parser *sm6, return value_count; } -static size_t sm6_parser_get_value_index(struct sm6_parser *sm6, uint64_t idx) +static size_t sm6_parser_get_value_index(struct sm6_parser *dxil, uint32_t idx) { size_t i; - /* The value relative index is 32 bits. */ - if (idx > UINT32_MAX) - WARN("Ignoring upper 32 bits of relative index.\n"); - i = (uint32_t)sm6->value_count - (uint32_t)idx; + i = (uint32_t)dxil->value_count - idx; - /* This may underflow to produce a forward reference, but it must not exceed the final value count. */ - if (i >= sm6->cur_max_value) + /* This may underflow to produce a forward reference, but it must not + * exceed the final value count. */ + if (i >= dxil->cur_max_value) { - WARN("Invalid value index %"PRIx64" at %zu.\n", idx, sm6->value_count); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Invalid value relative index %u.", (unsigned int)idx); + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Invalid value relative index %u.", idx); return SIZE_MAX; } - if (i == sm6->value_count) + + if (i == dxil->value_count) { - WARN("Invalid value self-reference at %zu.\n", sm6->value_count); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Invalid value self-reference."); + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Invalid value self-reference."); return SIZE_MAX; } @@ -3084,10 +3201,34 @@ static struct sm6_value *sm6_parser_get_value_safe(struct sm6_parser *sm6, unsig return NULL; } +static void sm6_parser_pre_init_or_validate_referenced_value(struct sm6_parser *dxil, + size_t operand, const struct sm6_type *fwd_type) +{ + struct sm6_value *value; + + value = &dxil->values[operand]; + + /* If the value has a type, validate that it matches the expected type, + * otherwise it is a forward reference and we must set the type and + * initialise the value's register to SSA so it can be consumed by an + * instruction. */ + if (value->type) + { + if (value->type != fwd_type) + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "The type of a source value does not match the predefined type."); + } + else + { + value->type = fwd_type; + value->value_type = VALUE_TYPE_SSA; + value->u.ssa.id = sm6_parser_alloc_ssa_id(dxil); + } +} + static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const struct dxil_record *record, const struct sm6_type *fwd_type, unsigned int *rec_idx) { - struct sm6_value *value; unsigned int idx; uint64_t val_ref; size_t operand; @@ -3097,6 +3238,11 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru return SIZE_MAX; val_ref = record->operands[idx++]; + /* Normally only the lower 32 bits are set in the value relative index. */ + if (val_ref > UINT32_MAX) + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring upper 32 bits of DXIL SSA value relative index %"PRIx64".", val_ref); + operand = sm6_parser_get_value_index(sm6, val_ref); if (operand == SIZE_MAX) return SIZE_MAX; @@ -3113,26 +3259,40 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru *rec_idx = idx; if (fwd_type) + sm6_parser_pre_init_or_validate_referenced_value(sm6, operand, fwd_type); + + return operand; +} + +static uint64_t decode_rotated_signed_value(uint64_t value) +{ + if (value != 1) { - value = &sm6->values[operand]; - if (value->type) - { - if (value->type != fwd_type) - { - WARN("Value already has a mismatching type.\n"); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, - "The type of a source value does not match the predefined type."); - } - } - else - { - value->type = fwd_type; - value->value_type = VALUE_TYPE_SSA; - value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); - } + bool neg = value & 1; + value >>= 1; + return neg ? -value : value; } - return operand; + return value << 63; +} + +static const struct sm6_value *sm6_parser_get_value_by_rotated_signed_idx(struct sm6_parser *dxil, + uint64_t idx, const struct sm6_type *fwd_type) +{ + int64_t rotated_idx; + size_t operand; + + rotated_idx = decode_rotated_signed_value(idx); + if (rotated_idx > INT32_MAX || rotated_idx < INT32_MIN) + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_OPERANDS, + "Ignoring upper 32 bits of DXIL SSA value signed relative index %"PRIx64".", rotated_idx); + + if ((operand = sm6_parser_get_value_index(dxil, rotated_idx)) == SIZE_MAX) + return NULL; + + sm6_parser_pre_init_or_validate_referenced_value(dxil, operand, fwd_type); + + return &dxil->values[operand]; } static const struct sm6_value *sm6_parser_get_value_by_ref(struct sm6_parser *sm6, @@ -3206,17 +3366,6 @@ static bool sm6_parser_declare_function(struct sm6_parser *sm6, const struct dxi return true; } -static inline uint64_t decode_rotated_signed_value(uint64_t value) -{ - if (value != 1) - { - bool neg = value & 1; - value >>= 1; - return neg ? -value : value; - } - return value << 63; -} - static struct sm6_index *sm6_get_value_index(struct sm6_parser *sm6, struct sm6_value *value) { switch (value->value_type) @@ -4295,35 +4444,9 @@ static const struct sm6_value *sm6_parser_next_function_definition(struct sm6_pa return &sm6->values[i]; } -static struct sm6_block *sm6_block_create() -{ - struct sm6_block *block = vkd3d_calloc(1, sizeof(*block)); - return block; -} - -static struct sm6_phi *sm6_block_phi_require_space(struct sm6_block *block, struct sm6_parser *sm6) -{ - struct sm6_phi *phi; - - if (!vkd3d_array_reserve((void **)&block->phi, &block->phi_capacity, block->phi_count + 1, sizeof(*block->phi))) - { - ERR("Failed to allocate phi array.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, - "Out of memory allocating a phi instruction."); - return NULL; - } - phi = &block->phi[block->phi_count++]; - - phi->incoming = NULL; - phi->incoming_capacity = 0; - phi->incoming_count = 0; - - return phi; -} - struct function_emission_state { - struct sm6_block *code_block; + struct sm6_function *function; struct vkd3d_shader_instruction *ins; unsigned int temp_idx; }; @@ -4623,7 +4746,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty } static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) + struct sm6_function *function, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { enum vkd3d_shader_opcode opcode, aux_opcode; struct vkd3d_shader_src_param *src_params; @@ -4664,7 +4787,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco register_init_with_id(&dst_params[0].reg, VKD3DSPR_SSA, src_params[0].reg.data_type, aux_id); ++ins; - ++code_block->instruction_count; + ++function->instructions.count; } vsir_instruction_init(ins, &sm6->p.location, opcode); @@ -4741,59 +4864,75 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco instruction_dst_param_init_ssa_scalar(ins, type_flags, sm6); } -static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, - struct sm6_parser *sm6) +static bool sm6_function_validate_block_index(const struct sm6_function *function, + uint64_t index, struct sm6_parser *dxil) { if (index >= function->block_count) { - WARN("Invalid code block index %#"PRIx64".\n", index); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, "Invalid code block index %#"PRIx64" for a control flow instruction.", index); - return NULL; + return false; } - return function->blocks[index]; + + return true; } -static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) +static void sm6_parser_emit_br(struct sm6_parser *dxil, const struct dxil_record *record, + struct sm6_function *function, struct vkd3d_shader_instruction *ins) { + struct vkd3d_shader_src_param *src_params; const struct sm6_value *value; unsigned int i = 2; if (record->operand_count != 1 && record->operand_count < 3) { - WARN("Invalid operand count %u.\n", record->operand_count); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, "Invalid operand count %u for a branch instruction.", record->operand_count); return; } if (record->operand_count == 1) { - code_block->terminator.type = TERMINATOR_UNCOND_BR; - code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6); + if (!sm6_function_validate_block_index(function, record->operands[0], dxil)) + return; + + vsir_instruction_init(ins, &dxil->p.location, VSIR_OP_BRANCH); + if (!(src_params = instruction_src_params_alloc(ins, 1, dxil))) + { + vkd3d_shader_instruction_make_nop(ins); + return; + } + /* Label id is 1-based. */ + vsir_src_param_init_label(&src_params[0], record->operands[0] + 1); } else { - if (!sm6->bool_type) + if (!dxil->bool_type) { - WARN("Bool type not found.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE, "Module does not define a boolean type for conditions."); return; } - if (!(value = sm6_parser_get_value_by_ref(sm6, record, sm6->bool_type, &i)) - || !sm6_value_validate_is_bool(value, sm6)) + if (!(value = sm6_parser_get_value_by_ref(dxil, record, dxil->bool_type, &i)) + || !sm6_value_validate_is_bool(value, dxil)) return; - dxil_record_validate_operand_max_count(record, i, sm6); + dxil_record_validate_operand_max_count(record, i, dxil); - code_block->terminator.type = TERMINATOR_COND_BR; - vsir_register_from_dxil_value(&code_block->terminator.conditional_reg, value, 0, sm6); - 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); - } + if (!sm6_function_validate_block_index(function, record->operands[0], dxil) + || !sm6_function_validate_block_index(function, record->operands[1], dxil)) + return; - ins->opcode = VSIR_OP_NOP; + vsir_instruction_init(ins, &dxil->p.location, VSIR_OP_BRANCH); + if (!(src_params = instruction_src_params_alloc(ins, 3, dxil))) + { + vkd3d_shader_instruction_make_nop(ins); + return; + } + src_param_init_from_value(&src_params[0], value, 0, dxil); + /* Label id is 1-based. */ + vsir_src_param_init_label(&src_params[1], record->operands[0] + 1); + vsir_src_param_init_label(&src_params[2], record->operands[1] + 1); + } } static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, @@ -4847,7 +4986,7 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, } state->ins = ins; - state->code_block->instruction_count += component_count; + state->function->instructions.count += component_count; return true; } @@ -5394,7 +5533,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ if (op == DX_EMIT_THEN_CUT_STREAM) { ++state->ins; - ++state->code_block->instruction_count; + ++state->function->instructions.count; sm6_parser_emit_dx_stream(sm6, DX_CUT_STREAM, operands, state); } } @@ -5672,7 +5811,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in src_param_init_vector_from_reg(&src_params[0], &dst->reg); state->ins = ins; - state->code_block->instruction_count += 2; + state->function->instructions.count += 2; } } else @@ -6828,13 +6967,13 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 'g': return sm6_type_is_floating_point(type); case 'H': - return sm6_value_is_handle(value) && type == sm6->handle_type; + return sm6_value_is_handle(value) && type->u.struc->well_known == WELL_KNOWN_HANDLE; case 'D': - return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Dimensions"); + return sm6_type_is_struct(type) && type->u.struc->well_known == WELL_KNOWN_DIMENSIONS; case 'S': - return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.splitdouble"); + return sm6_type_is_struct(type) && type->u.struc->well_known == WELL_KNOWN_SPLITDOUBLE; case 'V': - return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.fouri32"); + return sm6_type_is_struct(type) && type->u.struc->well_known == WELL_KNOWN_FOURI32; case 'v': return sm6_value_is_invalid(value) && !type; case 'o': @@ -7646,109 +7785,118 @@ static int phi_incoming_compare(const void *a, const void *b) { const struct incoming_value *incoming_a = a, *incoming_b = b; - return (incoming_a->block > incoming_b->block) - (incoming_a->block < incoming_b->block); + return vkd3d_u32_compare(incoming_a->block_idx, incoming_b->block_idx); } -static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins, - struct sm6_value *dst) +static void sm6_parser_emit_phi(struct sm6_parser *dxil, const struct dxil_record *record, + struct sm6_function *function, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { + struct vkd3d_shader_src_param *src_params; + unsigned int i, j, incoming_count; struct incoming_value *incoming; + const struct sm6_value *src; const struct sm6_type *type; - struct sm6_phi *phi; - unsigned int i, j; - uint64_t src_idx; if (!(record->operand_count & 1)) { - WARN("Invalid operand count %u.\n", record->operand_count); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, "Invalid operand count %u for phi instruction.", record->operand_count); return; } - if (!(type = sm6_parser_get_type(sm6, record->operands[0]))) + if (!(type = sm6_parser_get_type(dxil, record->operands[0]))) return; if (!sm6_type_is_numeric(type)) { /* dxc doesn't seem to use buffer/resource read return types here. */ - FIXME("Only scalar numeric types are supported.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, "Result type class %u of a phi instruction is not scalar numeric.", type->class); return; } dst->type = type; - sm6_parser_init_ssa_value(sm6, dst); - if (!(phi = sm6_block_phi_require_space(code_block, sm6))) - return; - phi->incoming_count = record->operand_count / 2u; - - if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, - sizeof(*phi->incoming))) + incoming_count = record->operand_count / 2u; + if (!(incoming = vkd3d_calloc(incoming_count, sizeof(*incoming)))) { - ERR("Failed to allocate phi incoming array.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, "Out of memory allocating a phi incoming array."); return; } - incoming = phi->incoming; for (i = 1; i < record->operand_count; i += 2) { - src_idx = sm6->value_count - decode_rotated_signed_value(record->operands[i]); - /* May be a forward reference. */ - if (src_idx >= sm6->cur_max_value) + /* Phi forward references are handled by the same mechanism as all + * others. Constant and undefined values are never forward references, + * and the only other valid incoming is an SSA value, which will be + * initialised if necessary. */ + if (!(src = sm6_parser_get_value_by_rotated_signed_idx(dxil, record->operands[i], type))) + goto done; + + if (!sm6_value_is_constant(src) && !sm6_value_is_undef(src) && !sm6_value_is_ssa(src)) { - WARN("Invalid value index %"PRIu64".\n", src_idx); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Invalid value index %"PRIu64" for a phi incoming value.", src_idx); - return; + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "A PHI incoming value is not a constant or SSA register."); + goto done; } + if (src->type != type) + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "The type of a phi incoming value does not match the result type."); + + if (!sm6_function_validate_block_index(function, record->operands[i + 1], dxil)) + goto done; + j = i / 2u; - /* Store the value index in the register for later resolution. */ - incoming[j].reg.idx[0].offset = src_idx; - incoming[j].block = sm6_function_get_block(function, record->operands[i + 1], sm6); + incoming[j].src = src; + incoming[j].block_idx = record->operands[i + 1]; } - ins->opcode = VSIR_OP_NOP; - - qsort(incoming, phi->incoming_count, sizeof(*incoming), phi_incoming_compare); + qsort(incoming, incoming_count, sizeof(*incoming), phi_incoming_compare); - for (i = 1, j = 1; i < phi->incoming_count; ++i) + /* Deduplicate incomings. DXIL phi instructions can contain duplicates. */ + for (i = 1, j = 1; i < incoming_count; ++i) { - if (incoming[i].block != incoming[i - 1].block) + if (incoming[i].block_idx != incoming[i - 1].block_idx) { incoming[j++] = incoming[i]; continue; } - if (incoming[i].reg.idx[0].offset != incoming[i - 1].reg.idx[0].offset) - { - WARN("PHI conflict.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + if (incoming[i].src != incoming[i - 1].src) + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Two phi incomings have the same block but different values."); - } } - /* if (j == 1) we should be able to set dst->u.reg to incoming[0].reg, but structurisation - * may potentially add new incomings. */ - phi->incoming_count = j; + incoming_count = j; + + vsir_instruction_init(ins, &dxil->p.location, VSIR_OP_PHI); + if (!(src_params = instruction_src_params_alloc(ins, incoming_count * 2u, dxil))) + goto done; + + for (i = 0; i < incoming_count; ++i) + { + j = i * 2u; + src_param_init_from_value(&src_params[j], incoming[i].src, 0, dxil); + vsir_src_param_init_label(&src_params[j + 1], incoming[i].block_idx + 1); + } + + instruction_dst_param_init_ssa_scalar(ins, 0, dxil); + +done: + vkd3d_free(incoming); } -static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) +static void sm6_parser_emit_ret(struct sm6_parser *dxil, + const struct dxil_record *record, struct vkd3d_shader_instruction *ins) { - if (!dxil_record_validate_operand_count(record, 0, 1, sm6)) + if (!dxil_record_validate_operand_count(record, 0, 1, dxil)) return; if (record->operand_count) - FIXME("Non-void return is not implemented.\n"); + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + "Non-void return is not implemented."); - code_block->terminator.type = TERMINATOR_RET; - - ins->opcode = VSIR_OP_NOP; + vsir_instruction_init(ins, &dxil->p.location, VSIR_OP_RET); } static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record, @@ -7831,87 +7979,98 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco dst_param->reg.idx_count = 1; } -static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_record *record, - struct sm6_function *function, struct sm6_block *code_block, struct vkd3d_shader_instruction *ins) +static void sm6_parser_emit_switch(struct sm6_parser *dxil, const struct dxil_record *record, + struct sm6_function *function, struct vkd3d_shader_instruction *ins) { - struct sm6_block_terminator *terminator = &code_block->terminator; + struct vkd3d_shader_src_param *src_params; const struct sm6_type *type; const struct sm6_value *src; - unsigned int i = 1, j; + uint64_t case_value; + unsigned int i = 1; if (record->operand_count < 3 || !(record->operand_count & 1)) { - WARN("Invalid operand count %u.\n", record->operand_count); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT, "Invalid operand count %u for a switch instruction.", record->operand_count); return; } - if (!(type = sm6_parser_get_type(sm6, record->operands[0]))) + if (!(type = sm6_parser_get_type(dxil, record->operands[0]))) return; - if (!(src = sm6_parser_get_value_by_ref(sm6, record, type, &i)) - || !sm6_value_validate_is_register(src, sm6)) + if (!(src = sm6_parser_get_value_by_ref(dxil, record, type, &i)) + || !sm6_value_validate_is_register(src, dxil)) return; VKD3D_ASSERT(i == 2); if (src->type != type) - { - WARN("Type mismatch.\n"); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, "The type of a switch selector value does not match the selector type."); - } + if (!sm6_type_is_integer(type)) { - WARN("Selector is not scalar integer.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Selector type class %u of a switch instruction is not scalar integer.", type->class); return; } - vsir_register_from_dxil_value(&terminator->conditional_reg, src, 0, sm6); - terminator->type = TERMINATOR_SWITCH; + if (!sm6_function_validate_block_index(function, record->operands[2], dxil)) + return; - terminator->case_count = record->operand_count / 2u; - if (!(terminator->cases = vkd3d_calloc(terminator->case_count, sizeof(*terminator->cases)))) + vsir_instruction_init(ins, &dxil->p.location, VSIR_OP_SWITCH_MONOLITHIC); + if (!(src_params = instruction_src_params_alloc(ins, record->operand_count, dxil))) { - ERR("Failed to allocate case array.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, - "Out of memory allocating a switch case array."); + vkd3d_shader_instruction_make_nop(ins); return; } - /* Executes 'operand_count / 2' times because operand_count is uneven. */ - for (; i < record->operand_count; i += 2) - { - j = i / 2u - 1; - terminator->cases[j].block = sm6_function_get_block(function, record->operands[i], sm6); - /* For structurisation it is convenient to store the default in the case array. */ - terminator->cases[j].is_default = !j; - } + src_param_init_from_value(&src_params[0], src, 0, dxil); + /* Set the default block label id, 1-based. */ + vsir_src_param_init_label(&src_params[1], record->operands[2] + 1); + /* Set a zero merge block label id as a placeholder until it is set during + * the structurisation pass. */ + vsir_src_param_init_label(&src_params[2], 0); for (i = 3; i < record->operand_count; i += 2) { - if (!(src = sm6_parser_get_value_safe(sm6, record->operands[i]))) + if (!(src = sm6_parser_get_value_safe(dxil, record->operands[i]))) + { + vkd3d_shader_instruction_make_nop(ins); return; + } if (src->type != type) - { - WARN("Type mismatch.\n"); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, "The type of a switch case value does not match the selector type."); - } if (!sm6_value_is_constant(src)) - { - WARN("Case value is not a constant.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "A switch case value is not a constant."); + + case_value = sm6_value_get_constant_uint64(src, dxil); + + /* Set the case constant value. 64-bit values are supported. */ + if (src_params[0].reg.data_type == VSIR_DATA_U64) + { + vsir_src_param_init(&src_params[i], VKD3DSPR_IMMCONST64, VSIR_DATA_U64, 0); + src_params[i].reg.u.immconst_u64[0] = case_value; + } + else + { + if (case_value > UINT_MAX) + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, + "Truncating 64-bit switch case value %"PRIx64" to 32 bits.", case_value); + vsir_src_param_init(&src_params[i], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); + src_params[i].reg.u.immconst_u32[0] = case_value; } - terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src, sm6); + if (!sm6_function_validate_block_index(function, record->operands[i + 1], dxil)) + { + vkd3d_shader_instruction_make_nop(ins); + return; + } + /* Set the case block label id, 1-based. */ + vsir_src_param_init_label(&src_params[i + 1], record->operands[i + 1] + 1); } - - ins->opcode = VSIR_OP_NOP; } static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, @@ -8232,72 +8391,24 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e } } -static bool sm6_function_blocks_reserve(struct sm6_function *function, unsigned int reserve) -{ - if (!vkd3d_array_reserve((void **)&function->blocks, &function->block_capacity, - reserve, sizeof(*function->blocks))) - { - ERR("Failed to allocate code block array.\n"); - return false; - } - return true; -} - -static struct sm6_block *sm6_function_create_block(struct sm6_function *function) +static void sm6_function_emit_label(struct sm6_function *function, unsigned int label_id, struct sm6_parser *dxil) { - struct sm6_block *block; - - if (!(block = sm6_block_create())) - return NULL; - - function->blocks[function->block_count++] = block; - /* Set the id to the array index + 1. */ - block->id = function->block_count; - - return block; -} + struct vkd3d_shader_src_param *src_param; + struct vkd3d_shader_instruction *ins; -static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_function *function, - struct sm6_parser *sm6) -{ - const struct sm6_block *block; - size_t i, j, block_idx; + ins = &function->instructions.elements[function->instructions.count++]; - for (block_idx = 0; block_idx < function->block_count; ++block_idx) + vsir_instruction_init(ins, &dxil->p.location, VSIR_OP_LABEL); + if (!(src_param = instruction_src_params_alloc(ins, 1, dxil))) { - block = function->blocks[block_idx]; - - for (i = 0; i < block->phi_count; ++i) - { - struct sm6_phi *phi = &block->phi[i]; - const struct sm6_value *src; - - for (j = 0; j < phi->incoming_count; ++j) - { - src = &sm6->values[phi->incoming[j].reg.idx[0].offset]; - if (!sm6_value_is_constant(src) && !sm6_value_is_undef(src) && !sm6_value_is_ssa(src)) - { - FIXME("PHI incoming value is not a constant or SSA register.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "A PHI incoming value is not a constant or SSA register."); - return VKD3D_ERROR_INVALID_SHADER; - } - if (src->type != phi->value.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."); - } - vsir_register_from_dxil_value(&phi->incoming[j].reg, src, 0, sm6); - } - } + vkd3d_shader_instruction_make_nop(ins); + return; } - - return VKD3D_OK; + vsir_src_param_init_label(src_param, label_id); } -static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, - struct sm6_function *function) +static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, + const struct dxil_block *block, struct sm6_function *function) { struct vsir_program *program = sm6->program; struct vkd3d_shader_instruction *ins; @@ -8305,7 +8416,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const const struct dxil_record *record; const struct sm6_type *fwd_type; bool ret_found, is_terminator; - struct sm6_block *code_block; + bool emitted_label = false; struct sm6_value *dst; if (!(function->declaration = sm6_parser_next_function_definition(sm6))) @@ -8333,20 +8444,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; } - if (!sm6_function_blocks_reserve(function, block_count)) - return VKD3D_ERROR_OUT_OF_MEMORY; - - /* Pre-allocate all blocks to simplify instruction parsing. */ - for (i = 0; i < block_count; ++i) - { - if (!sm6_function_create_block(function)) - { - ERR("Failed to allocate code block.\n"); - return VKD3D_ERROR_OUT_OF_MEMORY; - } - } function->block_count = block_count; - code_block = function->blocks[0]; sm6->cur_max_value = function->value_count; @@ -8354,24 +8452,31 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const { sm6->p.location.column = i; - if (!code_block) + if (block_idx >= function->block_count) { - WARN("Invalid block count %zu.\n", function->block_count); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Invalid block count %zu.", function->block_count); return VKD3D_ERROR_INVALID_SHADER; } /* Some instructions can emit >1 IR instruction, so extra may be used. */ - if (!vkd3d_array_reserve((void **)&code_block->instructions, &code_block->instruction_capacity, - code_block->instruction_count + MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION, - sizeof(*code_block->instructions))) + if (!vkd3d_array_reserve((void **)&function->instructions.elements, &function->instructions.capacity, + function->instructions.count + !emitted_label + MAX_IR_INSTRUCTIONS_PER_DXIL_INSTRUCTION, + sizeof(*function->instructions.elements))) { ERR("Failed to allocate instructions.\n"); return VKD3D_ERROR_OUT_OF_MEMORY; } - ins = &code_block->instructions[code_block->instruction_count]; + if (!emitted_label) + { + /* Label id is 1-based. Do not emit a label until it is known that + * instructions will follow. */ + sm6_function_emit_label(function, block_idx + 1, sm6); + emitted_label = true; + } + + ins = &function->instructions.elements[function->instructions.count]; ins->opcode = VSIR_OP_INVALID; dst = sm6_parser_get_current_value(sm6); @@ -8388,21 +8493,21 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const break; case FUNC_CODE_INST_ATOMICRMW: { - struct function_emission_state state = {code_block, ins}; + struct function_emission_state state = {function, ins}; sm6_parser_emit_atomicrmw(sm6, record, &state, dst); program->temp_count = max(program->temp_count, state.temp_idx); break; } case FUNC_CODE_INST_BINOP: - sm6_parser_emit_binop(sm6, record, code_block, ins, dst); + sm6_parser_emit_binop(sm6, record, function, ins, dst); break; case FUNC_CODE_INST_BR: - sm6_parser_emit_br(sm6, record, function, code_block, ins); + sm6_parser_emit_br(sm6, record, function, ins); is_terminator = true; break; case FUNC_CODE_INST_CALL: { - struct function_emission_state state = {code_block, ins}; + struct function_emission_state state = {function, ins}; sm6_parser_emit_call(sm6, record, &state, dst); program->temp_count = max(program->temp_count, state.temp_idx); break; @@ -8426,10 +8531,10 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const sm6_parser_emit_load(sm6, record, ins, dst); break; case FUNC_CODE_INST_PHI: - sm6_parser_emit_phi(sm6, record, function, code_block, ins, dst); + sm6_parser_emit_phi(sm6, record, function, ins, dst); break; case FUNC_CODE_INST_RET: - sm6_parser_emit_ret(sm6, record, code_block, ins); + sm6_parser_emit_ret(sm6, record, ins); is_terminator = true; ret_found = true; break; @@ -8437,7 +8542,7 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const sm6_parser_emit_store(sm6, record, ins, dst); break; case FUNC_CODE_INST_SWITCH: - sm6_parser_emit_switch(sm6, record, function, code_block, ins); + sm6_parser_emit_switch(sm6, record, function, ins); is_terminator = true; break; case FUNC_CODE_INST_VSELECT: @@ -8454,17 +8559,13 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const if (record->attachment) metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6); - /* This is specific for PHI nodes, but must happen after attachments have been applied. */ - if (record->code == FUNC_CODE_INST_PHI) - code_block->phi[code_block->phi_count - 1].value = *dst; + function->instructions.count += ins->opcode != VSIR_OP_NOP; if (is_terminator) { ++block_idx; - code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL; + emitted_label = false; } - if (code_block) - code_block->instruction_count += ins->opcode != VSIR_OP_NOP; if (dst->type && fwd_type && dst->type != fwd_type) { @@ -8482,148 +8583,117 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; } - return sm6_function_resolve_phi_incomings(function, sm6); + return VKD3D_OK; } -static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_parser *sm6) +static void sm6_parser_init_attribute_groups(struct sm6_parser *dxil, const struct dxil_block *block) { - struct vkd3d_shader_src_param *src_params; - struct vkd3d_shader_instruction *ins; - unsigned int i, count; + size_t i, j; - switch (block->terminator.type) + if (dxil->attribute_groups) { - case TERMINATOR_UNCOND_BR: - if (!block->terminator.true_block) - return; - if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH))) - return; - if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) - { - vkd3d_shader_instruction_make_nop(ins); - return; - } - vsir_src_param_init_label(&src_params[0], block->terminator.true_block->id); - break; + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_DUPLICATED_BLOCK, + "Duplicated PARAMATTR_GROUP block."); + return; + } - case TERMINATOR_COND_BR: - if (!block->terminator.true_block || !block->terminator.false_block) - return; - if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH))) - return; - if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) - { - vkd3d_shader_instruction_make_nop(ins); - return; - } - src_param_init(&src_params[0]); - src_params[0].reg = block->terminator.conditional_reg; - vsir_src_param_init_label(&src_params[1], block->terminator.true_block->id); - vsir_src_param_init_label(&src_params[2], block->terminator.false_block->id); - break; + dxil->attribute_group_count = block->record_count; - case TERMINATOR_SWITCH: - if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_SWITCH_MONOLITHIC))) - return; - if (!(src_params = instruction_src_params_alloc(ins, block->terminator.case_count * 2u + 1, sm6))) - { - vkd3d_shader_instruction_make_nop(ins); - return; - } - src_param_init(&src_params[0]); - src_params[0].reg = block->terminator.conditional_reg; - /* TODO: emit the merge block id. */ - vsir_src_param_init_label(&src_params[2], 0); + if (!(dxil->attribute_groups = vkd3d_calloc(block->record_count, sizeof(*dxil->attribute_groups)))) + { + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Out of memory while allocating the parameter attribute groups array."); + return; + } - for (i = 0, count = 3; i < block->terminator.case_count; ++i) - { - const struct terminator_case *switch_case; - const struct sm6_block *case_block; + for (i = 0, j = 0; i < block->record_count; ++i) + { + struct dxil_attribute_group *group = &dxil->attribute_groups[j]; + struct dxil_record *record = block->records[i]; + bool failed = false; + unsigned int k; - switch_case = &block->terminator.cases[i]; - if (!(case_block = switch_case->block)) - { - VKD3D_ASSERT(sm6->p.status < 0); - continue; - } - if (switch_case->is_default) - { - vsir_src_param_init_label(&src_params[1], case_block->id); - continue; - } + if (record->code != PARAMATTR_GRP_CODE_ENTRY) + { + vkd3d_shader_parser_warning(&dxil->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_RECORD, + "Ignoring PARAMATTR_GROUP record code %u.", record->code); + continue; + } - if (src_params[0].reg.data_type == VSIR_DATA_U64) - { - vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VSIR_DATA_U64, 0); - src_params[count++].reg.u.immconst_u64[0] = switch_case->value; - } - else - { - if (switch_case->value > UINT_MAX) - { - WARN("Truncating 64-bit constant %"PRIx64".\n", switch_case->value); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, - "Truncating 64-bit switch case value %"PRIx64" to 32 bits.", switch_case->value); - } - vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); - src_params[count++].reg.u.immconst_u32[0] = switch_case->value; - } - vsir_src_param_init_label(&src_params[count++], case_block->id); - } + if (!dxil_record_validate_operand_min_count(record, 2, dxil)) + continue; - break; + if (record->operands[0] > UINT_MAX || record->operands[0] == 0) + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "PARAMATTR_GROUP group id %"PRIu64" is invalid.", record->operands[0]); - case TERMINATOR_RET: - sm6_parser_add_instruction(sm6, VSIR_OP_RET); - break; + if (record->operands[1] > UINT_MAX) + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "PARAMATTR_GROUP parameter index %"PRIu64" is invalid.", record->operands[1]); - default: - vkd3d_unreachable(); - } -} + group->group_id = record->operands[0]; + group->parameter_idx = record->operands[1]; -static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser *sm6) -{ - struct vkd3d_shader_instruction *ins; - unsigned int i, j, incoming_count; - const struct sm6_phi *src_phi; + for (k = 2; k < record->operand_count && !failed;) + { + uint64_t kind = record->operands[k++]; + struct dxil_attribute *attribute; - for (i = 0; i < block->phi_count; ++i) - { - struct vkd3d_shader_src_param *src_params; - struct vkd3d_shader_dst_param *dst_param; + if (!vkd3d_array_reserve((void **)&group->attributes, &group->attribute_capacity, + group->attribute_count + 1, sizeof(*group->attributes))) + { + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Out of memory allocating the attribute array."); + break; + } - src_phi = &block->phi[i]; - incoming_count = src_phi->incoming_count; + attribute = &group->attributes[group->attribute_count++]; + memset(attribute, 0, sizeof(*attribute)); + attribute->kind = kind; - if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_PHI))) - return; - if (!(src_params = instruction_src_params_alloc(ins, incoming_count * 2u, sm6))) - { - vkd3d_shader_instruction_make_nop(ins); - return; - } - if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) - { - vkd3d_shader_instruction_make_nop(ins); - return; - } + switch (kind) + { + case ATTRIBUTE_WELL_KNOWN: + if (!dxil_record_validate_operand_min_count(record, k + 1, dxil)) + { + failed = true; + break; + } - for (j = 0; j < incoming_count; ++j) - { - const struct sm6_block *incoming_block = src_phi->incoming[j].block; - unsigned int index = j * 2; + attribute->key.well_known = record->operands[k++]; + break; + + case ATTRIBUTE_WELL_KNOWN_WITH_INTEGER_VALUE: + if (!dxil_record_validate_operand_min_count(record, k + 2, dxil)) + { + failed = true; + break; + } + + attribute->key.well_known = record->operands[k++]; + attribute->value.numeric = record->operands[k++]; + break; - src_param_init(&src_params[index]); - src_params[index].reg = src_phi->incoming[j].reg; - if (incoming_block) - vsir_src_param_init_label(&src_params[index + 1], incoming_block->id); - else - VKD3D_ASSERT(sm6->p.status < 0); + case ATTRIBUTE_STRING: + if (!(attribute->key.string = dxil_record_to_zero_terminated_string(record, &k, dxil))) + failed = true; + break; + + case ATTRIBUTE_STRING_WITH_STRING_VALUE: + if (!(attribute->key.string = dxil_record_to_zero_terminated_string(record, &k, dxil)) + || !(attribute->value.string = dxil_record_to_zero_terminated_string(record, &k, dxil))) + failed = true; + break; + + default: + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_INVALID_ATTRIBUTE_KIND, + "Unrecognised PARAMATTR_GROUP attribute kind %"PRIu64".", kind); + failed = true; + break; + } } - dst_param_init(dst_param); - vsir_register_from_dxil_value(&dst_param->reg, &src_phi->value, 0, sm6); + ++j; } } @@ -8647,6 +8717,10 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st switch (block->id) { + case PARAMATTR_GROUP_BLOCK: + sm6_parser_init_attribute_groups(sm6, block); + break; + case CONSTANTS_BLOCK: /* Level 1 (global) constants are already done in sm6_parser_globals_init(). */ if (level < 2) @@ -8669,7 +8743,6 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st case BLOCKINFO_BLOCK: case MODULE_BLOCK: case PARAMATTR_BLOCK: - case PARAMATTR_GROUP_BLOCK: case VALUE_SYMTAB_BLOCK: case METADATA_BLOCK: case METADATA_ATTACHMENT_BLOCK: @@ -8681,53 +8754,29 @@ static enum vkd3d_result sm6_parser_module_init(struct sm6_parser *sm6, const st break; } - return VKD3D_OK; -} - -static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) -{ - struct vkd3d_shader_src_param *src_param; - struct vkd3d_shader_instruction *ins; - - if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_LABEL))) - return; - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - { - vkd3d_shader_instruction_make_nop(ins); - return; - } - vsir_src_param_init_label(src_param, label_id); + return sm6->p.status; } -static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6) +static enum vkd3d_result sm6_function_emit_instructions(const struct sm6_function *function, struct sm6_parser *dxil) { - struct vsir_program *program = sm6->program; + struct vsir_program *program = dxil->program; struct vkd3d_shader_instruction *ins; - unsigned int i, j; + unsigned int i; program->block_count = max(program->block_count, function->block_count); - for (i = 0; i < function->block_count; ++i) + for (i = 0; i < function->instructions.count; ++i) { - const struct sm6_block *block = function->blocks[i]; - - sm6_parser_emit_label(sm6, block->id); - sm6_block_emit_phi(block, sm6); - - for (j = 0; j < block->instruction_count; ++j) + if (!(ins = vsir_program_append(program))) { - if (!(ins = vsir_program_append(program))) - { - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, - "Out of memory emitting block instructions."); - return sm6->p.status; - } - *ins = block->instructions[j]; + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Out of memory while emitting instructions."); + return dxil->p.status; } - sm6_block_emit_terminator(block, sm6); + *ins = function->instructions.elements[i]; } - return sm6->p.status; + return dxil->p.status; } static bool sm6_parser_allocate_named_metadata(struct sm6_parser *sm6) @@ -10706,34 +10755,48 @@ static void sm6_symtab_cleanup(struct sm6_symbol *symbols, size_t count) vkd3d_free(symbols); } -static void sm6_phi_destroy(struct sm6_phi *phi) -{ - vkd3d_free(phi->incoming); -} - -static void sm6_block_destroy(struct sm6_block *block) +static void sm6_functions_cleanup(struct sm6_function *functions, size_t count) { - unsigned int i; + size_t i; - vkd3d_free(block->instructions); - for (i = 0; i < block->phi_count; ++i) - sm6_phi_destroy(&block->phi[i]); - vkd3d_free(block->phi); - vkd3d_free(block->terminator.cases); - vkd3d_free(block); + for (i = 0; i < count; ++i) + { + vkd3d_free(functions[i].instructions.elements); + } + vkd3d_free(functions); } -static void sm6_functions_cleanup(struct sm6_function *functions, size_t count) +static void sm6_parser_cleanup_attribute_groups(struct sm6_parser *dxil) { + struct dxil_attribute_group *group; + struct dxil_attribute *attribute; size_t i, j; - for (i = 0; i < count; ++i) + for (i = 0; i < dxil->attribute_group_count; ++i) { - for (j = 0; j < functions[i].block_count; ++j) - sm6_block_destroy(functions[i].blocks[j]); - vkd3d_free(functions[i].blocks); + group = &dxil->attribute_groups[i]; + for (j = 0; j < group->attribute_count; ++j) + { + attribute = &group->attributes[j]; + switch (attribute->kind) + { + case ATTRIBUTE_WELL_KNOWN: + case ATTRIBUTE_WELL_KNOWN_WITH_INTEGER_VALUE: + break; + + case ATTRIBUTE_STRING: + vkd3d_free((void *)attribute->key.string); + break; + + case ATTRIBUTE_STRING_WITH_STRING_VALUE: + vkd3d_free((void *)attribute->key.string); + vkd3d_free((void *)attribute->value.string); + break; + } + } } - vkd3d_free(functions); + + vkd3d_free(dxil->attribute_groups); } static void sm6_parser_cleanup(struct sm6_parser *sm6) @@ -10743,6 +10806,7 @@ static void sm6_parser_cleanup(struct sm6_parser *sm6) sm6_type_table_cleanup(sm6->types, sm6->type_count); sm6_symtab_cleanup(sm6->global_symbols, sm6->global_symbol_count); sm6_functions_cleanup(sm6->functions, sm6->function_count); + sm6_parser_cleanup_attribute_groups(sm6); sm6_parser_metadata_cleanup(sm6); vkd3d_free(sm6->descriptors); vkd3d_free(sm6->values); @@ -11032,7 +11096,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro { sm6_parser_add_instruction(sm6, VSIR_OP_HS_CONTROL_POINT_PHASE); - if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) + if ((ret = sm6_function_emit_instructions(fn, sm6)) < 0) goto fail; if (!(fn = sm6_parser_get_function(sm6, sm6->patch_constant_function))) @@ -11046,14 +11110,14 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro } sm6_parser_add_instruction(sm6, VSIR_OP_HS_FORK_PHASE); - if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) + if ((ret = sm6_function_emit_instructions(fn, sm6)) < 0) goto fail; expected_function_count = 2; } else { - if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) + if ((ret = sm6_function_emit_instructions(fn, sm6)) < 0) goto fail; expected_function_count = 1; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index e349029521a..4efa1cd2873 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -544,16 +544,9 @@ static void check_loop_attributes(struct hlsl_ctx *ctx, const struct parse_attri hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, "Unroll attribute can't be used with 'fastopt' attribute."); } -static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx, - struct hlsl_block *block, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +static bool is_static_expression(struct hlsl_block *block) { - struct hlsl_default_value ret = {0}; struct hlsl_ir_node *node; - struct hlsl_block expr; - struct hlsl_src src; - - if (node_from_block(block)->data_type->class == HLSL_CLASS_ERROR) - return ret; LIST_FOR_EACH_ENTRY(node, &block->instrs, struct hlsl_ir_node, entry) { @@ -582,12 +575,28 @@ static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx case HLSL_IR_SWITCH: case HLSL_IR_STATEBLOCK_CONSTANT: case HLSL_IR_SYNC: - hlsl_error(ctx, &node->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, - "Expected literal expression."); - break; + return false; } } + return true; +} + +static struct hlsl_default_value evaluate_static_expression(struct hlsl_ctx *ctx, + struct hlsl_block *block, struct hlsl_type *dst_type, const struct vkd3d_shader_location *loc) +{ + struct hlsl_default_value ret = {0}; + struct hlsl_ir_node *node; + struct hlsl_block expr; + struct hlsl_src src; + + if (node_from_block(block)->data_type->class == HLSL_CLASS_ERROR) + return ret; + + if (!is_static_expression(block)) + hlsl_error(ctx, &node_from_block(block)->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SYNTAX, + "Expected literal expression."); + if (!hlsl_clone_block(ctx, &expr, &ctx->static_initializers)) return ret; hlsl_block_add_block(&expr, block); @@ -2670,7 +2679,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var if (v->initializer.args_count) { - bool is_default_values_initializer; + bool is_default_values_initializer, static_initialization; is_default_values_initializer = (ctx->cur_buffer != ctx->globals_buffer) || (var->storage_modifiers & HLSL_STORAGE_UNIFORM) @@ -2680,6 +2689,10 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var if (hlsl_type_is_shader(type)) is_default_values_initializer = false; + static_initialization = var->storage_modifiers & HLSL_STORAGE_STATIC + || (var->data_type->modifiers & HLSL_MODIFIER_CONST + && is_static_expression(v->initializer.instrs)); + if (is_default_values_initializer) { /* Default values might have been allocated already for another variable of the same name, @@ -2708,7 +2721,7 @@ static struct hlsl_block *initialize_vars(struct hlsl_ctx *ctx, struct list *var { hlsl_dump_var_default_values(var); } - else if (var->storage_modifiers & HLSL_STORAGE_STATIC) + else if (static_initialization) { hlsl_block_add_block(&ctx->static_initializers, v->initializer.instrs); } diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 6a1c5303eb4..241006e32c6 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -1936,8 +1936,36 @@ static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, return VKD3D_OK; } -static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, struct vkd3d_shader_instruction *ins) +static bool is_texture_projected(const struct vsir_program *program, + struct vkd3d_shader_message_context *message_context, unsigned int index) { + const struct vkd3d_shader_parameter1 *parameter; + + if (!(parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_PROJECTED_TEXTURE_MASK))) + return false; + + if (parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Unsupported projected texture mask parameter type %#x.", parameter->type); + return false; + } + + if (parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid projected texture mask parameter data type %#x.", parameter->data_type); + return false; + } + + return parameter->u.immediate_constant.u.u32 & (1u << index); +} + +static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, + struct vsir_program_iterator *it, struct vkd3d_shader_message_context *message_context) +{ + struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); + const struct vkd3d_shader_location location = ins->location; const struct vkd3d_shader_descriptor_info1 *sampler; unsigned int idx = ins->dst[0].reg.idx[0].offset; struct vkd3d_shader_src_param *srcs; @@ -1951,10 +1979,40 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, st if (!(srcs = vsir_program_get_src_params(program, 4))) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); - srcs[0].reg.idx[0].offset = idx; - srcs[0].reg.dimension = VSIR_DIMENSION_VEC4; - srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + if (is_texture_projected(program, message_context, idx)) + { + struct vkd3d_shader_dst_param *dst = ins->dst; + uint32_t coords = program->ssa_count++; + + /* div sr0, t#, t#.w */ + + if (!vsir_program_iterator_insert_after(it, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins = vsir_program_iterator_current(it); + if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_DIV, 1, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + dst_param_init_ssa_float4(&ins->dst[0], coords); + vsir_src_param_init(&ins->src[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); + ins->src[0].reg.idx[0].offset = idx; + ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + ins->src[1] = ins->src[0]; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); + + ins = vsir_program_iterator_next(it); + vsir_instruction_init(ins, &location, VSIR_OP_SAMPLE); + ins->dst_count = 1; + ins->dst = dst; + src_param_init_ssa_float4(&srcs[0], coords); + } + else + { + vsir_src_param_init(&srcs[0], VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); + srcs[0].reg.idx[0].offset = idx; + srcs[0].reg.dimension = VSIR_DIMENSION_VEC4; + srcs[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + } vsir_src_param_init_resource(&srcs[1], idx, idx); vsir_src_param_init_sampler(&srcs[2], idx, idx); @@ -2082,6 +2140,7 @@ static enum vkd3d_result vsir_program_lower_texbem(struct vsir_program *program, unsigned int idx = ins->dst[0].reg.idx[0].offset; uint32_t ssa_coords, ssa_luminance, ssa_sample; struct vkd3d_shader_src_param orig_coords; + bool projected; /* texbem t#, SRC * -> @@ -2097,6 +2156,11 @@ static enum vkd3d_result vsir_program_lower_texbem(struct vsir_program *program, * mad srLUM.x, SRC.z, BUMP_LUMINANCE_SCALE#, BUMP_LUMINANCE_OFFSET# * mul t#, t#, srLUM.xxxx * + * If projecting, we replace srCOORDS calculation with + * + * div srPROJ, t#, t#.w + * bem srCOORDS.xy, srPROJ.xy, SRC + * * Note that the t# destination will subsequently be turned into a temp. */ descriptor = vkd3d_shader_find_descriptor(&program->descriptors, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, idx); @@ -2115,7 +2179,8 @@ static enum vkd3d_result vsir_program_lower_texbem(struct vsir_program *program, return VKD3D_ERROR_NOT_IMPLEMENTED; } - if (!vsir_program_iterator_insert_after(it, is_texbeml ? 4 : 2)) + projected = is_texture_projected(program, message_context, idx); + if (!vsir_program_iterator_insert_after(it, 2 + (is_texbeml ? 2 : 0) + (projected ? 1 : 0))) return VKD3D_ERROR_OUT_OF_MEMORY; vsir_src_param_init(&orig_coords, VKD3DSPR_TEXTURE, VSIR_DATA_F32, 1); @@ -2123,6 +2188,23 @@ static enum vkd3d_result vsir_program_lower_texbem(struct vsir_program *program, orig_coords.reg.dimension = VSIR_DIMENSION_VEC4; orig_coords.swizzle = VKD3D_SHADER_NO_SWIZZLE; + if (projected) + { + uint32_t ssa_proj = program->ssa_count++; + + ins = vsir_program_iterator_current(it); + if (!vsir_instruction_init_with_params(program, ins, &location, VSIR_OP_DIV, 1, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + dst_param_init_ssa_float4(&ins->dst[0], ssa_proj); + ins->src[0] = orig_coords; + ins->src[1] = ins->src[0]; + ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); + + src_param_init_ssa_float4(&orig_coords, ssa_proj); + + vsir_program_iterator_next(it); + } + if (!(ins = generate_bump_coords(program, it, idx, &orig_coords, &src[0], &location))) return VKD3D_ERROR_OUT_OF_MEMORY; ssa_coords = ins->dst[0].reg.idx[0].offset; @@ -2290,7 +2372,7 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr break; case VSIR_OP_TEX: - ret = vsir_program_lower_tex(program, ins); + ret = vsir_program_lower_tex(program, &it, message_context); break; case VSIR_OP_TEXLD: diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l index 8913e57283a..f9b1d67ac36 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l @@ -20,6 +20,7 @@ %{ +#include "preproc.h" #include "preproc.tab.h" #undef ERROR /* defined in wingdi.h */ diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index ee113f57736..6f0520f19f9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -729,6 +729,7 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, parser->location.source_name = source_name; parser->location.line = 1; parser->location.column = 0; + parser->status = VKD3D_OK; } void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 97fe5238046..7e31a77da05 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -229,6 +229,9 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE = 8019, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT = 8020, VKD3D_SHADER_ERROR_DXIL_NOT_IMPLEMENTED = 8021, + VKD3D_SHADER_ERROR_DXIL_DUPLICATED_BLOCK = 8022, + VKD3D_SHADER_ERROR_DXIL_INVALID_STRING = 8023, + VKD3D_SHADER_ERROR_DXIL_INVALID_ATTRIBUTE_KIND = 8024, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, @@ -241,6 +244,7 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_DXIL_INVALID_OPERATION = 8308, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT = 8309, VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND = 8310, + VKD3D_SHADER_WARNING_DXIL_IGNORING_RECORD = 8311, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE = 9001, diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c index 69f42280e8a..7d9a86e909f 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_resource_list_cleanup(struct vkd3d_resource_list *list) +{ + vkd3d_free(list->resources); +} + +static void vkd3d_resource_list_init(struct vkd3d_resource_list *list) +{ + list->resources = NULL; + list->count = 0; + list->capacity = 0; +} + +static bool vkd3d_resource_list_contains(const struct vkd3d_resource_list *list, struct d3d12_resource *resource) +{ + size_t i; + + for (i = 0; i < list->count; i++) + { + if (list->resources[i] == resource) + return true; + } + + return false; +} + +static void vkd3d_resource_list_append(struct vkd3d_resource_list *list, struct d3d12_resource *resource) +{ + if (!vkd3d_array_reserve((void **)&list->resources, &list->capacity, list->count + 1, sizeof(*list->resources))) + ERR("Failed to grow resource list.\n"); + list->resources[list->count++] = resource; +} + +static void vkd3d_resource_list_clear(struct vkd3d_resource_list *list) +{ + list->count = 0; +} + static void vkd3d_null_event_signal(struct vkd3d_null_event *e) { vkd3d_mutex_lock(&e->mutex); @@ -2533,6 +2570,9 @@ static ULONG STDMETHODCALLTYPE d3d12_command_list_Release(ID3D12GraphicsCommandL vkd3d_pipeline_bindings_cleanup(&list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_COMPUTE]); vkd3d_pipeline_bindings_cleanup(&list->pipeline_bindings[VKD3D_PIPELINE_BIND_POINT_GRAPHICS]); + vkd3d_resource_list_cleanup(&list->rtv_resources_since_last_barrier); + vkd3d_resource_list_cleanup(&list->dsv_resources_since_last_barrier); + vkd3d_free(list); d3d12_device_release(device); @@ -2659,6 +2699,10 @@ static void d3d12_command_list_reset_state(struct d3d12_command_list *list, list->fb_width = 0; list->fb_height = 0; list->fb_layer_count = 0; + memset(list->rtv_resources, 0, sizeof(list->rtv_resources)); + list->dsv_resource = NULL; + vkd3d_resource_list_clear(&list->rtv_resources_since_last_barrier); + vkd3d_resource_list_clear(&list->dsv_resources_since_last_barrier); list->xfb_enabled = false; list->has_depth_bounds = false; @@ -3469,6 +3513,82 @@ static bool d3d12_command_list_update_compute_state(struct d3d12_command_list *l return true; } +/* Add a barrier to prevent hazards between multiple render passes to the same image. */ +static void d3d12_command_list_emit_rt_barrier(struct d3d12_command_list *list, bool colour, bool depth) +{ + const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; + VkMemoryBarrier barrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER }; + VkPipelineStageFlags srcStage = 0; + VkPipelineStageFlags dstStage = 0; + + if (colour) + { + srcStage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + dstStage |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + barrier.srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; + barrier.dstAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT; + } + + if (depth) + { + srcStage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + dstStage |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; + barrier.srcAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + barrier.dstAccessMask |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT + | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT; + } + + VK_CALL(vkCmdPipelineBarrier(list->vk_command_buffer, srcStage, dstStage, + VK_DEPENDENCY_BY_REGION_BIT, 1, &barrier, 0, NULL, 0, NULL)); + if (colour) + vkd3d_resource_list_clear(&list->rtv_resources_since_last_barrier); + if (depth) + vkd3d_resource_list_clear(&list->rtv_resources_since_last_barrier); +} + +static void d3d12_command_list_check_render_pass_hazards(struct d3d12_command_list *list) +{ + struct d3d12_graphics_pipeline_state *graphics = &list->state->u.graphics; + bool rtv_hazard = false; + bool dsv_hazard = false; + unsigned int i; + + for (i = 0; i < graphics->rt_count; ++i) + { + if (graphics->null_attachment_mask & (1u << i)) + continue; + + if (!list->rtv_resources[i]) + continue; + + if (vkd3d_resource_list_contains(&list->rtv_resources_since_last_barrier, list->rtv_resources[i])) + { + rtv_hazard = true; + break; + } + } + + dsv_hazard = d3d12_command_list_has_depth_stencil_view(list) && list->dsv_resource + && vkd3d_resource_list_contains(&list->dsv_resources_since_last_barrier, list->dsv_resource); + + if (rtv_hazard || dsv_hazard) + d3d12_command_list_emit_rt_barrier(list, rtv_hazard, dsv_hazard); + + for (i = 0; i < graphics->rt_count; ++i) + { + if (graphics->null_attachment_mask & (1u << i)) + continue; + + if (!list->rtv_resources[i]) + continue; + + vkd3d_resource_list_append(&list->rtv_resources_since_last_barrier, list->rtv_resources[i]); + } + + if (d3d12_command_list_has_depth_stencil_view(list) && list->dsv_resource) + vkd3d_resource_list_append(&list->dsv_resources_since_last_barrier, list->dsv_resource); +} + static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list) { const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; @@ -3486,6 +3606,8 @@ static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list if (list->current_render_pass != VK_NULL_HANDLE) return true; + d3d12_command_list_check_render_pass_hazards(list); + vk_render_pass = list->pso_render_pass; VKD3D_ASSERT(vk_render_pass); @@ -5137,6 +5259,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi { WARN("RTV descriptor %u is not initialized.\n", i); list->rtvs[i] = VK_NULL_HANDLE; + list->rtv_resources[i] = NULL; continue; } @@ -5150,6 +5273,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi } list->rtvs[i] = view->v.u.vk_image_view; + list->rtv_resources[i] = rtv_desc->resource; list->fb_width = max(list->fb_width, rtv_desc->width); list->fb_height = max(list->fb_height, rtv_desc->height); list->fb_layer_count = max(list->fb_layer_count, rtv_desc->layer_count); @@ -5171,9 +5295,11 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi { WARN("Failed to add view.\n"); list->dsv = VK_NULL_HANDLE; + list->dsv_resource = NULL; } list->dsv = view->v.u.vk_image_view; + list->dsv_resource = dsv_desc->resource; list->fb_width = max(list->fb_width, dsv_desc->width); list->fb_height = max(list->fb_height, dsv_desc->height); list->fb_layer_count = max(list->fb_layer_count, dsv_desc->layer_count); @@ -5209,8 +5335,6 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, unsigned int i; VkResult vr; - d3d12_command_list_end_current_render_pass(list); - if (!rect_count) { full_rect.top = 0; @@ -5344,6 +5468,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra ds_reference.attachment = 0; ds_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + d3d12_command_list_end_current_render_pass(list); + + if (vkd3d_resource_list_contains(&list->dsv_resources_since_last_barrier, dsv_desc->resource)) + d3d12_command_list_emit_rt_barrier(list, false, true); + vkd3d_resource_list_append(&list->dsv_resources_since_last_barrier, dsv_desc->resource); + d3d12_command_list_clear(list, &attachment_desc, NULL, &ds_reference, dsv_desc->view, dsv_desc->width, dsv_desc->height, dsv_desc->layer_count, &clear_value, rect_count, rects); @@ -5398,6 +5528,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra clear_value.color.float32[3] = color[3]; } + d3d12_command_list_end_current_render_pass(list); + + if (vkd3d_resource_list_contains(&list->rtv_resources_since_last_barrier, rtv_desc->resource)) + d3d12_command_list_emit_rt_barrier(list, true, false); + vkd3d_resource_list_append(&list->rtv_resources_since_last_barrier, rtv_desc->resource); + d3d12_command_list_clear(list, &attachment_desc, &color_reference, NULL, rtv_desc->view, rtv_desc->width, rtv_desc->height, rtv_desc->layer_count, &clear_value, rect_count, rects); @@ -6395,6 +6531,9 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, list->type = type; + vkd3d_resource_list_init(&list->rtv_resources_since_last_barrier); + vkd3d_resource_list_init(&list->dsv_resources_since_last_barrier); + if (FAILED(hr = vkd3d_private_store_init(&list->private_store))) return hr; diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h index 0a8c5aef674..b80a206294a 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -1277,6 +1277,13 @@ enum vkd3d_pipeline_bind_point VKD3D_PIPELINE_BIND_POINT_COUNT = 0x2, }; +struct vkd3d_resource_list +{ + struct d3d12_resource **resources; + size_t count; + size_t capacity; +}; + /* ID3D12CommandList */ struct d3d12_command_list { @@ -1302,6 +1309,13 @@ struct d3d12_command_list unsigned int fb_layer_count; VkFormat dsv_format; + /* Resources for views bound to d3d12 state */ + struct d3d12_resource *rtv_resources[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT]; + struct d3d12_resource *dsv_resource; + /* Resources bound since the last pipeline barrier */ + struct vkd3d_resource_list rtv_resources_since_last_barrier; + struct vkd3d_resource_list dsv_resources_since_last_barrier; + bool xfb_enabled; bool has_depth_bounds; bool is_predicated; -- 2.51.0