From 6539b8d0685337b99debbe678354c3a9a58747d7 Mon Sep 17 00:00:00 2001 From: Alistair Leslie-Hughes Date: Mon, 26 May 2025 07:03:34 +1000 Subject: [PATCH] Updated vkd3d to e69f3da089d472b723b016ef67c04c0f954fa792. --- dlls/msado15/tests/msado15.c | 2 +- libs/vkd3d/include/private/spirv_grammar.h | 561 +------- libs/vkd3d/include/private/vkd3d_common.h | 4 +- libs/vkd3d/include/private/vkd3d_version.h | 2 +- libs/vkd3d/include/vkd3d_shader.h | 38 +- libs/vkd3d/libs/vkd3d-common/blob.c | 1 + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 46 +- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 36 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 151 ++- libs/vkd3d/libs/vkd3d-shader/fx.c | 2 +- libs/vkd3d/libs/vkd3d-shader/glsl.c | 74 +- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 70 + libs/vkd3d/libs/vkd3d-shader/hlsl.h | 16 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 2 +- libs/vkd3d/libs/vkd3d-shader/hlsl.y | 60 +- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 752 ++++++++--- .../libs/vkd3d-shader/hlsl_constant_ops.c | 243 ++-- libs/vkd3d/libs/vkd3d-shader/ir.c | 1132 ++++++++++------- libs/vkd3d/libs/vkd3d-shader/msl.c | 45 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 13 +- libs/vkd3d/libs/vkd3d-shader/spirv.c | 319 ++--- libs/vkd3d/libs/vkd3d-shader/tpf.c | 43 +- .../libs/vkd3d-shader/vkd3d_shader_main.c | 222 +--- .../libs/vkd3d-shader/vkd3d_shader_private.h | 94 +- .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 17 +- libs/vkd3d/libs/vkd3d/command.c | 2 +- libs/vkd3d/libs/vkd3d/state.c | 6 +- libs/vkd3d/libs/vkd3d/utils.c | 3 +- 28 files changed, 2184 insertions(+), 1772 deletions(-) diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c index 03eaab92b39..3f4b55d2916 100644 --- a/dlls/msado15/tests/msado15.c +++ b/dlls/msado15/tests/msado15.c @@ -2023,8 +2023,8 @@ START_TEST(msado15) setup_database(); test_Connection(); - test_Connection_Open(); test_ConnectionPoint(); + test_Connection_Open(); test_ADORecordsetConstruction(FALSE); test_ADORecordsetConstruction(TRUE); test_Fields(); diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h index 34cadd9bd58..2aac5a6558c 100644 --- a/libs/vkd3d/include/private/spirv_grammar.h +++ b/libs/vkd3d/include/private/spirv_grammar.h @@ -43,12 +43,10 @@ enum spirv_parser_operand_type SPIRV_PARSER_OPERAND_TYPE_ADDRESSING_MODEL, SPIRV_PARSER_OPERAND_TYPE_BUILT_IN, SPIRV_PARSER_OPERAND_TYPE_CAPABILITY, - SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_REDUCE, SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_USE, - SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT, SPIRV_PARSER_OPERAND_TYPE_DECORATION, SPIRV_PARSER_OPERAND_TYPE_DIM, SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE, @@ -84,7 +82,6 @@ enum spirv_parser_operand_type SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING, SPIRV_PARSER_OPERAND_TYPE_LOAD_CACHE_CONTROL, SPIRV_PARSER_OPERAND_TYPE_LOOP_CONTROL, - SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, SPIRV_PARSER_OPERAND_TYPE_MEMORY_MODEL, SPIRV_PARSER_OPERAND_TYPE_MEMORY_SEMANTICS, @@ -149,7 +146,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_BUILT_IN] = { - "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 126, + "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 116, (struct spirv_parser_enumerant[]) { {0, "Position"}, @@ -210,9 +207,6 @@ spirv_parser_operand_type_info[] = {0x1156, "DeviceIndex"}, {0x1158, "ViewIndex"}, {0x115c, "ShadingRateKHR"}, - {0x118c, "TileOffsetQCOM"}, - {0x118d, "TileDimensionQCOM"}, - {0x118e, "TileApronSizeQCOM"}, {0x1380, "BaryCoordNoPerspAMD"}, {0x1381, "BaryCoordNoPerspCentroidAMD"}, {0x1382, "BaryCoordNoPerspSampleAMD"}, @@ -264,25 +258,18 @@ spirv_parser_operand_type_info[] = {0x14e0, "HitMicroTriangleVertexBarycentricsNV"}, {0x14e7, "IncomingRayFlagsKHR"}, {0x14e8, "RayGeometryIndexKHR"}, - {0x14ef, "HitIsSphereNV"}, - {0x14f0, "HitIsLSSNV"}, - {0x14f1, "HitSpherePositionNV"}, {0x14fe, "WarpsPerSMNV"}, {0x14ff, "SMCountNV"}, {0x1500, "WarpIDNV"}, {0x1501, "SMIDNV"}, - {0x1514, "HitLSSPositionsNV"}, {0x151d, "HitKindFrontFacingMicroTriangleNV"}, {0x151e, "HitKindBackFacingMicroTriangleNV"}, - {0x152c, "HitSphereRadiusNV"}, - {0x152d, "HitLSSRadiiNV"}, - {0x153c, "ClusterIDNV"}, {0x1785, "CullMaskKHR"}, } }, [SPIRV_PARSER_OPERAND_TYPE_CAPABILITY] = { - "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 261, + "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 245, (struct spirv_parser_enumerant[]) { {0, "Matrix"}, @@ -393,7 +380,6 @@ spirv_parser_operand_type_info[] = {0x1184, "TextureSampleWeightedQCOM"}, {0x1185, "TextureBoxFilterQCOM"}, {0x1186, "TextureBlockMatchQCOM"}, - {0x118f, "TileShadingQCOM"}, {0x1192, "TextureBlockMatch2QCOM"}, {0x1390, "Float16ImageAMD"}, {0x1391, "ImageGatherBiasLodAMD"}, @@ -404,9 +390,6 @@ spirv_parser_operand_type_info[] = {0x13bf, "ShaderClockKHR"}, {0x13cb, "ShaderEnqueueAMDX"}, {0x13df, "QuadControlKHR"}, - {0x13fc, "BFloat16TypeKHR"}, - {0x13fd, "BFloat16DotProductKHR"}, - {0x13fe, "BFloat16CooperativeMatrixKHR"}, {0x1481, "SampleMaskOverrideCoverageNV"}, {0x1483, "GeometryShaderPassthroughNV"}, {0x1486, "ShaderViewportIndexLayerEXT"}, @@ -452,19 +435,14 @@ spirv_parser_operand_type_info[] = {0x1507, "ShaderInvocationReorderNV"}, {0x150e, "BindlessTextureNV"}, {0x150f, "RayQueryPositionFetchKHR"}, - {0x1512, "CooperativeVectorNV"}, {0x151c, "AtomicFloat16VectorNV"}, {0x1521, "RayTracingDisplacementMicromapNV"}, {0x1526, "RawAccessChainsNV"}, - {0x152a, "RayTracingSpheresGeometryNV"}, - {0x152b, "RayTracingLinearSweptSpheresGeometryNV"}, {0x1536, "CooperativeMatrixReductionsNV"}, {0x1537, "CooperativeMatrixConversionsNV"}, {0x1538, "CooperativeMatrixPerElementOperationsNV"}, {0x1539, "CooperativeMatrixTensorAddressingNV"}, {0x153a, "CooperativeMatrixBlockLoadsNV"}, - {0x153b, "CooperativeVectorTrainingNV"}, - {0x153d, "RayTracingClusterAccelerationStructureNV"}, {0x153f, "TensorAddressingNV"}, {0x15c0, "SubgroupShuffleINTEL"}, {0x15c1, "SubgroupBufferBlockIOINTEL"}, @@ -529,47 +507,18 @@ spirv_parser_operand_type_info[] = {0x1800, "ArithmeticFenceEXT"}, {0x1806, "FPGAClusterAttributesV2INTEL"}, {0x1811, "FPGAKernelAttributesv2INTEL"}, - {0x1812, "TaskSequenceINTEL"}, {0x1819, "FPMaxErrorINTEL"}, {0x181b, "FPGALatencyControlINTEL"}, {0x181e, "FPGAArgumentInterfacesINTEL"}, {0x182b, "GlobalVariableHostAccessINTEL"}, {0x182d, "GlobalVariableFPGADecorationsINTEL"}, {0x184c, "SubgroupBufferPrefetchINTEL"}, - {0x1854, "Subgroup2DBlockIOINTEL"}, - {0x1855, "Subgroup2DBlockTransformINTEL"}, - {0x1856, "Subgroup2DBlockTransposeINTEL"}, - {0x185c, "SubgroupMatrixMultiplyAccumulateINTEL"}, - {0x1861, "TernaryBitwiseFunctionINTEL"}, {0x1900, "GroupUniformArithmeticKHR"}, - {0x1919, "TensorFloat32RoundingINTEL"}, {0x191b, "MaskedGatherScatterINTEL"}, {0x1929, "CacheControlsINTEL"}, {0x193c, "RegisterLimitsINTEL"}, } }, - [SPIRV_PARSER_OPERAND_TYPE_COMPONENT_TYPE] = - { - "ComponentType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 15, - (struct spirv_parser_enumerant[]) - { - {0, "Float16NV"}, - {0x1, "Float32NV"}, - {0x2, "Float64NV"}, - {0x3, "SignedInt8NV"}, - {0x4, "SignedInt16NV"}, - {0x5, "SignedInt32NV"}, - {0x6, "SignedInt64NV"}, - {0x7, "UnsignedInt8NV"}, - {0x8, "UnsignedInt16NV"}, - {0x9, "UnsignedInt32NV"}, - {0xa, "UnsignedInt64NV"}, - {0x3ba247f8, "SignedInt8PackedNV"}, - {0x3ba247f9, "UnsignedInt8PackedNV"}, - {0x3ba247fa, "FloatE4M3NV"}, - {0x3ba247fb, "FloatE5M2NV"}, - } - }, [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_LAYOUT] = { "CooperativeMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, @@ -614,17 +563,6 @@ spirv_parser_operand_type_info[] = {0x2, "MatrixAccumulatorKHR"}, } }, - [SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_VECTOR_MATRIX_LAYOUT] = - { - "CooperativeVectorMatrixLayout", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 4, - (struct spirv_parser_enumerant[]) - { - {0, "RowMajorNV"}, - {0x1, "ColumnMajorNV"}, - {0x2, "InferencingOptimalNV"}, - {0x3, "TrainingOptimalNV"}, - } - }, [SPIRV_PARSER_OPERAND_TYPE_DECORATION] = { "Decoration", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 142, @@ -1240,7 +1178,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE] = { - "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 96, + "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 94, (struct spirv_parser_enumerant[]) { { @@ -1389,16 +1327,6 @@ spirv_parser_operand_type_info[] = SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, } }, - {0x1189, "NonCoherentTileAttachmentReadQCOM"}, - { - 0x118a, "TileShadingRateQCOM", 3, - (enum spirv_parser_operand_type[]) - { - SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, - SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, - SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER, - } - }, {0x1399, "EarlyAndLateFragmentTestsAMD"}, {0x13a3, "StencilRefReplacingEXT"}, {0x13cd, "CoalescingAMDX"}, @@ -1628,11 +1556,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_FPENCODING] = { - "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 1, - (struct spirv_parser_enumerant[]) - { - {0, "BFloat16KHR"}, - } + "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM }, [SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE] = { @@ -1757,7 +1681,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE] = { - "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 26, + "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 20, (struct spirv_parser_enumerant[]) { {0, "SnormInt8"}, @@ -1777,15 +1701,9 @@ spirv_parser_operand_type_info[] = {0xe, "Float"}, {0xf, "UnormInt24"}, {0x10, "UnormInt101010_2"}, - {0x11, "UnormInt10X6EXT"}, {0x13, "UnsignedIntRaw10EXT"}, {0x14, "UnsignedIntRaw12EXT"}, {0x15, "UnormInt2_101010EXT"}, - {0x16, "UnsignedInt10X6EXT"}, - {0x17, "UnsignedInt12X4EXT"}, - {0x18, "UnsignedInt14X2EXT"}, - {0x19, "UnormInt12X4EXT"}, - {0x1a, "UnormInt14X2EXT"}, } }, [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_ORDER] = @@ -2146,28 +2064,6 @@ spirv_parser_operand_type_info[] = }, } }, - [SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS] = - { - "MatrixMultiplyAccumulateOperands", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 15, - (struct spirv_parser_enumerant[]) - { - {0, "None"}, - {0x1, "MatrixASignedComponentsINTEL"}, - {0x2, "MatrixBSignedComponentsINTEL"}, - {0x4, "MatrixCBFloat16INTEL"}, - {0x8, "MatrixResultBFloat16INTEL"}, - {0x10, "MatrixAPackedInt8INTEL"}, - {0x20, "MatrixBPackedInt8INTEL"}, - {0x40, "MatrixAPackedInt4INTEL"}, - {0x80, "MatrixBPackedInt4INTEL"}, - {0x100, "MatrixATF32INTEL"}, - {0x200, "MatrixBTF32INTEL"}, - {0x400, "MatrixAPackedFloat16INTEL"}, - {0x800, "MatrixBPackedFloat16INTEL"}, - {0x1000, "MatrixAPackedBFloat16INTEL"}, - {0x2000, "MatrixBPackedBFloat16INTEL"}, - } - }, [SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS] = { "MemoryAccess", SPIRV_PARSER_OPERAND_CATEGORY_BIT_ENUM, 9, @@ -2405,7 +2301,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE] = { - "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 14, + "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 13, (struct spirv_parser_enumerant[]) { {0, "Unknown"}, @@ -2421,12 +2317,11 @@ spirv_parser_operand_type_info[] = {0xa, "WGSL"}, {0xb, "Slang"}, {0xc, "Zig"}, - {0xd, "Rust"}, } }, [SPIRV_PARSER_OPERAND_TYPE_STORAGE_CLASS] = { - "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 28, + "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 27, (struct spirv_parser_enumerant[]) { {0, "UniformConstant"}, @@ -2443,7 +2338,6 @@ spirv_parser_operand_type_info[] = {0xb, "Image"}, {0xc, "StorageBuffer"}, {0x104c, "TileImageEXT"}, - {0x118b, "TileAttachmentQCOM"}, {0x13cc, "NodePayloadAMDX"}, {0x14d0, "CallableDataKHR"}, {0x14d1, "IncomingCallableDataKHR"}, @@ -6996,78 +6890,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_IMAGE_OPERANDS, '?'}, } }, - { - 0x14a8, "OpTypeCooperativeVectorNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x14a9, "OpCooperativeVectorMatrixMulNV", 13, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, - {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, - } - }, - { - 0x14aa, "OpCooperativeVectorOuterProductAccumulateNV", 7, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, - } - }, - { - 0x14ab, "OpCooperativeVectorReduceSumAccumulateNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x14ac, "OpCooperativeVectorMatrixMulAddNV", 16, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '?'}, - {SPIRV_PARSER_OPERAND_TYPE_COOPERATIVE_MATRIX_OPERANDS, '?'}, - } - }, { 0x14ad, "OpCooperativeMatrixConvertNV", 3, (struct spirv_parser_instruction_operand[]) @@ -7138,27 +6960,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x14b6, "OpCooperativeVectorLoadNV", 5, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, - } - }, - { - 0x14b7, "OpCooperativeVectorStoreNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, - } - }, { 0x14d6, "OpReportIntersectionKHR", 4, (struct spirv_parser_instruction_operand[]) @@ -7249,25 +7050,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x14e1, "OpRayQueryGetClusterIdNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x14e2, "OpHitObjectGetClusterIdNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x14ee, "OpTypeCooperativeMatrixNV", 5, (struct spirv_parser_instruction_operand[]) @@ -7580,130 +7362,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_RAW_ACCESS_CHAIN_OPERANDS, '?'}, } }, - { - 0x1533, "OpRayQueryGetIntersectionSpherePositionNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1534, "OpRayQueryGetIntersectionSphereRadiusNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1535, "OpRayQueryGetIntersectionLSSPositionsNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1536, "OpRayQueryGetIntersectionLSSRadiiNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1537, "OpRayQueryGetIntersectionLSSHitValueNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1538, "OpHitObjectGetSpherePositionNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1539, "OpHitObjectGetSphereRadiusNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153a, "OpHitObjectGetLSSPositionsNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153b, "OpHitObjectGetLSSRadiiNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153c, "OpHitObjectIsSphereHitNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153d, "OpHitObjectIsLSSHitNV", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153e, "OpRayQueryIsSphereHitNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x153f, "OpRayQueryIsLSSHitNV", 4, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x15c3, "OpSubgroupShuffleINTEL", 4, (struct spirv_parser_instruction_operand[]) @@ -7962,9 +7620,10 @@ spirv_parser_opcode_info[] = } }, { - 0x15e9, "OpAsmTargetINTEL", 2, + 0x15e9, "OpAsmTargetINTEL", 3, (struct spirv_parser_instruction_operand[]) { + {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, } @@ -9237,7 +8896,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 8, + 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -9248,6 +8907,7 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, + {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, } }, { @@ -9279,7 +8939,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16d3, "OpArbitraryFloatCastToIntINTEL", 8, + 0x16d3, "OpArbitraryFloatCastToIntINTEL", 7, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -9289,7 +8949,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, } }, { @@ -9803,7 +9462,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16fa, "OpArbitraryFloatPowNINTEL", 10, + 0x16fa, "OpArbitraryFloatPowNINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -9815,7 +9474,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, } }, { @@ -9851,12 +9509,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1723, "OpFixedSqrtINTEL", 8, + 0x1723, "OpFixedSqrtINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9865,12 +9524,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1724, "OpFixedRecipINTEL", 8, + 0x1724, "OpFixedRecipINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9879,12 +9539,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1725, "OpFixedRsqrtINTEL", 8, + 0x1725, "OpFixedRsqrtINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9893,12 +9554,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1726, "OpFixedSinINTEL", 8, + 0x1726, "OpFixedSinINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9907,12 +9569,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1727, "OpFixedCosINTEL", 8, + 0x1727, "OpFixedCosINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9921,12 +9584,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1728, "OpFixedSinCosINTEL", 8, + 0x1728, "OpFixedSinCosINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9935,12 +9599,13 @@ spirv_parser_opcode_info[] = } }, { - 0x1729, "OpFixedSinPiINTEL", 8, + 0x1729, "OpFixedSinPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9949,12 +9614,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172a, "OpFixedCosPiINTEL", 8, + 0x172a, "OpFixedCosPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9963,12 +9629,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172b, "OpFixedSinCosPiINTEL", 8, + 0x172b, "OpFixedSinCosPiINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9977,12 +9644,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172c, "OpFixedLogINTEL", 8, + 0x172c, "OpFixedLogINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9991,12 +9659,13 @@ spirv_parser_opcode_info[] = } }, { - 0x172d, "OpFixedExpINTEL", 8, + 0x172d, "OpFixedExpINTEL", 9, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -10043,12 +9712,13 @@ spirv_parser_opcode_info[] = } }, { - 0x173d, "OpFPGARegINTEL", 3, + 0x173d, "OpFPGARegINTEL", 4, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, + {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, { @@ -10311,50 +9981,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x1813, "OpTaskSequenceCreateINTEL", 7, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, - } - }, - { - 0x1814, "OpTaskSequenceAsyncINTEL", 2, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF, '*'}, - } - }, - { - 0x1815, "OpTaskSequenceGetINTEL", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1816, "OpTaskSequenceReleaseINTEL", 1, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1837, "OpTypeTaskSequenceINTEL", 1, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - } - }, { 0x184d, "OpSubgroupBlockPrefetchINTEL", 3, (struct spirv_parser_instruction_operand[]) @@ -10364,110 +9990,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_MEMORY_ACCESS, '?'}, } }, - { - 0x1857, "OpSubgroup2DBlockLoadINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1858, "OpSubgroup2DBlockLoadTransformINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x1859, "OpSubgroup2DBlockLoadTransposeINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x185a, "OpSubgroup2DBlockPrefetchINTEL", 9, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x185b, "OpSubgroup2DBlockStoreINTEL", 10, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, - { - 0x185d, "OpSubgroupMatrixMultiplyAccumulateINTEL", 7, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_MATRIX_MULTIPLY_ACCUMULATE_OPERANDS, '?'}, - } - }, - { - 0x1862, "OpBitwiseFunctionINTEL", 6, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x1901, "OpGroupIMulKHR", 5, (struct spirv_parser_instruction_operand[]) @@ -10556,15 +10078,6 @@ spirv_parser_opcode_info[] = {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, - { - 0x191a, "OpRoundFToTF32INTEL", 3, - (struct spirv_parser_instruction_operand[]) - { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - } - }, { 0x191c, "OpMaskedGatherINTEL", 6, (struct spirv_parser_instruction_operand[]) diff --git a/libs/vkd3d/include/private/vkd3d_common.h b/libs/vkd3d/include/private/vkd3d_common.h index 08341304eea..8b63acf68e1 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -38,6 +38,8 @@ #include #endif +#define VKD3D_SHADER_API_VERSION_CURRENT VKD3D_SHADER_API_VERSION_1_17 + #ifndef ARRAY_SIZE # define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) #endif @@ -279,7 +281,7 @@ static inline unsigned int vkd3d_popcount(unsigned int v) { #ifdef _MSC_VER return __popcnt(v); -#elif defined(__MINGW32__) +#elif defined(HAVE_BUILTIN_POPCOUNT) return __builtin_popcount(v); #else v -= (v >> 1) & 0x55555555; diff --git a/libs/vkd3d/include/private/vkd3d_version.h b/libs/vkd3d/include/private/vkd3d_version.h index 0edc4428022..687751d6a5f 100644 --- a/libs/vkd3d/include/private/vkd3d_version.h +++ b/libs/vkd3d/include/private/vkd3d_version.h @@ -1 +1 @@ -#define VKD3D_VCS_ID " (Wine bundled)" +#define VKD3D_VCS_ID " (git a8ca1f95)" diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index d82869e79ea..3a2f54c8f22 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -120,6 +120,11 @@ enum vkd3d_shader_structure_type * \since 1.15 */ VKD3D_SHADER_STRUCTURE_TYPE_SCAN_HULL_SHADER_TESSELLATION_INFO, + /** + * The structure is a vkd3d_shader_scan_thread_group_size_info structure. + * \since 1.18 + */ + VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO, VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_STRUCTURE_TYPE), }; @@ -417,10 +422,17 @@ struct vkd3d_shader_code { /** * Pointer to the code. Note that textual formats are not null-terminated. - * Therefore \a size should not include a null terminator, when this - * structure is passed as input to a vkd3d-shader function, and the - * allocated string will not include a null terminator when this structure - * is used as output. + * Therefore \a size should not include a null terminator when this + * structure is passed as input to a vkd3d-shader function, and \a size + * will not include a null terminator when this structure is used as + * output. + * + * For convenience, vkd3d_shader_preprocess() and vkd3d_shader_compile() + * will append a null terminator past the end of their output when + * outputting textual formats like VKD3D_SHADER_TARGET_D3D_ASM. This makes + * it safe to call functions like strlen() on \a code for such output, + * although doing so will obviously not account for any embedded null + * characters that may be present. */ const void *code; /** Size of \a code, in bytes. */ @@ -2282,6 +2294,24 @@ struct vkd3d_shader_scan_hull_shader_tessellation_info enum vkd3d_shader_tessellator_partitioning partitioning; }; +/** + * A chained structure describing the thread group size in a compute shader. + * + * This structure extends vkd3d_shader_compile_info. + * + * \since 1.18 + */ +struct vkd3d_shader_scan_thread_group_size_info +{ + /** Must be set to VKD3D_SHADER_STRUCTURE_TYPE_SCAN_THREAD_GROUP_SIZE_INFO. */ + enum vkd3d_shader_structure_type type; + /** Optional pointer to a structure containing further parameters. */ + const void *next; + + /** The thread group size in the x/y/z direction. */ + unsigned int x, y, z; +}; + /** * Data type of a shader varying, returned as part of struct * vkd3d_shader_signature_element. diff --git a/libs/vkd3d/libs/vkd3d-common/blob.c b/libs/vkd3d/libs/vkd3d-common/blob.c index f60ef7db769..c2c6ad67804 100644 --- a/libs/vkd3d/libs/vkd3d-common/blob.c +++ b/libs/vkd3d/libs/vkd3d-common/blob.c @@ -20,6 +20,7 @@ #define WIDL_C_INLINE_WRAPPERS #endif #define COBJMACROS + #define CONST_VTABLE #include "vkd3d.h" #include "vkd3d_blob.h" diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index 6425a8f62d2..e2fb8b12998 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -390,27 +390,10 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type) { - static const char *const data_type_names[] = - { - [VSIR_DATA_BOOL ] = "bool", - [VSIR_DATA_F16 ] = "half", - [VSIR_DATA_F32 ] = "float", - [VSIR_DATA_F64 ] = "double", - [VSIR_DATA_I32 ] = "int", - [VSIR_DATA_U8 ] = "uint8", - [VSIR_DATA_U16 ] = "uint16", - [VSIR_DATA_U32 ] = "uint", - [VSIR_DATA_U64 ] = "uint64", - [VSIR_DATA_SNORM ] = "snorm", - [VSIR_DATA_UNORM ] = "unorm", - [VSIR_DATA_OPAQUE ] = "opaque", - [VSIR_DATA_MIXED ] = "mixed", - [VSIR_DATA_CONTINUED] = "", - [VSIR_DATA_UNUSED ] = "", - }; + const char *name; - if (type < ARRAY_SIZE(data_type_names)) - vkd3d_string_buffer_printf(&compiler->buffer, "%s", data_type_names[type]); + if ((name = vsir_data_type_get_name(type, NULL))) + vkd3d_string_buffer_printf(&compiler->buffer, "%s", name); else vkd3d_string_buffer_printf(&compiler->buffer, "%s%s", compiler->colours.error, type, compiler->colours.reset); @@ -851,7 +834,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const && reg->type != VKD3DSPR_NULL && reg->type != VKD3DSPR_DEPTHOUT) { - if (offset != ~0u) + if (reg->idx_count) { bool is_sm_5_1 = vkd3d_shader_ver_ge(&compiler->shader_version, 5, 1); @@ -879,10 +862,10 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const /* For descriptors in sm < 5.1 we move the reg->idx values up one slot * to normalise with 5.1. * Here we should ignore it if it's a descriptor in sm < 5.1. */ - if (reg->idx[1].offset != ~0u && (!is_descriptor || is_sm_5_1)) + if (reg->idx_count > 1 && (!is_descriptor || is_sm_5_1)) shader_print_subscript(compiler, reg->idx[1].offset, reg->idx[1].rel_addr); - if (reg->idx[2].offset != ~0u) + if (reg->idx_count > 2) shader_print_subscript(compiler, reg->idx[2].offset, reg->idx[2].rel_addr); } } @@ -974,6 +957,22 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, vkd3d_string_buffer_printf(buffer, ">%s", suffix); } +static void shader_print_indexable_temp_data_type(struct vkd3d_d3d_asm_compiler *compiler, + const struct vkd3d_shader_indexable_temp *t) +{ + struct vkd3d_string_buffer *buffer = &compiler->buffer; + + if (!(compiler->flags & VSIR_ASM_FLAG_DUMP_TYPES)) + return; + + if (t->component_count > 1) + vkd3d_string_buffer_printf(buffer, " component_count); + else + vkd3d_string_buffer_printf(buffer, " data_type); + vkd3d_string_buffer_printf(buffer, ">"); +} + static void shader_print_write_mask(struct vkd3d_d3d_asm_compiler *compiler, const char *prefix, uint32_t mask, const char *suffix) { @@ -1528,6 +1527,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, vkd3d_string_buffer_printf(buffer, " %sx%u%s", compiler->colours.reg, ins->declaration.indexable_temp.register_idx, compiler->colours.reset); shader_print_subscript(compiler, ins->declaration.indexable_temp.register_size, NULL); + shader_print_indexable_temp_data_type(compiler, &ins->declaration.indexable_temp); shader_print_uint_literal(compiler, ", ", ins->declaration.indexable_temp.component_count, ""); if (ins->declaration.indexable_temp.alignment) shader_print_uint_literal(compiler, ", align ", ins->declaration.indexable_temp.alignment, ""); diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 751e5578276..a9195b3454a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -246,6 +246,7 @@ struct vkd3d_shader_sm1_parser bool abort; struct vkd3d_shader_parser p; + struct vsir_program *program; struct { @@ -468,7 +469,7 @@ static bool has_relative_address(uint32_t param) static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( const struct vkd3d_shader_sm1_parser *sm1, enum vkd3d_sm1_opcode opcode) { - const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; + const struct vkd3d_shader_version *version = &sm1->program->shader_version; const struct vkd3d_sm1_opcode_info *info; unsigned int i = 0; @@ -542,9 +543,9 @@ static enum vkd3d_shader_register_type parse_register_type( } if (d3dbc_type == VKD3D_SM1_REG_ADDR) - return sm1->p.program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; + return sm1->program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL ? VKD3DSPR_TEXTURE : VKD3DSPR_ADDR; if (d3dbc_type == VKD3D_SM1_REG_TEXCRDOUT) - return vkd3d_shader_ver_ge(&sm1->p.program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; + return vkd3d_shader_ver_ge(&sm1->program->shader_version, 3, 0) ? VKD3DSPR_OUTPUT : VKD3DSPR_TEXCRDOUT; for (unsigned int i = 0; i < ARRAY_SIZE(register_types); ++i) { @@ -660,7 +661,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp const char *name, unsigned int index, enum vkd3d_shader_sysval_semantic sysval, unsigned int register_index, bool is_dcl, unsigned int mask) { - struct vsir_program *program = sm1->p.program; + struct vsir_program *program = sm1->program; struct shader_signature *signature; struct signature_element *element; @@ -702,7 +703,7 @@ static bool add_signature_element(struct vkd3d_shader_sm1_parser *sm1, bool outp static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, unsigned int register_index, unsigned int mask) { - struct vsir_program *program = sm1->p.program; + struct vsir_program *program = sm1->program; struct shader_signature *signature; struct signature_element *element; @@ -749,7 +750,7 @@ static void add_signature_mask(struct vkd3d_shader_sm1_parser *sm1, bool output, static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_register *reg, bool is_dcl, unsigned int mask) { - const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; + const struct vkd3d_shader_version *version = &sm1->program->shader_version; unsigned int register_index = reg->idx_count > 0 ? reg->idx[0].offset : 0; switch (reg->type) @@ -844,7 +845,7 @@ static bool add_signature_element_from_register(struct vkd3d_shader_sm1_parser * static bool add_signature_element_from_semantic(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_semantic *semantic) { - const struct vkd3d_shader_version *version = &sm1->p.program->shader_version; + const struct vkd3d_shader_version *version = &sm1->program->shader_version; const struct vkd3d_shader_register *reg = &semantic->resource.reg.reg; enum vkd3d_shader_sysval_semantic sysval = VKD3D_SHADER_SV_NONE; unsigned int mask = semantic->resource.reg.write_mask; @@ -906,7 +907,7 @@ static void record_constant_register(struct vkd3d_shader_sm1_parser *sm1, static void shader_sm1_scan_register(struct vkd3d_shader_sm1_parser *sm1, const struct vkd3d_shader_register *reg, unsigned int mask, bool from_def) { - struct vsir_program *program = sm1->p.program; + struct vsir_program *program = sm1->program; uint32_t register_index = reg->idx[0].offset; switch (reg->type) @@ -955,7 +956,7 @@ static void shader_sm1_read_param(struct vkd3d_shader_sm1_parser *sm1, * VS >= 2.0 have relative addressing (with token) * VS >= 1.0 < 2.0 have relative addressing (without token) * The version check below should work in general. */ - if (sm1->p.program->shader_version.major < 2) + if (sm1->program->shader_version.major < 2) { *addr_token = (1u << 31) | ((VKD3DSPR_ADDR << VKD3D_SM1_REGISTER_TYPE_SHIFT2) & VKD3D_SM1_REGISTER_TYPE_MASK2) @@ -984,7 +985,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co /* Version 2.0+ shaders may contain address tokens, but fortunately they * have a useful length mask - use it here. Version 1.x shaders contain no * such tokens. */ - if (sm1->p.program->shader_version.major >= 2) + if (sm1->program->shader_version.major >= 2) { length = (opcode_token & VKD3D_SM1_INSTRUCTION_LENGTH_MASK) >> VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; *ptr += length; @@ -1019,7 +1020,7 @@ static void shader_sm1_read_src_param(struct vkd3d_shader_sm1_parser *sm1, const shader_sm1_read_param(sm1, ptr, &token, &addr_token); if (has_relative_address(token)) { - if (!(src_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) + if (!(src_rel_addr = vsir_program_get_src_params(sm1->program, 1))) { vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); @@ -1040,7 +1041,7 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const shader_sm1_read_param(sm1, ptr, &token, &addr_token); if (has_relative_address(token)) { - if (!(dst_rel_addr = vsir_program_get_src_params(sm1->p.program, 1))) + if (!(dst_rel_addr = vsir_program_get_src_params(sm1->program, 1))) { vkd3d_shader_parser_error(&sm1->p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); @@ -1052,9 +1053,9 @@ static void shader_sm1_read_dst_param(struct vkd3d_shader_sm1_parser *sm1, const shader_sm1_parse_dst_param(sm1, token, dst_rel_addr, dst_param); if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_POINT_SIZE) - sm1->p.program->has_point_size = true; + sm1->program->has_point_size = true; if (dst_param->reg.type == VKD3DSPR_RASTOUT && dst_param->reg.idx[0].offset == VSIR_RASTOUT_FOG) - sm1->p.program->has_fog = true; + sm1->program->has_fog = true; } static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, @@ -1214,7 +1215,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str { struct vkd3d_shader_src_param *src_params, *predicate; const struct vkd3d_sm1_opcode_info *opcode_info; - struct vsir_program *program = sm1->p.program; + struct vsir_program *program = sm1->program; unsigned int vsir_dst_count, vsir_src_count; struct vkd3d_shader_dst_param *dst_param; const uint32_t **ptr = &sm1->ptr; @@ -1446,7 +1447,8 @@ static enum vkd3d_result shader_sm1_init(struct vkd3d_shader_sm1_parser *sm1, st code_size != ~(size_t)0 ? token_count / 4u + 4 : 16, VSIR_CF_STRUCTURED, normalisation_level)) return VKD3D_ERROR_OUT_OF_MEMORY; - vkd3d_shader_parser_init(&sm1->p, program, message_context, compile_info->source_name); + vkd3d_shader_parser_init(&sm1->p, message_context, compile_info->source_name); + sm1->program = program; sm1->ptr = sm1->start; return VKD3D_OK; @@ -1952,7 +1954,7 @@ static void d3dbc_write_vsir_dcl(struct d3dbc_compiler *d3dbc, const struct vkd3 reg_id = semantic->resource.reg.reg.idx[0].offset; - if (semantic->resource.reg.reg.type != VKD3DSPR_SAMPLER) + if (semantic->resource.reg.reg.type != VKD3DSPR_COMBINED_SAMPLER) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_TYPE, "dcl instruction with register type %u.", semantic->resource.reg.reg.type); diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index c448e000cf9..fb2cde4501a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -892,6 +892,8 @@ struct sm6_parser const uint32_t *ptr, *start, *end; unsigned int bitpos; + struct vsir_program *program; + struct dxil_block root_block; struct dxil_block *current_block; @@ -2437,7 +2439,7 @@ static struct vkd3d_shader_src_param *instruction_src_params_alloc(struct vkd3d_ { struct vkd3d_shader_src_param *params; - if (!(params = vsir_program_get_src_params(sm6->p.program, count))) + if (!(params = vsir_program_get_src_params(sm6->program, count))) { ERR("Failed to allocate src params.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, @@ -2454,7 +2456,7 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ { struct vkd3d_shader_dst_param *params; - if (!(params = vsir_program_get_dst_params(sm6->p.program, count))) + if (!(params = vsir_program_get_dst_params(sm6->program, count))) { ERR("Failed to allocate dst params.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, @@ -2473,7 +2475,7 @@ static void register_init_with_id(struct vkd3d_shader_register *reg, reg->idx[0].offset = id; } -static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) +static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type, struct sm6_parser *dxil) { if (type->class == TYPE_CLASS_INTEGER) { @@ -2490,7 +2492,8 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) case 64: return VSIR_DATA_U64; default: - FIXME("Unhandled width %u.\n", type->u.width); + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, + "Unhandled integer width %u.", type->u.width); return VSIR_DATA_U32; } } @@ -2505,12 +2508,14 @@ static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) case 64: return VSIR_DATA_F64; default: - FIXME("Unhandled width %u.\n", type->u.width); + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, + "Unhandled floating-point width %u.", type->u.width); return VSIR_DATA_F32; } } - FIXME("Unhandled type %u.\n", type->class); + vkd3d_shader_parser_error(&dxil->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, + "Unhandled type %#x.", type->class); return VSIR_DATA_U32; } @@ -2597,7 +2602,7 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str enum vsir_data_type data_type; scalar_type = sm6_type_get_scalar_type(value->type, 0); - data_type = vsir_data_type_from_dxil(scalar_type); + data_type = vsir_data_type_from_dxil(scalar_type, sm6); switch (value->value_type) { @@ -2756,7 +2761,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, } else { - struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1); + struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->program, 1); if (rel_addr) src_param_init_from_value(rel_addr, address, sm6); idx->offset = 0; @@ -3224,7 +3229,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co "Out of memory allocating an immediate constant buffer of count %u.", count); return VKD3D_ERROR_OUT_OF_MEMORY; } - if (!shader_instruction_array_add_icb(&sm6->p.program->instructions, icb)) + if (!shader_instruction_array_add_icb(&sm6->program->instructions, icb)) { ERR("Failed to store icb object.\n"); vkd3d_free(icb); @@ -3237,7 +3242,7 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co dst->u.data = icb; icb->register_idx = sm6->icb_count++; - icb->data_type = vsir_data_type_from_dxil(elem_type); + icb->data_type = vsir_data_type_from_dxil(elem_type, sm6); icb->element_count = type->u.array.count; icb->component_count = 1; icb->is_null = !operands; @@ -3653,7 +3658,7 @@ static bool bitcode_parse_alignment(uint64_t encoded_alignment, unsigned int *al static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_parser *sm6, size_t extra) { - struct vkd3d_shader_instruction_array *instructions = &sm6->p.program->instructions; + struct vkd3d_shader_instruction_array *instructions = &sm6->program->instructions; if (!shader_instruction_array_reserve(instructions, instructions->count + extra)) { @@ -3663,14 +3668,15 @@ static struct vkd3d_shader_instruction *sm6_parser_require_space(struct sm6_pars return &instructions->elements[instructions->count]; } -/* Space should be reserved before calling this. It is intended to require no checking of the returned pointer. */ static struct vkd3d_shader_instruction *sm6_parser_add_instruction(struct sm6_parser *sm6, - enum vkd3d_shader_opcode handler_idx) + enum vkd3d_shader_opcode op) { - struct vkd3d_shader_instruction *ins = sm6_parser_require_space(sm6, 1); - VKD3D_ASSERT(ins); - vsir_instruction_init(ins, &sm6->p.location, handler_idx); - ++sm6->p.program->instructions.count; + struct vkd3d_shader_instruction *ins; + + if (!(ins = vsir_program_append(sm6->program))) + return NULL; + vsir_instruction_init(ins, &sm6->p.location, op); + return ins; } @@ -3690,7 +3696,15 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru unsigned int count, unsigned int alignment, bool has_function_scope, unsigned int init, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { - enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type); + enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type, sm6); + + if (!(sm6->program->global_flags & VKD3DSGF_FORCE_NATIVE_LOW_PRECISION)) + { + if (data_type == VSIR_DATA_F16) + data_type = VSIR_DATA_F32; + else if (data_type == VSIR_DATA_U16) + data_type = VSIR_DATA_U32; + } if (ins) vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP); @@ -3969,7 +3983,7 @@ static bool resolve_forward_zero_initialiser(size_t index, struct sm6_parser *sm static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) { - struct vsir_program_iterator it = vsir_program_iterator(&sm6->p.program->instructions); + struct vsir_program_iterator it = vsir_program_iterator(&sm6->program->instructions); size_t i, count, base_value_idx = sm6->value_count; const struct dxil_block *block = &sm6->root_block; struct vkd3d_shader_instruction *ins; @@ -4009,8 +4023,7 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) return VKD3D_ERROR_INVALID_SHADER; if ((version = record->operands[0]) != 1) { - FIXME("Unsupported format version %#"PRIx64".\n", version); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED_BITCODE_FORMAT, + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED, "Bitcode format version %#"PRIx64" is unsupported.", version); return VKD3D_ERROR_INVALID_SHADER; } @@ -4125,7 +4138,7 @@ static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shader_signature *s, bool is_input, enum vkd3d_shader_register_type reg_type, struct vkd3d_shader_dst_param *params) { - enum vkd3d_shader_type shader_type = sm6->p.program->shader_version.type; + enum vkd3d_shader_type shader_type = sm6->program->shader_version.type; enum vkd3d_shader_register_type io_reg_type; bool is_patch_constant, is_control_point; struct vkd3d_shader_dst_param *param; @@ -4175,7 +4188,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade if (is_control_point) { if (reg_type == VKD3DSPR_OUTPUT) - param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->p.program); + param->reg.idx[count].rel_addr = vsir_program_create_outpointid_param(sm6->program); param->reg.idx[count++].offset = 0; } @@ -4190,7 +4203,7 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct shader_signature *output_signature) { - if (!(sm6->output_params = vsir_program_get_dst_params(sm6->p.program, output_signature->element_count))) + if (!(sm6->output_params = vsir_program_get_dst_params(sm6->program, output_signature->element_count))) { vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, "Failed to allocate output parameters."); @@ -4204,7 +4217,7 @@ static int sm6_parser_init_output_signature(struct sm6_parser *sm6, const struct static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct shader_signature *input_signature) { - if (!(sm6->input_params = vsir_program_get_dst_params(sm6->p.program, input_signature->element_count))) + if (!(sm6->input_params = vsir_program_get_dst_params(sm6->program, input_signature->element_count))) { vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, "Failed to allocate input parameters."); @@ -4219,9 +4232,9 @@ static int sm6_parser_init_input_signature(struct sm6_parser *sm6, const struct static int sm6_parser_init_patch_constant_signature(struct sm6_parser *sm6, const struct shader_signature *patch_constant_signature) { - bool is_input = sm6->p.program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; + bool is_input = sm6->program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; - if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->p.program, + if (!(sm6->patch_constant_params = vsir_program_get_dst_params(sm6->program, patch_constant_signature->element_count))) { vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, @@ -5180,7 +5193,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr type = sm6_type_get_scalar_type(dst->type, 0); VKD3D_ASSERT(type); - src_param->reg.data_type = vsir_data_type_from_dxil(type); + src_param->reg.data_type = vsir_data_type_from_dxil(type, sm6); if (data_type_is_64_bit(src_param->reg.data_type)) src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); else @@ -5407,7 +5420,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri row_index = sm6_value_get_constant_uint(operands[0], sm6); column_index = sm6_value_get_constant_uint(operands[2], sm6); - signature = &sm6->p.program->input_signature; + signature = &sm6->program->input_signature; if (row_index >= signature->element_count) { WARN("Invalid row index %u.\n", row_index); @@ -5638,7 +5651,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin bool is_control_point = op == DX_LOAD_OUTPUT_CONTROL_POINT; bool is_patch_constant = op == DX_LOAD_PATCH_CONSTANT; struct vkd3d_shader_instruction *ins = state->ins; - struct vsir_program *program = sm6->p.program; + struct vsir_program *program = sm6->program; unsigned int count, row_index, column_index; const struct vkd3d_shader_dst_param *params; struct vkd3d_shader_src_param *src_param; @@ -6148,7 +6161,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { - const struct shader_signature *signature = &sm6->p.program->input_signature; + const struct shader_signature *signature = &sm6->program->input_signature; struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param; unsigned int element_idx; @@ -6207,7 +6220,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr { bool is_patch_constant = op == DX_STORE_PATCH_CONSTANT; struct vkd3d_shader_instruction *ins = state->ins; - struct vsir_program *program = sm6->p.program; + struct vsir_program *program = sm6->program; struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_dst_param *dst_param; const struct shader_signature *signature; @@ -8206,7 +8219,7 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const struct dxil_block *block, struct sm6_function *function) { - struct vsir_program *program = sm6->p.program; + struct vsir_program *program = sm6->program; struct vkd3d_shader_instruction *ins; size_t i, block_idx, block_count; const struct dxil_record *record; @@ -8586,8 +8599,9 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *function, struct sm6_parser *sm6) { - struct vsir_program *program = sm6->p.program; - unsigned int i; + struct vsir_program *program = sm6->program; + struct vkd3d_shader_instruction *ins; + unsigned int i, j; program->block_count = function->block_count; @@ -8605,10 +8619,11 @@ static enum vkd3d_result sm6_function_emit_blocks(const struct sm6_function *fun sm6_parser_emit_label(sm6, block->id); sm6_block_emit_phi(block, sm6); - memcpy(&program->instructions.elements[program->instructions.count], block->instructions, - block->instruction_count * sizeof(*block->instructions)); - program->instructions.count += block->instruction_count; - + for (j = 0; j < block->instruction_count; ++j) + { + ins = vsir_program_append(program); + *ins = block->instructions[j]; + } sm6_block_emit_terminator(block, sm6); } @@ -9510,8 +9525,8 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins; const struct sm6_metadata_node *node; const struct sm6_metadata_value *m; + enum vkd3d_result ret = VKD3D_OK; struct sm6_descriptor_info *d; - enum vkd3d_result ret; unsigned int i; for (i = 0; i < descriptor_node->operand_count; ++i) @@ -9560,9 +9575,10 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; } - if (!(ins = sm6_parser_require_space(sm6, 1))) + if (!(ins = sm6_parser_add_instruction(sm6, VSIR_OP_NOP))) { - ERR("Failed to allocate instruction.\n"); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_OUT_OF_MEMORY, + "Out of memory emitting shader instructions."); return VKD3D_ERROR_OUT_OF_MEMORY; } @@ -9570,32 +9586,34 @@ static enum vkd3d_result sm6_parser_descriptor_type_init(struct sm6_parser *sm6, { case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: if ((ret = sm6_parser_resources_load_cbv(sm6, node, d, ins)) < 0) - return ret; + goto done; break; case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: if ((ret = sm6_parser_resources_load_srv(sm6, node, d, ins)) < 0) - return ret; + goto done; break; case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: if ((ret = sm6_parser_resources_load_uav(sm6, node, d, ins)) < 0) - return ret; + goto done; break; case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: if ((ret = sm6_parser_resources_load_sampler(sm6, node, d, ins)) < 0) - return ret; + goto done; break; default: - FIXME("Unsupported descriptor type %u.\n", type); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, - "Resource descriptor type %u is unsupported.", type); - return VKD3D_ERROR_INVALID_SHADER; + "Resource descriptor type %#x is unsupported.", type); + ret = VKD3D_ERROR_INVALID_SHADER; + goto done; } ++sm6->descriptor_count; - ++sm6->p.program->instructions.count; } - return VKD3D_OK; +done: + if (ret < 0) + vsir_instruction_init(ins, &ins->location, VSIR_OP_NOP); + return ret; } static enum vkd3d_result sm6_parser_resources_init(struct sm6_parser *sm6) @@ -9711,7 +9729,7 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const { unsigned int i, j, column_count, operand_count, index; const struct sm6_metadata_node *node, *element_node; - struct vsir_program *program = sm6->p.program; + struct vsir_program *program = sm6->program; struct signature_element *elements, *e; unsigned int values[10]; bool native_16bit; @@ -9930,7 +9948,7 @@ invalid: static enum vkd3d_result sm6_parser_signatures_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m, enum vkd3d_tessellator_domain tessellator_domain) { - struct vsir_program *program = sm6->p.program; + struct vsir_program *program = sm6->program; enum vkd3d_result ret; if (!sm6_metadata_value_is_node(m)) @@ -9985,12 +10003,12 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_GLOBAL_FLAGS); ins->declaration.global_flags = global_flags; - sm6->p.program->global_flags = global_flags; + sm6->program->global_flags = global_flags; } static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, const struct sm6_metadata_value *m) { - struct vkd3d_shader_version *version = &sm6->p.program->shader_version; + struct vkd3d_shader_version *version = &sm6->program->shader_version; const struct sm6_metadata_node *node; struct vkd3d_shader_instruction *ins; unsigned int group_sizes[3]; @@ -10044,7 +10062,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co ins->declaration.thread_group_size.x = group_sizes[0]; ins->declaration.thread_group_size.y = group_sizes[1]; ins->declaration.thread_group_size.z = group_sizes[2]; - sm6->p.program->thread_group_size = ins->declaration.thread_group_size; + sm6->program->thread_group_size = ins->declaration.thread_group_size; return VKD3D_OK; } @@ -10082,7 +10100,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_DOMAIN); ins->declaration.tessellator_domain = tessellator_domain; - sm6->p.program->tess_domain = tessellator_domain; + sm6->program->tess_domain = tessellator_domain; } static void sm6_parser_validate_control_point_count(struct sm6_parser *sm6, @@ -10111,7 +10129,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_PARTITIONING); ins->declaration.tessellator_partitioning = tessellator_partitioning; - sm6->p.program->tess_partitioning = tessellator_partitioning; + sm6->program->tess_partitioning = tessellator_partitioning; } static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser *sm6, @@ -10129,7 +10147,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); ins->declaration.tessellator_output_primitive = primitive; - sm6->p.program->tess_output_primitive = primitive; + sm6->program->tess_output_primitive = primitive; } static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, struct sm6_metadata_value *m) @@ -10241,8 +10259,8 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s } sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); - sm6->p.program->input_primitive = input_primitive; - sm6->p.program->input_control_point_count = input_control_point_count; + sm6->program->input_primitive = input_primitive; + sm6->program->input_control_point_count = input_control_point_count; i = operands[1]; /* Max total scalar count sets an upper limit. We would need to scan outputs to be more precise. */ @@ -10253,7 +10271,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s "Geometry shader output vertex count %u is invalid.", i); } sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i); - sm6->p.program->vertices_out_count = i; + sm6->program->vertices_out_count = i; if (operands[2] > 1) { @@ -10271,7 +10289,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s output_primitive = VKD3D_PT_TRIANGLELIST; } sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); - sm6->p.program->output_topology = output_primitive; + sm6->program->output_topology = output_primitive; i = operands[4]; if (!i || i > MAX_GS_INSTANCE_COUNT) @@ -10326,7 +10344,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa sm6_parser_emit_dcl_tessellator_domain(sm6, operands[0]); sm6_parser_validate_control_point_count(sm6, operands[1], true, "Domain shader input"); - sm6->p.program->input_control_point_count = operands[1]; + sm6->program->input_control_point_count = operands[1]; return operands[0]; } @@ -10334,7 +10352,7 @@ static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_pa static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_parser *sm6, const struct sm6_metadata_value *m) { - struct vsir_program *program = sm6->p.program; + struct vsir_program *program = sm6->program; const struct sm6_metadata_node *node; unsigned int operands[6] = {0}; unsigned int i; @@ -10727,9 +10745,10 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro if (!vsir_program_init(program, compile_info, &version, (count + (count >> 2)) / 2u + 10, VSIR_CF_BLOCKS, VSIR_NORMALISED_SM6)) return VKD3D_ERROR_OUT_OF_MEMORY; - vkd3d_shader_parser_init(&sm6->p, program, message_context, compile_info->source_name); + vkd3d_shader_parser_init(&sm6->p, message_context, compile_info->source_name); sm6->ptr = &sm6->start[1]; sm6->bitpos = 2; + sm6->program = program; switch (program->shader_version.type) { diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c index 676c501bb08..a14346a45d2 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -4205,7 +4205,7 @@ static void fx_parse_shader_blob(struct fx_parser *parser, enum vkd3d_shader_sou static const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, }; info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index dfe0a40ddf0..b2679beff9f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -288,6 +288,14 @@ static void shader_glsl_print_register_name(struct vkd3d_string_buffer *buffer, shader_glsl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); break; + case VKD3DSPR_SAMPLEMASK: + if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled sample coverage mask in shader type #%x.", + gen->program->shader_version.type); + vkd3d_string_buffer_printf(buffer, "o_mask"); + break; + default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); @@ -792,7 +800,7 @@ static void shader_glsl_print_texel_offset(struct vkd3d_string_buffer *buffer, s static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { - unsigned int resource_id, resource_idx, resource_space, sample_count; + unsigned int coord_size, resource_id, resource_idx, resource_space, sample_count; const struct glsl_resource_type_info *resource_type_info; const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; @@ -800,11 +808,9 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ enum vsir_data_type data_type; struct glsl_src coord; struct glsl_dst dst; - uint32_t coord_mask; + bool array, offset; - if (vkd3d_shader_instruction_has_texel_offset(ins)) - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled texel fetch offset."); + offset = vkd3d_shader_instruction_has_texel_offset(ins); if (ins->src[1].reg.idx[0].rel_addr || ins->src[1].reg.idx[1].rel_addr) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_UNSUPPORTED, @@ -831,20 +837,22 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) { - coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); + coord_size = resource_type_info->coord_size; + array = resource_type_info->array; } else { vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled resource type %#x.", resource_type); - coord_mask = vkd3d_write_mask_from_component_count(2); + coord_size = 2; + array = false; } glsl_dst_init(&dst, gen, ins, &ins->dst[0]); - glsl_src_init(&coord, gen, &ins->src[0], coord_mask); + glsl_src_init(&coord, gen, &ins->src[0], vkd3d_write_mask_from_component_count(coord_size)); fetch = vkd3d_string_buffer_get(&gen->string_buffers); - vkd3d_string_buffer_printf(fetch, "texelFetch("); + vkd3d_string_buffer_printf(fetch, "texelFetch%s(", offset ? "Offset" : ""); shader_glsl_print_combined_sampler_name(fetch, gen, resource_idx, resource_space, VKD3D_SHADER_DUMMY_SAMPLER_INDEX, 0); vkd3d_string_buffer_printf(fetch, ", %s", coord.str->buffer); @@ -860,6 +868,11 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ else shader_glsl_print_src(fetch, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, ins->src[2].reg.data_type); } + if (offset) + { + vkd3d_string_buffer_printf(fetch, ", "); + shader_glsl_print_texel_offset(fetch, gen, coord_size - array, &ins->texel_offset); + } vkd3d_string_buffer_printf(fetch, ")"); shader_glsl_print_swizzle(fetch, ins->src[1].swizzle, ins->dst[0].write_mask); @@ -1281,6 +1294,13 @@ static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, st vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_VertexID, 0, 0, 0))"); break; + case VKD3D_SHADER_SV_INSTANCE_ID: + if (version->type != VKD3D_SHADER_TYPE_VERTEX) + vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, + "Internal compiler error: Unhandled SV_INSTANCE_ID in shader type #%x.", version->type); + vkd3d_string_buffer_printf(buffer, "intBitsToFloat(ivec4(gl_InstanceID, 0, 0, 0))"); + break; + case VKD3D_SHADER_SV_IS_FRONT_FACE: if (version->type != VKD3D_SHADER_TYPE_PIXEL) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, @@ -1429,6 +1449,12 @@ static void shader_glsl_shader_epilogue(struct vkd3d_glsl_generator *gen) shader_glsl_print_write_mask(buffer, e->mask); vkd3d_string_buffer_printf(buffer, ";\n"); } + + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + { + shader_glsl_print_indent(buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "gl_SampleMask[0] = floatBitsToInt(o_mask);\n"); + } } static void shader_glsl_ret(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) @@ -1475,6 +1501,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_CONTINUE: shader_glsl_continue(gen); break; + case VSIR_OP_COS: + shader_glsl_intrinsic(gen, ins, "cos"); + break; case VSIR_OP_DCL_INDEXABLE_TEMP: shader_glsl_dcl_indexable_temp(gen, ins); break; @@ -1495,6 +1524,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_DP4: shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); break; + case VSIR_OP_DSX: + shader_glsl_intrinsic(gen, ins, "dFdx"); + break; + case VSIR_OP_DSY: + shader_glsl_intrinsic(gen, ins, "dFdy"); + break; case VSIR_OP_ELSE: shader_glsl_else(gen, ins); break; @@ -1531,6 +1566,7 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, break; case VSIR_OP_GEO: case VSIR_OP_IGE: + case VSIR_OP_UGE: shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); break; case VSIR_OP_IF: @@ -1620,6 +1656,9 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_RSQ: shader_glsl_intrinsic(gen, ins, "inversesqrt"); break; + case VSIR_OP_SIN: + shader_glsl_intrinsic(gen, ins, "sin"); + break; case VSIR_OP_SQRT: shader_glsl_intrinsic(gen, ins, "sqrt"); break; @@ -1629,6 +1668,12 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen, case VSIR_OP_SWITCH: shader_glsl_switch(gen, ins); break; + case VSIR_OP_UDIV_SIMPLE: + shader_glsl_binop(gen, ins, "/"); + break; + case VSIR_OP_UREM: + shader_glsl_binop(gen, ins, "%"); + break; case VSIR_OP_XOR: shader_glsl_binop(gen, ins, "^"); break; @@ -2318,6 +2363,8 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen) vkd3d_string_buffer_printf(buffer, "vec4 %s_in[%u];\n", gen->prefix, gen->limits.input_count); if (gen->limits.output_count) vkd3d_string_buffer_printf(buffer, "vec4 %s_out[%u];\n", gen->prefix, gen->limits.output_count); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, "float o_mask;\n"); if (program->temp_count) vkd3d_string_buffer_printf(buffer, "vec4 r[%u];\n", program->temp_count); vkd3d_string_buffer_printf(buffer, "\n"); @@ -2328,7 +2375,6 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc struct vkd3d_string_buffer *buffer = gen->buffer; struct vkd3d_shader_instruction *ins; struct vsir_program_iterator it; - void *code; MESSAGE("Generating a GLSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n"); @@ -2357,13 +2403,7 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc if (gen->failed) return VKD3D_ERROR_INVALID_SHADER; - if ((code = vkd3d_malloc(buffer->buffer_size))) - { - memcpy(code, buffer->buffer, buffer->content_size); - out->size = buffer->content_size; - out->code = code; - } - else return VKD3D_ERROR_OUT_OF_MEMORY; + vkd3d_shader_code_from_string_buffer(out, buffer); return VKD3D_OK; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index 62335086e20..d8eb18e39c7 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -1809,6 +1809,76 @@ struct hlsl_ir_node *hlsl_new_null_constant(struct hlsl_ctx *ctx, const struct v return hlsl_new_constant(ctx, ctx->builtin_types.null, &value, loc); } +bool hlsl_constant_is_zero(struct hlsl_ir_constant *c) +{ + struct hlsl_type *data_type = c->node.data_type; + unsigned int k; + + for (k = 0; k < data_type->e.numeric.dimx; ++k) + { + switch (data_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + if (c->value.u[k].f != 0.0f) + return false; + break; + + case HLSL_TYPE_DOUBLE: + if (c->value.u[k].d != 0.0) + return false; + break; + + case HLSL_TYPE_UINT: + case HLSL_TYPE_INT: + case HLSL_TYPE_BOOL: + case HLSL_TYPE_MIN16UINT: + if (c->value.u[k].u != 0) + return false; + break; + } + } + + return true; +} + +bool hlsl_constant_is_one(struct hlsl_ir_constant *c) +{ + struct hlsl_type *data_type = c->node.data_type; + unsigned int k; + + for (k = 0; k < data_type->e.numeric.dimx; ++k) + { + switch (data_type->e.numeric.type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + if (c->value.u[k].f != 1.0f) + return false; + break; + + case HLSL_TYPE_DOUBLE: + if (c->value.u[k].d != 1.0) + return false; + break; + + case HLSL_TYPE_UINT: + case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: + if (c->value.u[k].u != 1) + return false; + break; + + case HLSL_TYPE_BOOL: + if (c->value.u[k].u != ~0) + return false; + break; + } + } + + return true; +} + static struct hlsl_ir_node *hlsl_new_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS], struct hlsl_type *data_type, const struct vkd3d_shader_location *loc) diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index d67f820fe8b..a3e8ccc1e2a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -233,6 +233,9 @@ struct hlsl_type /* Offset where the type's description starts in the output bytecode, in bytes. */ size_t bytecode_offset; + /* Offset where the type's packed description starts in the output bytecode, in bytes. */ + size_t packed_bytecode_offset; + bool is_typedef; uint32_t is_minimum_precision : 1; @@ -1184,8 +1187,8 @@ struct hlsl_ctx } constant_defs; /* 'c' registers where the constants expected by SM2 sincos are stored. */ struct hlsl_reg d3dsincosconst1, d3dsincosconst2; - /* Number of allocated SSA IDs, used in translation to vsir. */ - unsigned int ssa_count; + /* Number of allocated registers, used in translation to vsir. */ + unsigned int ssa_count, temp_count, indexable_temp_count; /* Number of threads to be executed (on the X, Y, and Z dimensions) in a single thread group in * compute shader profiles. It is set using the numthreads() attribute in the entry point. */ @@ -1541,6 +1544,12 @@ static inline bool hlsl_var_has_buffer_offset_register_reservation(struct hlsl_c return var->reg_reservation.reg_type == 'c' && var->buffer == ctx->globals_buffer; } +static inline bool hlsl_is_comparison_op(enum hlsl_ir_expr_op op) +{ + return op == HLSL_OP2_EQUAL || op == HLSL_OP2_GEQUAL + || op == HLSL_OP2_LESS || op == HLSL_OP2_NEQUAL; +} + char *hlsl_sprintf_alloc(struct hlsl_ctx *ctx, const char *fmt, ...) VKD3D_PRINTF_FUNC(2, 3); const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op); @@ -1693,6 +1702,9 @@ struct hlsl_type *hlsl_new_stream_output_type(struct hlsl_ctx *ctx, struct hlsl_ir_node *hlsl_new_ternary_expr(struct hlsl_ctx *ctx, enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg1, struct hlsl_ir_node *arg2, struct hlsl_ir_node *arg3); +bool hlsl_constant_is_zero(struct hlsl_ir_constant *c); +bool hlsl_constant_is_one(struct hlsl_ir_constant *c); + void hlsl_init_simple_deref_from_var(struct hlsl_deref *deref, struct hlsl_ir_var *var); struct hlsl_ir_load *hlsl_new_var_load(struct hlsl_ctx *ctx, struct hlsl_ir_var *var, diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l index 0cdebb8a657..da9f0d39136 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l @@ -346,7 +346,7 @@ while {return KW_WHILE; } {ANY} {} {ANY} { - return yytext[0]; + return (unsigned char)yytext[0]; } %% diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 024d96c5663..d83ad9fe7d8 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -3983,6 +3983,53 @@ static bool intrinsic_frac(struct hlsl_ctx *ctx, return !!add_unary_arithmetic_expr(ctx, params->instrs, HLSL_OP1_FRACT, arg, loc); } +static bool intrinsic_frexp(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type, *uint_dim_type, *int_dim_type, *bool_dim_type; + struct hlsl_ir_function_decl *func; + char *body; + + static const char template[] = + "%s frexp(%s x, out %s exp)\n" + "{\n" + /* If x is zero, always return zero for exp and mantissa. */ + " %s is_nonzero_mask = x != 0.0;\n" + " %s bits = asuint(x);\n" + /* Subtract 126, not 127, to increase the exponent */ + " %s exp_int = asint((bits & 0x7f800000u) >> 23) - 126;\n" + /* Clear the given exponent and replace it with the bit pattern + * for 2^-1 */ + " %s mantissa = asfloat((bits & 0x007fffffu) | 0x3f000000);\n" + " exp = is_nonzero_mask * %s(exp_int);\n" + " return is_nonzero_mask * mantissa;\n" + "}\n"; + + if (!elementwise_intrinsic_float_convert_args(ctx, params, loc)) + return false; + type = params->args[0]->data_type; + + if (type->e.numeric.type == HLSL_TYPE_DOUBLE) + { + hlsl_fixme(ctx, loc, "frexp() on doubles."); + return false; + } + type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_FLOAT, type->e.numeric.dimx, type->e.numeric.dimy); + uint_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_UINT, type->e.numeric.dimx, type->e.numeric.dimy); + int_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_INT, type->e.numeric.dimx, type->e.numeric.dimy); + bool_dim_type = hlsl_get_numeric_type(ctx, type->class, HLSL_TYPE_BOOL, type->e.numeric.dimx, type->e.numeric.dimy); + + if (!(body = hlsl_sprintf_alloc(ctx, template, type->name, type->name, type->name, + bool_dim_type->name, uint_dim_type->name, int_dim_type->name, type->name, type->name))) + return false; + func = hlsl_compile_internal_function(ctx, "frexp", body); + vkd3d_free(body); + if (!func) + return false; + + return !!add_user_call(ctx, func, params, false, loc); +} + static bool intrinsic_fwidth(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -4701,7 +4748,8 @@ static bool intrinsic_tex(struct hlsl_ctx *ctx, const struct parse_initializer * } if (!strcmp(name, "tex2Dbias") - || !strcmp(name, "tex2Dlod")) + || !strcmp(name, "tex2Dlod") + || !strcmp(name, "texCUBEbias")) { struct hlsl_ir_node *lod, *c; @@ -4853,6 +4901,12 @@ static bool intrinsic_texCUBE(struct hlsl_ctx *ctx, return intrinsic_tex(ctx, params, loc, "texCUBE", HLSL_SAMPLER_DIM_CUBE); } +static bool intrinsic_texCUBEbias(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + return intrinsic_tex(ctx, params, loc, "texCUBEbias", HLSL_SAMPLER_DIM_CUBE); +} + static bool intrinsic_texCUBEgrad(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -5283,6 +5337,7 @@ intrinsic_functions[] = {"floor", 1, true, intrinsic_floor}, {"fmod", 2, true, intrinsic_fmod}, {"frac", 1, true, intrinsic_frac}, + {"frexp", 2, true, intrinsic_frexp}, {"fwidth", 1, true, intrinsic_fwidth}, {"isinf", 1, true, intrinsic_isinf}, {"ldexp", 2, true, intrinsic_ldexp}, @@ -5327,6 +5382,7 @@ intrinsic_functions[] = {"tex3Dgrad", 4, false, intrinsic_tex3Dgrad}, {"tex3Dproj", 2, false, intrinsic_tex3Dproj}, {"texCUBE", -1, false, intrinsic_texCUBE}, + {"texCUBEbias", 2, false, intrinsic_texCUBEbias}, {"texCUBEgrad", 4, false, intrinsic_texCUBEgrad}, {"texCUBEproj", 2, false, intrinsic_texCUBEproj}, {"transpose", 1, true, intrinsic_transpose}, @@ -8059,7 +8115,7 @@ resource_format: { uint32_t modifiers = $1; - if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, false, &@1))) + if (!($$ = apply_type_modifiers(ctx, $2, &modifiers, true, &@1))) YYABORT; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 0b3dee4d2ce..eaf7d7a3d63 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -175,12 +175,29 @@ static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) } } +static unsigned int struct_field_get_packed_offset(const struct hlsl_type *record, unsigned int field_idx) +{ + unsigned int offset = 0; + + VKD3D_ASSERT(record->class == HLSL_CLASS_STRUCT); + VKD3D_ASSERT(field_idx < record->e.record.field_count); + + for (unsigned int i = 0; i < field_idx; ++i) + { + struct hlsl_struct_field *field = &record->e.record.fields[i]; + offset = align(offset, hlsl_type_get_packed_alignment(field->type)) + hlsl_type_get_packed_size(field->type); + } + + return align(offset, hlsl_type_get_packed_alignment(record->e.record.fields[field_idx].type)); +} + + static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_node *prev_offset, struct hlsl_ir_node *idx, struct hlsl_type *type, const struct vkd3d_shader_location *loc) { struct hlsl_ir_node *idx_offset = NULL, *c; - unsigned int field_idx, offset, size, i; + unsigned int field_idx, offset, size; switch (type->class) { @@ -203,15 +220,7 @@ static struct hlsl_ir_node *hlsl_block_add_packed_index_offset_append(struct hls case HLSL_CLASS_STRUCT: field_idx = hlsl_ir_constant(idx)->value.u[0].u; - for (i = 0, offset = 0; i < field_idx; ++i) - { - struct hlsl_struct_field *field = &type->e.record.fields[i]; - - offset = align(offset, hlsl_type_get_packed_alignment(field->type)) - + hlsl_type_get_packed_size(field->type); - } - - offset = align(offset, hlsl_type_get_packed_alignment(type->e.record.fields[field_idx].type)); + offset = struct_field_get_packed_offset(type, field_idx); idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); break; @@ -5029,8 +5038,7 @@ static bool lower_comparison_operators(struct hlsl_ctx *ctx, struct hlsl_ir_node if (instr->type != HLSL_IR_EXPR) return false; expr = hlsl_ir_expr(instr); - if (expr->op != HLSL_OP2_EQUAL && expr->op != HLSL_OP2_NEQUAL && expr->op != HLSL_OP2_LESS - && expr->op != HLSL_OP2_GEQUAL) + if (!hlsl_is_comparison_op(expr->op)) return false; arg1 = expr->operands[0].node; @@ -5906,11 +5914,13 @@ static void mark_vars_usage(struct hlsl_ctx *ctx) struct register_allocator { + /* Type of registers we are allocating (not counting indexable temps). */ + enum vkd3d_shader_register_type type; + struct allocation { uint32_t reg; unsigned int writemask; - unsigned int first_write, last_read; /* Two allocations with different mode can't share the same register. */ int mode; @@ -5920,11 +5930,7 @@ struct register_allocator } *allocations; size_t count, capacity; - /* Indexable temps are allocated separately and always keep their index regardless of their - * lifetime. */ - uint32_t indexable_count; - - /* Total number of registers allocated so far. Used to declare sm4 temp count. */ + /* Total number of registers allocated so far. */ uint32_t reg_count; /* Special flag so allocations that can share registers prioritize those @@ -5936,7 +5942,7 @@ struct register_allocator }; static unsigned int get_available_writemask(const struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, uint32_t reg_idx, int mode, bool vip) + uint32_t reg_idx, int mode, bool vip) { unsigned int writemask = VKD3DSP_WRITEMASK_ALL; size_t i; @@ -5945,12 +5951,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all { const struct allocation *allocation = &allocator->allocations[i]; - /* We do not overlap if first write == last read: - * this is the case where we are allocating the result of that - * expression, e.g. "add r0, r0, r1". */ - - if (allocation->reg == reg_idx - && first_write < allocation->last_read && last_read > allocation->first_write) + if (allocation->reg == reg_idx) { writemask &= ~allocation->writemask; if (allocation->mode != mode) @@ -5967,7 +5968,7 @@ static unsigned int get_available_writemask(const struct register_allocator *all } static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *allocator, uint32_t reg_idx, - unsigned int writemask, unsigned int first_write, unsigned int last_read, int mode, bool vip) + unsigned int writemask, int mode, bool vip) { struct allocation *allocation; @@ -5978,8 +5979,6 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a allocation = &allocator->allocations[allocator->count++]; allocation->reg = reg_idx; allocation->writemask = writemask; - allocation->first_write = first_write; - allocation->last_read = last_read; allocation->mode = mode; allocation->vip = vip; @@ -5998,8 +5997,7 @@ static void record_allocation(struct hlsl_ctx *ctx, struct register_allocator *a * 'vip' can be used so that no new allocations can be made in the given register * unless they are 'vip' as well. */ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, unsigned int reg_size, - unsigned int component_count, int mode, bool force_align, bool vip) + unsigned int reg_size, unsigned int component_count, int mode, bool force_align, bool vip) { struct hlsl_reg ret = {.allocation_size = 1, .allocated = true}; unsigned int required_size = force_align ? 4 : reg_size; @@ -6012,62 +6010,34 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a { for (uint32_t reg_idx = 0; reg_idx < allocator->reg_count; ++reg_idx) { - unsigned int available_writemask = get_available_writemask(allocator, - first_write, last_read, reg_idx, mode, vip); + unsigned int available_writemask = get_available_writemask(allocator, reg_idx, mode, vip); if (vkd3d_popcount(available_writemask) >= pref) { unsigned int writemask = hlsl_combine_writemasks(available_writemask, vkd3d_write_mask_from_component_count(reg_size)); - ret.type = VKD3DSPR_TEMP; + ret.type = allocator->type; ret.id = reg_idx; ret.writemask = hlsl_combine_writemasks(writemask, vkd3d_write_mask_from_component_count(component_count)); - record_allocation(ctx, allocator, reg_idx, writemask, first_write, last_read, mode, vip); + record_allocation(ctx, allocator, reg_idx, writemask, mode, vip); return ret; } } } - ret.type = VKD3DSPR_TEMP; + ret.type = allocator->type; ret.id = allocator->reg_count; ret.writemask = vkd3d_write_mask_from_component_count(component_count); record_allocation(ctx, allocator, allocator->reg_count, - vkd3d_write_mask_from_component_count(reg_size), first_write, last_read, mode, vip); + vkd3d_write_mask_from_component_count(reg_size), mode, vip); return ret; } -/* Allocate a register with writemask, while reserving reg_writemask. */ -static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx, - struct register_allocator *allocator, unsigned int first_write, unsigned int last_read, - uint32_t reg_writemask, uint32_t writemask, int mode, bool vip) -{ - struct hlsl_reg ret = {0}; - uint32_t reg_idx; - - VKD3D_ASSERT((reg_writemask & writemask) == writemask); - - for (reg_idx = 0;; ++reg_idx) - { - if ((get_available_writemask(allocator, first_write, last_read, - reg_idx, mode, vip) & reg_writemask) == reg_writemask) - break; - } - - record_allocation(ctx, allocator, reg_idx, reg_writemask, first_write, last_read, mode, vip); - - ret.type = VKD3DSPR_TEMP; - ret.id = reg_idx; - ret.allocation_size = 1; - ret.writemask = writemask; - ret.allocated = true; - return ret; -} - -static bool is_range_available(const struct register_allocator *allocator, unsigned int first_write, - unsigned int last_read, uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) +static bool is_range_available(const struct register_allocator *allocator, + uint32_t reg_idx, unsigned int reg_size, int mode, bool vip) { unsigned int last_reg_mask = (1u << (reg_size % 4)) - 1; unsigned int writemask; @@ -6075,18 +6045,18 @@ static bool is_range_available(const struct register_allocator *allocator, unsig for (i = 0; i < (reg_size / 4); ++i) { - writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + i, mode, vip); + writemask = get_available_writemask(allocator, reg_idx + i, mode, vip); if (writemask != VKD3DSP_WRITEMASK_ALL) return false; } - writemask = get_available_writemask(allocator, first_write, last_read, reg_idx + (reg_size / 4), mode, vip); + writemask = get_available_writemask(allocator, reg_idx + (reg_size / 4), mode, vip); if ((writemask & last_reg_mask) != last_reg_mask) return false; return true; } -static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, unsigned int reg_size, int mode, bool vip) +static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, + struct register_allocator *allocator, unsigned int reg_size, int mode, bool vip) { struct hlsl_reg ret = {0}; uint32_t reg_idx; @@ -6094,35 +6064,33 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo for (reg_idx = 0;; ++reg_idx) { - if (is_range_available(allocator, first_write, last_read, reg_idx, reg_size, mode, vip)) + if (is_range_available(allocator, reg_idx, reg_size, mode, vip)) break; } for (i = 0; i < reg_size / 4; ++i) - record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, first_write, last_read, mode, vip); + record_allocation(ctx, allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, mode, vip); if (reg_size % 4) - record_allocation(ctx, allocator, reg_idx + (reg_size / 4), - (1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip); + record_allocation(ctx, allocator, reg_idx + (reg_size / 4), (1u << (reg_size % 4)) - 1, mode, vip); - ret.type = VKD3DSPR_TEMP; + ret.type = allocator->type; ret.id = reg_idx; ret.allocation_size = align(reg_size, 4) / 4; ret.allocated = true; return ret; } -static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, struct register_allocator *allocator, - unsigned int first_write, unsigned int last_read, const struct hlsl_type *type) +static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, + struct register_allocator *allocator, const struct hlsl_type *type) { unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; /* FIXME: We could potentially pack structs or arrays more efficiently... */ if (type->class <= HLSL_CLASS_VECTOR) - return allocate_register(ctx, allocator, first_write, last_read, - type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); + return allocate_register(ctx, allocator, type->e.numeric.dimx, type->e.numeric.dimx, 0, false, false); else - return allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); + return allocate_range(ctx, allocator, reg_size, 0, false); } static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) @@ -6287,10 +6255,9 @@ static void calculate_resource_register_counts(struct hlsl_ctx *ctx) } } -static void allocate_instr_temp_register(struct hlsl_ctx *ctx, - struct hlsl_ir_node *instr, struct register_allocator *allocator) +static void allocate_instr_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr) { - unsigned int reg_writemask = 0, dst_writemask = 0; + unsigned int dst_writemask = 0; bool is_per_component = false; if (instr->reg.allocated || !instr->last_read) @@ -6302,12 +6269,10 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, { case HLSL_OP1_COS_REDUCED: dst_writemask = VKD3DSP_WRITEMASK_0; - reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_0; break; case HLSL_OP1_SIN_REDUCED: dst_writemask = VKD3DSP_WRITEMASK_1; - reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_1; break; case HLSL_OP1_EXP2: @@ -6329,12 +6294,22 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); - if (reg_writemask) - instr->reg = allocate_register_with_masks(ctx, allocator, - instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false); + if (dst_writemask) + { + instr->reg.writemask = dst_writemask; + instr->reg.allocation_size = 1; + instr->reg.allocated = true; + instr->reg.type = VKD3DSPR_TEMP; + instr->reg.id = ctx->temp_count++; + } else if (is_per_component) - instr->reg = allocate_numeric_registers_for_type(ctx, allocator, - instr->index, instr->last_read, instr->data_type); + { + instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); + instr->reg.allocation_size = 1; + instr->reg.allocated = true; + instr->reg.type = VKD3DSPR_TEMP; + instr->reg.id = ctx->temp_count++; + } else { instr->reg.writemask = vkd3d_write_mask_from_component_count(instr->data_type->e.numeric.dimx); @@ -6344,40 +6319,46 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, instr->reg.id = ctx->ssa_count++; } - TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, - debug_register(instr->reg, instr->data_type), instr->index, instr->last_read); + TRACE("Allocated anonymous expression @%u to %s.\n", instr->index, + debug_register(instr->reg, instr->data_type)); } -static void allocate_variable_temp_register(struct hlsl_ctx *ctx, - struct hlsl_ir_var *var, struct register_allocator *allocator) +static void allocate_variable_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_var *var) { + struct hlsl_reg *reg = &var->regs[HLSL_REGSET_NUMERIC]; + if (var->is_input_semantic || var->is_output_semantic || var->is_uniform) return; - if (!var->regs[HLSL_REGSET_NUMERIC].allocated && var->last_read) + if (!reg->allocated && var->last_read) { if (var->indexable) { - var->regs[HLSL_REGSET_NUMERIC].id = allocator->indexable_count++; - var->regs[HLSL_REGSET_NUMERIC].allocation_size = 1; - var->regs[HLSL_REGSET_NUMERIC].writemask = 0; - var->regs[HLSL_REGSET_NUMERIC].allocated = true; + reg->id = ctx->indexable_temp_count++; + reg->allocation_size = 1; + reg->writemask = 0; + reg->allocated = true; - TRACE("Allocated %s to x%u[].\n", var->name, var->regs[HLSL_REGSET_NUMERIC].id); + TRACE("Allocated %s to x%u[].\n", var->name, reg->id); } else { - var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator, - var->first_write, var->last_read, var->data_type); + reg->type = VKD3DSPR_TEMP; + reg->id = ctx->temp_count; + reg->allocation_size = align(var->data_type->reg_size[HLSL_REGSET_NUMERIC], 4) / 4; + if (var->data_type->class <= HLSL_CLASS_VECTOR) + reg->writemask = vkd3d_write_mask_from_component_count(var->data_type->e.numeric.dimx); + reg->allocated = true; - TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, - debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); + ctx->temp_count += reg->allocation_size; + + TRACE("Allocated %s to %s.\n", var->name, + debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); } } } -static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, - struct hlsl_block *block, struct register_allocator *allocator) +static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block) { struct hlsl_ir_node *instr; @@ -6387,15 +6368,15 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, if (ctx->profile->major_version >= 4 && instr->type == HLSL_IR_CONSTANT) continue; - allocate_instr_temp_register(ctx, instr, allocator); + allocate_instr_temp_register(ctx, instr); switch (instr->type) { case HLSL_IR_IF: { struct hlsl_ir_if *iff = hlsl_ir_if(instr); - allocate_temp_registers_recurse(ctx, &iff->then_block, allocator); - allocate_temp_registers_recurse(ctx, &iff->else_block, allocator); + allocate_temp_registers_recurse(ctx, &iff->then_block); + allocate_temp_registers_recurse(ctx, &iff->else_block); break; } @@ -6404,21 +6385,21 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_load *load = hlsl_ir_load(instr); /* We need to at least allocate a variable for undefs. * FIXME: We should probably find a way to remove them instead. */ - allocate_variable_temp_register(ctx, load->src.var, allocator); + allocate_variable_temp_register(ctx, load->src.var); break; } case HLSL_IR_LOOP: { struct hlsl_ir_loop *loop = hlsl_ir_loop(instr); - allocate_temp_registers_recurse(ctx, &loop->body, allocator); + allocate_temp_registers_recurse(ctx, &loop->body); break; } case HLSL_IR_STORE: { struct hlsl_ir_store *store = hlsl_ir_store(instr); - allocate_variable_temp_register(ctx, store->lhs.var, allocator); + allocate_variable_temp_register(ctx, store->lhs.var); break; } @@ -6429,7 +6410,7 @@ static void allocate_temp_registers_recurse(struct hlsl_ctx *ctx, LIST_FOR_EACH_ENTRY(c, &s->cases, struct hlsl_ir_switch_case, entry) { - allocate_temp_registers_recurse(ctx, &c->body, allocator); + allocate_temp_registers_recurse(ctx, &c->body); } break; } @@ -6553,8 +6534,7 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, break; } - constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); - constant->reg.type = VKD3DSPR_CONST; + constant->reg = allocate_numeric_registers_for_type(ctx, allocator, type); TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type)); for (unsigned int x = 0, i = 0; x < 4; ++x) @@ -6651,16 +6631,14 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl { type = hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4); - ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); - ctx->d3dsincosconst1.type = VKD3DSPR_CONST; + ctx->d3dsincosconst1 = allocate_numeric_registers_for_type(ctx, allocator, type); TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type)); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 2, 2.60416674e-03f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 3, 2.60416680e-04f, &instr->loc); - ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); - ctx->d3dsincosconst2.type = VKD3DSPR_CONST; + ctx->d3dsincosconst2 = allocate_numeric_registers_for_type(ctx, allocator, type); TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type)); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc); @@ -6674,8 +6652,7 @@ static void allocate_sincos_const_registers(struct hlsl_ctx *ctx, struct hlsl_bl static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *body) { - struct register_allocator allocator_used = {0}; - struct register_allocator allocator = {0}; + struct register_allocator allocator = {.type = VKD3DSPR_CONST}, allocator_used = {.type = VKD3DSPR_CONST}; struct hlsl_ir_var *var; sort_uniforms_by_bind_count(ctx, HLSL_REGSET_NUMERIC); @@ -6698,15 +6675,14 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo { if (i < bind_count) { - if (get_available_writemask(&allocator_used, 1, UINT_MAX, - reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) + if (get_available_writemask(&allocator_used, reg_idx + i, 0, false) != VKD3DSP_WRITEMASK_ALL) { hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_RESERVATION, "Overlapping register() reservations on 'c%u'.", reg_idx + i); } - record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); + record_allocation(ctx, &allocator_used, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); } - record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); + record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 0, false); } var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; @@ -6730,8 +6706,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo if (!var->regs[HLSL_REGSET_NUMERIC].allocated) { - var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false); - var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; + var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, alloc_size, 0, false); TRACE("Allocated %s to %s.\n", var->name, debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); } @@ -6748,12 +6723,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *bo * index to all (simultaneously live) variables or intermediate values. Agnostic * as to how many registers are actually available for the current backend, and * does not handle constants. */ -static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) +static void allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) { - struct register_allocator allocator = {0}; struct hlsl_scope *scope; struct hlsl_ir_var *var; + ctx->indexable_temp_count = 0; + /* Reset variable temp register allocations. */ LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { @@ -6771,25 +6747,13 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block { if (var->is_output_semantic) { - record_allocation(ctx, &allocator, 0, VKD3DSP_WRITEMASK_ALL, - var->first_write, UINT_MAX, 0, false); + ctx->temp_count = 1; break; } } } - allocate_temp_registers_recurse(ctx, body, &allocator); - vkd3d_free(allocator.allocations); - - if (allocator.indexable_count) - TRACE("Declaration of %s function required %u temp registers, and %u indexable temps.\n", - ctx->is_patch_constant_func ? "patch constant" : "main", - allocator.reg_count, allocator.indexable_count); - else - TRACE("Declaration of %s function required %u temp registers.\n", - ctx->is_patch_constant_func ? "patch constant" : "main", allocator.reg_count); - - return allocator.reg_count; + allocate_temp_registers_recurse(ctx, body); } static enum vkd3d_shader_interpolation_mode sm4_get_interpolation_mode(struct hlsl_type *type, @@ -6928,9 +6892,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var if (special_interpolation) mode = VKD3DSIM_NONE; - var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, + var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, reg_size, component_count, mode, var->force_align, vip_allocation); - var->regs[HLSL_REGSET_NUMERIC].type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; TRACE("Allocated %s to %s (mode %d).\n", var->name, debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); @@ -6945,11 +6908,17 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *seman bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; struct hlsl_ir_var *var; + in_prim_allocator.type = VKD3DSPR_INPUT; in_prim_allocator.prioritize_smaller_writemasks = true; + patch_constant_out_patch_allocator.type = VKD3DSPR_INPUT; patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; + input_allocator.type = VKD3DSPR_INPUT; input_allocator.prioritize_smaller_writemasks = true; for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) + { + output_allocators[i].type = VKD3DSPR_OUTPUT; output_allocators[i].prioritize_smaller_writemasks = true; + } LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { @@ -8266,6 +8235,282 @@ void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body) lower_ir(ctx, lower_index_loads, body); } +static enum hlsl_ir_expr_op invert_comparison_op(enum hlsl_ir_expr_op op) +{ + switch (op) + { + case HLSL_OP2_EQUAL: + return HLSL_OP2_NEQUAL; + + case HLSL_OP2_GEQUAL: + return HLSL_OP2_LESS; + + case HLSL_OP2_LESS: + return HLSL_OP2_GEQUAL; + + case HLSL_OP2_NEQUAL: + return HLSL_OP2_EQUAL; + + default: + vkd3d_unreachable(); + } +} + +static bool fold_unary_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *res = NULL; + struct hlsl_ir_expr *expr, *x; + + if (instr->type != HLSL_IR_EXPR) + return false; + + if (instr->data_type->class > HLSL_CLASS_VECTOR) + return false; + + expr = hlsl_ir_expr(instr); + if (!expr->operands[0].node) + return false; + + if (expr->operands[0].node->type != HLSL_IR_EXPR) + return false; + x = hlsl_ir_expr(expr->operands[0].node); + + switch (expr->op) + { + case HLSL_OP1_ABS: + if (x->op == HLSL_OP1_ABS) + { + /* ||x|| -> |x| */ + hlsl_replace_node(instr, &x->node); + return true; + } + + if (x->op == HLSL_OP1_NEG) + { + /* |-x| -> |x| */ + hlsl_src_remove(&expr->operands[0]); + hlsl_src_from_node(&expr->operands[0], x->operands[0].node); + return true; + } + break; + + case HLSL_OP1_BIT_NOT: + if (x->op == HLSL_OP1_BIT_NOT) + { + /* ~(~x) -> x */ + hlsl_replace_node(instr, x->operands[0].node); + return true; + } + break; + + case HLSL_OP1_CEIL: + case HLSL_OP1_FLOOR: + if (x->op == HLSL_OP1_CEIL || x->op == HLSL_OP1_FLOOR) + { + /* f(g(x)) -> g(x), where f(), g() are floor() or ceil() functions. */ + hlsl_replace_node(instr, &x->node); + return true; + } + break; + + case HLSL_OP1_NEG: + if (x->op == HLSL_OP1_NEG) + { + /* -(-x) -> x */ + hlsl_replace_node(instr, x->operands[0].node); + return true; + } + break; + + case HLSL_OP1_LOGIC_NOT: + if (x->op == HLSL_OP1_LOGIC_NOT) + { + /* !!x -> x */ + hlsl_replace_node(instr, x->operands[0].node); + return true; + } + + if (hlsl_is_comparison_op(x->op) + && hlsl_base_type_is_integer(x->operands[0].node->data_type->e.numeric.type) + && hlsl_base_type_is_integer(x->operands[1].node->data_type->e.numeric.type)) + { + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {x->operands[0].node, x->operands[1].node}; + struct hlsl_block block; + + hlsl_block_init(&block); + + /* !(x == y) -> x != y, !(x < y) -> x >= y, etc. */ + res = hlsl_block_add_expr(ctx, &block, invert_comparison_op(x->op), + operands, instr->data_type, &instr->loc); + + list_move_before(&instr->entry, &block.instrs); + hlsl_replace_node(instr, res); + return true; + } + + break; + + default: + break; + } + + return false; +} + +static bool nodes_are_equivalent(const struct hlsl_ir_node *c1, const struct hlsl_ir_node *c2) +{ + if (c1 == c2) + return true; + + if (c1->type == HLSL_IR_SWIZZLE && c2->type == HLSL_IR_SWIZZLE + && hlsl_types_are_equal(c1->data_type, c2->data_type)) + { + const struct hlsl_ir_swizzle *s1 = hlsl_ir_swizzle(c1), *s2 = hlsl_ir_swizzle(c2); + + VKD3D_ASSERT(c1->data_type->class <= HLSL_CLASS_VECTOR); + + if (s1->val.node == s2->val.node && s1->u.vector == s2->u.vector) + return true; + } + + return false; +} + +/* Replaces all conditionals in an expression chain of the form (cond ? x : y) + * with x or y, assuming cond = cond_value. */ +static struct hlsl_ir_node *evaluate_conditionals_recurse(struct hlsl_ctx *ctx, + struct hlsl_block *block, const struct hlsl_ir_node *cond, bool cond_value, + struct hlsl_ir_node *instr, const struct vkd3d_shader_location *loc) +{ + struct hlsl_ir_node *operands[HLSL_MAX_OPERANDS] = {0}; + struct hlsl_ir_expr *expr; + struct hlsl_ir_node *res; + bool progress = false; + unsigned int i; + + if (instr->type != HLSL_IR_EXPR) + return NULL; + expr = hlsl_ir_expr(instr); + + if (expr->op == HLSL_OP3_TERNARY && nodes_are_equivalent(cond, expr->operands[0].node)) + { + struct hlsl_ir_node *x = cond_value ? expr->operands[1].node : expr->operands[2].node; + + res = evaluate_conditionals_recurse(ctx, block, cond, cond_value, x, loc); + return res ? res : x; + } + + for (i = 0; i < HLSL_MAX_OPERANDS; ++i) + { + if (!expr->operands[i].node) + break; + + operands[i] = evaluate_conditionals_recurse(ctx, block, cond, cond_value, expr->operands[i].node, loc); + + if (operands[i]) + progress = true; + else + operands[i] = expr->operands[i].node; + } + + if (progress) + return hlsl_block_add_expr(ctx, block, expr->op, operands, expr->node.data_type, loc); + + return NULL; +} + +static bool fold_conditional_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) +{ + struct hlsl_ir_node *c, *x, *y, *res_x, *res_y; + struct hlsl_ir_node *res = NULL; + struct hlsl_ir_expr *expr, *ec; + struct hlsl_block block; + + if (instr->type != HLSL_IR_EXPR) + return false; + + if (instr->data_type->class > HLSL_CLASS_VECTOR) + return false; + + expr = hlsl_ir_expr(instr); + if (expr->op != HLSL_OP3_TERNARY) + return false; + + c = expr->operands[0].node; + x = expr->operands[1].node; + y = expr->operands[2].node; + + VKD3D_ASSERT(c->data_type->e.numeric.type == HLSL_TYPE_BOOL); + + if (nodes_are_equivalent(x, y)) + { + /* c ? x : x -> x */ + hlsl_replace_node(instr, x); + return true; + } + + if (c->type == HLSL_IR_CONSTANT) + { + if (hlsl_constant_is_zero(hlsl_ir_constant(c))) + { + /* false ? x : y -> y */ + hlsl_replace_node(instr, y); + return true; + } + + if (hlsl_constant_is_one(hlsl_ir_constant(c))) + { + /* true ? x : y -> x */ + hlsl_replace_node(instr, x); + return true; + } + } + + hlsl_block_init(&block); + + if (x->type == HLSL_IR_CONSTANT && y->type == HLSL_IR_CONSTANT + && hlsl_types_are_equal(c->data_type, x->data_type) + && hlsl_types_are_equal(c->data_type, y->data_type)) + { + if (hlsl_constant_is_one(hlsl_ir_constant(x)) && hlsl_constant_is_zero(hlsl_ir_constant(y))) + { + /* c ? true : false -> c */ + res = c; + goto done; + } + + if (hlsl_constant_is_zero(hlsl_ir_constant(x)) && hlsl_constant_is_one(hlsl_ir_constant(y))) + { + /* c ? false : true -> !c */ + res = hlsl_block_add_unary_expr(ctx, &block, HLSL_OP1_LOGIC_NOT, c, &instr->loc); + goto done; + } + } + + ec = c->type == HLSL_IR_EXPR ? hlsl_ir_expr(c) : NULL; + if (ec && ec->op == HLSL_OP1_LOGIC_NOT) + { + /* !c ? x : y -> c ? y : x */ + res = hlsl_add_conditional(ctx, &block, ec->operands[0].node, y, x); + goto done; + } + + res_x = evaluate_conditionals_recurse(ctx, &block, c, true, x, &instr->loc); + res_y = evaluate_conditionals_recurse(ctx, &block, c, false, y, &instr->loc); + if (res_x || res_y) + res = hlsl_add_conditional(ctx, &block, c, res_x ? res_x : x, res_y ? res_y : y); + +done: + if (res) + { + list_move_before(&instr->entry, &block.instrs); + hlsl_replace_node(instr, res); + return true; + } + + hlsl_block_cleanup(&block); + return false; +} static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) { @@ -8275,6 +8520,8 @@ static bool simplify_exprs(struct hlsl_ctx *ctx, struct hlsl_block *block) { progress = hlsl_transform_ir(ctx, hlsl_fold_constant_exprs, block, NULL); progress |= hlsl_transform_ir(ctx, hlsl_normalize_binary_exprs, block, NULL); + progress |= hlsl_transform_ir(ctx, fold_unary_identities, block, NULL); + progress |= hlsl_transform_ir(ctx, fold_conditional_identities, block, NULL); progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_identities, block, NULL); progress |= hlsl_transform_ir(ctx, hlsl_fold_constant_swizzles, block, NULL); @@ -8448,6 +8695,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog if (!ascii_strcasecmp(var->semantic.name, "PSIZE") && output && program->shader_version.type == VKD3D_SHADER_TYPE_VERTEX) { + program->has_point_size = true; if (var->data_type->e.numeric.dimx > 1) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_SEMANTIC, "PSIZE output must have only 1 component in this shader model."); @@ -8570,9 +8818,8 @@ static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, c case HLSL_TYPE_DOUBLE: return VSIR_DATA_F64; case HLSL_TYPE_FLOAT: - return VSIR_DATA_F32; case HLSL_TYPE_HALF: - return VSIR_DATA_F16; + return VSIR_DATA_F32; case HLSL_TYPE_INT: return VSIR_DATA_I32; case HLSL_TYPE_UINT: @@ -8703,7 +8950,7 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, semantic->resource_type = resource_type; dst_param = &semantic->resource.reg; - vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1); + vsir_register_init(&dst_param->reg, VKD3DSPR_COMBINED_SAMPLER, VSIR_DATA_F32, 1); dst_param->reg.dimension = VSIR_DIMENSION_NONE; dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index + i; dst_param->write_mask = 0; @@ -9467,8 +9714,6 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break; case HLSL_OP3_CMP: - if (!hlsl_type_is_floating_point(type)) - goto err; generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true); break; @@ -9930,10 +10175,14 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co struct hlsl_ir_function_decl *func, struct list *semantic_vars, struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) { + struct hlsl_ir_var *var; struct hlsl_block block; + struct hlsl_reg *reg; + unsigned int *count; program->ssa_count = 0; - program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); + program->temp_count = 0; + allocate_temp_registers(ctx, body, semantic_vars); if (ctx->result) return; @@ -9944,7 +10193,19 @@ static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_co sm1_generate_vsir_block(ctx, body, program); + count = &program->flat_constant_count[VKD3D_SHADER_D3DBC_FLOAT_CONSTANT_REGISTER]; + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->is_uniform) + continue; + + if (!(reg = &var->regs[HLSL_REGSET_NUMERIC])->allocation_size) + continue; + + *count = max(*count, reg->id + reg->allocation_size); + } program->ssa_count = ctx->ssa_count; + program->temp_count = ctx->temp_count; if (ctx->result) return; @@ -11437,6 +11698,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, const struct vkd3d_shader_version *version = &program->shader_version; const struct hlsl_ir_node *sample_index = load->sample_index.node; const struct hlsl_ir_node *texel_offset = load->texel_offset.node; + const struct hlsl_ir_node *byte_offset = load->byte_offset.node; const struct hlsl_ir_node *coords = load->coords.node; unsigned int coords_writemask = VKD3DSP_WRITEMASK_ALL; const struct hlsl_deref *resource = &load->resource; @@ -11444,20 +11706,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim = load->sampling_dim; bool tgsm = load->resource.var->is_tgsm; struct vkd3d_shader_instruction *ins; + bool multisampled, raw, structured; enum vkd3d_shader_opcode opcode; - bool multisampled, raw; VKD3D_ASSERT(load->load_type == HLSL_RESOURCE_LOAD); - if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) - { - hlsl_fixme(ctx, &load->node.loc, "Structured buffer loads."); - return false; - } - multisampled = resource_type->class == HLSL_CLASS_TEXTURE && (resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMS || resource_type->sampler_dim == HLSL_SAMPLER_DIM_2DMSARRAY); + structured = resource_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; if (!tgsm) { @@ -11468,15 +11725,19 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); return false; } + VKD3D_ASSERT(!(structured && multisampled)); - if (uav) + if (structured) + opcode = VSIR_OP_LD_STRUCTURED; + else if (uav) opcode = VSIR_OP_LD_UAV_TYPED; else if (raw) opcode = VSIR_OP_LD_RAW; else opcode = multisampled ? VSIR_OP_LD2DMS : VSIR_OP_LD; - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, + &instr->loc, opcode, 1, 2 + multisampled + structured))) return false; if (texel_offset && !sm4_generate_vsir_validate_texel_offset_aoffimmi(texel_offset)) @@ -11504,10 +11765,15 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, vsir_src_from_hlsl_node(&ins->src[0], ctx, coords, coords_writemask); if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, - &ins->src[1], resource, ins->dst[0].write_mask, &instr->loc)) + &ins->src[structured ? 2 : 1], resource, ins->dst[0].write_mask, &instr->loc)) return false; - if (multisampled) + if (structured) + { + VKD3D_ASSERT(byte_offset); + vsir_src_from_hlsl_node(&ins->src[1], ctx, byte_offset, VKD3DSP_WRITEMASK_ALL); + } + else if (multisampled) { if (sample_index->type == HLSL_IR_CONSTANT) vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, @@ -12093,16 +12359,15 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se struct hlsl_block block = {0}; struct hlsl_scope *scope; struct hlsl_ir_var *var; - uint32_t temp_count; ctx->is_patch_constant_func = func == ctx->patch_constant_func; compute_liveness(ctx, body); mark_indexable_vars(ctx, body); - temp_count = allocate_temp_registers(ctx, body, semantic_vars); + allocate_temp_registers(ctx, body, semantic_vars); if (ctx->result) return; - program->temp_count = max(program->temp_count, temp_count); + program->temp_count = max(program->temp_count, ctx->temp_count); hlsl_block_init(&block); @@ -12113,8 +12378,8 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *se sm4_generate_vsir_instr_dcl_semantic(ctx, program, var, &block, &var->loc); } - if (temp_count) - sm4_generate_vsir_instr_dcl_temps(ctx, program, temp_count, &block, &func->loc); + if (ctx->temp_count) + sm4_generate_vsir_instr_dcl_temps(ctx, program, ctx->temp_count, &block, &func->loc); LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { @@ -12427,7 +12692,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, return; } - ins->declaration.cb.size = cbuffer->size; + ins->declaration.cb.size = align(cbuffer->size, 4) * sizeof(float); src_param = &ins->declaration.cb.src; vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 0); @@ -12592,6 +12857,9 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, { switch (component_type->sampler_dim) { + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: + opcode = VSIR_OP_DCL_RESOURCE_STRUCTURED; + break; case HLSL_SAMPLER_DIM_RAW_BUFFER: opcode = VSIR_OP_DCL_RESOURCE_RAW; break; @@ -12647,7 +12915,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) { ins->structured = true; - ins->resource_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; + ins->resource_stride = hlsl_type_get_packed_size(component_type->e.resource.format); ins->declaration.structured_resource.byte_stride = ins->resource_stride; } else @@ -12784,6 +13052,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, } program->ssa_count = 0; + program->temp_count = 0; if (version->type == VKD3D_SHADER_TYPE_HULL) generate_vsir_add_program_instruction(ctx, program, @@ -12801,6 +13070,7 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, generate_vsir_scan_global_flags(ctx, program, semantic_vars, func); program->ssa_count = ctx->ssa_count; + program->temp_count = ctx->temp_count; } /* For some reason, for matrices, values from default value initializers end @@ -12915,14 +13185,16 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) static D3D_SHADER_INPUT_TYPE sm4_resource_type(const struct hlsl_type *type) { + bool structured = type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + switch (type->class) { case HLSL_CLASS_SAMPLER: return D3D_SIT_SAMPLER; case HLSL_CLASS_TEXTURE: - return D3D_SIT_TEXTURE; + return structured ? D3D_SIT_STRUCTURED : D3D_SIT_TEXTURE; case HLSL_CLASS_UAV: - return D3D_SIT_UAV_RWTYPED; + return structured ? D3D_SIT_UAV_RWSTRUCTURED : D3D_SIT_UAV_RWTYPED; default: break; } @@ -12998,7 +13270,8 @@ static D3D_SHADER_VARIABLE_TYPE sm4_base_type(const struct hlsl_type *type) vkd3d_unreachable(); } -static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, struct hlsl_type *type) +static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *buffer, + struct hlsl_type *type, bool structured) { const struct hlsl_type *array_type = hlsl_get_multiarray_element_type(type); const char *name = array_type->name ? array_type->name : ""; @@ -13007,7 +13280,10 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b size_t name_offset = 0; size_t i; - if (type->bytecode_offset) + if (!structured && type->bytecode_offset) + return; + + if (structured && type->packed_bytecode_offset) return; if (profile->major_version >= 5) @@ -13029,7 +13305,7 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b continue; field->name_bytecode_offset = put_string(buffer, field->name); - write_sm4_type(ctx, buffer, field->type); + write_sm4_type(ctx, buffer, field->type, structured); ++field_count; } @@ -13038,15 +13314,29 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b for (i = 0; i < array_type->e.record.field_count; ++i) { struct hlsl_struct_field *field = &array_type->e.record.fields[i]; + unsigned int field_type_offset, offset; if (!field->type->reg_size[HLSL_REGSET_NUMERIC]) continue; put_u32(buffer, field->name_bytecode_offset); - put_u32(buffer, field->type->bytecode_offset); - put_u32(buffer, field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float)); + + if (!structured) + field_type_offset = field->type->bytecode_offset; + else + field_type_offset = field->type->packed_bytecode_offset; + put_u32(buffer, field_type_offset); + + if (!structured) + offset = field->reg_offset[HLSL_REGSET_NUMERIC] * sizeof(float); + else + offset = struct_field_get_packed_offset(array_type, i); + put_u32(buffer, offset); } - type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); + if (!structured) + type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); + else + type->packed_bytecode_offset = put_u32(buffer, vkd3d_make_u32(D3D_SVC_STRUCT, D3D_SVT_VOID)); put_u32(buffer, vkd3d_make_u32(1, hlsl_type_component_count(array_type))); put_u32(buffer, vkd3d_make_u32(array_size, field_count)); put_u32(buffer, fields_offset); @@ -13054,7 +13344,11 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b else { VKD3D_ASSERT(array_type->class <= HLSL_CLASS_LAST_NUMERIC); - type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); + if (!structured) + type->bytecode_offset = put_u32(buffer, vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); + else + type->packed_bytecode_offset = put_u32(buffer, + vkd3d_make_u32(sm4_class(array_type), sm4_base_type(array_type))); put_u32(buffer, vkd3d_make_u32(array_type->e.numeric.dimy, array_type->e.numeric.dimx)); put_u32(buffer, vkd3d_make_u32(array_size, 0)); put_u32(buffer, 1); @@ -13073,9 +13367,9 @@ static void write_sm4_type(struct hlsl_ctx *ctx, struct vkd3d_bytecode_buffer *b static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rdef) { uint32_t binding_desc_size = (hlsl_version_ge(ctx, 5, 1) ? 10 : 8) * sizeof(uint32_t); - size_t cbuffers_offset, resources_offset, creator_offset, string_offset; - unsigned int cbuffer_count = 0, extern_resources_count, i, j; + size_t buffers_offset, resources_offset, creator_offset, string_offset; size_t cbuffer_position, resource_position, creator_position; + unsigned int buffer_count = 0, extern_resources_count, i, j; const struct hlsl_profile_info *profile = ctx->profile; struct vkd3d_bytecode_buffer buffer = {0}; struct extern_resource *extern_resources; @@ -13097,10 +13391,20 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { if (cbuffer->reg.allocated) - ++cbuffer_count; + ++buffer_count; + } + + for (i = 0; i < extern_resources_count; ++i) + { + const struct extern_resource *resource = &extern_resources[i]; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + ++buffer_count; } - put_u32(&buffer, cbuffer_count); + put_u32(&buffer, buffer_count); cbuffer_position = put_u32(&buffer, 0); put_u32(&buffer, extern_resources_count); resource_position = put_u32(&buffer, 0); @@ -13141,12 +13445,19 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd put_u32(&buffer, sm4_resource_type(resource->component_type)); if (resource->regset == HLSL_REGSET_TEXTURES || resource->regset == HLSL_REGSET_UAVS) { + bool structured = resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; unsigned int dimx = resource->component_type->e.resource.format->e.numeric.dimx; put_u32(&buffer, sm4_data_type(resource->component_type)); put_u32(&buffer, sm4_rdef_resource_dimension(resource->component_type)); - put_u32(&buffer, ~0u); /* FIXME: multisample count */ - flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; + + if (structured) + put_u32(&buffer, hlsl_type_get_packed_size(resource->component_type->e.resource.format)); + else + put_u32(&buffer, ~0u); /* FIXME: multisample count */ + + if (!structured) + flags |= (dimx - 1) << VKD3D_SM4_SIF_TEXTURE_COMPONENTS_SHIFT; } else { @@ -13175,8 +13486,8 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd /* Buffers. */ - cbuffers_offset = bytecode_align(&buffer); - set_u32(&buffer, cbuffer_position, cbuffers_offset); + buffers_offset = bytecode_align(&buffer); + set_u32(&buffer, cbuffer_position, buffers_offset); LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { unsigned int var_count = 0; @@ -13198,6 +13509,24 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd put_u32(&buffer, cbuffer->type == HLSL_BUFFER_CONSTANT ? D3D_CT_CBUFFER : D3D_CT_TBUFFER); } + for (i = 0; i < extern_resources_count; ++i) + { + const struct extern_resource *resource = &extern_resources[i]; + struct hlsl_type *resource_type; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + resource_type = resource->component_type->e.resource.format; + + put_u32(&buffer, 0); /* name */ + put_u32(&buffer, 1); /* var count */ + put_u32(&buffer, 0); /* variable offset */ + put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); /* size */ + put_u32(&buffer, 0); /* FIXME: flags */ + put_u32(&buffer, D3D_CT_RESOURCE_BIND_INFO); + } + i = 0; LIST_FOR_EACH_ENTRY(cbuffer, &ctx->buffers, struct hlsl_buffer, entry) { @@ -13205,7 +13534,18 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd continue; string_offset = put_string(&buffer, cbuffer->name); - set_u32(&buffer, cbuffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); + set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); + } + + for (j = 0; j < extern_resources_count; ++j) + { + const struct extern_resource *resource = &extern_resources[j]; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + string_offset = put_string(&buffer, resource->name); + set_u32(&buffer, buffers_offset + i++ * 6 * sizeof(uint32_t), string_offset); } i = 0; @@ -13216,7 +13556,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd if (!cbuffer->reg.allocated) continue; - set_u32(&buffer, cbuffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); + set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { @@ -13255,7 +13595,7 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd string_offset = put_string(&buffer, var->name); set_u32(&buffer, var_offset, string_offset); - write_sm4_type(ctx, &buffer, var->data_type); + write_sm4_type(ctx, &buffer, var->data_type, false); set_u32(&buffer, var_offset + 4 * sizeof(uint32_t), var->data_type->bytecode_offset); if (var->default_values) @@ -13298,6 +13638,42 @@ static void sm4_generate_rdef(struct hlsl_ctx *ctx, struct vkd3d_shader_code *rd } } + for (j = 0; j < extern_resources_count; ++j) + { + const struct extern_resource *resource = &extern_resources[j]; + struct hlsl_type *resource_type; + size_t vars_start; + + if (resource->buffer || resource->component_type->sampler_dim != HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + continue; + + resource_type = resource->component_type->e.resource.format; + + vars_start = bytecode_align(&buffer); + + set_u32(&buffer, buffers_offset + (i++ * 6 + 2) * sizeof(uint32_t), vars_start); + + put_u32(&buffer, 0); /* name */ + put_u32(&buffer, 0); /* offset */ + put_u32(&buffer, hlsl_type_get_packed_size(resource_type)); + put_u32(&buffer, D3D_SVF_USED); + put_u32(&buffer, 0); /* type */ + put_u32(&buffer, 0); /* default value */ + + if (profile->major_version >= 5) + { + put_u32(&buffer, ~0u); /* texture start */ + put_u32(&buffer, 0); /* texture count */ + put_u32(&buffer, ~0u); /* sampler start */ + put_u32(&buffer, 0); /* sampler count */ + } + + string_offset = put_string(&buffer, "$Element"); + set_u32(&buffer, vars_start, string_offset); + write_sm4_type(ctx, &buffer, resource_type, true); + set_u32(&buffer, vars_start + 4 * sizeof(uint32_t), resource_type->packed_bytecode_offset); + } + creator_offset = put_string(&buffer, vkd3d_shader_get_version(NULL, NULL)); set_u32(&buffer, creator_position, creator_offset); diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c index d339a06e6c7..252ed51a4e4 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_constant_ops.c @@ -250,6 +250,36 @@ static bool fold_ceil(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, return true; } +static bool fold_cos(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->e.numeric.type; + unsigned int k; + + VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); + + for (k = 0; k < dst_type->e.numeric.dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = cosf(src->value.u[k].f); + break; + + case HLSL_TYPE_DOUBLE: + dst->u[k].d = cos(src->value.u[k].d); + break; + + default: + FIXME("Fold 'cos' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_exp2(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) { @@ -478,6 +508,48 @@ static bool fold_rcp(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons return true; } +static bool fold_reinterpret(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + unsigned int k; + + for (k = 0; k < dst_type->e.numeric.dimx; ++k) + { + dst->u[k] = src->value.u[k]; + } + + return true; +} + +static bool fold_round(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->e.numeric.type; + unsigned int k; + + VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); + + for (k = 0; k < dst_type->e.numeric.dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + /* Somewhat unfortunately, constant folded round() rounds + * halfway cases towards positive infinity, as opposed to + * nearest even like vsir/TPF round_ne. */ + dst->u[k].f = floorf(src->value.u[k].f + 0.5f); + break; + + default: + FIXME("Fold 'round' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_rsq(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { @@ -544,6 +616,36 @@ static bool fold_sat(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, cons return true; } +static bool fold_sin(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, + const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src) +{ + enum hlsl_base_type type = dst_type->e.numeric.type; + unsigned int k; + + VKD3D_ASSERT(type == src->node.data_type->e.numeric.type); + + for (k = 0; k < dst_type->e.numeric.dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = sinf(src->value.u[k].f); + break; + + case HLSL_TYPE_DOUBLE: + dst->u[k].d = sin(src->value.u[k].d); + break; + + default: + FIXME("Fold 'sin' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_sqrt(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src, const struct vkd3d_shader_location *loc) { @@ -974,6 +1076,44 @@ static bool fold_lshift(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, c return true; } +static bool fold_mad(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, + const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2, const struct hlsl_ir_constant *src3) +{ + enum hlsl_base_type type = dst_type->e.numeric.type; + unsigned int k; + + VKD3D_ASSERT(type == src1->node.data_type->e.numeric.type); + VKD3D_ASSERT(type == src2->node.data_type->e.numeric.type); + VKD3D_ASSERT(type == src3->node.data_type->e.numeric.type); + + for (k = 0; k < dst_type->e.numeric.dimx; ++k) + { + switch (type) + { + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_HALF: + dst->u[k].f = fmaf(src1->value.u[k].f, src2->value.u[k].f, src3->value.u[k].f); + break; + + case HLSL_TYPE_DOUBLE: + dst->u[k].d = fma(src1->value.u[k].d, src2->value.u[k].d, src3->value.u[k].d); + break; + + case HLSL_TYPE_INT: + case HLSL_TYPE_MIN16UINT: + case HLSL_TYPE_UINT: + dst->u[k].u = src1->value.u[k].u * src2->value.u[k].u + src3->value.u[k].u; + break; + + default: + FIXME("Fold 'mad' for type %s.\n", debug_hlsl_type(ctx, dst_type)); + return false; + } + } + + return true; +} + static bool fold_max(struct hlsl_ctx *ctx, struct hlsl_constant_value *dst, const struct hlsl_type *dst_type, const struct hlsl_ir_constant *src1, const struct hlsl_ir_constant *src2) { @@ -1263,6 +1403,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_ceil(ctx, &res, instr->data_type, arg1); break; + case HLSL_OP1_COS: + success = fold_cos(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_EXP2: success = fold_exp2(ctx, &res, instr->data_type, arg1); break; @@ -1291,6 +1435,14 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_rcp(ctx, &res, instr->data_type, arg1, &instr->loc); break; + case HLSL_OP1_REINTERPRET: + success = fold_reinterpret(ctx, &res, instr->data_type, arg1); + break; + + case HLSL_OP1_ROUND: + success = fold_round(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_RSQ: success = fold_rsq(ctx, &res, instr->data_type, arg1, &instr->loc); break; @@ -1299,6 +1451,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_sat(ctx, &res, instr->data_type, arg1); break; + case HLSL_OP1_SIN: + success = fold_sin(ctx, &res, instr->data_type, arg1); + break; + case HLSL_OP1_SQRT: success = fold_sqrt(ctx, &res, instr->data_type, arg1, &instr->loc); break; @@ -1373,6 +1529,10 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, success = fold_dp2add(ctx, &res, instr->data_type, arg1, arg2, arg3); break; + case HLSL_OP3_MAD: + success = fold_mad(ctx, &res, instr->data_type, arg1, arg2, arg3); + break; + case HLSL_OP3_TERNARY: success = fold_ternary(ctx, &res, instr->data_type, arg1, arg2, arg3); break; @@ -1393,74 +1553,6 @@ bool hlsl_fold_constant_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return success; } -static bool constant_is_zero(struct hlsl_ir_constant *const_arg) -{ - struct hlsl_type *data_type = const_arg->node.data_type; - unsigned int k; - - for (k = 0; k < data_type->e.numeric.dimx; ++k) - { - switch (data_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - if (const_arg->value.u[k].f != 0.0f) - return false; - break; - - case HLSL_TYPE_DOUBLE: - if (const_arg->value.u[k].d != 0.0) - return false; - break; - - case HLSL_TYPE_UINT: - case HLSL_TYPE_INT: - case HLSL_TYPE_BOOL: - case HLSL_TYPE_MIN16UINT: - if (const_arg->value.u[k].u != 0) - return false; - break; - } - } - return true; -} - -static bool constant_is_one(struct hlsl_ir_constant *const_arg) -{ - struct hlsl_type *data_type = const_arg->node.data_type; - unsigned int k; - - for (k = 0; k < data_type->e.numeric.dimx; ++k) - { - switch (data_type->e.numeric.type) - { - case HLSL_TYPE_FLOAT: - case HLSL_TYPE_HALF: - if (const_arg->value.u[k].f != 1.0f) - return false; - break; - - case HLSL_TYPE_DOUBLE: - if (const_arg->value.u[k].d != 1.0) - return false; - break; - - case HLSL_TYPE_UINT: - case HLSL_TYPE_INT: - case HLSL_TYPE_MIN16UINT: - if (const_arg->value.u[k].u != 1) - return false; - break; - - case HLSL_TYPE_BOOL: - if (const_arg->value.u[k].u != ~0) - return false; - break; - } - } - return true; -} - bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct hlsl_ir_constant *const_arg = NULL; @@ -1502,26 +1594,26 @@ bool hlsl_fold_constant_identities(struct hlsl_ctx *ctx, struct hlsl_ir_node *in switch (expr->op) { case HLSL_OP2_ADD: - if (constant_is_zero(const_arg)) + if (hlsl_constant_is_zero(const_arg)) res_node = mut_arg; break; case HLSL_OP2_MUL: - if (constant_is_one(const_arg)) + if (hlsl_constant_is_one(const_arg)) res_node = mut_arg; break; case HLSL_OP2_LOGIC_AND: - if (constant_is_zero(const_arg)) + if (hlsl_constant_is_zero(const_arg)) res_node = &const_arg->node; - else if (constant_is_one(const_arg)) + else if (hlsl_constant_is_one(const_arg)) res_node = mut_arg; break; case HLSL_OP2_LOGIC_OR: - if (constant_is_zero(const_arg)) + if (hlsl_constant_is_zero(const_arg)) res_node = mut_arg; - else if (constant_is_one(const_arg)) + else if (hlsl_constant_is_one(const_arg)) res_node = &const_arg->node; break; @@ -1649,6 +1741,9 @@ bool hlsl_normalize_binary_exprs(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst if (instr->data_type->class > HLSL_CLASS_VECTOR) return false; + if (expr->operands[2].node) + return false; + hlsl_block_init(&block); arg1 = expr->operands[0].node; diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 23e059a3490..29bf62709eb 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -27,8 +27,53 @@ struct vsir_transformation_context uint64_t config_flags; const struct vkd3d_shader_compile_info *compile_info; struct vkd3d_shader_message_context *message_context; + struct vkd3d_shader_location null_location; }; +static void vsir_transformation_context_init(struct vsir_transformation_context *ctx, + struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context) +{ + *ctx = (struct vsir_transformation_context) + { + .result = VKD3D_OK, + .program = program, + .config_flags = config_flags, + .compile_info = compile_info, + .message_context = message_context, + .null_location = {.source_name = compile_info->source_name}, + }; +}; + +const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error) +{ + static const char * const names[] = + { + [VSIR_DATA_BOOL ] = "bool", + [VSIR_DATA_F16 ] = "half", + [VSIR_DATA_F32 ] = "float", + [VSIR_DATA_F64 ] = "double", + [VSIR_DATA_I16 ] = "i16", + [VSIR_DATA_I32 ] = "int", + [VSIR_DATA_I64 ] = "i64", + [VSIR_DATA_U8 ] = "uint8", + [VSIR_DATA_U16 ] = "uint16", + [VSIR_DATA_U32 ] = "uint", + [VSIR_DATA_U64 ] = "uint64", + [VSIR_DATA_SNORM ] = "snorm", + [VSIR_DATA_UNORM ] = "unorm", + [VSIR_DATA_OPAQUE ] = "opaque", + [VSIR_DATA_MIXED ] = "mixed", + [VSIR_DATA_CONTINUED] = "", + [VSIR_DATA_UNUSED ] = "", + }; + + if ((size_t)t < ARRAY_SIZE(names)) + return names[t] ? names[t] : error; + + return error; +} + const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) { static const char * const names[] = @@ -373,6 +418,183 @@ const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) return error; } +static struct vkd3d_shader_param_node *shader_param_allocator_node_create( + struct vkd3d_shader_param_allocator *allocator) +{ + struct vkd3d_shader_param_node *node; + + if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride])))) + return NULL; + node->next = NULL; + + return node; +} + +static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, size_t count, size_t stride) +{ + allocator->count = max(count, MAX_REG_OUTPUT); + allocator->stride = stride; + allocator->head = NULL; + allocator->current = NULL; + allocator->index = allocator->count; +} + +static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator) +{ + struct vkd3d_shader_param_node *current = allocator->head; + + while (current) + { + struct vkd3d_shader_param_node *next = current->next; + vkd3d_free(current); + current = next; + } +} + +void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) +{ + void *params; + + if (!allocator->current || count > allocator->count - allocator->index) + { + struct vkd3d_shader_param_node *next; + + allocator->count = max(allocator->count, count); + if (!(next = shader_param_allocator_node_create(allocator))) + return NULL; + if (allocator->current) + allocator->current->next = next; + else + allocator->head = next; + allocator->current = next; + allocator->index = 0; + } + + params = &allocator->current->param[allocator->index * allocator->stride]; + allocator->index += count; + + return params; +} + +bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *array, size_t reserve) +{ + if (!vkd3d_array_reserve((void **)&array->elements, &array->capacity, reserve, sizeof(*array->elements))) + { + ERR("Failed to allocate instructions.\n"); + return false; + } + + return true; +} + +bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *array, size_t idx, size_t count) +{ + VKD3D_ASSERT(idx <= array->count); + + if (!shader_instruction_array_reserve(array, array->count + count)) + return false; + + memmove(&array->elements[idx + count], &array->elements[idx], (array->count - idx) * sizeof(*array->elements)); + memset(&array->elements[idx], 0, count * sizeof(*array->elements)); + array->count += count; + + return true; +} + +bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *array, + struct vkd3d_shader_immediate_constant_buffer *icb) +{ + if (!vkd3d_array_reserve((void **)&array->icbs, &array->icb_capacity, array->icb_count + 1, sizeof(*array->icbs))) + return false; + + array->icbs[array->icb_count++] = icb; + + return true; +} + +static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( + struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count); + +static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, + struct vkd3d_shader_instruction_array *array) +{ + size_t i; + + for (i = 0; i < reg->idx_count; ++i) + { + if (!reg->idx[i].rel_addr) + continue; + + if (!(reg->idx[i].rel_addr = shader_instruction_array_clone_src_params(array, reg->idx[i].rel_addr, 1))) + return false; + } + + return true; +} + +static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( + struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_dst_param *params, size_t count) +{ + struct vkd3d_shader_dst_param *dst_params; + size_t i; + + if (!(dst_params = shader_dst_param_allocator_get(&array->dst_params, count))) + return NULL; + + memcpy(dst_params, params, count * sizeof(*params)); + for (i = 0; i < count; ++i) + { + if (!shader_register_clone_relative_addresses(&dst_params[i].reg, array)) + return NULL; + } + + return dst_params; +} + +static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( + struct vkd3d_shader_instruction_array *array, const struct vkd3d_shader_src_param *params, size_t count) +{ + struct vkd3d_shader_src_param *src_params; + size_t i; + + if (!(src_params = shader_src_param_allocator_get(&array->src_params, count))) + return NULL; + + memcpy(src_params, params, count * sizeof(*params)); + for (i = 0; i < count; ++i) + { + if (!shader_register_clone_relative_addresses(&src_params[i].reg, array)) + return NULL; + } + + return src_params; +} + +static void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *array) +{ + unsigned int i; + + vkd3d_free(array->elements); + shader_param_allocator_destroy(&array->dst_params); + shader_param_allocator_destroy(&array->src_params); + for (i = 0; i < array->icb_count; ++i) + { + vkd3d_free(array->icbs[i]); + } + vkd3d_free(array->icbs); +} + +static bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *array, size_t reserve) +{ + memset(array, 0, sizeof(*array)); + /* Size the parameter initial allocations so they are large enough for most shaders. The + * code path for chained allocations will be tested if a few shaders need to use it. */ + shader_param_allocator_init(&array->dst_params, reserve - reserve / 8u, sizeof(struct vkd3d_shader_dst_param)); + shader_param_allocator_init(&array->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); + + return shader_instruction_array_reserve(array, reserve); +} + static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) { @@ -864,6 +1086,23 @@ static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *i vsir_instruction_init(ins, &location, VSIR_OP_NOP); } +/* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the + * destination is in use. This seems like a reasonable requirement given how this is currently used. */ +static bool vsir_program_iterator_clone_instruction(struct vsir_program_iterator *dst_it, + const struct vkd3d_shader_instruction *src) +{ + struct vkd3d_shader_instruction *dst = vsir_program_iterator_current(dst_it); + + *dst = *src; + + if (dst->dst_count && !(dst->dst = shader_instruction_array_clone_dst_params(dst_it->array, + dst->dst, dst->dst_count))) + return false; + + return !dst->src_count || !!(dst->src = shader_instruction_array_clone_src_params(dst_it->array, + dst->src, dst->src_count)); +} + static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vsir_data_type data_type, enum vkd3d_shader_opcode *opcode, bool *requires_swap) { @@ -1669,10 +1908,22 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr switch (ins->opcode) { + case VSIR_OP_IFC: + ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context); + break; + + case VSIR_OP_SINCOS: + ret = vsir_program_lower_sm1_sincos(program, &it); + break; + case VSIR_OP_TEXCRD: ret = vsir_program_lower_texcrd(program, ins, message_context); break; + case VSIR_OP_TEXKILL: + ret = vsir_program_lower_texkill(program, &it, &tmp_idx); + break; + case VSIR_OP_TEXLD: if (program->shader_version.major == 1) ret = vsir_program_lower_texld_sm1(program, ins, message_context); @@ -1682,6 +1933,14 @@ static enum vkd3d_result vsir_program_lower_d3dbc_instructions(struct vsir_progr ret = vsir_program_lower_texld(program, ins, message_context); break; + case VSIR_OP_TEXLDD: + ret = vsir_program_lower_texldd(program, ins); + break; + + case VSIR_OP_TEXLDL: + ret = vsir_program_lower_texldl(program, ins); + break; + default: ret = VKD3D_OK; break; @@ -1698,7 +1957,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr struct vsir_transformation_context *ctx) { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct vkd3d_shader_message_context *message_context = ctx->message_context; struct vkd3d_shader_instruction *ins; unsigned int tmp_idx = ~0u; enum vkd3d_result ret; @@ -1707,16 +1965,6 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr { switch (ins->opcode) { - case VSIR_OP_IFC: - if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0) - return ret; - break; - - case VSIR_OP_TEXKILL: - if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) - return ret; - break; - case VSIR_OP_MAD: if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) return ret; @@ -1725,6 +1973,8 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr case VSIR_OP_DCL: case VSIR_OP_DCL_CONSTANT_BUFFER: case VSIR_OP_DCL_GLOBAL_FLAGS: + case VSIR_OP_DCL_INPUT_PRIMITIVE: + case VSIR_OP_DCL_OUTPUT_TOPOLOGY: case VSIR_OP_DCL_SAMPLER: case VSIR_OP_DCL_TEMPS: case VSIR_OP_DCL_TESSELLATOR_DOMAIN: @@ -1765,25 +2015,7 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr break; case VSIR_OP_SINCOS: - if (ins->dst_count == 1) - { - if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) - return ret; - } - else - { - if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) - return ret; - } - break; - - case VSIR_OP_TEXLDD: - if ((ret = vsir_program_lower_texldd(program, ins)) < 0) - return ret; - break; - - case VSIR_OP_TEXLDL: - if ((ret = vsir_program_lower_texldl(program, ins)) < 0) + if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) return ret; break; @@ -1823,16 +2055,19 @@ static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, struct vsir_transformation_context *ctx) { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - static const struct vkd3d_shader_location no_loc; struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_location loc; - ins = vsir_program_iterator_tail(&it); - if (ins && ins->opcode == VSIR_OP_RET) + if (!(ins = vsir_program_iterator_tail(&it))) + loc = ctx->null_location; + else if (ins->opcode == VSIR_OP_RET) return VKD3D_OK; + else + loc = ins->location; if (!(ins = vsir_program_append(program))) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_instruction_init(ins, &no_loc, VSIR_OP_RET); + vsir_instruction_init(ins, &loc, VSIR_OP_RET); return VKD3D_OK; } @@ -1923,7 +2158,7 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra struct vsir_transformation_context *ctx) { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_location loc = ctx->null_location; struct vkd3d_shader_instruction *ins; unsigned int i; @@ -1937,15 +2172,16 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) + { + loc = ins->location; break; + } } - vsir_program_iterator_prev(&it); - if (!vsir_program_iterator_insert_after(&it, 1)) + if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(&it); - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = 0; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; @@ -2162,10 +2398,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program continue; loc = ins->location; - vsir_program_iterator_prev(&it); - if (!vsir_program_iterator_insert_after(&it, uninit_varying_count)) + if (!(ins = vsir_program_iterator_insert_before_and_move(&it, uninit_varying_count))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(&it); for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) { @@ -2200,8 +2434,6 @@ struct hull_flattener { struct vsir_program *program; - unsigned int instance_count; - unsigned int phase_body_idx; enum vkd3d_shader_opcode phase; struct vkd3d_shader_location last_ret_location; unsigned int *ssa_map; @@ -2213,68 +2445,6 @@ static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flat return flattener->phase == VSIR_OP_HS_FORK_PHASE || flattener->phase == VSIR_OP_HS_JOIN_PHASE; } -struct shader_phase_location -{ - unsigned int index; - unsigned int instance_count; - unsigned int instruction_count; -}; - -struct shader_phase_location_array -{ - /* Unlikely worst case: one phase for each component of each output register. */ - struct shader_phase_location locations[MAX_REG_OUTPUT * VKD3D_VEC4_SIZE]; - unsigned int count; -}; - -static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, unsigned int index, - struct vkd3d_shader_instruction *ins, struct shader_phase_location_array *locations) -{ - struct shader_phase_location *loc; - bool b; - - if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) - { - b = flattener_is_in_fork_or_join_phase(normaliser); - /* Reset the phase info. */ - normaliser->phase_body_idx = ~0u; - normaliser->phase = ins->opcode; - normaliser->instance_count = 1; - /* Leave the first occurrence and delete the rest. */ - if (b) - vkd3d_shader_instruction_make_nop(ins); - return; - } - else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT - || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) - { - normaliser->instance_count = ins->declaration.count + !ins->declaration.count; - vkd3d_shader_instruction_make_nop(ins); - return; - } - - if (normaliser->phase == VSIR_OP_INVALID || vsir_instruction_is_dcl(ins)) - return; - - if (normaliser->phase_body_idx == ~0u) - normaliser->phase_body_idx = index; - - if (ins->opcode == VSIR_OP_RET) - { - normaliser->last_ret_location = ins->location; - vkd3d_shader_instruction_make_nop(ins); - if (locations->count >= ARRAY_SIZE(locations->locations)) - { - FIXME("Insufficient space for phase location.\n"); - return; - } - loc = &locations->locations[locations->count++]; - loc->index = normaliser->phase_body_idx; - loc->instance_count = normaliser->instance_count; - loc->instruction_count = index - normaliser->phase_body_idx; - } -} - static void flattener_fixup_ssa_register(struct hull_flattener *normaliser, struct vkd3d_shader_register *reg, unsigned int instance_id) { @@ -2337,54 +2507,109 @@ static void flattener_fixup_registers(struct hull_flattener *normaliser, flattener_fixup_register_indices(normaliser, &ins->dst[i].reg, instance_id); } -static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser, - struct shader_phase_location_array *locations) +static enum vkd3d_result flattener_replicate_location(struct hull_flattener *normaliser, + struct vsir_program_iterator *it, size_t instance_count, size_t instruction_count) { - struct vkd3d_shader_instruction_array *instructions = &normaliser->program->instructions; - struct shader_phase_location *loc; - unsigned int i, j, k, end, count; - - for (i = 0, count = 0; i < locations->count; ++i) - count += (locations->locations[i].instance_count - 1) * locations->locations[i].instruction_count; + struct vsir_program_iterator dst_it, src_it, first_it; + struct vkd3d_shader_instruction *ins; + unsigned int i, j; + size_t count; - if (!shader_instruction_array_reserve(instructions, instructions->count + count)) + VKD3D_ASSERT(instance_count); + count = (instance_count - 1) * instruction_count; + if (!vsir_program_iterator_insert_before(it, &first_it, count)) return VKD3D_ERROR_OUT_OF_MEMORY; - end = instructions->count; - instructions->count += count; - for (i = locations->count; i > 0; --i) + /* Make a copy of the non-dcl instructions for each instance. */ + dst_it = first_it; + for (i = 1; i < instance_count; ++i) { - loc = &locations->locations[i - 1]; - j = loc->index + loc->instruction_count; - memmove(&instructions->elements[j + count], &instructions->elements[j], - (end - j) * sizeof(*instructions->elements)); - end = j; - count -= (loc->instance_count - 1) * loc->instruction_count; - loc->index += count; + src_it = *it; + for (j = 0; j < instruction_count; ++j) + { + if (!vsir_program_iterator_clone_instruction(&dst_it, vsir_program_iterator_current(&src_it))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + vsir_program_iterator_next(&dst_it); + vsir_program_iterator_next(&src_it); + } + } + /* Replace each reference to the instance id with a constant instance id. */ + *it = first_it; + for (i = 0; i < instance_count; ++i) + { + if (i) + memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); + + for (j = 0; j < instruction_count; ++j) + { + ins = vsir_program_iterator_current(it); + flattener_fixup_registers(normaliser, ins, i); + vsir_program_iterator_next(it); + } } - for (i = 0, count = 0; i < locations->count; ++i) + return VKD3D_OK; +} + +static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normaliser) +{ + struct vsir_program_iterator it = vsir_program_iterator(&normaliser->program->instructions); + struct vsir_program_iterator phase_body_it; + struct vkd3d_shader_instruction *ins; + bool b, phase_body_it_valid = false; + unsigned int instruction_count = 0; + unsigned int instance_count = 0; + enum vkd3d_result res; + + normaliser->phase = VSIR_OP_INVALID; + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - loc = &locations->locations[i]; - /* Make a copy of the non-dcl instructions for each instance. */ - for (j = 1; j < loc->instance_count; ++j) + if (ins->opcode == VSIR_OP_HS_FORK_PHASE || ins->opcode == VSIR_OP_HS_JOIN_PHASE) { - for (k = 0; k < loc->instruction_count; ++k) - { - if (!shader_instruction_array_clone_instruction(instructions, - loc->index + loc->instruction_count * j + k, loc->index + k)) - return VKD3D_ERROR_OUT_OF_MEMORY; - } + b = flattener_is_in_fork_or_join_phase(normaliser); + /* Reset the phase info. */ + phase_body_it_valid = false; + normaliser->phase = ins->opcode; + instance_count = 1; + instruction_count = 0; + /* Leave the first occurrence and delete the rest. */ + if (b) + vkd3d_shader_instruction_make_nop(ins); + continue; + } + else if (ins->opcode == VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT + || ins->opcode == VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) + { + instance_count = ins->declaration.count + !ins->declaration.count; + vkd3d_shader_instruction_make_nop(ins); + ++instruction_count; + continue; } - /* Replace each reference to the instance id with a constant instance id. */ - for (j = 0; j < loc->instance_count; ++j) + + if (normaliser->phase == VSIR_OP_INVALID) + continue; + + if (!phase_body_it_valid && !vsir_instruction_is_dcl(ins)) { - if (j != 0) - memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); + phase_body_it_valid = true; + phase_body_it = it; + instruction_count = 0; + } - for (k = 0; k < loc->instruction_count; ++k) - flattener_fixup_registers(normaliser, - &instructions->elements[loc->index + loc->instruction_count * j + k], j); + if (ins->opcode == VSIR_OP_RET) + { + normaliser->last_ret_location = ins->location; + vkd3d_shader_instruction_make_nop(ins); + it = phase_body_it; + if ((res = flattener_replicate_location(normaliser, &it, + instance_count, instruction_count)) < 0) + return res; + phase_body_it_valid = false; + } + else + { + ++instruction_count; } } @@ -2394,19 +2619,10 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_program *program, struct vsir_transformation_context *ctx) { - struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - struct shader_phase_location_array locations; struct hull_flattener flattener = {program}; struct vkd3d_shader_instruction *ins; enum vkd3d_result result = VKD3D_OK; - unsigned int i; - flattener.phase = VSIR_OP_INVALID; - locations.count = 0; - for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) - { - flattener_eliminate_phase_related_dcls(&flattener, i, ins, &locations); - } bitmap_clear(program->io_dcls, VKD3DSPR_FORKINSTID); bitmap_clear(program->io_dcls, VKD3DSPR_JOININSTID); @@ -2414,8 +2630,7 @@ static enum vkd3d_result vsir_program_flatten_hull_shader_phases(struct vsir_pro if (!(flattener.ssa_map = vkd3d_calloc(flattener.orig_ssa_count, sizeof(*flattener.ssa_map)))) return VKD3D_ERROR_OUT_OF_MEMORY; - result = flattener_flatten_phases(&flattener, &locations); - + result = flattener_flatten_phases(&flattener); vkd3d_free(flattener.ssa_map); flattener.ssa_map = NULL; @@ -2481,8 +2696,8 @@ static void shader_dst_param_normalise_outpointid(struct vkd3d_shader_dst_param } static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_point_normaliser *normaliser, - const struct shader_signature *s, unsigned int input_control_point_count, unsigned int dst, - const struct vkd3d_shader_location *location) + const struct shader_signature *s, unsigned int input_control_point_count, + struct vsir_program_iterator *dst_it, const struct vkd3d_shader_location *location) { struct vkd3d_shader_instruction *ins; const struct signature_element *e; @@ -2491,17 +2706,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p for (i = 0; i < s->element_count; ++i) count += !!s->elements[i].used_mask; - if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count)) + if (!(ins = vsir_program_iterator_insert_before_and_move(dst_it, count))) return VKD3D_ERROR_OUT_OF_MEMORY; - - memmove(&normaliser->instructions.elements[dst + count], &normaliser->instructions.elements[dst], - (normaliser->instructions.count - dst) * sizeof(*normaliser->instructions.elements)); - normaliser->instructions.count += count; - - ins = &normaliser->instructions.elements[dst]; vsir_instruction_init(ins, location, VSIR_OP_HS_CONTROL_POINT_PHASE); - ++ins; + ins = vsir_program_iterator_next(dst_it); for (i = 0; i < s->element_count; ++i) { @@ -2533,7 +2742,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p ins->src[0].reg.idx[0].rel_addr = normaliser->outpointid_param; ins->src[0].reg.idx[1].offset = e->register_index; - ++ins; + ins = vsir_program_iterator_next(dst_it); } vsir_instruction_init(ins, location, VSIR_OP_RET); @@ -2605,8 +2814,8 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i case VSIR_OP_HS_JOIN_PHASE: /* ins may be relocated if the instruction array expands. */ location = ins->location; - ret = control_point_normaliser_emit_hs_input(&normaliser, &program->input_signature, - input_control_point_count, i, &location); + ret = control_point_normaliser_emit_hs_input(&normaliser, + &program->input_signature, input_control_point_count, &it, &location); program->instructions = normaliser.instructions; program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; return ret; @@ -4233,9 +4442,11 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs struct vsir_transformation_context *ctx) { unsigned int block_count = program->block_count, ssa_count = program->ssa_count, current_label = 0, if_label; - size_t ins_capacity = 0, ins_count = 0, i, map_capacity = 0, map_count = 0; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + size_t ins_capacity = 0, ins_count = 0, map_capacity = 0, map_count = 0; struct vkd3d_shader_instruction *instructions = NULL; struct lower_switch_to_if_ladder_block_mapping *block_map = NULL; + struct vkd3d_shader_instruction *ins; VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); @@ -4245,9 +4456,8 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs /* First subpass: convert SWITCH_MONOLITHIC instructions to * selection ladders, keeping a map between blocks before and * after the subpass. */ - for (i = 0; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; unsigned int case_count, j, default_label; switch (ins->opcode) @@ -4800,8 +5010,8 @@ struct vsir_cfg { struct vkd3d_shader_message_context *message_context; struct vsir_program *program; - size_t function_begin; - size_t function_end; + struct vsir_program_iterator function_begin; + struct vsir_program_iterator function_end; struct vsir_block *blocks; struct vsir_block *entry; size_t block_count; @@ -5046,10 +5256,11 @@ static void vsir_cfg_dump_structured_program(struct vsir_cfg *cfg) } static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program *program, - struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, - size_t *pos) + struct vkd3d_shader_message_context *message_context, + struct vsir_cfg_emit_target *target, struct vsir_program_iterator *it) { struct vsir_block *current_block = NULL; + struct vkd3d_shader_instruction *ins; enum vkd3d_result ret; size_t i; @@ -5058,7 +5269,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program cfg->program = program; cfg->block_count = program->block_count; cfg->target = target; - cfg->function_begin = *pos; + cfg->function_begin = *it; vsir_block_list_init(&cfg->order); @@ -5068,12 +5279,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program if (TRACE_ON()) vkd3d_string_buffer_init(&cfg->debug_buffer); - for (i = *pos; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_current(it); ins; ins = vsir_program_iterator_next(it)) { - struct vkd3d_shader_instruction *instruction = &program->instructions.elements[i]; bool finish = false; - switch (instruction->opcode) + switch (ins->opcode) { case VSIR_OP_PHI: case VSIR_OP_SWITCH_MONOLITHIC: @@ -5081,7 +5291,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program case VSIR_OP_LABEL: { - unsigned int label = label_from_src_param(&instruction->src[0]); + unsigned int label = label_from_src_param(&ins->src[0]); VKD3D_ASSERT(!current_block); VKD3D_ASSERT(label > 0); @@ -5090,7 +5300,8 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program VKD3D_ASSERT(current_block->label == 0); if ((ret = vsir_block_init(current_block, label, program->block_count)) < 0) goto fail; - current_block->begin = &program->instructions.elements[i + 1]; + current_block->begin = vsir_program_iterator_next(it); + vsir_program_iterator_prev(it); if (!cfg->entry) cfg->entry = current_block; break; @@ -5099,7 +5310,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program case VSIR_OP_BRANCH: case VSIR_OP_RET: VKD3D_ASSERT(current_block); - current_block->end = instruction; + current_block->end = ins; current_block = NULL; break; @@ -5118,8 +5329,7 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program break; } - *pos = i; - cfg->function_end = *pos; + cfg->function_end = *it; for (i = 0; i < cfg->block_count; ++i) { @@ -6616,13 +6826,13 @@ static enum vkd3d_result vsir_cfg_emit_structured_program(struct vsir_cfg *cfg) } static enum vkd3d_result vsir_program_structurize_function(struct vsir_program *program, - struct vkd3d_shader_message_context *message_context, struct vsir_cfg_emit_target *target, - size_t *pos) + struct vkd3d_shader_message_context *message_context, + struct vsir_cfg_emit_target *target, struct vsir_program_iterator *it) { enum vkd3d_result ret; struct vsir_cfg cfg; - if ((ret = vsir_cfg_init(&cfg, program, message_context, target, pos)) < 0) + if ((ret = vsir_cfg_init(&cfg, program, message_context, target, it)) < 0) return ret; vsir_cfg_compute_dominators(&cfg); @@ -6653,10 +6863,11 @@ out: static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_message_context *message_context = ctx->message_context; struct vsir_cfg_emit_target target = {0}; + struct vkd3d_shader_instruction *ins; enum vkd3d_result ret; - size_t i; VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); @@ -6666,19 +6877,17 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, if (!reserve_instructions(&target.instructions, &target.ins_capacity, program->instructions.count)) return VKD3D_ERROR_OUT_OF_MEMORY; - for (i = 0; i < program->instructions.count;) + for (ins = vsir_program_iterator_head(&it); ins;) { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - switch (ins->opcode) { case VSIR_OP_LABEL: VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); TRACE("Structurizing a non-hull shader.\n"); - if ((ret = vsir_program_structurize_function(program, message_context, - &target, &i)) < 0) + if ((ret = vsir_program_structurize_function(program, message_context, &target, &it)) < 0) goto fail; - VKD3D_ASSERT(i == program->instructions.count); + ins = vsir_program_iterator_current(&it); + VKD3D_ASSERT(!ins); break; case VSIR_OP_HS_CONTROL_POINT_PHASE: @@ -6687,17 +6896,17 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); TRACE("Structurizing phase %u of a hull shader.\n", ins->opcode); target.instructions[target.ins_count++] = *ins; - ++i; - if ((ret = vsir_program_structurize_function(program, message_context, - &target, &i)) < 0) + vsir_program_iterator_next(&it); + if ((ret = vsir_program_structurize_function(program, message_context, &target, &it)) < 0) goto fail; + ins = vsir_program_iterator_current(&it); break; default: if (!reserve_instructions(&target.instructions, &target.ins_capacity, target.ins_count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; target.instructions[target.ins_count++] = *ins; - ++i; + ins = vsir_program_iterator_next(&it); break; } } @@ -6742,8 +6951,10 @@ static void register_map_undominated_use(struct vkd3d_shader_register *reg, stru static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct vsir_cfg *cfg) { struct vsir_program *program = cfg->program; + struct vkd3d_shader_instruction *ins, *end; struct ssas_to_temps_alloc alloc = {0}; struct vsir_block **origin_blocks; + struct vsir_program_iterator it; unsigned int j; size_t i; @@ -6761,7 +6972,6 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v for (i = 0; i < cfg->block_count; ++i) { struct vsir_block *block = &cfg->blocks[i]; - struct vkd3d_shader_instruction *ins; if (block->label == 0) continue; @@ -6779,7 +6989,6 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v for (i = 0; i < cfg->block_count; ++i) { struct vsir_block *block = &cfg->blocks[i]; - struct vkd3d_shader_instruction *ins; if (block->label == 0) continue; @@ -6796,10 +7005,10 @@ static enum vkd3d_result vsir_cfg_materialize_undominated_ssas_to_temps(struct v TRACE("Emitting temps for %u values with undominated usage.\n", alloc.next_temp_idx - program->temp_count); - for (i = cfg->function_begin; i < cfg->function_end; ++i) + it = cfg->function_begin; + end = vsir_program_iterator_current(&cfg->function_end); + for (ins = vsir_program_iterator_current(&it); ins != end; ins = vsir_program_iterator_next(&it)) { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - for (j = 0; j < ins->dst_count; ++j) materialize_ssas_to_temps_process_reg(program, &alloc, &ins->dst[j].reg); @@ -6815,14 +7024,13 @@ done: return VKD3D_OK; } -static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function( - struct vsir_program *program, struct vkd3d_shader_message_context *message_context, - size_t *pos) +static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_function(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context, struct vsir_program_iterator *it) { enum vkd3d_result ret; struct vsir_cfg cfg; - if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, pos)) < 0) + if ((ret = vsir_cfg_init(&cfg, program, message_context, NULL, it)) < 0) return ret; vsir_cfg_compute_dominators(&cfg); @@ -6837,25 +7045,25 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps_in_f static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_message_context *message_context = ctx->message_context; + struct vkd3d_shader_instruction *ins; enum vkd3d_result ret; - size_t i; VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); - for (i = 0; i < program->instructions.count;) + for (ins = vsir_program_iterator_head(&it); ins;) { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - switch (ins->opcode) { case VSIR_OP_LABEL: VKD3D_ASSERT(program->shader_version.type != VKD3D_SHADER_TYPE_HULL); TRACE("Materializing undominated SSAs in a non-hull shader.\n"); if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( - program, message_context, &i)) < 0) + program, message_context, &it)) < 0) return ret; - VKD3D_ASSERT(i == program->instructions.count); + ins = vsir_program_iterator_current(&it); + VKD3D_ASSERT(!ins); break; case VSIR_OP_HS_CONTROL_POINT_PHASE: @@ -6863,14 +7071,15 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru case VSIR_OP_HS_JOIN_PHASE: VKD3D_ASSERT(program->shader_version.type == VKD3D_SHADER_TYPE_HULL); TRACE("Materializing undominated SSAs in phase %u of a hull shader.\n", ins->opcode); - ++i; + vsir_program_iterator_next(&it); if ((ret = vsir_program_materialize_undominated_ssas_to_temps_in_function( - program, message_context, &i)) < 0) + program, message_context, &it)) < 0) return ret; + ins = vsir_program_iterator_current(&it); break; default: - ++i; + ins = vsir_program_iterator_next(&it); break; } } @@ -6881,7 +7090,6 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru static bool use_flat_interpolation(const struct vsir_program *program, struct vkd3d_shader_message_context *message_context, bool *flat) { - static const struct vkd3d_shader_location no_loc; const struct vkd3d_shader_parameter1 *parameter; *flat = false; @@ -6891,13 +7099,13 @@ static bool use_flat_interpolation(const struct vsir_program *program, if (parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unsupported flat interpolation parameter type %#x.", parameter->type); return false; } if (parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid flat interpolation parameter data type %#x.", parameter->data_type); return false; } @@ -6938,7 +7146,6 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; - static const struct vkd3d_shader_location no_loc; struct vkd3d_shader_instruction *ins; static const struct @@ -6959,10 +7166,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) { - vsir_program_iterator_prev(it); - if (!vsir_program_iterator_insert_after(it, 1)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(it); vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; @@ -6972,10 +7177,8 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr return VKD3D_OK; } - vsir_program_iterator_prev(it); - if (!vsir_program_iterator_insert_after(it, 3)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 3))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(it); switch (ref->data_type) { @@ -6994,7 +7197,7 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr break; case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4: - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, "Alpha test reference data type must be a single component."); return VKD3D_ERROR_INVALID_ARGUMENT; @@ -7036,7 +7239,6 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro struct vkd3d_shader_message_context *message_context = ctx->message_context; const struct vkd3d_shader_parameter1 *func = NULL, *ref = NULL; uint32_t colour_signature_idx, colour_temp = ~0u; - static const struct vkd3d_shader_location no_loc; enum vkd3d_shader_comparison_func compare_func; struct vkd3d_shader_instruction *ins; int ret; @@ -7054,13 +7256,13 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro if (func->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unsupported alpha test function parameter type %#x.", func->type); return VKD3D_ERROR_NOT_IMPLEMENTED; } if (func->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid alpha test function parameter data type %#x.", func->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -7117,10 +7319,8 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog struct vkd3d_shader_instruction *ins; unsigned int output_idx = 0; - vsir_program_iterator_prev(it); - if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, vkd3d_popcount(mask) + 1))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(it); for (unsigned int i = 0; i < 8; ++i) { @@ -7166,7 +7366,6 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; const struct vkd3d_shader_parameter1 *mask_parameter = NULL; uint32_t position_signature_idx, position_temp, mask; - static const struct vkd3d_shader_location no_loc; struct signature_element *clip_element; struct vkd3d_shader_instruction *ins; unsigned int plane_count; @@ -7188,13 +7387,13 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr if (mask_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unsupported clip plane mask parameter type %#x.", mask_parameter->type); return VKD3D_ERROR_NOT_IMPLEMENTED; } if (mask_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid clip plane mask parameter data type %#x.", mask_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -7207,7 +7406,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr { if (signature->elements[i].sysval_semantic == VKD3D_SHADER_SV_CLIP_DISTANCE) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, + vkd3d_shader_error(ctx->message_context, &ctx->null_location, VKD3D_SHADER_ERROR_VSIR_INVALID_PARAMETER, "Clip planes cannot be used if the shader writes clip distance."); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -7215,7 +7414,7 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr if (!vsir_signature_find_sysval(signature, VKD3D_SHADER_SV_POSITION, 0, &position_signature_idx)) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, + vkd3d_shader_error(ctx->message_context, &ctx->null_location, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); return VKD3D_ERROR_INVALID_SHADER; } @@ -7288,10 +7487,8 @@ static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *progr const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; struct vkd3d_shader_instruction *ins; - vsir_program_iterator_prev(it); - if (!vsir_program_iterator_insert_after(it, 1)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(it); vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); @@ -7307,7 +7504,6 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); const struct vkd3d_shader_parameter1 *size_parameter = NULL; - static const struct vkd3d_shader_location no_loc; struct vkd3d_shader_instruction *ins; if (program->has_point_size) @@ -7329,7 +7525,7 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro if (size_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid point size parameter data type %#x.", size_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -7356,7 +7552,6 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra { const struct vkd3d_shader_parameter1 *min_parameter = NULL, *max_parameter = NULL; struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); - static const struct vkd3d_shader_location no_loc; struct vkd3d_shader_instruction *ins; if (!program->has_point_size) @@ -7380,14 +7575,14 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra if (min_parameter && min_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid minimum point size parameter data type %#x.", min_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } if (max_parameter && max_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid maximum point size parameter data type %#x.", max_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -7530,7 +7725,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr { struct vsir_program_iterator it = vsir_program_iterator(&program->instructions), it2; const struct vkd3d_shader_parameter1 *sprite_parameter = NULL; - static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_location loc = ctx->null_location; struct vkd3d_shader_instruction *ins; bool used_texcoord = false; unsigned int coord_temp; @@ -7552,13 +7747,13 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr if (sprite_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unsupported point sprite parameter type %#x.", sprite_parameter->type); return VKD3D_ERROR_NOT_IMPLEMENTED; } if (sprite_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) { - vkd3d_shader_error(ctx->message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(ctx->message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid point sprite parameter data type %#x.", sprite_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -7578,7 +7773,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) + { + loc = ins->location; break; + } } it2 = it; @@ -7613,12 +7811,10 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr if (used_texcoord) { - vsir_program_iterator_prev(&it); - if (!vsir_program_iterator_insert_after(&it, 2)) + if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 2))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = vsir_program_iterator_next(&it); - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); dst_param_init_temp_float4(&ins->dst[0], coord_temp); ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); @@ -7626,7 +7822,7 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; ins = vsir_program_iterator_next(&it); - vsir_instruction_init_with_params(program, ins, &no_loc, VSIR_OP_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); dst_param_init_temp_float4(&ins->dst[0], coord_temp); ins->dst[0].write_mask = VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3; vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); @@ -7668,15 +7864,12 @@ static enum vkd3d_result vsir_program_add_fog_input(struct vsir_program *program } static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *program, - const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_fragment_mode mode, - uint32_t fog_signature_idx, uint32_t colour_signature_idx, uint32_t colour_temp, - size_t *ret_pos, struct vkd3d_shader_message_context *message_context) + struct vsir_program_iterator *it, enum vkd3d_shader_fog_fragment_mode mode, uint32_t fog_signature_idx, + uint32_t colour_signature_idx, uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - struct vkd3d_shader_location loc = ret->location; + struct vkd3d_shader_instruction *ins = vsir_program_iterator_current(it); + struct vkd3d_shader_location loc = ins->location; uint32_t ssa_factor = program->ssa_count++; - size_t pos = ret - instructions->elements; - struct vkd3d_shader_instruction *ins; uint32_t ssa_temp, ssa_temp2; switch (mode) @@ -7687,16 +7880,11 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * add sr0, FOG_END, -vFOG.x * mul_sat srFACTOR, sr0, FOG_SCALE */ - if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - - *ret_pos = pos + 4; ssa_temp = program->ssa_count++; - ins = &program->instructions.elements[pos]; - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); @@ -7705,12 +7893,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); ins->src[1].modifiers = VKD3DSPSM_NEG; + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp); src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); + ins = vsir_program_iterator_next(it); + break; case VKD3D_SHADER_FOG_FRAGMENT_EXP: @@ -7719,16 +7910,11 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * mul sr0, FOG_SCALE, vFOG.x * exp_sat srFACTOR, -sr0 */ - if (!shader_instruction_array_insert_at(&program->instructions, pos, 4)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 4))) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - - *ret_pos = pos + 4; ssa_temp = program->ssa_count++; - ins = &program->instructions.elements[pos]; - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); @@ -7736,12 +7922,14 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins->src[1].reg.idx[0].offset = fog_signature_idx; ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp); ins->src[0].modifiers = VKD3DSPSM_NEG; + ins = vsir_program_iterator_next(it); break; case VKD3D_SHADER_FOG_FRAGMENT_EXP2: @@ -7751,17 +7939,12 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * mul sr1, sr0, sr0 * exp_sat srFACTOR, -sr1 */ - if (!shader_instruction_array_insert_at(&program->instructions, pos, 5)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 5))) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - - *ret_pos = pos + 5; ssa_temp = program->ssa_count++; ssa_temp2 = program->ssa_count++; - ins = &program->instructions.elements[pos]; - vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp); src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); @@ -7769,17 +7952,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro ins->src[1].reg.idx[0].offset = fog_signature_idx; ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MUL, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MUL, 1, 2); dst_param_init_ssa_float(&ins->dst[0], ssa_temp2); src_param_init_ssa_float(&ins->src[0], ssa_temp); src_param_init_ssa_float(&ins->src[1], ssa_temp); + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_EXP, 1, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_EXP, 1, 1); dst_param_init_ssa_float(&ins->dst[0], ssa_factor); ins->dst[0].modifiers = VKD3DSPDM_SATURATE; src_param_init_ssa_float(&ins->src[0], ssa_temp2); ins->src[0].modifiers = VKD3DSPSM_NEG; + ins = vsir_program_iterator_next(it); break; default: @@ -7792,18 +7978,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro * mad oC0, sr0, srFACTOR, FOG_COLOUR */ - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_ADD, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_ADD, 1, 2); dst_param_init_ssa_float4(&ins->dst[0], program->ssa_count++); src_param_init_temp_float4(&ins->src[0], colour_temp); src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ins->src[1].modifiers = VKD3DSPSM_NEG; + ins = vsir_program_iterator_next(it); - vsir_instruction_init_with_params(program, ++ins, &loc, VSIR_OP_MAD, 1, 3); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MAD, 1, 3); dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, colour_signature_idx, program->output_signature.elements[colour_signature_idx].mask); src_param_init_ssa_float4(&ins->src[0], program->ssa_count - 1); src_param_init_ssa_float(&ins->src[1], ssa_factor); src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); + ins = vsir_program_iterator_next(it); return VKD3D_OK; } @@ -7811,14 +7999,13 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_message_context *message_context = ctx->message_context; uint32_t colour_signature_idx, fog_signature_idx, colour_temp; const struct vkd3d_shader_parameter1 *mode_parameter = NULL; - static const struct vkd3d_shader_location no_loc; const struct signature_element *fog_element; enum vkd3d_shader_fog_fragment_mode mode; struct vkd3d_shader_instruction *ins; - size_t new_pos; int ret; if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) @@ -7832,13 +8019,13 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p if (mode_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unsupported fog fragment mode parameter type %#x.", mode_parameter->type); return VKD3D_ERROR_NOT_IMPLEMENTED; } if (mode_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid fog fragment mode parameter data type %#x.", mode_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -7859,19 +8046,16 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p * through the whole shader and convert it to a temp. */ colour_temp = program->temp_count++; - for (size_t i = 0; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - ins = &program->instructions.elements[i]; - if (vsir_instruction_is_dcl(ins)) continue; if (ins->opcode == VSIR_OP_RET) { - if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, - colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) + if ((ret = insert_fragment_fog_before_ret(program, &it, mode, fog_signature_idx, + colour_signature_idx, colour_temp, message_context)) < 0) return ret; - i = new_pos; continue; } @@ -7927,21 +8111,16 @@ static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *progra return VKD3D_OK; } -static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, - const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_fog_source source, uint32_t temp, - uint32_t fog_signature_idx, uint32_t source_signature_idx, size_t *ret_pos) +static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *program, struct vsir_program_iterator *it, + enum vkd3d_shader_fog_source source, uint32_t temp, uint32_t fog_signature_idx, uint32_t source_signature_idx) { const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; - struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vkd3d_shader_instruction *ret = vsir_program_iterator_current(it); const struct vkd3d_shader_location loc = ret->location; - size_t pos = ret - instructions->elements; struct vkd3d_shader_instruction *ins; - if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) + if (!(ins = vsir_program_iterator_insert_before_and_move(it, 2))) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - - ins = &program->instructions.elements[pos]; /* Write the fog output. */ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); @@ -7951,26 +8130,26 @@ static enum vkd3d_result insert_vertex_fog_before_ret(struct vsir_program *progr ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z); else /* Position or specular W. */ ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W); - ++ins; + ins = vsir_program_iterator_next(it); /* Write the position or specular output. */ vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); dst_param_init_output(&ins->dst[0], vsir_data_type_from_component_type(e->component_type), source_signature_idx, e->mask); src_param_init_temp_float4(&ins->src[0], temp); - ++ins; + ins = vsir_program_iterator_next(it); - *ret_pos = pos + 2; return VKD3D_OK; } static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_message_context *message_context = ctx->message_context; const struct vkd3d_shader_parameter1 *source_parameter = NULL; uint32_t fog_signature_idx, source_signature_idx, temp; - static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins; enum vkd3d_shader_fog_source source; const struct signature_element *e; @@ -7982,13 +8161,13 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Unsupported fog source parameter type %#x.", source_parameter->type); return VKD3D_ERROR_NOT_IMPLEMENTED; } if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid fog source parameter data type %#x.", source_parameter->data_type); return VKD3D_ERROR_INVALID_ARGUMENT; } @@ -8010,7 +8189,7 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro if (!vsir_signature_find_sysval(&program->output_signature, VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx)) { - vkd3d_shader_error(ctx->message_context, &no_loc, + vkd3d_shader_error(ctx->message_context, &ctx->null_location, VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); return VKD3D_ERROR_INVALID_SHADER; } @@ -8027,22 +8206,18 @@ static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *pro /* Insert a fog write before each ret, and convert either specular or * position output to a temp. */ - for (size_t i = 0; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - if (vsir_instruction_is_dcl(ins)) continue; if (ins->opcode == VSIR_OP_RET) { - size_t new_pos; int ret; - if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp, - fog_signature_idx, source_signature_idx, &new_pos)) < 0) + if ((ret = insert_vertex_fog_before_ret(program, &it, source, temp, + fog_signature_idx, source_signature_idx)) < 0) return ret; - i = new_pos; continue; } @@ -8450,7 +8625,7 @@ struct liveness_tracker bool fixed_mask; uint8_t mask; unsigned int first_write, last_access; - } *ssa_regs; + } *ssa_regs, *temp_regs; }; static void liveness_track_src(struct liveness_tracker *tracker, @@ -8464,6 +8639,8 @@ static void liveness_track_src(struct liveness_tracker *tracker, if (src->reg.type == VKD3DSPR_SSA) tracker->ssa_regs[src->reg.idx[0].offset].last_access = index; + else if (src->reg.type == VKD3DSPR_TEMP) + tracker->temp_regs[src->reg.idx[0].offset].last_access = index; } static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst, @@ -8479,6 +8656,8 @@ static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_sh if (dst->reg.type == VKD3DSPR_SSA) reg = &tracker->ssa_regs[dst->reg.idx[0].offset]; + else if (dst->reg.type == VKD3DSPR_TEMP) + reg = &tracker->temp_regs[dst->reg.idx[0].offset]; else return; @@ -8565,20 +8744,22 @@ static void liveness_tracker_cleanup(struct liveness_tracker *tracker) static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_instruction *ins; struct liveness_tracker_reg *regs; unsigned int loop_depth = 0; unsigned int loop_start = 0; + unsigned int i; memset(tracker, 0, sizeof(*tracker)); - if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) + if (!(regs = vkd3d_calloc(program->ssa_count + program->temp_count, sizeof(*regs)))) return VKD3D_ERROR_OUT_OF_MEMORY; tracker->ssa_regs = regs; + tracker->temp_regs = ®s[program->ssa_count]; - for (unsigned int i = 0; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) { - const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - if (ins->opcode == VSIR_OP_LOOP || ins->opcode == VSIR_OP_REP) { if (!loop_depth++) @@ -8604,8 +8785,7 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv * should be illegal for an SSA value to be read in a block * containing L.) * We don't try to perform this optimization yet, in the name of - * maximal simplicity, and also because this code is intended to - * be extended to non-SSA values. */ + * maximal simplicity. */ for (unsigned int j = 0; j < program->ssa_count; ++j) { struct liveness_tracker_reg *reg = &tracker->ssa_regs[j]; @@ -8615,6 +8795,16 @@ static enum vkd3d_result track_liveness(struct vsir_program *program, struct liv if (reg->last_access < i) reg->last_access = i; } + + for (unsigned int j = 0; j < program->temp_count; ++j) + { + struct liveness_tracker_reg *reg = &tracker->temp_regs[j]; + + if (reg->first_write > loop_start) + reg->first_write = loop_start; + if (reg->last_access < i) + reg->last_access = i; + } } } @@ -8634,8 +8824,8 @@ struct temp_allocator { uint8_t allocated_mask; uint32_t temp_id; - } *ssa_regs; - size_t allocated_ssa_count; + } *ssa_regs, *temp_regs; + size_t allocated_ssa_count, allocated_temp_count; enum vkd3d_result result; }; @@ -8662,16 +8852,30 @@ static uint8_t get_available_writemask(const struct temp_allocator *allocator, return writemask; } + for (size_t i = 0; i < allocator->allocated_temp_count; ++i) + { + const struct temp_allocator_reg *reg = &allocator->temp_regs[i]; + const struct liveness_tracker_reg *liveness_reg = &tracker->temp_regs[i]; + + if (reg->temp_id == temp_id + && first_write < liveness_reg->last_access + && last_access > liveness_reg->first_write) + writemask &= ~reg->allocated_mask; + + if (!writemask) + return writemask; + } + return writemask; } static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liveness_tracker *tracker, - struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg, uint32_t base_id) + struct temp_allocator_reg *reg, const struct liveness_tracker_reg *liveness_reg) { if (!liveness_reg->written) return false; - for (uint32_t id = base_id;; ++id) + for (uint32_t id = 0;; ++id) { uint8_t available_mask = get_available_writemask(allocator, tracker, liveness_reg->first_write, liveness_reg->last_access, id); @@ -8688,13 +8892,21 @@ static bool temp_allocator_allocate(struct temp_allocator *allocator, struct liv else { /* For SSA values the mask is always zero-based and contiguous. - * We don't correctly handle cases where it's not, currently. */ - VKD3D_ASSERT((liveness_reg->mask | (liveness_reg->mask - 1)) == liveness_reg->mask); - - if (vkd3d_popcount(available_mask) >= vkd3d_popcount(liveness_reg->mask)) + * For TEMP values we assume the register was allocated that way, + * but it may only be partially used. + * We currently only handle cases where the mask is zero-based and + * contiguous, so we need to fill in the missing components to + * ensure this. */ + uint8_t mask = (1u << (vkd3d_log2i(liveness_reg->mask) + 1)) - 1; + + if (vkd3d_popcount(available_mask) >= vkd3d_popcount(mask)) { + if (mask != liveness_reg->mask) + WARN("Allocating a mask %#x with used components %#x; this is not optimized.\n", + mask, liveness_reg->mask); + reg->temp_id = id; - reg->allocated_mask = vsir_combine_write_masks(available_mask, liveness_reg->mask); + reg->allocated_mask = vsir_combine_write_masks(available_mask, mask); return true; } } @@ -8713,6 +8925,8 @@ static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3 if (src->reg.type == VKD3DSPR_SSA) reg = &allocator->ssa_regs[src->reg.idx[0].offset]; + else if (src->reg.type == VKD3DSPR_TEMP) + reg = &allocator->temp_regs[src->reg.idx[0].offset]; else return; @@ -8792,6 +9006,7 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, struct vkd3d_shader_dst_param *dst, const struct vkd3d_shader_instruction *ins) { struct temp_allocator_reg *reg; + uint32_t remapped_mask; for (unsigned int k = 0; k < dst->reg.idx_count; ++k) { @@ -8801,15 +9016,18 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, if (dst->reg.type == VKD3DSPR_SSA) reg = &allocator->ssa_regs[dst->reg.idx[0].offset]; + else if (dst->reg.type == VKD3DSPR_TEMP) + reg = &allocator->temp_regs[dst->reg.idx[0].offset]; else return; dst->reg.type = VKD3DSPR_TEMP; dst->reg.dimension = VSIR_DIMENSION_VEC4; dst->reg.idx[0].offset = reg->temp_id; - if (reg->allocated_mask != dst->write_mask) + remapped_mask = vsir_combine_write_masks(reg->allocated_mask, dst->write_mask); + if (dst->write_mask != remapped_mask) { - dst->write_mask = reg->allocated_mask; + dst->write_mask = remapped_mask; if (vsir_opcode_is_double(ins->opcode)) { @@ -8825,47 +9043,90 @@ static void temp_allocator_set_dst(struct temp_allocator *allocator, if (vsir_src_is_masked(ins->opcode, i)) { if (src->reg.type == VKD3DSPR_IMMCONST) - vsir_remap_immconst(src, dst->write_mask); + vsir_remap_immconst(src, reg->allocated_mask); else if (src->reg.type == VKD3DSPR_IMMCONST64) - vsir_remap_immconst64(src, dst->write_mask); + vsir_remap_immconst64(src, reg->allocated_mask); else - src->swizzle = vsir_map_swizzle(src->swizzle, dst->write_mask); + src->swizzle = vsir_map_swizzle(src->swizzle, reg->allocated_mask); } } } } +/* This pass does two things: + * + * - converts SSA registers (sr#) into temp registers (r#); + * + * - contracts temp registers with non-overlapping ranges by reallocating them + * into the same register. + * + * These are done at the same time so that SSA and temp registers with + * non-overlapping liveness can share the same register. + * + * The temp contraction is not particularly sophisticated. In particular, it + * does not detect cases where a single temp register has multiple disjoint + * ranges of liveness, and it also assumes that the components used by a single + * registers is zero-based and contiguous. + * The intent for temp contraction is that HLSL will output each distinct + * variable to a unique temp ID. */ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, struct vkd3d_shader_message_context *message_context) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); const unsigned int prev_temp_count = program->temp_count; struct temp_allocator allocator = {0}; + struct vkd3d_shader_instruction *ins; struct temp_allocator_reg *regs; struct liveness_tracker tracker; enum vkd3d_result ret; - if (!program->ssa_count) + if (!program->ssa_count && !prev_temp_count) return VKD3D_OK; if ((ret = track_liveness(program, &tracker))) return ret; - if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) + if (!(regs = vkd3d_calloc(program->ssa_count + prev_temp_count, sizeof(*regs)))) { liveness_tracker_cleanup(&tracker); return VKD3D_ERROR_OUT_OF_MEMORY; } allocator.message_context = message_context; allocator.ssa_regs = regs; + allocator.temp_regs = regs + program->ssa_count; + + program->temp_count = 0; + + /* Reallocate temps first. We do this specifically to make sure that r0 is + * the first register to be allocated, and thus will be reallocated in + * place, and left alone. + * This is necessary because, in pixel shader model 1.x, r0 doubles as the + * output register, and needs to remain at r0. (Note that we need to already + * have the output in r0, rather than e.g. putting it in o0 and converting + * it to r0 after this pass, so that we know when r0 is live.) */ + for (unsigned int i = 0; i < prev_temp_count; ++i) + { + const struct liveness_tracker_reg *liveness_reg = &tracker.temp_regs[i]; + struct temp_allocator_reg *reg = &allocator.temp_regs[i]; + + if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg)) + { + TRACE("Reallocated r%u%s for r%u (liveness %u-%u).\n", + reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, + liveness_reg->first_write, liveness_reg->last_access); + program->temp_count = max(program->temp_count, reg->temp_id + 1); + } + ++allocator.allocated_temp_count; + } for (unsigned int i = 0; i < program->ssa_count; ++i) { const struct liveness_tracker_reg *liveness_reg = &tracker.ssa_regs[i]; struct temp_allocator_reg *reg = &allocator.ssa_regs[i]; - if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg, prev_temp_count)) + if (temp_allocator_allocate(&allocator, &tracker, reg, liveness_reg)) { - TRACE("Allocated r%u%s to sr%u (liveness %u-%u).\n", + TRACE("Allocated r%u%s for sr%u (liveness %u-%u).\n", reg->temp_id, debug_vsir_writemask(reg->allocated_mask), i, liveness_reg->first_write, liveness_reg->last_access); program->temp_count = max(program->temp_count, reg->temp_id + 1); @@ -8873,10 +9134,8 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, ++allocator.allocated_ssa_count; } - for (unsigned int i = 0; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - const struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; - /* Make sure we do the srcs first; setting the dst writemask may need * to remap their swizzles. */ for (unsigned int j = 0; j < ins->src_count; ++j) @@ -8902,11 +9161,14 @@ enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, struct vkd3d_shader_message_context *message_context) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_location location; + struct vkd3d_shader_instruction *ins; unsigned int temp_count = 0; - for (int i = program->instructions.count - 1; i >= 0; --i) + for (ins = vsir_program_iterator_tail(&it); ins; ins = vsir_program_iterator_prev(&it)) { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i]; + location = ins->location; if (ins->opcode == VSIR_OP_DCL_TEMPS) { @@ -8922,11 +9184,11 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, { /* The phase didn't have a dcl_temps instruction, but we added * temps here, so we need to insert one. */ - if (!shader_instruction_array_insert_at(&program->instructions, i + 1, 1)) + if (!vsir_program_iterator_insert_after(&it, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[i + 1]; - vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS); + ins = vsir_program_iterator_next(&it); + vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); ins->declaration.count = temp_count; temp_count = 0; continue; @@ -8947,13 +9209,13 @@ enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, if (temp_count && program->shader_version.major >= 4) { - struct vkd3d_shader_instruction *ins; + ins = vsir_program_iterator_head(&it); + location = ins->location; - if (!shader_instruction_array_insert_at(&program->instructions, 0, 1)) + if (!(ins = vsir_program_iterator_insert_before_and_move(&it, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[0]; - vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS); + vsir_instruction_init(ins, &location, VSIR_OP_DCL_TEMPS); ins->declaration.count = temp_count; } @@ -8965,7 +9227,7 @@ struct validation_context struct vkd3d_shader_message_context *message_context; const struct vsir_program *program; size_t instruction_idx; - struct vkd3d_shader_location null_location; + struct vkd3d_shader_location location; bool invalid_instruction_idx; enum vkd3d_result status; bool dcl_temps_found; @@ -9024,13 +9286,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) validator_error(struct validation_context *c if (ctx->invalid_instruction_idx) { - vkd3d_shader_error(ctx->message_context, &ctx->null_location, error, "%s", buf.buffer); + vkd3d_shader_error(ctx->message_context, &ctx->location, error, "%s", buf.buffer); WARN("VSIR validation error: %s\n", buf.buffer); } else { - const struct vkd3d_shader_instruction *ins = &ctx->program->instructions.elements[ctx->instruction_idx]; - vkd3d_shader_error(ctx->message_context, &ins->location, error, + vkd3d_shader_error(ctx->message_context, &ctx->location, error, "instruction %zu: %s", ctx->instruction_idx + 1, buf.buffer); WARN("VSIR validation error: instruction %zu: %s\n", ctx->instruction_idx + 1, buf.buffer); } @@ -9459,7 +9720,8 @@ static void vsir_validate_label_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a LABEL register.", reg->data_type); + "Invalid data type \"%s\" (%#x) for a LABEL register.", + vsir_data_type_get_name(reg->data_type, ""), reg->data_type); if (reg->dimension != VSIR_DIMENSION_NONE) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, @@ -9538,7 +9800,8 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a SAMPLER register.", reg->data_type); + "Invalid data type \"%s\" (%#x) for a SAMPLER register.", + vsir_data_type_get_name(reg->data_type, ""), reg->data_type); /* VEC4 is allowed in gather operations. */ if (reg->dimension == VSIR_DIMENSION_SCALAR) @@ -9564,7 +9827,8 @@ static void vsir_validate_resource_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a RESOURCE register.", reg->data_type); + "Invalid data type \"%s\" (%#x) for a RESOURCE register.", + vsir_data_type_get_name(reg->data_type, ""), reg->data_type); if (reg->dimension != VSIR_DIMENSION_VEC4) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, @@ -9590,8 +9854,8 @@ static void vsir_validate_uav_register(struct validation_context *ctx, if (reg->data_type != VSIR_DATA_UNUSED) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a UAV register.", - reg->data_type); + "Invalid data type \"%s\" (%#x) for a UAV register.", + vsir_data_type_get_name(reg->data_type, ""), reg->data_type); /* NONE is allowed in counter operations. */ if (reg->dimension == VSIR_DIMENSION_SCALAR) @@ -9663,9 +9927,10 @@ static void vsir_validate_ssa_register(struct validation_context *ctx, if (data_type_is_64_bit(data->data_type) != data_type_is_64_bit(reg->data_type)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for a SSA register: " - "it has already been seen with data type %#x at instruction %zu.", - reg->data_type, data->data_type, data->first_seen); + "Invalid data type \"%s\" (%#x) for SSA register %u: " + "it has already been seen with data type \"%s\" (%#x) at instruction %zu.", + vsir_data_type_get_name(reg->data_type, ""), reg->data_type, reg->idx[0].offset, + vsir_data_type_get_name(data->data_type, ""), data->data_type, data->first_seen); } } @@ -9913,7 +10178,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, default: validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for destination with saturate modifier.", dst->reg.data_type); + "Invalid data type \"%s\" (%#x) for destination with saturate modifier.", + vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); break; } @@ -9932,7 +10198,8 @@ static void vsir_validate_dst_param(struct validation_context *ctx, case 15: if (dst->reg.data_type != VSIR_DATA_F32) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for destination with shift.", dst->reg.data_type); + "Invalid data type \"%s\" (%#x) for destination with shift.", + vsir_data_type_get_name(dst->reg.data_type, ""), dst->reg.data_type); break; default: @@ -10070,7 +10337,8 @@ static void vsir_validate_src_param(struct validation_context *ctx, { if (!(src_modifier_data[src->modifiers].data_type_mask & (1u << src->reg.data_type))) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, - "Source has invalid modifier %#x for data type %u.", src->modifiers, src->reg.data_type); + "Source has invalid modifier %#x for data type \"%s\" (%#x).", + src->modifiers, vsir_data_type_get_name(src->reg.data_type, ""), src->reg.data_type); } switch (src->reg.type) @@ -10722,7 +10990,7 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, static void vsir_validate_elementwise_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) { - enum vsir_data_type dst_data_type; + enum vsir_data_type dst_data_type, src_data_type; unsigned int i; if (instruction->dst_count < 1) @@ -10735,16 +11003,18 @@ static void vsir_validate_elementwise_operation(struct validation_context *ctx, if (!types[dst_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for elementwise operation \"%s\" (%#x).", - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid data type \"%s\" (%#x) for elementwise operation \"%s\" (%#x).", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); for (i = 0; i < instruction->src_count; ++i) { - if (instruction->src[i].reg.data_type != dst_data_type) + if ((src_data_type = instruction->src[i].reg.data_type) != dst_data_type) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Data type %#x for operand %u doesn't match the destination data type %#x " + "Data type \"%s\" (%#x) for operand %u doesn't match the destination data type \"%s\" (%#x) " "for elementwise operation \"%s\" (%#x).", - instruction->src[i].reg.data_type, i, dst_data_type, + vsir_data_type_get_name(src_data_type, ""), src_data_type, i, + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } } @@ -10801,7 +11071,7 @@ static void vsir_validate_logic_elementwise_operation(struct validation_context static void vsir_validate_comparison_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, const bool types[VSIR_DATA_TYPE_COUNT]) { - enum vsir_data_type dst_data_type, src_data_type; + enum vsir_data_type dst_data_type, src_data_type, data_type; unsigned int i; if (instruction->dst_count < 1) @@ -10811,8 +11081,9 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, if (dst_data_type != VSIR_DATA_U32 && dst_data_type != VSIR_DATA_BOOL) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for result of comparison operation \"%s\" (%#x).", - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid data type \"%s\" (%#x) for result of comparison operation \"%s\" (%#x).", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); if (instruction->src_count == 0) return; @@ -10824,16 +11095,18 @@ static void vsir_validate_comparison_operation(struct validation_context *ctx, if (!types[src_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid data type %#x for comparison operation \"%s\" (%#x).", - src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", + vsir_data_type_get_name(src_data_type, ""), src_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); for (i = 1; i < instruction->src_count; ++i) { - if (instruction->src[i].reg.data_type != src_data_type) + if ((data_type = instruction->src[i].reg.data_type) != src_data_type) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Data type %#x for operand %u doesn't match the first operands data type %#x " - "for comparison operation \"%s\" (%#x).", - instruction->src[i].reg.data_type, i, src_data_type, + "Data type \"%s\" (%#x) for operand %u doesn't match the first " + "operands data type \"%s\" (%#x) for comparison operation \"%s\" (%#x).", + vsir_data_type_get_name(data_type, ""), data_type, i, + vsir_data_type_get_name(src_data_type, ""), src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } } @@ -10891,19 +11164,21 @@ static void vsir_validate_cast_operation(struct validation_context *ctx, if (!src_types[src_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid source data type %#x for cast operation \"%s\" (%#x).", - src_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid source data type \"%s\" (%#x) for cast operation \"%s\" (%#x).", + vsir_data_type_get_name(src_data_type, ""), src_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); if (!dst_types[dst_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid destination data type %#x for cast operation \"%s\" (%#x).", - dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid destination data type \"%s\" (%#x) for cast operation \"%s\" (%#x).", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } static void vsir_validate_shift_operation(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { - enum vsir_data_type data_type; + enum vsir_data_type dst_data_type, src_data_type; static const bool types[] = { @@ -10912,24 +11187,27 @@ static void vsir_validate_shift_operation(struct validation_context *ctx, [VSIR_DATA_U64] = true, }; - data_type = instruction->dst[0].reg.data_type; - if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) + dst_data_type = instruction->dst[0].reg.data_type; + if ((size_t)dst_data_type >= ARRAY_SIZE(types) || !types[dst_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid destination data type %#x for shift operation \"%s\" (%#x).", - data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid destination data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - if (instruction->src[0].reg.data_type != data_type) + if ((src_data_type = instruction->src[0].reg.data_type) != dst_data_type) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Data type %#x for source operand 0 doesn't match destination data type %#x " + "Data type \"%s\" (%#x) for source operand 0 doesn't match destination data type \"%s\" (%#x) " "for shift operation \"%s\" (%#x).", - instruction->src[0].reg.data_type, data_type, + vsir_data_type_get_name(src_data_type, ""), src_data_type, + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); - data_type = instruction->src[1].reg.data_type; - if ((size_t)data_type >= ARRAY_SIZE(types) || !types[data_type]) + src_data_type = instruction->src[1].reg.data_type; + if ((size_t)src_data_type >= ARRAY_SIZE(types) || !types[src_data_type]) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid source operand 1 data type %#x for shift operation \"%s\" (%#x).", - data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); + "Invalid source operand 1 data type \"%s\" (%#x) for shift operation \"%s\" (%#x).", + vsir_data_type_get_name(src_data_type, ""), src_data_type, + vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode); } static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) @@ -11624,7 +11902,8 @@ static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validat enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid destination data type %#x for operation \"%s\" (%#x) with flags %#x.", dst_data_type, + "Invalid destination data type \"%s\" (%#x) for operation \"%s\" (%#x) with flags %#x.", + vsir_data_type_get_name(dst_data_type, ""), dst_data_type, vsir_opcode_get_name(instruction->opcode, ""), instruction->opcode, instruction->flags); } @@ -11842,14 +12121,12 @@ static const struct vsir_validator_instruction_desc vsir_validator_instructions[ [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, }; -static void vsir_validate_instruction(struct validation_context *ctx) +static void vsir_validate_instruction(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) { const struct vkd3d_shader_version *version = &ctx->program->shader_version; - const struct vkd3d_shader_instruction *instruction; size_t i; - instruction = &ctx->program->instructions.elements[ctx->instruction_idx]; - for (i = 0; i < instruction->dst_count; ++i) vsir_validate_dst_param(ctx, &instruction->dst[i]); @@ -11927,7 +12204,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c { .message_context = message_context, .program = program, - .null_location = {.source_name = source_name}, + .location = {.source_name = source_name}, .status = VKD3D_OK, .phase = VSIR_OP_INVALID, .invalid_instruction_idx = true, @@ -11938,6 +12215,8 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c .inner_tess_idxs[0] = ~0u, .inner_tess_idxs[1] = ~0u, }; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_instruction *ins; unsigned int i; if (!(config_flags & VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION)) @@ -12046,11 +12325,17 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c ctx.invalid_instruction_idx = false; - for (ctx.instruction_idx = 0; ctx.instruction_idx < program->instructions.count - && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; ++ctx.instruction_idx) - vsir_validate_instruction(&ctx); + ctx.instruction_idx = 0; + for (ins = vsir_program_iterator_head(&it); ins && ctx.status != VKD3D_ERROR_OUT_OF_MEMORY; + ins = vsir_program_iterator_next(&it)) + { + ctx.location = ins->location; + vsir_validate_instruction(&ctx, ins); + ++ctx.instruction_idx; + } ctx.invalid_instruction_idx = true; + ctx.location = (struct vkd3d_shader_location){.source_name = source_name}; if (ctx.depth != 0) validator_error(&ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "%zu nested blocks were not closed.", ctx.depth); @@ -12113,14 +12398,9 @@ static void vsir_transform_( enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) { - struct vsir_transformation_context ctx = - { - .result = VKD3D_OK, - .program = program, - .config_flags = config_flags, - .compile_info = compile_info, - .message_context = message_context, - }; + struct vsir_transformation_context ctx; + + vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); /* For vsir_program_ensure_diffuse(). */ if (program->shader_version.major <= 2) @@ -12138,15 +12418,9 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) { - struct vsir_transformation_context ctx = - { - .result = VKD3D_OK, - .program = program, - .config_flags = config_flags, - .compile_info = compile_info, - .message_context = message_context, - }; + struct vsir_transformation_context ctx; + vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); vsir_transform(&ctx, vsir_program_lower_d3dbc_instructions); if (program->shader_version.major == 1 && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL) vsir_transform(&ctx, vsir_program_normalise_ps1_output); @@ -12160,15 +12434,9 @@ enum vkd3d_result vsir_program_lower_d3dbc(struct vsir_program *program, uint64_ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context) { - struct vsir_transformation_context ctx = - { - .result = VKD3D_OK, - .program = program, - .config_flags = config_flags, - .compile_info = compile_info, - .message_context = message_context, - }; + struct vsir_transformation_context ctx; + vsir_transformation_context_init(&ctx, program, config_flags, compile_info, message_context); vsir_transform(&ctx, vsir_program_lower_instructions); if (program->shader_version.major >= 6) diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index c6e048adb20..9150e77e2c6 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -943,8 +943,8 @@ static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct ms static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { + unsigned int resource_id, resource_idx, resource_space, sample_count; const struct msl_resource_type_info *resource_type_info; - unsigned int resource_id, resource_idx, resource_space; const struct vkd3d_shader_descriptor_info1 *descriptor; const struct vkd3d_shader_descriptor_binding *binding; enum vkd3d_shader_resource_type resource_type; @@ -969,6 +969,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct { resource_type = descriptor->resource_type; resource_space = descriptor->register_space; + sample_count = descriptor->sample_count; data_type = descriptor->resource_data_type; } else @@ -977,6 +978,7 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct "Internal compiler error: Undeclared resource descriptor %u.", resource_id); resource_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + sample_count = 1; data_type = VSIR_DATA_F32; } @@ -988,6 +990,16 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, "Texel fetches from resource type %#x are not supported.", resource_type); + if (sample_count == 1) + { + /* Similar to the SPIR-V and GLSL targets, we map multi-sample + * textures with sample count 1 to their single-sample equivalents. */ + if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS) + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + else if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY; + } + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -1030,6 +1042,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct vkd3d_string_buffer_printf(read, ", "); if (ins->opcode != VSIR_OP_LD2DMS) msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32); + else if (sample_count == 1) + /* If the resource isn't a true multisample resource, this is the + * "lod" parameter instead of the "sample" parameter. */ + vkd3d_string_buffer_printf(read, "0"); else msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); } @@ -1294,6 +1310,11 @@ static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_sh data_type = VSIR_DATA_F32; } + if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Storing to resource type %#x is not supported.", resource_type); + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -1414,6 +1435,12 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc static void msl_dcl_indexable_temp(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { const char *type = ins->declaration.indexable_temp.component_count == 4 ? "vkd3d_vec4" : "vkd3d_scalar"; + + if (ins->declaration.indexable_temp.initialiser) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled initialiser for indexable temporary %u.", + ins->declaration.indexable_temp.register_idx); + msl_print_indent(gen->buffer, gen->indent); vkd3d_string_buffer_printf(gen->buffer, "%s x%u[%u];\n", type, ins->declaration.indexable_temp.register_idx, @@ -1516,6 +1543,7 @@ static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d break; case VSIR_OP_GEO: case VSIR_OP_IGE: + case VSIR_OP_UGE: msl_relop(gen, ins, ">="); break; case VSIR_OP_IF: @@ -1995,6 +2023,7 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) static void msl_generate_entrypoint(struct msl_generator *gen) { enum vkd3d_shader_type type = gen->program->shader_version.type; + bool output = true; switch (type) { @@ -2006,13 +2035,21 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, "[[early_fragment_tests]]\n"); vkd3d_string_buffer_printf(gen->buffer, "fragment "); break; + case VKD3D_SHADER_TYPE_COMPUTE: + vkd3d_string_buffer_printf(gen->buffer, "kernel "); + output = false; + break; default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled shader type %#x.", type); return; } - vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out shader_entry(\n", gen->prefix); + if (output) + vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_out ", gen->prefix); + else + vkd3d_string_buffer_printf(gen->buffer, "void "); + vkd3d_string_buffer_printf(gen->buffer, "shader_entry(\n"); if (gen->program->descriptors.descriptor_count) { @@ -2054,7 +2091,9 @@ static void msl_generate_entrypoint(struct msl_generator *gen) msl_generate_entrypoint_epilogue(gen); - vkd3d_string_buffer_printf(gen->buffer, " return output;\n}\n"); + if (output) + vkd3d_string_buffer_printf(gen->buffer, " return output;\n"); + vkd3d_string_buffer_printf(gen->buffer, "}\n"); } static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out) diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l index a8c0db358bc..f9b1d67ac36 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l @@ -20,6 +20,7 @@ %{ +#include "preproc.h" #include "preproc.tab.h" #undef ERROR /* defined in wingdi.h */ @@ -823,7 +824,6 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, static const struct vkd3d_shader_preprocess_info default_preprocess_info = {0}; struct preproc_ctx ctx = {0}; char *source_name = NULL; - void *output_code; unsigned int i; vkd3d_string_buffer_init(&ctx.buffer); @@ -900,16 +900,9 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, return VKD3D_ERROR_INVALID_SHADER; } - if (!(output_code = vkd3d_malloc(ctx.buffer.content_size))) - { - vkd3d_string_buffer_cleanup(&ctx.buffer); - return VKD3D_ERROR_OUT_OF_MEMORY; - } - memcpy(output_code, ctx.buffer.buffer, ctx.buffer.content_size); - out->size = ctx.buffer.content_size; - out->code = output_code; vkd3d_string_buffer_trace(&ctx.buffer); - vkd3d_string_buffer_cleanup(&ctx.buffer); + + vkd3d_shader_code_from_string_buffer(out, &ctx.buffer); return VKD3D_OK; fail: diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 97c0d0e73a8..8bc851f9c5b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -2518,7 +2518,7 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_nclamp(struct vkd3d_spirv_build GLSLstd450NClamp, operands, ARRAY_SIZE(operands)); } -static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, +static uint32_t spirv_get_type_id_for_component_type(struct vkd3d_spirv_builder *builder, enum vkd3d_shader_component_type component_type, unsigned int component_count) { uint32_t scalar_id, type_id; @@ -2553,8 +2553,9 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, case VKD3D_SHADER_COMPONENT_DOUBLE: type_id = vkd3d_spirv_get_op_type_float(builder, 64); break; + case VKD3D_SHADER_COMPONENT_INT64: case VKD3D_SHADER_COMPONENT_UINT64: - type_id = vkd3d_spirv_get_op_type_int(builder, 64, 0); + type_id = vkd3d_spirv_get_op_type_int(builder, 64, component_type == VKD3D_SHADER_COMPONENT_INT64); break; default: FIXME("Unhandled component type %#x.\n", component_type); @@ -2564,7 +2565,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, else { VKD3D_ASSERT(component_type != VKD3D_SHADER_COMPONENT_VOID); - scalar_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + scalar_id = spirv_get_type_id_for_component_type(builder, component_type, 1); type_id = vkd3d_spirv_get_op_type_vector(builder, scalar_id, component_count); } @@ -2573,13 +2574,13 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, return type_id; } -static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, +static uint32_t spirv_get_type_id(struct vkd3d_spirv_builder *builder, enum vsir_data_type data_type, unsigned int component_count) { enum vkd3d_shader_component_type component_type; component_type = vkd3d_component_type_from_data_type(data_type); - return vkd3d_spirv_get_type_id(builder, component_type, component_count); + return spirv_get_type_id_for_component_type(builder, component_type, component_count); } static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, @@ -3656,7 +3657,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, unsigned int i; VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_VEC4_SIZE); - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); switch (component_type) { @@ -3683,7 +3684,7 @@ static uint32_t spirv_compiler_get_constant(struct spirv_compiler *compiler, } else { - scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + scalar_type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); for (i = 0; i < component_count; ++i) component_ids[i] = vkd3d_spirv_get_op_constant(builder, scalar_type_id, values[i]); return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count); @@ -3698,9 +3699,10 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, unsigned int i; VKD3D_ASSERT(0 < component_count && component_count <= VKD3D_DVEC2_SIZE); - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); - if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_UINT64) + if (component_type != VKD3D_SHADER_COMPONENT_DOUBLE && component_type != VKD3D_SHADER_COMPONENT_INT64 + && component_type != VKD3D_SHADER_COMPONENT_UINT64) { FIXME("Unhandled component_type %#x.\n", component_type); return vkd3d_spirv_get_op_undef(builder, type_id); @@ -3712,7 +3714,7 @@ static uint32_t spirv_compiler_get_constant64(struct spirv_compiler *compiler, } else { - scalar_type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + scalar_type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); for (i = 0; i < component_count; ++i) component_ids[i] = vkd3d_spirv_get_op_constant64(builder, scalar_type_id, values[i]); return vkd3d_spirv_get_op_constant_composite(builder, type_id, component_ids, component_count); @@ -3772,9 +3774,7 @@ static uint32_t spirv_compiler_get_type_id_for_reg(struct spirv_compiler *compil { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - return vkd3d_spirv_get_type_id(builder, - vkd3d_component_type_from_data_type(reg->data_type), - vsir_write_mask_component_count(write_mask)); + return spirv_get_type_id(builder, reg->data_type, vsir_write_mask_component_count(write_mask)); } static uint32_t spirv_compiler_get_type_id_for_dst(struct spirv_compiler *compiler, @@ -3901,7 +3901,7 @@ static uint32_t spirv_compiler_emit_array_variable(struct spirv_compiler *compil uint32_t type_id, length_id, ptr_type_id; unsigned int i; - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); for (i = 0; i < length_count; ++i) { if (!array_lengths[i]) @@ -4000,8 +4000,8 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile info = get_spec_constant_info(name); default_value = info ? info->default_value.u : 0; - scalar_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), 1); - vector_type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); + scalar_type_id = spirv_get_type_id(builder, type, 1); + vector_type_id = spirv_get_type_id(builder, type, component_count); for (unsigned int i = 0; i < component_count; ++i) { @@ -4050,7 +4050,7 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi unsigned int index = parameter - compiler->program->parameters; uint32_t type_id, ptr_id, ptr_type_id; - type_id = vkd3d_spirv_get_type_id(builder, vkd3d_component_type_from_data_type(type), component_count); + type_id = spirv_get_type_id(builder, type, component_count); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); ptr_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, compiler->spirv_parameter_info[index].buffer_id, @@ -4114,7 +4114,7 @@ static uint32_t spirv_compiler_emit_construct_vector(struct spirv_compiler *comp VKD3D_ASSERT(val_component_idx < val_component_count); - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); if (val_component_count == 1) { for (i = 0; i < component_count; ++i) @@ -4147,10 +4147,11 @@ static uint32_t spirv_compiler_emit_register_addressing(struct spirv_compiler *c addr_id = spirv_compiler_emit_load_src(compiler, reg_index->rel_addr, VKD3DSP_WRITEMASK_0); if (reg_index->offset) { - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); - addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, - addr_id, spirv_compiler_get_constant_uint(compiler, reg_index->offset)); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); + addr_id = vkd3d_spirv_build_op_iadd(builder, type_id, addr_id, + spirv_compiler_get_constant_uint(compiler, reg_index->offset)); } + return addr_id; } @@ -4296,7 +4297,7 @@ static uint32_t spirv_compiler_get_descriptor_index(struct spirv_compiler *compi struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, ptr_type_id, ptr_id, offset_id, index_ids[2]; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); if (!(offset_id = compiler->descriptor_offset_ids[push_constant_index])) { index_ids[0] = compiler->descriptor_offsets_member_id; @@ -4369,7 +4370,7 @@ static void spirv_compiler_emit_dereference_register(struct spirv_compiler *comp if (index_count) { component_count = vsir_write_mask_component_count(register_info->write_mask); - type_id = vkd3d_spirv_get_type_id(builder, register_info->component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, register_info->component_type, component_count); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, register_info->storage_class, type_id); register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id, register_info->id, indexes, index_count); @@ -4428,7 +4429,7 @@ static uint32_t spirv_compiler_emit_swizzle(struct spirv_compiler *compiler, && (component_count == 1 || vkd3d_swizzle_is_equal(val_write_mask, swizzle, write_mask))) return val_id; - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); if (component_count == 1) { @@ -4479,7 +4480,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil components[i] = VKD3D_VEC4_SIZE + vsir_swizzle_get_component(swizzle, i); } - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); return vkd3d_spirv_build_op_vector_shuffle(builder, type_id, vector1_id, vector2_id, components, component_count); } @@ -4494,10 +4495,11 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, VKD3D_ASSERT(!(condition & ~(VKD3D_SHADER_CONDITIONAL_OP_NZ | VKD3D_SHADER_CONDITIONAL_OP_Z))); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_BOOL, component_count); op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; + return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, - data_type == VSIR_DATA_U64 + data_type_is_64_bit(data_type) ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); } @@ -4510,7 +4512,8 @@ static uint32_t spirv_compiler_emit_bool_to_int(struct spirv_compiler *compiler, true_id = spirv_compiler_get_constant_uint_vector(compiler, signedness ? 0xffffffff : 1, component_count); false_id = spirv_compiler_get_constant_uint_vector(compiler, 0, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_U32, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } @@ -4523,7 +4526,8 @@ static uint32_t spirv_compiler_emit_bool_to_int64(struct spirv_compiler *compile true_id = spirv_compiler_get_constant_uint64_vector(compiler, signedness ? UINT64_MAX : 1, component_count); false_id = spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT64, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_U64, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } @@ -4535,7 +4539,8 @@ static uint32_t spirv_compiler_emit_bool_to_float(struct spirv_compiler *compile true_id = spirv_compiler_get_constant_float_vector(compiler, signedness ? -1.0f : 1.0f, component_count); false_id = spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_F32, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } @@ -4547,7 +4552,8 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil true_id = spirv_compiler_get_constant_double_vector(compiler, signedness ? -1.0 : 1.0, component_count); false_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_DOUBLE, component_count); + type_id = spirv_get_type_id(builder, VSIR_DATA_F64, component_count); + return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); } @@ -4614,7 +4620,8 @@ static uint32_t spirv_compiler_emit_load_undef(struct spirv_compiler *compiler, VKD3D_ASSERT(reg->type == VKD3DSPR_UNDEF); - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, reg->data_type, component_count); + type_id = spirv_get_type_id(builder, reg->data_type, component_count); + return vkd3d_spirv_get_op_undef(builder, type_id); } @@ -4646,7 +4653,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, component_idx, reg->type, reg->idx[0].offset, reg_info->write_mask); } - type_id = vkd3d_spirv_get_type_id(builder, reg_info->component_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, reg_info->component_type, 1); reg_id = reg_info->id; if (reg_component_count != 1) { @@ -4663,7 +4670,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, { if (reg_info->component_type != VKD3D_SHADER_COMPONENT_UINT) { - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } val_id = spirv_compiler_emit_int_to_bool(compiler, @@ -4671,7 +4678,7 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, } else { - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } } @@ -4691,7 +4698,7 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil component_type = vkd3d_component_type_from_data_type(icb->data_type); component_count = icb->component_count; - elem_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, icb->data_type, component_count); + elem_type_id = spirv_get_type_id(builder, icb->data_type, component_count); length_id = spirv_compiler_get_constant_uint(compiler, element_count); type_id = vkd3d_spirv_get_op_type_array(builder, elem_type_id, length_id); @@ -4722,6 +4729,7 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil &icb->data[component_count * i]); break; case VSIR_DATA_F64: + case VSIR_DATA_I64: case VSIR_DATA_U64: { uint64_t *data = (uint64_t *)icb->data; @@ -4777,7 +4785,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, if (!spirv_compiler_get_register_info(compiler, reg, ®_info)) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); return vkd3d_spirv_get_op_undef(builder, type_id); } spirv_compiler_emit_dereference_register(compiler, reg, ®_info); @@ -4796,7 +4804,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, } else { - type_id = vkd3d_spirv_get_type_id(builder, + type_id = spirv_get_type_id_for_component_type(builder, reg_info.component_type, vsir_write_mask_component_count(reg_info.write_mask)); val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone); swizzle = data_type_is_64_bit(reg->data_type) ? vsir_swizzle_32_from_64(swizzle) : swizzle; @@ -4811,7 +4819,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, { if (reg_info.component_type != VKD3D_SHADER_COMPONENT_UINT) { - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, component_count); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } val_id = spirv_compiler_emit_int_to_bool(compiler, @@ -4819,7 +4827,7 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, } else { - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } } @@ -4923,7 +4931,7 @@ static void spirv_compiler_emit_store_scalar(struct spirv_compiler *compiler, if (vsir_write_mask_component_count(dst_write_mask) > 1) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); component_idx = vsir_write_mask_get_component_idx(write_mask); component_idx -= vsir_write_mask_get_component_idx(dst_write_mask); @@ -4951,7 +4959,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, if (dst_component_count == 1 && component_count != 1) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); val_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, vsir_write_mask_get_component_idx(dst_write_mask)); write_mask &= dst_write_mask; @@ -4966,7 +4974,7 @@ static void spirv_compiler_emit_store(struct spirv_compiler *compiler, if (dst_component_count != component_count) { - type_id = vkd3d_spirv_get_type_id(builder, component_type, dst_component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, dst_component_count); dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); VKD3D_ASSERT(component_count <= ARRAY_SIZE(components)); @@ -5018,7 +5026,7 @@ static void spirv_compiler_emit_store_reg(struct spirv_compiler *compiler, if (component_type == VKD3D_SHADER_COMPONENT_BOOL) val_id = spirv_compiler_emit_bool_to_int(compiler, vsir_write_mask_component_count(src_write_mask), val_id, false); - type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, + type_id = spirv_get_type_id_for_component_type(builder, reg_info.component_type, vsir_write_mask_component_count(src_write_mask)); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); component_type = reg_info.component_type; @@ -5101,7 +5109,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, dst_type_id, val_id; - type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, component_count); if (component_count > 1) { val_id = vkd3d_spirv_build_op_composite_construct(builder, @@ -5112,7 +5120,7 @@ static void spirv_compiler_emit_store_dst_components(struct spirv_compiler *comp val_id = *component_ids; } - dst_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); + dst_type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); if (dst_type_id != type_id) val_id = vkd3d_spirv_build_op_bitcast(builder, dst_type_id, val_id); @@ -5281,9 +5289,8 @@ static uint32_t spirv_compiler_emit_draw_parameter_fixup(struct spirv_compiler * vkd3d_spirv_add_iface_variable(builder, base_var_id); spirv_compiler_decorate_builtin(compiler, base_var_id, base); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); - base_id = vkd3d_spirv_build_op_load(builder, - type_id, base_var_id, SpvMemoryAccessMaskNone); + type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); + base_id = vkd3d_spirv_build_op_load(builder, type_id, base_var_id, SpvMemoryAccessMaskNone); return vkd3d_spirv_build_op_isub(builder, type_id, index_id, base_id); } @@ -5311,17 +5318,16 @@ static uint32_t sv_front_face_fixup(struct spirv_compiler *compiler, } /* frag_coord.w = 1.0f / frag_coord.w */ -static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, - uint32_t frag_coord_id) +static uint32_t frag_coord_fixup(struct spirv_compiler *compiler, uint32_t frag_coord_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, w_id; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 1); w_id = vkd3d_spirv_build_op_composite_extract1(builder, type_id, frag_coord_id, 3); - w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, - spirv_compiler_get_constant_float(compiler, 1.0f), w_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); + w_id = vkd3d_spirv_build_op_fdiv(builder, type_id, spirv_compiler_get_constant_float(compiler, 1.0f), w_id); + type_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); + return vkd3d_spirv_build_op_composite_insert1(builder, type_id, w_id, frag_coord_id, 3); } @@ -5527,7 +5533,8 @@ static uint32_t spirv_compiler_emit_load_invocation_id(struct spirv_compiler *co uint32_t type_id, id; id = spirv_compiler_get_invocation_id(compiler); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_INT, 1); + type_id = spirv_get_type_id(builder, VSIR_DATA_I32, 1); + return vkd3d_spirv_build_op_load(builder, type_id, id, SpvMemoryAccessMaskNone); } @@ -5867,7 +5874,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, vsir_register_init(&dst_reg, reg_type, VSIR_DATA_F32, 1); dst_reg.idx[0].offset = element_idx; - type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count); + type_id = spirv_get_type_id_for_component_type(builder, component_type, input_component_count); val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone); @@ -5876,7 +5883,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, if (component_type != VKD3D_SHADER_COMPONENT_FLOAT) { - float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, input_component_count); + float_type_id = spirv_get_type_id_for_component_type(builder, + VKD3D_SHADER_COMPONENT_FLOAT, input_component_count); val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id); } @@ -6225,7 +6233,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi if (output_info->component_type != VKD3D_SHADER_COMPONENT_FLOAT) { - type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); } @@ -6250,7 +6258,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi output_id = output_info->id; if (output_index_id) { - type_id = vkd3d_spirv_get_type_id(builder, + type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, vsir_write_mask_component_count(dst_write_mask)); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); output_id = vkd3d_spirv_build_op_access_chain1(builder, ptr_type_id, output_id, output_index_id); @@ -6263,7 +6271,7 @@ static void spirv_compiler_emit_store_shader_output(struct spirv_compiler *compi return; } - type_id = vkd3d_spirv_get_type_id(builder, output_info->component_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, output_info->component_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassOutput, type_id); mask = output_info->array_element_mask; array_idx = spirv_compiler_get_output_array_index(compiler, output); @@ -6305,7 +6313,7 @@ static void spirv_compiler_emit_shader_epilogue_function(struct spirv_compiler * function_id = compiler->epilogue_function_id; void_id = vkd3d_spirv_get_op_type_void(builder); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 4); + type_id = spirv_get_type_id(builder, VSIR_DATA_F32, 4); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassPrivate, type_id); for (i = 0, count = 0; i < ARRAY_SIZE(compiler->private_output_variable); ++i) { @@ -6536,7 +6544,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil vkd3d_spirv_begin_function_stream_insertion(builder, function_location); component_type = vkd3d_component_type_from_data_type(temp->data_type); - type_id = vkd3d_spirv_get_type_id(builder, component_type, temp->component_count); + type_id = spirv_get_type_id(builder, temp->data_type, temp->component_count); length_id = spirv_compiler_get_constant_uint(compiler, temp->register_size); type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, storage_class, type_id); @@ -6577,7 +6585,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com if (!(member_ids = vkd3d_calloc(count, sizeof(*member_ids)))) return; - vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); + vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); for (i = 0, j = 0; i < compiler->shader_interface.push_constant_buffer_count; ++i) { @@ -6594,7 +6602,7 @@ static void spirv_compiler_emit_push_constant_buffers(struct spirv_compiler *com if (compiler->offset_info.descriptor_table_count) { - uint32_t type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + uint32_t type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); length_id = spirv_compiler_get_constant_uint(compiler, compiler->offset_info.descriptor_table_count); member_ids[j] = vkd3d_spirv_build_op_type_array(builder, type_id, length_id); vkd3d_spirv_build_op_decorate1(builder, member_ids[j], SpvDecorationArrayStride, 4); @@ -6788,7 +6796,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, return; } - vec4_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); + vec4_id = spirv_get_type_id(builder, VSIR_DATA_F32, VKD3D_VEC4_SIZE); length_id = spirv_compiler_get_constant_uint(compiler, size); array_type_id = vkd3d_spirv_build_op_type_array(builder, vec4_id, length_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 16); @@ -6927,7 +6935,7 @@ static uint32_t spirv_compiler_get_image_type_id(struct spirv_compiler *compiler vkd3d_spirv_enable_capability(builder, SpvCapabilityStorageImageReadWithoutFormat); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, data_type, 1); + sampled_type_id = spirv_get_type_id_for_component_type(builder, data_type, 1); return vkd3d_spirv_get_op_type_image(builder, sampled_type_id, resource_type_info->dim, 2, resource_type_info->arrayed, resource_type_info->ms, reg->type == VKD3DSPR_UAV ? 2 : 1, format); @@ -7053,7 +7061,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp { uint32_t array_type_id, struct_id; - type_id = vkd3d_spirv_get_type_id(builder, sampled_type, 1); + type_id = spirv_get_type_id(builder, descriptor->resource_data_type, 1); array_type_id = vkd3d_spirv_get_op_type_runtime_array(builder, type_id); vkd3d_spirv_build_op_decorate1(builder, array_type_id, SpvDecorationArrayStride, 4); @@ -7094,7 +7102,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp { VKD3D_ASSERT(structure_stride); /* counters are valid only for structured buffers */ - counter_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + counter_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); if (spirv_compiler_is_opengl_target(compiler)) { vkd3d_spirv_enable_capability(builder, SpvCapabilityAtomicStorage); @@ -7158,7 +7166,7 @@ static void spirv_compiler_emit_workgroup_memory(struct spirv_compiler *compiler if (alignment) TRACE("Ignoring alignment %u.\n", alignment); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); length_id = spirv_compiler_get_constant_uint(compiler, size); array_type_id = vkd3d_spirv_get_op_type_array(builder, type_id, length_id); @@ -7209,10 +7217,9 @@ static void spirv_compiler_emit_output_vertex_count(struct spirv_compiler *compi SpvExecutionModeOutputVertices, instruction->declaration.count); } -static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) +static void spirv_compiler_emit_input_primitive(struct spirv_compiler *compiler) { - enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; + enum vkd3d_primitive_type primitive_type = compiler->program->input_primitive; SpvExecutionMode mode; switch (primitive_type) @@ -7233,7 +7240,8 @@ static void spirv_compiler_emit_dcl_input_primitive(struct spirv_compiler *compi mode = SpvExecutionModeInputTrianglesAdjacency; break; default: - FIXME("Unhandled primitive type %#x.\n", primitive_type); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled input primitive type %#x.", primitive_type); return; } @@ -7263,10 +7271,9 @@ static void spirv_compiler_emit_point_size(struct spirv_compiler *compiler) } } -static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) +static void spirv_compiler_emit_output_topology(struct spirv_compiler *compiler) { - enum vkd3d_primitive_type primitive_type = instruction->declaration.primitive_type.type; + enum vkd3d_primitive_type primitive_type = compiler->program->output_topology; SpvExecutionMode mode; switch (primitive_type) @@ -7282,7 +7289,8 @@ static void spirv_compiler_emit_dcl_output_topology(struct spirv_compiler *compi mode = SpvExecutionModeOutputTriangleStrip; break; default: - ERR("Unexpected primitive type %#x.\n", primitive_type); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled output topology %#x.", primitive_type); return; } @@ -7624,11 +7632,12 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, /* ITOD is not supported. Frontends which emit bool casts must use ITOF for double. */ val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); } - else if (dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) + else if (dst->reg.data_type == VSIR_DATA_I16 || dst->reg.data_type == VSIR_DATA_I32 + || dst->reg.data_type == VSIR_DATA_U16 || dst->reg.data_type == VSIR_DATA_U32) { val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); } - else if (dst->reg.data_type == VSIR_DATA_U64) + else if (dst->reg.data_type == VSIR_DATA_I64 || dst->reg.data_type == VSIR_DATA_U64) { val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); } @@ -7724,7 +7733,7 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src_ids[1]); - if (dst[0].reg.data_type == VSIR_DATA_U64) + if (data_type_is_64_bit(dst[0].reg.data_type)) uint_max_id = spirv_compiler_get_constant_uint64_vector(compiler, UINT64_MAX, component_count); else uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); @@ -7839,7 +7848,7 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp unsigned int i, component_count; enum GLSLstd450 glsl_inst; - if (src[0].reg.data_type == VSIR_DATA_U64 && (instruction->opcode == VSIR_OP_FIRSTBIT_HI + if (data_type_is_64_bit(src[0].reg.data_type) && (instruction->opcode == VSIR_OP_FIRSTBIT_HI || instruction->opcode == VSIR_OP_FIRSTBIT_LO || instruction->opcode == VSIR_OP_FIRSTBIT_SHI)) { /* At least some drivers support this anyway, but if validation is enabled it will fail. */ @@ -7878,7 +7887,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp component_count = vsir_write_mask_component_count(dst->write_mask); uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT32_MAX, component_count); condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpIEqual, - vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), val_id, uint_max_id); + spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), + val_id, uint_max_id); rev_val_id = vkd3d_spirv_build_op_isub(builder, type_id, spirv_compiler_get_constant_uint_vector(compiler, 31, component_count), val_id); val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, rev_val_id); @@ -7928,7 +7938,7 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); src_id = spirv_compiler_get_register_id(compiler, &src->reg); - type_id = vkd3d_spirv_get_type_id(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, dst_reg_info.component_type, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone); dst_val_id = vkd3d_spirv_build_op_load(builder, type_id, dst_id, SpvMemoryAccessMaskNone); @@ -7957,7 +7967,7 @@ general_implementation: val_id = spirv_compiler_emit_load_src(compiler, src, write_mask); if (dst->reg.data_type != src->reg.data_type) { - val_id = vkd3d_spirv_build_op_bitcast(builder, vkd3d_spirv_get_type_id_for_data_type(builder, + val_id = vkd3d_spirv_build_op_bitcast(builder, spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)), val_id); } spirv_compiler_emit_store_dst(compiler, dst, val_id); @@ -7983,8 +7993,8 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, { if (instruction->opcode == VSIR_OP_CMP) condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, - vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), condition_id, - spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); + spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count), + condition_id, spirv_compiler_get_constant_float_vector(compiler, 0.0f, component_count)); else condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); @@ -8010,7 +8020,7 @@ static void spirv_compiler_emit_swapc(struct spirv_compiler *compiler, src2_id = spirv_compiler_emit_load_src(compiler, &src[2], dst->write_mask); component_count = vsir_write_mask_component_count(dst->write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, component_count, condition_id); @@ -8046,7 +8056,7 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, for (i = 0; i < ARRAY_SIZE(src_ids); ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], write_mask); - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpDot, type_id, src_ids[0], src_ids[1]); @@ -8092,7 +8102,7 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, unsigned int i, component_count; component_count = vsir_write_mask_component_count(dst->write_mask); - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, component_count); + type_id = spirv_get_type_id(builder, dst->reg.data_type, component_count); for (i = 0; i < ARRAY_SIZE(src_ids); ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask); @@ -8146,7 +8156,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); int_max_id = spirv_compiler_get_constant_vector(compiler, component_type, component_count, INT_MAX); - condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); @@ -8199,7 +8209,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_glsl_std450_max(builder, src_type_id, src_id, zero_id); uint_max_id = spirv_compiler_get_constant_uint_vector(compiler, UINT_MAX, component_count); - condition_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + condition_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); condition_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, SpvOpFOrdGreaterThanEqual, condition_type_id, val_id, float_max_id); @@ -8224,7 +8234,7 @@ static void spirv_compiler_emit_dtof(struct spirv_compiler *compiler, src_id = spirv_compiler_emit_load_src(compiler, src, write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, component_count); val_id = vkd3d_spirv_build_op_tr1(builder, &builder->function_stream, SpvOpFConvert, type_id, src_id); if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); @@ -8248,8 +8258,8 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp VKD3D_ASSERT(2 <= src_count && src_count <= ARRAY_SIZE(src_ids)); component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20; + type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); + size = data_type_is_64_bit(src[src_count - 1].reg.data_type) ? 0x40 : 0x20; mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); size_id = spirv_compiler_get_constant_uint(compiler, size); @@ -8305,8 +8315,8 @@ static void spirv_compiler_emit_f16tof32(struct spirv_compiler *compiler, unsigned int i, j; instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); - scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); + scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 1); /* FIXME: Consider a single UnpackHalf2x16 instruction per 2 components. */ VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); @@ -8338,8 +8348,8 @@ static void spirv_compiler_emit_f32tof16(struct spirv_compiler *compiler, unsigned int i, j; instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); - scalar_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); + scalar_type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); zero_id = spirv_compiler_get_constant_float(compiler, 0.0f); /* FIXME: Consider a single PackHalf2x16 instruction per 2 components. */ @@ -8418,7 +8428,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co src0_id = spirv_compiler_emit_load_src(compiler, &src[0], write_mask); src1_id = spirv_compiler_emit_load_src(compiler, &src[1], write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); @@ -8470,7 +8480,7 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst->write_mask); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id); result_id = spirv_compiler_emit_bool_to_float(compiler, component_count, result_id, false); @@ -8999,7 +9009,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); if (image.resource_type_info->resource_type != VKD3D_SHADER_RESOURCE_BUFFER && !multisample) @@ -9045,7 +9055,7 @@ static void spirv_compiler_emit_lod(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &resource->reg, &sampler->reg, VKD3D_IMAGE_FLAG_SAMPLED); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); val_id = vkd3d_spirv_build_op_image_query_lod(builder, type_id, image.sampled_image_id, coordinate_id); @@ -9115,7 +9125,7 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, instruction, image.resource_type_info); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); + sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); VKD3D_ASSERT(image_operand_count <= ARRAY_SIZE(image_operands)); val_id = vkd3d_spirv_build_op_image_sample(builder, op, sampled_type_id, @@ -9160,7 +9170,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, instruction, image.resource_type_info); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); + sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, 1); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_ALL); dref_id = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_image_sample_dref(builder, op, sampled_type_id, @@ -9219,7 +9229,7 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, instruction, image.resource_type_info); } - sampled_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); + sampled_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; coordinate_id = spirv_compiler_emit_load_src(compiler, addr, coordinate_mask); if (image_flags & VKD3D_IMAGE_FLAG_DEPTH) @@ -9301,10 +9311,10 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler if (storage_buffer_uav) { - texel_type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); + texel_type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, texel_type_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9336,11 +9346,11 @@ static void spirv_compiler_emit_ld_raw_structured_srv_uav(struct spirv_compiler spirv_compiler_prepare_image(compiler, &image, &resource->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); - texel_type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); + texel_type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); VKD3D_ASSERT(dst->write_mask & VKD3DSP_WRITEMASK_ALL); for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { @@ -9379,7 +9389,7 @@ static void spirv_compiler_emit_ld_tgsm(struct spirv_compiler *compiler, if (!spirv_compiler_get_register_info(compiler, &resource->reg, ®_info)) return; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9438,10 +9448,10 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { - type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, resource_symbol->info.resource.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9469,7 +9479,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * } else { - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); spirv_compiler_prepare_image(compiler, &image, &dst->reg, NULL, VKD3D_IMAGE_FLAG_NONE); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9512,7 +9522,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, if (!spirv_compiler_get_register_info(compiler, &dst->reg, ®_info)) return; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id); base_coordinate_id = spirv_compiler_emit_raw_structured_addressing(compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0); @@ -9570,7 +9580,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { - type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); indices[0] = spirv_compiler_get_constant_uint(compiler, 0); @@ -9585,7 +9595,7 @@ static void spirv_compiler_emit_ld_uav_typed(struct spirv_compiler *compiler, else { spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, VKD3D_VEC4_SIZE); coordinate_mask = (1u << image.resource_type_info->coordinate_component_count) - 1; coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], coordinate_mask); @@ -9613,7 +9623,7 @@ static void spirv_compiler_emit_store_uav_typed(struct spirv_compiler *compiler, if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { - type_id = vkd3d_spirv_get_type_id(builder, resource_symbol->info.resource.sampled_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, resource_symbol->info.resource.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); coordinate_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); indices[0] = spirv_compiler_get_constant_uint(compiler, 0); @@ -9658,7 +9668,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c counter_id = resource_symbol->info.resource.uav_counter_id; VKD3D_ASSERT(counter_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); if (resource_symbol->info.resource.uav_counter_array) { @@ -9820,7 +9830,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil } } - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); if (structure_stride || raw) { VKD3D_ASSERT(!raw != !structure_stride); @@ -9845,7 +9855,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil if (spirv_compiler_use_storage_buffer(compiler, &resource_symbol->info.resource)) { component_type = resource_symbol->info.resource.sampled_type; - type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, component_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassUniform, type_id); operands[0] = spirv_compiler_get_constant_uint(compiler, 0); operands[1] = coordinate_id; @@ -9854,7 +9864,7 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil else { component_type = image.sampled_type; - type_id = vkd3d_spirv_get_type_id(builder, image.sampled_type, 1); + type_id = spirv_get_type_id_for_component_type(builder, image.sampled_type, 1); ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassImage, type_id); sample_id = spirv_compiler_get_constant_uint(compiler, 0); pointer_id = vkd3d_spirv_build_op_image_texel_pointer(builder, @@ -9907,7 +9917,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, { resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_array_length(builder, type_id, resource_symbol->id, 0); write_mask = VKD3DSP_WRITEMASK_0; } @@ -9917,7 +9927,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_image_query_size(builder, type_id, image.image_id); write_mask = VKD3DSP_WRITEMASK_0; } @@ -9927,7 +9937,7 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, stride_id = spirv_compiler_get_constant_uint(compiler, image.structure_stride); constituents[0] = vkd3d_spirv_build_op_udiv(builder, type_id, val_id, stride_id); constituents[1] = stride_id; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, ARRAY_SIZE(constituents)); val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, ARRAY_SIZE(constituents)); write_mask |= VKD3DSP_WRITEMASK_1; @@ -9966,14 +9976,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, size_component_count = image.resource_type_info->coordinate_component_count; if (image.resource_type_info->dim == SpvDimCube) --size_component_count; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, size_component_count); supports_mipmaps = src[1].reg.type != VKD3DSPR_UAV && !image.resource_type_info->ms; if (supports_mipmaps) { lod_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_image_query_size_lod(builder, type_id, image.image_id, lod_id); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); miplevel_count_id = vkd3d_spirv_build_op_image_query_levels(builder, type_id, image.image_id); } else @@ -9987,14 +9997,14 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, for (i = 0; i < 3 - size_component_count; ++i) constituents[i + 1] = spirv_compiler_get_constant_uint(compiler, 0); constituents[i + 1] = miplevel_count_id; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, i + 2); if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) { component_type = VKD3D_SHADER_COMPONENT_FLOAT; - type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); @@ -10022,7 +10032,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery); spirv_compiler_prepare_image(compiler, &image, &src->reg, NULL, VKD3D_IMAGE_FLAG_NONE); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_image_query_samples(builder, type_id, image.image_id); } @@ -10049,13 +10059,13 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, constituents[0] = val_id; for (i = 1; i < VKD3D_VEC4_SIZE; ++i) constituents[i] = spirv_compiler_get_constant_uint(compiler, 0); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE); if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) { component_type = VKD3D_SHADER_COMPONENT_FLOAT; - type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, component_type, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_convert_utof(builder, type_id, val_id); if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0); @@ -10121,13 +10131,13 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, sample_count_id = spirv_compiler_emit_query_sample_count(compiler, &instruction->src[0]); sample_index_id = spirv_compiler_emit_load_src(compiler, &instruction->src[1], VKD3DSP_WRITEMASK_0); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); index_id = vkd3d_spirv_build_op_iadd(builder, type_id, sample_count_id, sample_index_id); index_id = vkd3d_spirv_build_op_isub(builder, type_id, index_id, spirv_compiler_get_constant_uint(compiler, 1)); /* Validate sample index. */ - bool_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); + bool_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_BOOL, 1); id = vkd3d_spirv_build_op_logical_and(builder, bool_id, vkd3d_spirv_build_op_uless_than(builder, bool_id, sample_index_id, sample_count_id), vkd3d_spirv_build_op_uless_than_equal(builder, @@ -10135,7 +10145,7 @@ static void spirv_compiler_emit_sample_position(struct spirv_compiler *compiler, index_id = vkd3d_spirv_build_op_select(builder, type_id, id, index_id, spirv_compiler_get_constant_uint(compiler, 0)); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, 2); if (!(id = compiler->sample_positions_id)) { length_id = spirv_compiler_get_constant_uint(compiler, ARRAY_SIZE(standard_sample_positions)); @@ -10199,7 +10209,7 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler, src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); } - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_FLOAT, vsir_write_mask_component_count(register_info.write_mask)); instr_set_id = vkd3d_spirv_get_glsl_std450_instr_set(builder); @@ -10334,9 +10344,8 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler const struct vkd3d_shader_src_param *src = instruction->src; uint32_t type_id, direction_type_id, direction_id, val_id; - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); - direction_type_id = vkd3d_spirv_get_type_id_for_data_type(builder, VSIR_DATA_U32, 1); + type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); + direction_type_id = spirv_get_type_id(builder, VSIR_DATA_U32, 1); val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); direction_id = map_quad_read_across_direction(instruction->opcode); direction_id = vkd3d_spirv_get_op_constant(builder, direction_type_id, direction_id); @@ -10355,14 +10364,12 @@ static void spirv_compiler_emit_quad_read_lane_at(struct spirv_compiler *compile if (!register_is_constant_or_undef(&src[1].reg)) { - FIXME("Unsupported non-constant quad read lane index.\n"); spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Non-constant quad read lane indices are not supported."); return; } - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); + type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_group_nonuniform_quad_broadcast(builder, type_id, val_id, lane_id); @@ -10411,7 +10418,7 @@ static uint32_t spirv_compiler_emit_group_nonuniform_ballot(struct spirv_compile struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, val_id; - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); val_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); val_id = vkd3d_spirv_build_op_group_nonuniform_ballot(builder, type_id, val_id); @@ -10470,8 +10477,7 @@ static void spirv_compiler_emit_wave_alu_op(struct spirv_compiler *compiler, op = map_wave_alu_op(instruction->opcode, data_type_is_floating_point(src->reg.data_type)); - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); + type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); vkd3d_spirv_enable_capability(builder, SpvCapabilityGroupNonUniformArithmetic); @@ -10495,7 +10501,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, : SpvGroupOperationReduce; val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, 1); + type_id = spirv_get_type_id_for_component_type(builder, VKD3D_SHADER_COMPONENT_UINT, 1); val_id = vkd3d_spirv_build_op_group_nonuniform_ballot_bit_count(builder, type_id, group_op, val_id); spirv_compiler_emit_store_dst(compiler, dst, val_id); @@ -10520,8 +10526,7 @@ static void spirv_compiler_emit_wave_read_lane_at(struct spirv_compiler *compile const struct vkd3d_shader_src_param *src = instruction->src; uint32_t type_id, lane_id, val_id; - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); + type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, &src[0], dst->write_mask); lane_id = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); @@ -10548,8 +10553,7 @@ static void spirv_compiler_emit_wave_read_lane_first(struct spirv_compiler *comp const struct vkd3d_shader_src_param *src = instruction->src; uint32_t type_id, val_id; - type_id = vkd3d_spirv_get_type_id_for_data_type(builder, dst->reg.data_type, - vsir_write_mask_component_count(dst->write_mask)); + type_id = spirv_get_type_id(builder, dst->reg.data_type, vsir_write_mask_component_count(dst->write_mask)); val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); val_id = vkd3d_spirv_build_op_group_nonuniform_broadcast_first(builder, type_id, val_id); @@ -10608,12 +10612,6 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, case VSIR_OP_DCL_VERTICES_OUT: spirv_compiler_emit_output_vertex_count(compiler, instruction); break; - case VSIR_OP_DCL_INPUT_PRIMITIVE: - spirv_compiler_emit_dcl_input_primitive(compiler, instruction); - break; - case VSIR_OP_DCL_OUTPUT_TOPOLOGY: - spirv_compiler_emit_dcl_output_topology(compiler, instruction); - break; case VSIR_OP_DCL_GS_INSTANCES: spirv_compiler_emit_dcl_gs_instances(compiler, instruction); break; @@ -11066,7 +11064,14 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (program->ssa_count) spirv_compiler_allocate_ssa_register_ids(compiler, program->ssa_count); if (compiler->shader_type == VKD3D_SHADER_TYPE_COMPUTE) + { spirv_compiler_emit_thread_group_size(compiler, &program->thread_group_size); + } + else if (compiler->shader_type == VKD3D_SHADER_TYPE_GEOMETRY) + { + spirv_compiler_emit_input_primitive(compiler); + spirv_compiler_emit_output_topology(compiler); + } spirv_compiler_emit_global_flags(compiler, program->global_flags); spirv_compiler_emit_descriptor_declarations(compiler); @@ -11080,7 +11085,7 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, { uint32_t type_id, struct_id, ptr_type_id, var_id; - type_id = vkd3d_spirv_get_type_id(builder, + type_id = spirv_get_type_id_for_component_type(builder, vkd3d_component_type_from_data_type(parameter_data_type_map[parameter->data_type].type), parameter_data_type_map[parameter->data_type].component_count); diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index ea15c1a9ad5..ec1d8b91e09 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -665,6 +665,8 @@ struct vkd3d_shader_sm4_parser { const uint32_t *start, *end, *ptr; + struct vsir_program *program; + enum vkd3d_shader_opcode phase; bool has_control_point_phase; unsigned int input_register_masks[MAX_REG_OUTPUT]; @@ -764,7 +766,7 @@ static const enum vsir_data_type data_type_table[] = static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) { - const struct vkd3d_shader_version *version = &sm4->p.program->shader_version; + const struct vkd3d_shader_version *version = &sm4->program->shader_version; return version->major >= 5 && version->minor >= 1; } @@ -849,7 +851,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui icb->element_count = icb_size / VKD3D_VEC4_SIZE; icb->is_null = false; memcpy(icb->data, tokens, sizeof(*tokens) * icb_size); - shader_instruction_array_add_icb(&priv->p.program->instructions, icb); + shader_instruction_array_add_icb(&priv->program->instructions, icb); ins->declaration.icb = icb; } @@ -971,7 +973,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { struct vkd3d_shader_index_range *index_range = &ins->declaration.index_range; - struct vsir_program *program = priv->p.program; + struct vsir_program *program = priv->program; unsigned int i, register_idx, register_count; const struct shader_signature *signature; enum vkd3d_shader_register_type type; @@ -1094,14 +1096,14 @@ static void shader_sm4_read_dcl_output_topology(struct vkd3d_shader_instruction if (ins->declaration.primitive_type.type == VKD3D_PT_UNDEFINED) FIXME("Unhandled output primitive type %#x.\n", primitive_type); - priv->p.program->output_topology = ins->declaration.primitive_type.type; + priv->program->output_topology = ins->declaration.primitive_type.type; } static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) { enum vkd3d_sm4_input_primitive_type primitive_type; - struct vsir_program *program = sm4->p.program; + struct vsir_program *program = sm4->program; primitive_type = (opcode_token & VKD3D_SM4_PRIMITIVE_TYPE_MASK) >> VKD3D_SM4_PRIMITIVE_TYPE_SHIFT; if (VKD3D_SM5_INPUT_PT_PATCH1 <= primitive_type && primitive_type <= VKD3D_SM5_INPUT_PT_PATCH32) @@ -1129,7 +1131,7 @@ static void shader_sm4_read_dcl_input_primitive(struct vkd3d_shader_instruction static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) { - struct vsir_program *program = sm4->p.program; + struct vsir_program *program = sm4->program; ins->declaration.count = *tokens; if (opcode == VKD3D_SM4_OP_DCL_TEMPS) @@ -1161,7 +1163,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) { struct signature_element *e = vsir_signature_find_element_for_reg( - &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); if (!e) { @@ -1187,7 +1189,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, dst)) { struct signature_element *e = vsir_signature_find_element_for_reg( - &priv->p.program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); + &priv->program->input_signature, dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); if (!e) { @@ -1220,7 +1222,7 @@ static void shader_sm4_read_dcl_global_flags(struct vkd3d_shader_instruction *in uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) { ins->declaration.global_flags = (opcode_token & VKD3D_SM4_GLOBAL_FLAGS_MASK) >> VKD3D_SM4_GLOBAL_FLAGS_SHIFT; - sm4->p.program->global_flags = ins->declaration.global_flags; + sm4->program->global_flags = ins->declaration.global_flags; } static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, @@ -1256,7 +1258,7 @@ static void shader_sm5_read_dcl_interface(struct vkd3d_shader_instruction *ins, static void shader_sm5_read_control_point_count(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) { - struct vsir_program *program = sm4->p.program; + struct vsir_program *program = sm4->program; ins->declaration.count = (opcode_token & VKD3D_SM5_CONTROL_POINT_COUNT_MASK) >> VKD3D_SM5_CONTROL_POINT_COUNT_SHIFT; @@ -1272,7 +1274,7 @@ static void shader_sm5_read_dcl_tessellator_domain(struct vkd3d_shader_instructi { ins->declaration.tessellator_domain = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) >> VKD3D_SM5_TESSELLATOR_SHIFT; - priv->p.program->tess_domain = ins->declaration.tessellator_domain; + priv->program->tess_domain = ins->declaration.tessellator_domain; } static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -1280,7 +1282,7 @@ static void shader_sm5_read_dcl_tessellator_partitioning(struct vkd3d_shader_ins { ins->declaration.tessellator_partitioning = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) >> VKD3D_SM5_TESSELLATOR_SHIFT; - priv->p.program->tess_partitioning = ins->declaration.tessellator_partitioning; + priv->program->tess_partitioning = ins->declaration.tessellator_partitioning; } static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -1288,7 +1290,7 @@ static void shader_sm5_read_dcl_tessellator_output_primitive(struct vkd3d_shader { ins->declaration.tessellator_output_primitive = (opcode_token & VKD3D_SM5_TESSELLATOR_MASK) >> VKD3D_SM5_TESSELLATOR_SHIFT; - priv->p.program->tess_output_primitive = ins->declaration.tessellator_output_primitive; + priv->program->tess_output_primitive = ins->declaration.tessellator_output_primitive; } static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -1300,7 +1302,7 @@ static void shader_sm5_read_dcl_hs_max_tessfactor(struct vkd3d_shader_instructio static void shader_sm5_read_dcl_thread_group(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *sm4) { - struct vsir_program *program = sm4->p.program; + struct vsir_program *program = sm4->program; ins->declaration.thread_group_size.x = *tokens++; ins->declaration.thread_group_size.y = *tokens++; @@ -2009,7 +2011,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const { if (addressing & VKD3D_SM4_ADDRESSING_RELATIVE) { - struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->p.program, 1); + struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(priv->program, 1); if (!(reg_idx->rel_addr = rel_addr)) { @@ -2284,7 +2286,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register * { return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT || (reg->type == VKD3DSPR_INPUT && (priv->phase == VSIR_OP_HS_CONTROL_POINT_PHASE - || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); + || priv->program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); } static uint32_t mask_from_swizzle(uint32_t swizzle) @@ -2608,8 +2610,8 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, struct vkd3d_shader_instruction *ins) { const struct vkd3d_sm4_opcode_info *opcode_info; - struct vsir_program *program = sm4->p.program; uint32_t opcode_token, opcode, previous_token; + struct vsir_program *program = sm4->program; struct vkd3d_shader_dst_param *dst_params; struct vkd3d_shader_src_param *src_params; const uint32_t **ptr = &sm4->ptr; @@ -2814,8 +2816,9 @@ static bool shader_sm4_init(struct vkd3d_shader_sm4_parser *sm4, struct vsir_pro if (!vsir_program_init(program, compile_info, &version, token_count / 7u + 20, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) return false; - vkd3d_shader_parser_init(&sm4->p, program, message_context, compile_info->source_name); + vkd3d_shader_parser_init(&sm4->p, message_context, compile_info->source_name); sm4->ptr = sm4->start; + sm4->program = program; init_sm4_lookup_tables(&sm4->lookup); @@ -3692,7 +3695,7 @@ static void write_sm4_instruction(const struct tpf_compiler *tpf, const struct s static void tpf_dcl_constant_buffer(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { const struct vkd3d_shader_constant_buffer *cb = &ins->declaration.cb; - size_t size = (cb->size + 3) / 4; + size_t size = cb->size / VKD3D_VEC4_SIZE / sizeof(float); struct sm4_instruction instr = { @@ -4222,6 +4225,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_DCL: case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_RESOURCE_STRUCTURED: case VSIR_OP_DCL_UAV_RAW: case VSIR_OP_DCL_UAV_STRUCTURED: case VSIR_OP_DCL_UAV_TYPED: @@ -4305,6 +4309,7 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ case VSIR_OP_LD: case VSIR_OP_LD2DMS: case VSIR_OP_LD_RAW: + case VSIR_OP_LD_STRUCTURED: case VSIR_OP_LD_UAV_TYPED: case VSIR_OP_LOG: case VSIR_OP_LOOP: diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index 5fcc836aae1..6949c1cd38f 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -23,6 +23,8 @@ #include #include +/* VKD3D_DEBUG_ENV_NAME("VKD3D_SHADER_DEBUG"); */ + static inline int char_to_int(char c) { if ('0' <= c && c <= '9') @@ -722,14 +724,13 @@ uint64_t vkd3d_shader_init_config_flags(void) return config_flags; } -void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, +void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name) { parser->message_context = message_context; parser->location.source_name = source_name; parser->location.line = 1; parser->location.column = 0; - parser->program = program; } void VKD3D_PRINTF_FUNC(3, 4) vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, @@ -1683,6 +1684,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_scan_combined_resource_sampler_info *combined_sampler_info; struct vkd3d_shader_scan_hull_shader_tessellation_info *tessellation_info; + struct vkd3d_shader_scan_thread_group_size_info *thread_group_size_info; struct vkd3d_shader_scan_descriptor_info *descriptor_info; struct vkd3d_shader_scan_signature_info *signature_info; struct vkd3d_shader_scan_context context; @@ -1704,6 +1706,7 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh } tessellation_info = vkd3d_find_struct(compile_info->next, SCAN_HULL_SHADER_TESSELLATION_INFO); + thread_group_size_info = vkd3d_find_struct(compile_info->next, SCAN_THREAD_GROUP_SIZE_INFO); vkd3d_shader_scan_context_init(&context, &program->shader_version, compile_info, add_descriptor_info ? &program->descriptors : NULL, combined_sampler_info, message_context); @@ -1756,6 +1759,13 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh tessellation_info->partitioning = context.partitioning; } + if (!ret && thread_group_size_info) + { + thread_group_size_info->x = program->thread_group_size.x; + thread_group_size_info->y = program->thread_group_size.y; + thread_group_size_info->z = program->thread_group_size.z; + } + if (ret < 0) { if (combined_sampler_info) @@ -2182,6 +2192,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_D3D_BYTECODE, VKD3D_SHADER_TARGET_DXBC_TPF, VKD3D_SHADER_TARGET_FX, +#ifdef VKD3D_SHADER_UNSUPPORTED_MSL + VKD3D_SHADER_TARGET_MSL, +#endif }; static const enum vkd3d_shader_target_type d3dbc_types[] = @@ -2253,6 +2266,7 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info struct vkd3d_shader_code *out, char **messages) { struct vkd3d_shader_message_context message_context; + struct shader_dump_data dump_data; int ret; TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages); @@ -2265,7 +2279,11 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info vkd3d_shader_message_context_init(&message_context, compile_info->log_level); - ret = preproc_lexer_parse(compile_info, out, &message_context); + fill_shader_dump_data(compile_info, &dump_data); + vkd3d_shader_dump_shader(&dump_data, compile_info->source.code, compile_info->source.size, SHADER_DUMP_TYPE_SOURCE); + + if ((ret = preproc_lexer_parse(compile_info, out, &message_context)) >= 0) + vkd3d_shader_dump_shader(&dump_data, out->code, out->size, SHADER_DUMP_TYPE_PREPROC); vkd3d_shader_message_context_trace_messages(&message_context); if (!vkd3d_shader_message_context_copy_messages(&message_context, messages)) @@ -2279,204 +2297,6 @@ void vkd3d_shader_set_log_callback(PFN_vkd3d_log callback) vkd3d_dbg_set_log_callback(callback); } -static struct vkd3d_shader_param_node *shader_param_allocator_node_create( - struct vkd3d_shader_param_allocator *allocator) -{ - struct vkd3d_shader_param_node *node; - - if (!(node = vkd3d_malloc(offsetof(struct vkd3d_shader_param_node, param[allocator->count * allocator->stride])))) - return NULL; - node->next = NULL; - return node; -} - -static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, - size_t count, size_t stride) -{ - allocator->count = max(count, MAX_REG_OUTPUT); - allocator->stride = stride; - allocator->head = NULL; - allocator->current = NULL; - allocator->index = allocator->count; -} - -static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator *allocator) -{ - struct vkd3d_shader_param_node *current = allocator->head; - - while (current) - { - struct vkd3d_shader_param_node *next = current->next; - vkd3d_free(current); - current = next; - } -} - -void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) -{ - void *params; - - if (!allocator->current || count > allocator->count - allocator->index) - { - struct vkd3d_shader_param_node *next; - - /* Monolithic switch has no definite parameter count limit. */ - allocator->count = max(allocator->count, count); - - if (!(next = shader_param_allocator_node_create(allocator))) - return NULL; - if (allocator->current) - allocator->current->next = next; - else - allocator->head = next; - allocator->current = next; - allocator->index = 0; - } - - params = &allocator->current->param[allocator->index * allocator->stride]; - allocator->index += count; - return params; -} - -bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve) -{ - memset(instructions, 0, sizeof(*instructions)); - /* Size the parameter initial allocations so they are large enough for most shaders. The - * code path for chained allocations will be tested if a few shaders need to use it. */ - shader_param_allocator_init(&instructions->dst_params, reserve - reserve / 8u, - sizeof(struct vkd3d_shader_dst_param)); - shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(struct vkd3d_shader_src_param)); - return shader_instruction_array_reserve(instructions, reserve); -} - -bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve) -{ - if (!vkd3d_array_reserve((void **)&instructions->elements, &instructions->capacity, reserve, - sizeof(*instructions->elements))) - { - ERR("Failed to allocate instructions.\n"); - return false; - } - return true; -} - -bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, - size_t idx, size_t count) -{ - VKD3D_ASSERT(idx <= instructions->count); - - if (!shader_instruction_array_reserve(instructions, instructions->count + count)) - return false; - - memmove(&instructions->elements[idx + count], &instructions->elements[idx], - (instructions->count - idx) * sizeof(*instructions->elements)); - memset(&instructions->elements[idx], 0, count * sizeof(*instructions->elements)); - - instructions->count += count; - - return true; -} - -bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, - struct vkd3d_shader_immediate_constant_buffer *icb) -{ - if (!vkd3d_array_reserve((void **)&instructions->icbs, &instructions->icb_capacity, instructions->icb_count + 1, - sizeof(*instructions->icbs))) - return false; - instructions->icbs[instructions->icb_count++] = icb; - return true; -} - -static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( - struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, - size_t count); - -static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, - struct vkd3d_shader_instruction_array *instructions) -{ - unsigned int i; - - for (i = 0; i < reg->idx_count; ++i) - { - if (!reg->idx[i].rel_addr) - continue; - - if (!(reg->idx[i].rel_addr = shader_instruction_array_clone_src_params(instructions, reg->idx[i].rel_addr, 1))) - return false; - } - - return true; -} - -static struct vkd3d_shader_dst_param *shader_instruction_array_clone_dst_params( - struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_dst_param *params, - size_t count) -{ - struct vkd3d_shader_dst_param *dst_params; - size_t i; - - if (!(dst_params = shader_dst_param_allocator_get(&instructions->dst_params, count))) - return NULL; - - memcpy(dst_params, params, count * sizeof(*params)); - for (i = 0; i < count; ++i) - { - if (!shader_register_clone_relative_addresses(&dst_params[i].reg, instructions)) - return NULL; - } - - return dst_params; -} - -static struct vkd3d_shader_src_param *shader_instruction_array_clone_src_params( - struct vkd3d_shader_instruction_array *instructions, const struct vkd3d_shader_src_param *params, - size_t count) -{ - struct vkd3d_shader_src_param *src_params; - size_t i; - - if (!(src_params = shader_src_param_allocator_get(&instructions->src_params, count))) - return NULL; - - memcpy(src_params, params, count * sizeof(*params)); - for (i = 0; i < count; ++i) - { - if (!shader_register_clone_relative_addresses(&src_params[i].reg, instructions)) - return NULL; - } - - return src_params; -} - -/* NOTE: Immediate constant buffers are not cloned, so the source must not be destroyed while the - * destination is in use. This seems like a reasonable requirement given how this is currently used. */ -bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, - size_t dst, size_t src) -{ - struct vkd3d_shader_instruction *ins = &instructions->elements[dst]; - - *ins = instructions->elements[src]; - - if (ins->dst_count && ins->dst && !(ins->dst = shader_instruction_array_clone_dst_params(instructions, - ins->dst, ins->dst_count))) - return false; - - return !ins->src_count || !!(ins->src = shader_instruction_array_clone_src_params(instructions, - ins->src, ins->src_count)); -} - -void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions) -{ - unsigned int i; - - vkd3d_free(instructions->elements); - shader_param_allocator_destroy(&instructions->dst_params); - shader_param_allocator_destroy(&instructions->src_params); - for (i = 0; i < instructions->icb_count; ++i) - vkd3d_free(instructions->icbs[i]); - vkd3d_free(instructions->icbs); -} - void vkd3d_shader_build_varying_map(const struct vkd3d_shader_signature *output_signature, const struct vkd3d_shader_signature *input_signature, unsigned int *ret_count, struct vkd3d_shader_varying_map *varyings) diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index e758c16b3d4..c00a7825610 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -213,7 +213,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND_COUNT = 8005, VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_TABLE = 8006, VKD3D_SHADER_ERROR_DXIL_INVALID_VALUE_SYMTAB = 8007, - VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED_BITCODE_FORMAT = 8008, + VKD3D_SHADER_ERROR_DXIL_UNSUPPORTED = 8008, VKD3D_SHADER_ERROR_DXIL_INVALID_FUNCTION_DCL = 8009, VKD3D_SHADER_ERROR_DXIL_INVALID_TYPE_ID = 8010, VKD3D_SHADER_ERROR_DXIL_INVALID_MODULE = 8011, @@ -716,7 +716,9 @@ enum vsir_data_type VSIR_DATA_F32, VSIR_DATA_F64, + VSIR_DATA_I16, VSIR_DATA_I32, + VSIR_DATA_I64, VSIR_DATA_U8, VSIR_DATA_U16, @@ -734,10 +736,13 @@ enum vsir_data_type VSIR_DATA_TYPE_COUNT, }; +const char *vsir_data_type_get_name(enum vsir_data_type t, const char *error); + static inline bool data_type_is_integer(enum vsir_data_type data_type) { - return data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 - || data_type == VSIR_DATA_U32 || data_type == VSIR_DATA_U64; + return data_type == VSIR_DATA_I16 || data_type == VSIR_DATA_I32 || data_type == VSIR_DATA_I64 + || data_type == VSIR_DATA_U8 || data_type == VSIR_DATA_U16 || data_type == VSIR_DATA_U32 + || data_type == VSIR_DATA_U64; } static inline bool data_type_is_bool(enum vsir_data_type data_type) @@ -752,7 +757,7 @@ static inline bool data_type_is_floating_point(enum vsir_data_type data_type) static inline bool data_type_is_64_bit(enum vsir_data_type data_type) { - return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_U64; + return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_I64 || data_type == VSIR_DATA_U64; } enum vsir_dimension @@ -1439,15 +1444,11 @@ struct vkd3d_shader_instruction_array struct vkd3d_shader_src_param *outpointid_param; }; -bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, size_t reserve); bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, size_t reserve); bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, size_t idx, size_t count); bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *instructions, struct vkd3d_shader_immediate_constant_buffer *icb); -bool shader_instruction_array_clone_instruction(struct vkd3d_shader_instruction_array *instructions, - size_t dst, size_t src); -void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions); struct vsir_program_iterator { @@ -1510,6 +1511,38 @@ static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterat return shader_instruction_array_insert_at(it->array, it->idx + 1, count); } +/* When insertion takes place, argument `it' is updated to point to the same + * instruction as before the insertion, and the optional argument `ins_it' is + * initialized to point to the first inserted instruction. + * A pointer to the first inserted instruction is returned. */ +static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before( + struct vsir_program_iterator *it, struct vsir_program_iterator *ins_it, size_t count) +{ + VKD3D_ASSERT(it != ins_it); + VKD3D_ASSERT(it->idx != SIZE_MAX); + + if (!shader_instruction_array_insert_at(it->array, it->idx, count)) + return NULL; + + *ins_it = *it; + it->idx += count; + + return vsir_program_iterator_current(ins_it); +} + +/* When insertion takes place, argument `it' is updated to point to the first + * inserted instruction. A pointer to this first inserted instruction is + * returned. */ +static inline struct vkd3d_shader_instruction *vsir_program_iterator_insert_before_and_move( + struct vsir_program_iterator *it, size_t count) +{ + VKD3D_ASSERT(it->idx != SIZE_MAX); + + if (!shader_instruction_array_insert_at(it->array, it->idx, count)) + return NULL; + return vsir_program_iterator_current(it); +} + enum vkd3d_shader_config_flags { VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, @@ -1651,13 +1684,12 @@ struct vkd3d_shader_parser { struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_location location; - struct vsir_program *program; bool failed; }; void vkd3d_shader_parser_error(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); -void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_program *program, +void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vkd3d_shader_message_context *message_context, const char *source_name); void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4); @@ -1852,20 +1884,28 @@ static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_ty { case VSIR_DATA_BOOL: return VKD3D_SHADER_COMPONENT_BOOL; - case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ + case VSIR_DATA_F16: + return VKD3D_SHADER_COMPONENT_FLOAT16; case VSIR_DATA_F32: case VSIR_DATA_SNORM: case VSIR_DATA_UNORM: return VKD3D_SHADER_COMPONENT_FLOAT; case VSIR_DATA_F64: return VKD3D_SHADER_COMPONENT_DOUBLE; + case VSIR_DATA_I16: + return VKD3D_SHADER_COMPONENT_INT16; case VSIR_DATA_I32: return VKD3D_SHADER_COMPONENT_INT; - case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */ + case VSIR_DATA_I64: + return VKD3D_SHADER_COMPONENT_INT64; + case VSIR_DATA_U16: + return VKD3D_SHADER_COMPONENT_UINT16; case VSIR_DATA_U32: return VKD3D_SHADER_COMPONENT_UINT; case VSIR_DATA_U64: return VKD3D_SHADER_COMPONENT_UINT64; + case VSIR_DATA_UNUSED: + return VKD3D_SHADER_COMPONENT_VOID; default: FIXME("Unhandled data type %#x.\n", data_type); /* fall-through */ @@ -1878,23 +1918,41 @@ static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_ { switch (component_type) { - case VKD3D_SHADER_COMPONENT_FLOAT: - return VSIR_DATA_F32; + case VKD3D_SHADER_COMPONENT_VOID: + return VSIR_DATA_UNUSED; case VKD3D_SHADER_COMPONENT_UINT: return VSIR_DATA_U32; case VKD3D_SHADER_COMPONENT_INT: return VSIR_DATA_I32; + case VKD3D_SHADER_COMPONENT_FLOAT: + return VSIR_DATA_F32; + case VKD3D_SHADER_COMPONENT_BOOL: + return VSIR_DATA_BOOL; case VKD3D_SHADER_COMPONENT_DOUBLE: return VSIR_DATA_F64; - default: - FIXME("Unhandled component type %#x.\n", component_type); - return VSIR_DATA_F32; + case VKD3D_SHADER_COMPONENT_UINT64: + return VSIR_DATA_U64; + case VKD3D_SHADER_COMPONENT_INT64: + return VSIR_DATA_I64; + case VKD3D_SHADER_COMPONENT_FLOAT16: + return VSIR_DATA_F16; + case VKD3D_SHADER_COMPONENT_UINT16: + return VSIR_DATA_U16; + case VKD3D_SHADER_COMPONENT_INT16: + return VSIR_DATA_I16; + case VKD3D_SHADER_COMPONENT_TYPE_FORCE_32BIT: + break; } + + FIXME("Unhandled component type %#x.\n", component_type); + + return VSIR_DATA_UNUSED; } static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type component_type) { - return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; + return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_INT64 + || component_type == VKD3D_SHADER_COMPONENT_UINT64; } static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c index f2967835b62..fea8c2440d1 100644 --- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c @@ -19,6 +19,8 @@ #include "vkd3d_utils_private.h" #undef D3D12CreateDevice +/* VKD3D_DEBUG_ENV_NAME("VKD3D_DEBUG"); */ + static const char *debug_d3d_blob_part(D3D_BLOB_PART part) { switch (part) @@ -269,7 +271,7 @@ HRESULT WINAPI D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char * option = &options[0]; option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; - option->value = VKD3D_SHADER_API_VERSION_1_17; + option->value = VKD3D_SHADER_API_VERSION_CURRENT; compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; compile_info.next = &preprocess_info; @@ -433,7 +435,7 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename static const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, }; TRACE("data %p, size %"PRIuPTR", filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", @@ -482,7 +484,10 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename if (!ret) { - if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, preprocessed_code.size, preprocessed_blob))) + /* vkd3d-shader output is null-terminated, but the null terminator isn't + * included in the size. Increase the size to account for that. */ + if (FAILED(hr = vkd3d_blob_create((void *)preprocessed_code.code, + preprocessed_code.size + 1, preprocessed_blob))) { vkd3d_shader_free_shader_code(&preprocessed_code); return hr; @@ -979,7 +984,7 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, static const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, }; TRACE("data %p, data_size %"PRIuPTR", flags %#x, comments %p, blob %p.\n", @@ -1032,7 +1037,9 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size, return hresult_from_vkd3d_result(ret); } - if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size, blob))) + /* vkd3d-shader output is null-terminated, but the null terminator isn't + * included in the size. Increase the size to account for that. */ + if (FAILED(hr = vkd3d_blob_create((void *)output.code, output.size + 1, blob))) vkd3d_shader_free_shader_code(&output); return hr; diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c index 074d8430585..d933e7ec463 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -3049,7 +3049,7 @@ static void d3d12_command_list_update_descriptor_table(struct d3d12_command_list if (descriptor_count > range->vk_binding_count) { - ERR("Heap descriptor count %u exceeds maximum Vulkan count %u. Reducing to the Vulkan maximum.\n", + MESSAGE("Heap descriptor count %u exceeds maximum Vulkan count %u. Reducing to the Vulkan maximum.\n", descriptor_count, range->vk_binding_count); descriptor_count = range->vk_binding_count; } diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c index 6bbd6533b74..b6055a50a99 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c @@ -2391,7 +2391,7 @@ static HRESULT create_shader_stage(struct d3d12_device *device, const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, {VKD3D_SHADER_COMPILE_OPTION_WRITE_TESS_GEOM_POINT_SIZE, 0}, {VKD3D_SHADER_COMPILE_OPTION_FEATURE, feature_flags_compile_option(device)}, @@ -2456,7 +2456,7 @@ static int vkd3d_scan_dxbc(const struct d3d12_device *device, const D3D12_SHADER const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, }; @@ -4135,7 +4135,7 @@ static int compile_hlsl_cs(const struct vkd3d_shader_code *hlsl, struct vkd3d_sh static const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_CURRENT}, }; info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; diff --git a/libs/vkd3d/libs/vkd3d/utils.c b/libs/vkd3d/libs/vkd3d/utils.c index c2832a61f67..2d0510e5456 100644 --- a/libs/vkd3d/libs/vkd3d/utils.c +++ b/libs/vkd3d/libs/vkd3d/utils.c @@ -703,7 +703,7 @@ const char *debug_vk_extent_3d(VkExtent3D extent) const char *debug_vk_queue_flags(VkQueueFlags flags) { - char buffer[191]; + char buffer[222]; buffer[0] = '\0'; #define FLAG_TO_STR(f) if (flags & f) { strcat(buffer, " | "#f); flags &= ~f; } @@ -716,6 +716,7 @@ const char *debug_vk_queue_flags(VkQueueFlags flags) #define FLAG_TO_STR(f, n) if (flags & f) { strcat(buffer, " | "#n); flags &= ~f; } FLAG_TO_STR(0x20, VK_QUEUE_VIDEO_DECODE_BIT_KHR) FLAG_TO_STR(0x40, VK_QUEUE_VIDEO_ENCODE_BIT_KHR) + FLAG_TO_STR(0x100, VK_QUEUE_OPTICAL_FLOW_BIT_NV) #undef FLAG_TO_STR if (flags) FIXME("Unrecognized flag(s) %#x.\n", flags); -- 2.51.0