From: Alexandre Julliard julliard@winehq.org
--- server/hook.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/server/hook.c b/server/hook.c index e0281d92b81..e53ba4514bf 100644 --- a/server/hook.c +++ b/server/hook.c @@ -257,7 +257,7 @@ static inline struct hook *get_first_valid_hook( struct hook_table *table, int i } } } - return hook; + return NULL; }
/* find the next hook in the chain, skipping the deleted ones */ @@ -286,11 +286,9 @@ static struct hook *get_next_hook( struct thread *thread, struct hook *hook, int } } global_hooks = get_global_hooks( thread ); - if (global_hooks && table != global_hooks) /* now search through the global table */ - { - hook = get_first_valid_hook( global_hooks, index, event, win, object_id, child_id ); - } - return hook; + if (!global_hooks || global_hooks == table) return NULL; + /* now search through the global table */ + return get_first_valid_hook( global_hooks, index, event, win, object_id, child_id ); }
static void hook_table_dump( struct object *obj, int verbose )
From: Alexandre Julliard julliard@winehq.org
--- libs/vkd3d/config.h | 4 +- libs/vkd3d/include/private/spirv_grammar.h | 561 ++- libs/vkd3d/include/private/vkd3d_common.h | 1 + .../include/private/vkd3d_shader_utils.h | 4 - libs/vkd3d/include/vkd3d.h | 1 + libs/vkd3d/include/vkd3d_shader.h | 8 + libs/vkd3d/libs/vkd3d-shader/d3d_asm.c | 626 +-- libs/vkd3d/libs/vkd3d-shader/d3dbc.c | 459 +- libs/vkd3d/libs/vkd3d-shader/dxbc.c | 10 +- libs/vkd3d/libs/vkd3d-shader/dxil.c | 1752 ++++---- libs/vkd3d/libs/vkd3d-shader/fx.c | 1383 ++++-- libs/vkd3d/libs/vkd3d-shader/glsl.c | 320 +- libs/vkd3d/libs/vkd3d-shader/hlsl.c | 289 +- libs/vkd3d/libs/vkd3d-shader/hlsl.h | 47 +- libs/vkd3d/libs/vkd3d-shader/hlsl.l | 1 + libs/vkd3d/libs/vkd3d-shader/hlsl.y | 128 +- libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c | 1917 +++++--- libs/vkd3d/libs/vkd3d-shader/ir.c | 4000 +++++++++++++---- libs/vkd3d/libs/vkd3d-shader/msl.c | 1064 ++++- libs/vkd3d/libs/vkd3d-shader/preproc.h | 2 +- libs/vkd3d/libs/vkd3d-shader/preproc.l | 38 +- libs/vkd3d/libs/vkd3d-shader/spirv.c | 1479 +++--- libs/vkd3d/libs/vkd3d-shader/tpf.c | 1045 +++-- .../libs/vkd3d-shader/vkd3d_shader_main.c | 460 +- .../libs/vkd3d-shader/vkd3d_shader_private.h | 964 ++-- .../vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c | 6 +- libs/vkd3d/libs/vkd3d/command.c | 21 +- libs/vkd3d/libs/vkd3d/device.c | 7 +- libs/vkd3d/libs/vkd3d/resource.c | 73 +- libs/vkd3d/libs/vkd3d/state.c | 42 +- libs/vkd3d/libs/vkd3d/vkd3d_private.h | 13 +- 31 files changed, 10689 insertions(+), 6036 deletions(-)
diff --git a/libs/vkd3d/config.h b/libs/vkd3d/config.h index 85d63e5fddd..4d3ba130ab7 100644 --- a/libs/vkd3d/config.h +++ b/libs/vkd3d/config.h @@ -1,5 +1,5 @@ #define PACKAGE_NAME "vkd3d" -#define PACKAGE_STRING "vkd3d 1.16" -#define PACKAGE_VERSION "1.16" +#define PACKAGE_STRING "vkd3d 1.17" +#define PACKAGE_VERSION "1.17" #define PATH_MAX 1024 #define SONAME_LIBVULKAN "vulkan-1.dll" diff --git a/libs/vkd3d/include/private/spirv_grammar.h b/libs/vkd3d/include/private/spirv_grammar.h index 2aac5a6558c..34cadd9bd58 100644 --- a/libs/vkd3d/include/private/spirv_grammar.h +++ b/libs/vkd3d/include/private/spirv_grammar.h @@ -43,10 +43,12 @@ 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, @@ -82,6 +84,7 @@ 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, @@ -146,7 +149,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_BUILT_IN] = { - "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 116, + "BuiltIn", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 126, (struct spirv_parser_enumerant[]) { {0, "Position"}, @@ -207,6 +210,9 @@ spirv_parser_operand_type_info[] = {0x1156, "DeviceIndex"}, {0x1158, "ViewIndex"}, {0x115c, "ShadingRateKHR"}, + {0x118c, "TileOffsetQCOM"}, + {0x118d, "TileDimensionQCOM"}, + {0x118e, "TileApronSizeQCOM"}, {0x1380, "BaryCoordNoPerspAMD"}, {0x1381, "BaryCoordNoPerspCentroidAMD"}, {0x1382, "BaryCoordNoPerspSampleAMD"}, @@ -258,18 +264,25 @@ 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, 245, + "Capability", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 261, (struct spirv_parser_enumerant[]) { {0, "Matrix"}, @@ -380,6 +393,7 @@ spirv_parser_operand_type_info[] = {0x1184, "TextureSampleWeightedQCOM"}, {0x1185, "TextureBoxFilterQCOM"}, {0x1186, "TextureBlockMatchQCOM"}, + {0x118f, "TileShadingQCOM"}, {0x1192, "TextureBlockMatch2QCOM"}, {0x1390, "Float16ImageAMD"}, {0x1391, "ImageGatherBiasLodAMD"}, @@ -390,6 +404,9 @@ spirv_parser_operand_type_info[] = {0x13bf, "ShaderClockKHR"}, {0x13cb, "ShaderEnqueueAMDX"}, {0x13df, "QuadControlKHR"}, + {0x13fc, "BFloat16TypeKHR"}, + {0x13fd, "BFloat16DotProductKHR"}, + {0x13fe, "BFloat16CooperativeMatrixKHR"}, {0x1481, "SampleMaskOverrideCoverageNV"}, {0x1483, "GeometryShaderPassthroughNV"}, {0x1486, "ShaderViewportIndexLayerEXT"}, @@ -435,14 +452,19 @@ 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"}, @@ -507,18 +529,47 @@ 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, @@ -563,6 +614,17 @@ 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, @@ -1178,7 +1240,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_EXECUTION_MODE] = { - "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 94, + "ExecutionMode", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 96, (struct spirv_parser_enumerant[]) { { @@ -1327,6 +1389,16 @@ 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"}, @@ -1556,7 +1628,11 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_FPENCODING] = { - "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM + "FPEncoding", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 1, + (struct spirv_parser_enumerant[]) + { + {0, "BFloat16KHR"}, + } }, [SPIRV_PARSER_OPERAND_TYPE_FPFAST_MATH_MODE] = { @@ -1681,7 +1757,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_IMAGE_CHANNEL_DATA_TYPE] = { - "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 20, + "ImageChannelDataType", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 26, (struct spirv_parser_enumerant[]) { {0, "SnormInt8"}, @@ -1701,9 +1777,15 @@ 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] = @@ -2064,6 +2146,28 @@ 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, @@ -2301,7 +2405,7 @@ spirv_parser_operand_type_info[] = }, [SPIRV_PARSER_OPERAND_TYPE_SOURCE_LANGUAGE] = { - "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 13, + "SourceLanguage", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 14, (struct spirv_parser_enumerant[]) { {0, "Unknown"}, @@ -2317,11 +2421,12 @@ 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, 27, + "StorageClass", SPIRV_PARSER_OPERAND_CATEGORY_VALUE_ENUM, 28, (struct spirv_parser_enumerant[]) { {0, "UniformConstant"}, @@ -2338,6 +2443,7 @@ spirv_parser_operand_type_info[] = {0xb, "Image"}, {0xc, "StorageBuffer"}, {0x104c, "TileImageEXT"}, + {0x118b, "TileAttachmentQCOM"}, {0x13cc, "NodePayloadAMDX"}, {0x14d0, "CallableDataKHR"}, {0x14d1, "IncomingCallableDataKHR"}, @@ -6890,6 +6996,78 @@ 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[]) @@ -6960,6 +7138,27 @@ 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[]) @@ -7050,6 +7249,25 @@ 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[]) @@ -7362,6 +7580,130 @@ 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[]) @@ -7620,10 +7962,9 @@ spirv_parser_opcode_info[] = } }, { - 0x15e9, "OpAsmTargetINTEL", 3, + 0x15e9, "OpAsmTargetINTEL", 2, (struct spirv_parser_instruction_operand[]) { - {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_STRING}, } @@ -8896,7 +9237,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 9, + 0x16d0, "OpArbitraryFloatSinCosPiINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -8907,7 +9248,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}, } }, { @@ -8939,7 +9279,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16d3, "OpArbitraryFloatCastToIntINTEL", 7, + 0x16d3, "OpArbitraryFloatCastToIntINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -8949,6 +9289,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}, } }, { @@ -9462,7 +9803,7 @@ spirv_parser_opcode_info[] = } }, { - 0x16fa, "OpArbitraryFloatPowNINTEL", 9, + 0x16fa, "OpArbitraryFloatPowNINTEL", 10, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, @@ -9474,6 +9815,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}, } }, { @@ -9509,13 +9851,12 @@ spirv_parser_opcode_info[] = } }, { - 0x1723, "OpFixedSqrtINTEL", 9, + 0x1723, "OpFixedSqrtINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9524,13 +9865,12 @@ spirv_parser_opcode_info[] = } }, { - 0x1724, "OpFixedRecipINTEL", 9, + 0x1724, "OpFixedRecipINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9539,13 +9879,12 @@ spirv_parser_opcode_info[] = } }, { - 0x1725, "OpFixedRsqrtINTEL", 9, + 0x1725, "OpFixedRsqrtINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9554,13 +9893,12 @@ spirv_parser_opcode_info[] = } }, { - 0x1726, "OpFixedSinINTEL", 9, + 0x1726, "OpFixedSinINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9569,13 +9907,12 @@ spirv_parser_opcode_info[] = } }, { - 0x1727, "OpFixedCosINTEL", 9, + 0x1727, "OpFixedCosINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9584,13 +9921,12 @@ spirv_parser_opcode_info[] = } }, { - 0x1728, "OpFixedSinCosINTEL", 9, + 0x1728, "OpFixedSinCosINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9599,13 +9935,12 @@ spirv_parser_opcode_info[] = } }, { - 0x1729, "OpFixedSinPiINTEL", 9, + 0x1729, "OpFixedSinPiINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9614,13 +9949,12 @@ spirv_parser_opcode_info[] = } }, { - 0x172a, "OpFixedCosPiINTEL", 9, + 0x172a, "OpFixedCosPiINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9629,13 +9963,12 @@ spirv_parser_opcode_info[] = } }, { - 0x172b, "OpFixedSinCosPiINTEL", 9, + 0x172b, "OpFixedSinCosPiINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9644,13 +9977,12 @@ spirv_parser_opcode_info[] = } }, { - 0x172c, "OpFixedLogINTEL", 9, + 0x172c, "OpFixedLogINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9659,13 +9991,12 @@ spirv_parser_opcode_info[] = } }, { - 0x172d, "OpFixedExpINTEL", 9, + 0x172d, "OpFixedExpINTEL", 8, (struct spirv_parser_instruction_operand[]) { {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT_TYPE}, {SPIRV_PARSER_OPERAND_TYPE_ID_RESULT}, {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, {SPIRV_PARSER_OPERAND_TYPE_LITERAL_INTEGER}, @@ -9712,13 +10043,12 @@ spirv_parser_opcode_info[] = } }, { - 0x173d, "OpFPGARegINTEL", 4, + 0x173d, "OpFPGARegINTEL", 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}, - {SPIRV_PARSER_OPERAND_TYPE_ID_REF}, } }, { @@ -9981,6 +10311,50 @@ 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[]) @@ -9990,6 +10364,110 @@ 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[]) @@ -10078,6 +10556,15 @@ 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 beb23257fb7..08341304eea 100644 --- a/libs/vkd3d/include/private/vkd3d_common.h +++ b/libs/vkd3d/include/private/vkd3d_common.h @@ -66,6 +66,7 @@
#define TAG_AON9 VKD3D_MAKE_TAG('A', 'o', 'n', '9') #define TAG_CLI4 VKD3D_MAKE_TAG('C', 'L', 'I', '4') +#define TAG_CLIT VKD3D_MAKE_TAG('C', 'L', 'I', 'T') #define TAG_CTAB VKD3D_MAKE_TAG('C', 'T', 'A', 'B') #define TAG_DXBC VKD3D_MAKE_TAG('D', 'X', 'B', 'C') #define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') diff --git a/libs/vkd3d/include/private/vkd3d_shader_utils.h b/libs/vkd3d/include/private/vkd3d_shader_utils.h index 00052a89988..465734dfbff 100644 --- a/libs/vkd3d/include/private/vkd3d_shader_utils.h +++ b/libs/vkd3d/include/private/vkd3d_shader_utils.h @@ -21,10 +21,6 @@
#include "vkd3d_shader.h"
-#define TAG_DXIL VKD3D_MAKE_TAG('D', 'X', 'I', 'L') -#define TAG_SHDR VKD3D_MAKE_TAG('S', 'H', 'D', 'R') -#define TAG_SHEX VKD3D_MAKE_TAG('S', 'H', 'E', 'X') - static inline enum vkd3d_result vkd3d_shader_parse_dxbc_source_type(const struct vkd3d_shader_code *dxbc, enum vkd3d_shader_source_type *type, char **messages) { diff --git a/libs/vkd3d/include/vkd3d.h b/libs/vkd3d/include/vkd3d.h index 2cb150dce16..8286f36f6ba 100644 --- a/libs/vkd3d/include/vkd3d.h +++ b/libs/vkd3d/include/vkd3d.h @@ -101,6 +101,7 @@ enum vkd3d_api_version VKD3D_API_VERSION_1_14, VKD3D_API_VERSION_1_15, VKD3D_API_VERSION_1_16, + VKD3D_API_VERSION_1_17,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_API_VERSION), }; diff --git a/libs/vkd3d/include/vkd3d_shader.h b/libs/vkd3d/include/vkd3d_shader.h index 30b6a070018..d82869e79ea 100644 --- a/libs/vkd3d/include/vkd3d_shader.h +++ b/libs/vkd3d/include/vkd3d_shader.h @@ -59,6 +59,7 @@ enum vkd3d_shader_api_version VKD3D_SHADER_API_VERSION_1_14, VKD3D_SHADER_API_VERSION_1_15, VKD3D_SHADER_API_VERSION_1_16, + VKD3D_SHADER_API_VERSION_1_17,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_API_VERSION), }; @@ -1431,6 +1432,11 @@ enum vkd3d_shader_source_type * Input is a raw FX section without container. \since 1.14 */ VKD3D_SHADER_SOURCE_FX, + /** + * A D3DX texture shader. This is the format used for the 'tx_1_0' HLSL + * target profile. \since 1.17 + */ + VKD3D_SHADER_SOURCE_TX,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_SHADER_SOURCE_TYPE), }; @@ -2761,6 +2767,7 @@ VKD3D_SHADER_API const enum vkd3d_shader_target_type *vkd3d_shader_get_supported * - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_DXBC_TPF * - VKD3D_SHADER_SOURCE_HLSL to VKD3D_SHADER_TARGET_FX * - VKD3D_SHADER_SOURCE_FX to VKD3D_SHADER_TARGET_D3D_ASM + * - VKD3D_SHADER_SOURCE_TX to VKD3D_SHADER_TARGET_D3D_ASM * * Supported transformations can also be detected at runtime with the functions * vkd3d_shader_get_supported_source_types() and @@ -2960,6 +2967,7 @@ VKD3D_SHADER_API int vkd3d_shader_convert_root_signature(struct vkd3d_shader_ver * - VKD3D_SHADER_SOURCE_DXBC_DXIL * - VKD3D_SHADER_SOURCE_DXBC_TPF * - VKD3D_SHADER_SOURCE_D3D_BYTECODE + * - VKD3D_SHADER_SOURCE_HLSL * * \param compile_info A chained structure containing scan parameters. * \n diff --git a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c index 4521bfabd8e..6425a8f62d2 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3d_asm.c @@ -27,333 +27,6 @@ #include <stdio.h> #include <math.h>
-static const char * const shader_opcode_names[] = -{ - [VKD3DSIH_ABS ] = "abs", - [VKD3DSIH_ACOS ] = "acos", - [VKD3DSIH_ADD ] = "add", - [VKD3DSIH_AND ] = "and", - [VKD3DSIH_ASIN ] = "asin", - [VKD3DSIH_ATAN ] = "atan", - [VKD3DSIH_ATOMIC_AND ] = "atomic_and", - [VKD3DSIH_ATOMIC_CMP_STORE ] = "atomic_cmp_store", - [VKD3DSIH_ATOMIC_IADD ] = "atomic_iadd", - [VKD3DSIH_ATOMIC_IMAX ] = "atomic_imax", - [VKD3DSIH_ATOMIC_IMIN ] = "atomic_imin", - [VKD3DSIH_ATOMIC_OR ] = "atomic_or", - [VKD3DSIH_ATOMIC_UMAX ] = "atomic_umax", - [VKD3DSIH_ATOMIC_UMIN ] = "atomic_umin", - [VKD3DSIH_ATOMIC_XOR ] = "atomic_xor", - [VKD3DSIH_BEM ] = "bem", - [VKD3DSIH_BFI ] = "bfi", - [VKD3DSIH_BFREV ] = "bfrev", - [VKD3DSIH_BRANCH ] = "branch", - [VKD3DSIH_BREAK ] = "break", - [VKD3DSIH_BREAKC ] = "break", - [VKD3DSIH_BREAKP ] = "breakp", - [VKD3DSIH_BUFINFO ] = "bufinfo", - [VKD3DSIH_CALL ] = "call", - [VKD3DSIH_CALLNZ ] = "callnz", - [VKD3DSIH_CASE ] = "case", - [VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", - [VKD3DSIH_CMP ] = "cmp", - [VKD3DSIH_CND ] = "cnd", - [VKD3DSIH_CONTINUE ] = "continue", - [VKD3DSIH_CONTINUEP ] = "continuec", - [VKD3DSIH_COUNTBITS ] = "countbits", - [VKD3DSIH_CRS ] = "crs", - [VKD3DSIH_CUT ] = "cut", - [VKD3DSIH_CUT_STREAM ] = "cut_stream", - [VKD3DSIH_DADD ] = "dadd", - [VKD3DSIH_DCL ] = "dcl", - [VKD3DSIH_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", - [VKD3DSIH_DCL_FUNCTION_BODY ] = "dcl_function_body", - [VKD3DSIH_DCL_FUNCTION_TABLE ] = "dcl_function_table", - [VKD3DSIH_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", - [VKD3DSIH_DCL_GS_INSTANCES ] = "dcl_gs_instances", - [VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", - [VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", - [VKD3DSIH_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", - [VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", - [VKD3DSIH_DCL_INDEX_RANGE ] = "dcl_index_range", - [VKD3DSIH_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", - [VKD3DSIH_DCL_INPUT ] = "dcl_input", - [VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", - [VKD3DSIH_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", - [VKD3DSIH_DCL_INPUT_PS ] = "dcl_input_ps", - [VKD3DSIH_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", - [VKD3DSIH_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", - [VKD3DSIH_DCL_INPUT_SGV ] = "dcl_input_sgv", - [VKD3DSIH_DCL_INPUT_SIV ] = "dcl_input_siv", - [VKD3DSIH_DCL_INTERFACE ] = "dcl_interface", - [VKD3DSIH_DCL_OUTPUT ] = "dcl_output", - [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", - [VKD3DSIH_DCL_OUTPUT_SIV ] = "dcl_output_siv", - [VKD3DSIH_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", - [VKD3DSIH_DCL_RESOURCE_RAW ] = "dcl_resource_raw", - [VKD3DSIH_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", - [VKD3DSIH_DCL_SAMPLER ] = "dcl_sampler", - [VKD3DSIH_DCL_STREAM ] = "dcl_stream", - [VKD3DSIH_DCL_TEMPS ] = "dcl_temps", - [VKD3DSIH_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", - [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", - [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", - [VKD3DSIH_DCL_TGSM_RAW ] = "dcl_tgsm_raw", - [VKD3DSIH_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", - [VKD3DSIH_DCL_THREAD_GROUP ] = "dcl_thread_group", - [VKD3DSIH_DCL_UAV_RAW ] = "dcl_uav_raw", - [VKD3DSIH_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", - [VKD3DSIH_DCL_UAV_TYPED ] = "dcl_uav_typed", - [VKD3DSIH_DCL_VERTICES_OUT ] = "dcl_maxout", - [VKD3DSIH_DDIV ] = "ddiv", - [VKD3DSIH_DEF ] = "def", - [VKD3DSIH_DEFAULT ] = "default", - [VKD3DSIH_DEFB ] = "defb", - [VKD3DSIH_DEFI ] = "defi", - [VKD3DSIH_DEQO ] = "deq", - [VKD3DSIH_DFMA ] = "dfma", - [VKD3DSIH_DGEO ] = "dge", - [VKD3DSIH_DISCARD ] = "discard", - [VKD3DSIH_DIV ] = "div", - [VKD3DSIH_DLT ] = "dlt", - [VKD3DSIH_DMAX ] = "dmax", - [VKD3DSIH_DMIN ] = "dmin", - [VKD3DSIH_DMOV ] = "dmov", - [VKD3DSIH_DMOVC ] = "dmovc", - [VKD3DSIH_DMUL ] = "dmul", - [VKD3DSIH_DNE ] = "dne", - [VKD3DSIH_DP2 ] = "dp2", - [VKD3DSIH_DP2ADD ] = "dp2add", - [VKD3DSIH_DP3 ] = "dp3", - [VKD3DSIH_DP4 ] = "dp4", - [VKD3DSIH_DRCP ] = "drcp", - [VKD3DSIH_DST ] = "dst", - [VKD3DSIH_DSX ] = "dsx", - [VKD3DSIH_DSX_COARSE ] = "deriv_rtx_coarse", - [VKD3DSIH_DSX_FINE ] = "deriv_rtx_fine", - [VKD3DSIH_DSY ] = "dsy", - [VKD3DSIH_DSY_COARSE ] = "deriv_rty_coarse", - [VKD3DSIH_DSY_FINE ] = "deriv_rty_fine", - [VKD3DSIH_DTOF ] = "dtof", - [VKD3DSIH_DTOI ] = "dtoi", - [VKD3DSIH_DTOU ] = "dtou", - [VKD3DSIH_ELSE ] = "else", - [VKD3DSIH_EMIT ] = "emit", - [VKD3DSIH_EMIT_STREAM ] = "emit_stream", - [VKD3DSIH_ENDIF ] = "endif", - [VKD3DSIH_ENDLOOP ] = "endloop", - [VKD3DSIH_ENDREP ] = "endrep", - [VKD3DSIH_ENDSWITCH ] = "endswitch", - [VKD3DSIH_EQO ] = "eq", - [VKD3DSIH_EQU ] = "eq_unord", - [VKD3DSIH_EVAL_CENTROID ] = "eval_centroid", - [VKD3DSIH_EVAL_SAMPLE_INDEX ] = "eval_sample_index", - [VKD3DSIH_EXP ] = "exp", - [VKD3DSIH_EXPP ] = "expp", - [VKD3DSIH_F16TOF32 ] = "f16tof32", - [VKD3DSIH_F32TOF16 ] = "f32tof16", - [VKD3DSIH_FCALL ] = "fcall", - [VKD3DSIH_FIRSTBIT_HI ] = "firstbit_hi", - [VKD3DSIH_FIRSTBIT_LO ] = "firstbit_lo", - [VKD3DSIH_FIRSTBIT_SHI ] = "firstbit_shi", - [VKD3DSIH_FRC ] = "frc", - [VKD3DSIH_FREM ] = "frem", - [VKD3DSIH_FTOD ] = "ftod", - [VKD3DSIH_FTOI ] = "ftoi", - [VKD3DSIH_FTOU ] = "ftou", - [VKD3DSIH_GATHER4 ] = "gather4", - [VKD3DSIH_GATHER4_C ] = "gather4_c", - [VKD3DSIH_GATHER4_C_S ] = "gather4_c_s", - [VKD3DSIH_GATHER4_PO ] = "gather4_po", - [VKD3DSIH_GATHER4_PO_C ] = "gather4_po_c", - [VKD3DSIH_GATHER4_PO_C_S ] = "gather4_po_c_s", - [VKD3DSIH_GATHER4_PO_S ] = "gather4_po_s", - [VKD3DSIH_GATHER4_S ] = "gather4_s", - [VKD3DSIH_GEO ] = "ge", - [VKD3DSIH_GEU ] = "ge_unord", - [VKD3DSIH_HCOS ] = "hcos", - [VKD3DSIH_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", - [VKD3DSIH_HS_DECLS ] = "hs_decls", - [VKD3DSIH_HS_FORK_PHASE ] = "hs_fork_phase", - [VKD3DSIH_HS_JOIN_PHASE ] = "hs_join_phase", - [VKD3DSIH_HSIN ] = "hsin", - [VKD3DSIH_HTAN ] = "htan", - [VKD3DSIH_IADD ] = "iadd", - [VKD3DSIH_IBFE ] = "ibfe", - [VKD3DSIH_IDIV ] = "idiv", - [VKD3DSIH_IEQ ] = "ieq", - [VKD3DSIH_IF ] = "if", - [VKD3DSIH_IFC ] = "if", - [VKD3DSIH_IGE ] = "ige", - [VKD3DSIH_ILT ] = "ilt", - [VKD3DSIH_IMAD ] = "imad", - [VKD3DSIH_IMAX ] = "imax", - [VKD3DSIH_IMIN ] = "imin", - [VKD3DSIH_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", - [VKD3DSIH_IMM_ATOMIC_AND ] = "imm_atomic_and", - [VKD3DSIH_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", - [VKD3DSIH_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", - [VKD3DSIH_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", - [VKD3DSIH_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", - [VKD3DSIH_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", - [VKD3DSIH_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", - [VKD3DSIH_IMM_ATOMIC_OR ] = "imm_atomic_or", - [VKD3DSIH_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", - [VKD3DSIH_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", - [VKD3DSIH_IMM_ATOMIC_XOR ] = "imm_atomic_xor", - [VKD3DSIH_IMUL ] = "imul", - [VKD3DSIH_INE ] = "ine", - [VKD3DSIH_INEG ] = "ineg", - [VKD3DSIH_ISFINITE ] = "isfinite", - [VKD3DSIH_ISHL ] = "ishl", - [VKD3DSIH_ISHR ] = "ishr", - [VKD3DSIH_ISINF ] = "isinf", - [VKD3DSIH_ISNAN ] = "isnan", - [VKD3DSIH_ITOD ] = "itod", - [VKD3DSIH_ITOF ] = "itof", - [VKD3DSIH_ITOI ] = "itoi", - [VKD3DSIH_LABEL ] = "label", - [VKD3DSIH_LD ] = "ld", - [VKD3DSIH_LD2DMS ] = "ld2dms", - [VKD3DSIH_LD2DMS_S ] = "ld2dms_s", - [VKD3DSIH_LD_RAW ] = "ld_raw", - [VKD3DSIH_LD_RAW_S ] = "ld_raw_s", - [VKD3DSIH_LD_S ] = "ld_s", - [VKD3DSIH_LD_STRUCTURED ] = "ld_structured", - [VKD3DSIH_LD_STRUCTURED_S ] = "ld_structured_s", - [VKD3DSIH_LD_UAV_TYPED ] = "ld_uav_typed", - [VKD3DSIH_LD_UAV_TYPED_S ] = "ld_uav_typed_s", - [VKD3DSIH_LIT ] = "lit", - [VKD3DSIH_LOD ] = "lod", - [VKD3DSIH_LOG ] = "log", - [VKD3DSIH_LOGP ] = "logp", - [VKD3DSIH_LOOP ] = "loop", - [VKD3DSIH_LRP ] = "lrp", - [VKD3DSIH_LTO ] = "lt", - [VKD3DSIH_LTU ] = "lt_unord", - [VKD3DSIH_M3x2 ] = "m3x2", - [VKD3DSIH_M3x3 ] = "m3x3", - [VKD3DSIH_M3x4 ] = "m3x4", - [VKD3DSIH_M4x3 ] = "m4x3", - [VKD3DSIH_M4x4 ] = "m4x4", - [VKD3DSIH_MAD ] = "mad", - [VKD3DSIH_MAX ] = "max", - [VKD3DSIH_MIN ] = "min", - [VKD3DSIH_MOV ] = "mov", - [VKD3DSIH_MOVA ] = "mova", - [VKD3DSIH_MOVC ] = "movc", - [VKD3DSIH_MSAD ] = "msad", - [VKD3DSIH_MUL ] = "mul", - [VKD3DSIH_NEO ] = "ne_ord", - [VKD3DSIH_NEU ] = "ne", - [VKD3DSIH_NOP ] = "nop", - [VKD3DSIH_NOT ] = "not", - [VKD3DSIH_NRM ] = "nrm", - [VKD3DSIH_OR ] = "or", - [VKD3DSIH_ORD ] = "ord", - [VKD3DSIH_PHASE ] = "phase", - [VKD3DSIH_PHI ] = "phi", - [VKD3DSIH_POW ] = "pow", - [VKD3DSIH_QUAD_READ_ACROSS_D ] = "quad_read_across_d", - [VKD3DSIH_QUAD_READ_ACROSS_X ] = "quad_read_across_x", - [VKD3DSIH_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", - [VKD3DSIH_QUAD_READ_LANE_AT ] = "quad_read_lane_at", - [VKD3DSIH_RCP ] = "rcp", - [VKD3DSIH_REP ] = "rep", - [VKD3DSIH_RESINFO ] = "resinfo", - [VKD3DSIH_RET ] = "ret", - [VKD3DSIH_RETP ] = "retp", - [VKD3DSIH_ROUND_NE ] = "round_ne", - [VKD3DSIH_ROUND_NI ] = "round_ni", - [VKD3DSIH_ROUND_PI ] = "round_pi", - [VKD3DSIH_ROUND_Z ] = "round_z", - [VKD3DSIH_RSQ ] = "rsq", - [VKD3DSIH_SAMPLE ] = "sample", - [VKD3DSIH_SAMPLE_B ] = "sample_b", - [VKD3DSIH_SAMPLE_B_CL_S ] = "sample_b_cl_s", - [VKD3DSIH_SAMPLE_C ] = "sample_c", - [VKD3DSIH_SAMPLE_C_CL_S ] = "sample_c_cl_s", - [VKD3DSIH_SAMPLE_C_LZ ] = "sample_c_lz", - [VKD3DSIH_SAMPLE_C_LZ_S ] = "sample_c_lz_s", - [VKD3DSIH_SAMPLE_CL_S ] = "sample_cl_s", - [VKD3DSIH_SAMPLE_GRAD ] = "sample_d", - [VKD3DSIH_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", - [VKD3DSIH_SAMPLE_INFO ] = "sample_info", - [VKD3DSIH_SAMPLE_LOD ] = "sample_l", - [VKD3DSIH_SAMPLE_LOD_S ] = "sample_l_s", - [VKD3DSIH_SAMPLE_POS ] = "sample_pos", - [VKD3DSIH_SETP ] = "setp", - [VKD3DSIH_SGE ] = "sge", - [VKD3DSIH_SGN ] = "sgn", - [VKD3DSIH_SINCOS ] = "sincos", - [VKD3DSIH_SLT ] = "slt", - [VKD3DSIH_SQRT ] = "sqrt", - [VKD3DSIH_STORE_RAW ] = "store_raw", - [VKD3DSIH_STORE_STRUCTURED ] = "store_structured", - [VKD3DSIH_STORE_UAV_TYPED ] = "store_uav_typed", - [VKD3DSIH_SUB ] = "sub", - [VKD3DSIH_SWAPC ] = "swapc", - [VKD3DSIH_SWITCH ] = "switch", - [VKD3DSIH_SWITCH_MONOLITHIC ] = "switch", - [VKD3DSIH_SYNC ] = "sync", - [VKD3DSIH_TAN ] = "tan", - [VKD3DSIH_TEX ] = "texld", - [VKD3DSIH_TEXBEM ] = "texbem", - [VKD3DSIH_TEXBEML ] = "texbeml", - [VKD3DSIH_TEXCOORD ] = "texcrd", - [VKD3DSIH_TEXDEPTH ] = "texdepth", - [VKD3DSIH_TEXDP3 ] = "texdp3", - [VKD3DSIH_TEXDP3TEX ] = "texdp3tex", - [VKD3DSIH_TEXKILL ] = "texkill", - [VKD3DSIH_TEXLDD ] = "texldd", - [VKD3DSIH_TEXLDL ] = "texldl", - [VKD3DSIH_TEXM3x2DEPTH ] = "texm3x2depth", - [VKD3DSIH_TEXM3x2PAD ] = "texm3x2pad", - [VKD3DSIH_TEXM3x2TEX ] = "texm3x2tex", - [VKD3DSIH_TEXM3x3 ] = "texm3x3", - [VKD3DSIH_TEXM3x3DIFF ] = "texm3x3diff", - [VKD3DSIH_TEXM3x3PAD ] = "texm3x3pad", - [VKD3DSIH_TEXM3x3SPEC ] = "texm3x3spec", - [VKD3DSIH_TEXM3x3TEX ] = "texm3x3tex", - [VKD3DSIH_TEXM3x3VSPEC ] = "texm3x3vspec", - [VKD3DSIH_TEXREG2AR ] = "texreg2ar", - [VKD3DSIH_TEXREG2GB ] = "texreg2gb", - [VKD3DSIH_TEXREG2RGB ] = "texreg2rgb", - [VKD3DSIH_UBFE ] = "ubfe", - [VKD3DSIH_UDIV ] = "udiv", - [VKD3DSIH_UGE ] = "uge", - [VKD3DSIH_ULT ] = "ult", - [VKD3DSIH_UMAX ] = "umax", - [VKD3DSIH_UMIN ] = "umin", - [VKD3DSIH_UMUL ] = "umul", - [VKD3DSIH_UNO ] = "uno", - [VKD3DSIH_USHR ] = "ushr", - [VKD3DSIH_UTOD ] = "utod", - [VKD3DSIH_UTOF ] = "utof", - [VKD3DSIH_UTOU ] = "utou", - [VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", - [VKD3DSIH_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", - [VKD3DSIH_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", - [VKD3DSIH_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", - [VKD3DSIH_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", - [VKD3DSIH_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", - [VKD3DSIH_WAVE_ALL_TRUE ] = "wave_all_true", - [VKD3DSIH_WAVE_ANY_TRUE ] = "wave_any_true", - [VKD3DSIH_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", - [VKD3DSIH_WAVE_OP_ADD ] = "wave_op_add", - [VKD3DSIH_WAVE_OP_IMAX ] = "wave_op_imax", - [VKD3DSIH_WAVE_OP_IMIN ] = "wave_op_imin", - [VKD3DSIH_WAVE_OP_MAX ] = "wave_op_max", - [VKD3DSIH_WAVE_OP_MIN ] = "wave_op_min", - [VKD3DSIH_WAVE_OP_MUL ] = "wave_op_mul", - [VKD3DSIH_WAVE_OP_UMAX ] = "wave_op_umax", - [VKD3DSIH_WAVE_OP_UMIN ] = "wave_op_umin", - [VKD3DSIH_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", - [VKD3DSIH_WAVE_READ_LANE_AT ] = "wave_read_lane_at", - [VKD3DSIH_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", - [VKD3DSIH_XOR ] = "xor", -}; - static const char * const shader_register_names[] = { [VKD3DSPR_ADDR ] = "a", @@ -483,6 +156,8 @@ static void shader_dump_atomic_op_flags(struct vkd3d_d3d_asm_compiler *compiler, atomic_flags &= ~VKD3DARF_VOLATILE; }
+ atomic_flags &= ~VKD3DSI_PRECISE_XYZW; + if (atomic_flags) vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", atomic_flags); } @@ -510,6 +185,8 @@ static void shader_dump_sync_flags(struct vkd3d_d3d_asm_compiler *compiler, uint sync_flags &= ~VKD3DSSF_THREAD_GROUP; }
+ sync_flags &= ~VKD3DSI_PRECISE_XYZW; + if (sync_flags) vkd3d_string_buffer_printf(&compiler->buffer, "_unknown_flags(%#x)", sync_flags); } @@ -711,25 +388,25 @@ static void shader_print_resource_type(struct vkd3d_d3d_asm_compiler *compiler, compiler->colours.error, type, compiler->colours.reset); }
-static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_data_type type) +static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum vsir_data_type type) { static const char *const data_type_names[] = { - [VKD3D_DATA_FLOAT ] = "float", - [VKD3D_DATA_INT ] = "int", - [VKD3D_DATA_UINT ] = "uint", - [VKD3D_DATA_UNORM ] = "unorm", - [VKD3D_DATA_SNORM ] = "snorm", - [VKD3D_DATA_OPAQUE ] = "opaque", - [VKD3D_DATA_MIXED ] = "mixed", - [VKD3D_DATA_DOUBLE ] = "double", - [VKD3D_DATA_CONTINUED] = "<continued>", - [VKD3D_DATA_UNUSED ] = "<unused>", - [VKD3D_DATA_UINT8 ] = "uint8", - [VKD3D_DATA_UINT64 ] = "uint64", - [VKD3D_DATA_BOOL ] = "bool", - [VKD3D_DATA_UINT16 ] = "uint16", - [VKD3D_DATA_HALF ] = "half", + [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] = "<continued>", + [VSIR_DATA_UNUSED ] = "<unused>", };
if (type < ARRAY_SIZE(data_type_names)) @@ -739,7 +416,7 @@ static void shader_print_data_type(struct vkd3d_d3d_asm_compiler *compiler, enum compiler->colours.error, type, compiler->colours.reset); }
-static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vkd3d_data_type *type) +static void shader_dump_resource_data_type(struct vkd3d_d3d_asm_compiler *compiler, const enum vsir_data_type *type) { int i;
@@ -917,9 +594,10 @@ static void shader_print_double_literal(struct vkd3d_d3d_asm_compiler *compiler, static void shader_print_int_literal(struct vkd3d_d3d_asm_compiler *compiler, const char *prefix, int i, const char *suffix) { + /* Note that we need to handle INT_MIN here as well. */ if (i < 0) - vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%d%s%s", - prefix, compiler->colours.literal, -i, compiler->colours.reset, suffix); + vkd3d_string_buffer_printf(&compiler->buffer, "%s-%s%u%s%s", + prefix, compiler->colours.literal, -(unsigned int)i, compiler->colours.reset, suffix); else vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%d%s%s", prefix, compiler->colours.literal, i, compiler->colours.reset, suffix); @@ -1041,8 +719,8 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const
switch (compiler->current->opcode) { - case VKD3DSIH_MOV: - case VKD3DSIH_MOVC: + case VSIR_OP_MOV: + case VSIR_OP_MOVC: untyped = true; break;
@@ -1056,16 +734,16 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const case VSIR_DIMENSION_SCALAR: switch (reg->data_type) { - case VKD3D_DATA_FLOAT: + case VSIR_DATA_F32: if (untyped) shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], ""); else shader_print_float_literal(compiler, "", reg->u.immconst_f32[0], ""); break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], ""); break; - case VKD3D_DATA_UINT: + case VSIR_DATA_U32: shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], ""); break; default: @@ -1078,7 +756,7 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const case VSIR_DIMENSION_VEC4: switch (reg->data_type) { - case VKD3D_DATA_FLOAT: + case VSIR_DATA_F32: if (untyped) { shader_print_untyped_literal(compiler, "", reg->u.immconst_u32[0], ""); @@ -1094,13 +772,13 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const shader_print_float_literal(compiler, ", ", reg->u.immconst_f32[3], ""); } break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: shader_print_int_literal(compiler, "", reg->u.immconst_u32[0], ""); shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[1], ""); shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[2], ""); shader_print_int_literal(compiler, ", ", reg->u.immconst_u32[3], ""); break; - case VKD3D_DATA_UINT: + case VSIR_DATA_U32: shader_print_uint_literal(compiler, "", reg->u.immconst_u32[0], ""); shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[1], ""); shader_print_uint_literal(compiler, ", ", reg->u.immconst_u32[2], ""); @@ -1126,13 +804,13 @@ static void shader_print_register(struct vkd3d_d3d_asm_compiler *compiler, const /* A double2 vector is treated as a float4 vector in enum vsir_dimension. */ if (reg->dimension == VSIR_DIMENSION_SCALAR || reg->dimension == VSIR_DIMENSION_VEC4) { - if (reg->data_type == VKD3D_DATA_DOUBLE) + if (reg->data_type == VSIR_DATA_F64) { shader_print_double_literal(compiler, "", reg->u.immconst_f64[0], ""); if (reg->dimension == VSIR_DIMENSION_VEC4) shader_print_double_literal(compiler, ", ", reg->u.immconst_f64[1], ""); } - else if (reg->data_type == VKD3D_DATA_UINT64) + else if (reg->data_type == VSIR_DATA_U64) { shader_print_uint64_literal(compiler, "", reg->u.immconst_u64[0], ""); if (reg->dimension == VSIR_DIMENSION_VEC4) @@ -1283,7 +961,7 @@ static void shader_print_reg_type(struct vkd3d_d3d_asm_compiler *compiler, return; }
- if (reg->data_type == VKD3D_DATA_UNUSED) + if (reg->data_type == VSIR_DATA_UNUSED) return;
if (reg->dimension < ARRAY_SIZE(dimensions)) @@ -1610,11 +1288,11 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile
switch (ins->opcode) { - case VKD3DSIH_BREAKP: - case VKD3DSIH_CONTINUEP: - case VKD3DSIH_DISCARD: - case VKD3DSIH_IF: - case VKD3DSIH_RETP: + case VSIR_OP_BREAKP: + case VSIR_OP_CONTINUEP: + case VSIR_OP_DISCARD: + case VSIR_OP_IF: + case VSIR_OP_RETP: switch (ins->flags) { case VKD3D_SHADER_CONDITIONAL_OP_NZ: @@ -1629,8 +1307,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break;
- case VKD3DSIH_IFC: - case VKD3DSIH_BREAKC: + case VSIR_OP_IFC: + case VSIR_OP_BREAKC: switch (ins->flags) { case VKD3D_SHADER_REL_OP_GT: @@ -1657,8 +1335,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break;
- case VKD3DSIH_RESINFO: - switch (ins->flags) + case VSIR_OP_RESINFO: + switch (ins->flags & ~VKD3DSI_PRECISE_XYZW) { case VKD3DSI_NONE: break; @@ -1674,8 +1352,8 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break;
- case VKD3DSIH_SAMPLE_INFO: - switch (ins->flags) + case VSIR_OP_SAMPLE_INFO: + switch (ins->flags & ~VKD3DSI_PRECISE_XYZW) { case VKD3DSI_NONE: break; @@ -1688,24 +1366,24 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break;
- case VKD3DSIH_IMM_ATOMIC_CMP_EXCH: - case VKD3DSIH_IMM_ATOMIC_IADD: - case VKD3DSIH_IMM_ATOMIC_AND: - case VKD3DSIH_IMM_ATOMIC_IMAX: - case VKD3DSIH_IMM_ATOMIC_IMIN: - case VKD3DSIH_IMM_ATOMIC_OR: - case VKD3DSIH_IMM_ATOMIC_UMAX: - case VKD3DSIH_IMM_ATOMIC_UMIN: - case VKD3DSIH_IMM_ATOMIC_EXCH: - case VKD3DSIH_IMM_ATOMIC_XOR: + case VSIR_OP_IMM_ATOMIC_CMP_EXCH: + case VSIR_OP_IMM_ATOMIC_IADD: + case VSIR_OP_IMM_ATOMIC_AND: + case VSIR_OP_IMM_ATOMIC_IMAX: + case VSIR_OP_IMM_ATOMIC_IMIN: + case VSIR_OP_IMM_ATOMIC_OR: + case VSIR_OP_IMM_ATOMIC_UMAX: + case VSIR_OP_IMM_ATOMIC_UMIN: + case VSIR_OP_IMM_ATOMIC_EXCH: + case VSIR_OP_IMM_ATOMIC_XOR: shader_dump_atomic_op_flags(compiler, ins->flags); break;
- case VKD3DSIH_SYNC: + case VSIR_OP_SYNC: shader_dump_sync_flags(compiler, ins->flags); break;
- case VKD3DSIH_TEX: + case VSIR_OP_TEXLD: if (vkd3d_shader_ver_ge(&compiler->shader_version, 2, 0)) { if (ins->flags & VKD3DSI_TEXLD_PROJECT) @@ -1715,25 +1393,25 @@ static void shader_dump_instruction_flags(struct vkd3d_d3d_asm_compiler *compile } break;
- case VKD3DSIH_WAVE_OP_ADD: - case VKD3DSIH_WAVE_OP_IMAX: - case VKD3DSIH_WAVE_OP_IMIN: - case VKD3DSIH_WAVE_OP_MAX: - case VKD3DSIH_WAVE_OP_MIN: - case VKD3DSIH_WAVE_OP_MUL: - case VKD3DSIH_WAVE_OP_UMAX: - case VKD3DSIH_WAVE_OP_UMIN: + case VSIR_OP_WAVE_OP_ADD: + case VSIR_OP_WAVE_OP_IMAX: + case VSIR_OP_WAVE_OP_IMIN: + case VSIR_OP_WAVE_OP_MAX: + case VSIR_OP_WAVE_OP_MIN: + case VSIR_OP_WAVE_OP_MUL: + case VSIR_OP_WAVE_OP_UMAX: + case VSIR_OP_WAVE_OP_UMIN: vkd3d_string_buffer_printf(&compiler->buffer, (ins->flags & VKD3DSI_WAVE_PREFIX) ? "_prefix" : "_active"); break;
- case VKD3DSIH_ISHL: - case VKD3DSIH_ISHR: - case VKD3DSIH_USHR: + case VSIR_OP_ISHL: + case VSIR_OP_ISHR: + case VSIR_OP_USHR: if (ins->flags & VKD3DSI_SHIFT_UNMASKED) vkd3d_string_buffer_printf(buffer, "_unmasked"); - /* fall through */ + break; + default: - shader_dump_precise_flags(compiler, ins->flags); break; } } @@ -1747,7 +1425,7 @@ static void shader_dump_register_space(struct vkd3d_d3d_asm_compiler *compiler, static void shader_print_opcode(struct vkd3d_d3d_asm_compiler *compiler, enum vkd3d_shader_opcode opcode) { vkd3d_string_buffer_printf(&compiler->buffer, "%s%s%s", compiler->colours.opcode, - shader_opcode_names[opcode], compiler->colours.reset); + vsir_opcode_get_name(opcode, "<unknown>"), compiler->colours.reset); }
static void shader_dump_icb(struct vkd3d_d3d_asm_compiler *compiler, @@ -1799,8 +1477,8 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler,
switch (ins->opcode) { - case VKD3DSIH_DCL: - case VKD3DSIH_DCL_UAV_TYPED: + case VSIR_OP_DCL: + case VSIR_OP_DCL_UAV_TYPED: vkd3d_string_buffer_printf(buffer, "%s", compiler->colours.opcode); shader_print_dcl_usage(compiler, "_", &ins->declaration.semantic, ins->flags, ""); shader_dump_ins_modifiers(compiler, &ins->declaration.semantic.resource.reg); @@ -1809,7 +1487,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_dump_register_space(compiler, ins->declaration.semantic.resource.range.space); break;
- case VKD3DSIH_DCL_CONSTANT_BUFFER: + case VSIR_OP_DCL_CONSTANT_BUFFER: shader_print_register(compiler, " ", &ins->declaration.cb.src.reg, true, ""); if (vkd3d_shader_ver_ge(&compiler->shader_version, 6, 0)) shader_print_subscript(compiler, ins->declaration.cb.size, NULL); @@ -1820,33 +1498,33 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_dump_register_space(compiler, ins->declaration.cb.range.space); break;
- case VKD3DSIH_DCL_FUNCTION_BODY: + case VSIR_OP_DCL_FUNCTION_BODY: vkd3d_string_buffer_printf(buffer, " fb%u", ins->declaration.index); break;
- case VKD3DSIH_DCL_FUNCTION_TABLE: + case VSIR_OP_DCL_FUNCTION_TABLE: vkd3d_string_buffer_printf(buffer, " ft%u = {...}", ins->declaration.index); break;
- case VKD3DSIH_DCL_GLOBAL_FLAGS: + case VSIR_OP_DCL_GLOBAL_FLAGS: vkd3d_string_buffer_printf(buffer, " "); shader_dump_global_flags(compiler, ins->declaration.global_flags); break;
- case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: + case VSIR_OP_DCL_HS_MAX_TESSFACTOR: shader_print_float_literal(compiler, " ", ins->declaration.max_tessellation_factor, ""); break;
- case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: + case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: shader_dump_icb(compiler, ins->declaration.icb); break;
- case VKD3DSIH_DCL_INDEX_RANGE: + case VSIR_OP_DCL_INDEX_RANGE: shader_print_dst_param(compiler, " ", &ins->declaration.index_range.dst, true, ""); shader_print_uint_literal(compiler, " ", ins->declaration.index_range.register_count, ""); break;
- case VKD3DSIH_DCL_INDEXABLE_TEMP: + case VSIR_OP_DCL_INDEXABLE_TEMP: 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); @@ -1857,112 +1535,113 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_dump_icb(compiler, ins->declaration.indexable_temp.initialiser); break;
- case VKD3DSIH_DCL_INPUT_PS: + case VSIR_OP_DCL_INPUT_PS: shader_print_interpolation_mode(compiler, " ", ins->flags, ""); shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, ""); break;
- case VKD3DSIH_DCL_INPUT_PS_SGV: - case VKD3DSIH_DCL_INPUT_SGV: - case VKD3DSIH_DCL_INPUT_SIV: - case VKD3DSIH_DCL_OUTPUT_SIV: + case VSIR_OP_DCL_INPUT_PS_SGV: + case VSIR_OP_DCL_INPUT_SGV: + case VSIR_OP_DCL_INPUT_SIV: + case VSIR_OP_DCL_OUTPUT_SGV: + case VSIR_OP_DCL_OUTPUT_SIV: shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, ""); shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, ""); break;
- case VKD3DSIH_DCL_INPUT_PS_SIV: + case VSIR_OP_DCL_INPUT_PS_SIV: shader_print_interpolation_mode(compiler, " ", ins->flags, ""); shader_print_dst_param(compiler, " ", &ins->declaration.register_semantic.reg, true, ""); shader_print_input_sysval_semantic(compiler, ", ", ins->declaration.register_semantic.sysval_semantic, ""); break;
- case VKD3DSIH_DCL_INPUT: - case VKD3DSIH_DCL_OUTPUT: + case VSIR_OP_DCL_INPUT: + case VSIR_OP_DCL_OUTPUT: shader_print_dst_param(compiler, " ", &ins->declaration.dst, true, ""); break;
- case VKD3DSIH_DCL_INPUT_PRIMITIVE: - case VKD3DSIH_DCL_OUTPUT_TOPOLOGY: + case VSIR_OP_DCL_INPUT_PRIMITIVE: + case VSIR_OP_DCL_OUTPUT_TOPOLOGY: shader_print_primitive_type(compiler, " ", &ins->declaration.primitive_type, ""); break;
- case VKD3DSIH_DCL_INTERFACE: + case VSIR_OP_DCL_INTERFACE: vkd3d_string_buffer_printf(buffer, " fp%u", ins->declaration.fp.index); shader_print_subscript(compiler, ins->declaration.fp.array_size, NULL); shader_print_subscript(compiler, ins->declaration.fp.body_count, NULL); vkd3d_string_buffer_printf(buffer, " = {...}"); break;
- case VKD3DSIH_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_RESOURCE_RAW: shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, ""); shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space); break;
- case VKD3DSIH_DCL_RESOURCE_STRUCTURED: + case VSIR_OP_DCL_RESOURCE_STRUCTURED: shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, ""); shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, ""); shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space); break;
- case VKD3DSIH_DCL_SAMPLER: + case VSIR_OP_DCL_SAMPLER: shader_print_register(compiler, " ", &ins->declaration.sampler.src.reg, true, ins->flags == VKD3DSI_SAMPLER_COMPARISON_MODE ? ", comparisonMode" : ""); shader_dump_register_space(compiler, ins->declaration.sampler.range.space); break;
- case VKD3DSIH_DCL_TEMPS: - case VKD3DSIH_DCL_GS_INSTANCES: - case VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT: - case VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: - case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: - case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: - case VKD3DSIH_DCL_VERTICES_OUT: + case VSIR_OP_DCL_TEMPS: + case VSIR_OP_DCL_GS_INSTANCES: + case VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT: + case VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: + case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: + case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: + case VSIR_OP_DCL_VERTICES_OUT: shader_print_uint_literal(compiler, " ", ins->declaration.count, ""); break;
- case VKD3DSIH_DCL_TESSELLATOR_DOMAIN: + case VSIR_OP_DCL_TESSELLATOR_DOMAIN: shader_print_tessellator_domain(compiler, " ", ins->declaration.tessellator_domain, ""); break;
- case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: + case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: shader_print_tessellator_output_primitive(compiler, " ", ins->declaration.tessellator_output_primitive, ""); break;
- case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING: + case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: shader_print_tessellator_partitioning(compiler, " ", ins->declaration.tessellator_partitioning, ""); break;
- case VKD3DSIH_DCL_TGSM_RAW: + case VSIR_OP_DCL_TGSM_RAW: shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_raw.reg, true, ""); shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_raw.byte_count, ""); break;
- case VKD3DSIH_DCL_TGSM_STRUCTURED: + case VSIR_OP_DCL_TGSM_STRUCTURED: shader_print_dst_param(compiler, " ", &ins->declaration.tgsm_structured.reg, true, ""); shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.byte_stride, ""); shader_print_uint_literal(compiler, ", ", ins->declaration.tgsm_structured.structure_count, ""); break;
- case VKD3DSIH_DCL_THREAD_GROUP: + case VSIR_OP_DCL_THREAD_GROUP: shader_print_uint_literal(compiler, " ", ins->declaration.thread_group_size.x, ""); shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.y, ""); shader_print_uint_literal(compiler, ", ", ins->declaration.thread_group_size.z, ""); break;
- case VKD3DSIH_DCL_UAV_RAW: + case VSIR_OP_DCL_UAV_RAW: shader_dump_uav_flags(compiler, ins->flags); shader_print_dst_param(compiler, " ", &ins->declaration.raw_resource.resource.reg, true, ""); shader_dump_register_space(compiler, ins->declaration.raw_resource.resource.range.space); break;
- case VKD3DSIH_DCL_UAV_STRUCTURED: + case VSIR_OP_DCL_UAV_STRUCTURED: shader_dump_uav_flags(compiler, ins->flags); shader_print_dst_param(compiler, " ", &ins->declaration.structured_resource.resource.reg, true, ""); shader_print_uint_literal(compiler, ", ", ins->declaration.structured_resource.byte_stride, ""); shader_dump_register_space(compiler, ins->declaration.structured_resource.resource.range.space); break;
- case VKD3DSIH_DEF: + case VSIR_OP_DEF: vkd3d_string_buffer_printf(buffer, " %sc%u%s", compiler->colours.reg, ins->dst[0].reg.idx[0].offset, compiler->colours.reset); shader_print_float_literal(compiler, " = ", ins->src[0].reg.u.immconst_f32[0], ""); @@ -1971,7 +1650,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_print_float_literal(compiler, ", ", ins->src[0].reg.u.immconst_f32[3], ""); break;
- case VKD3DSIH_DEFI: + case VSIR_OP_DEFI: vkd3d_string_buffer_printf(buffer, " %si%u%s", compiler->colours.reg, ins->dst[0].reg.idx[0].offset, compiler->colours.reset); shader_print_int_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], ""); @@ -1980,7 +1659,7 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_print_int_literal(compiler, ", ", ins->src[0].reg.u.immconst_u32[3], ""); break;
- case VKD3DSIH_DEFB: + case VSIR_OP_DEFB: vkd3d_string_buffer_printf(buffer, " %sb%u%s", compiler->colours.reg, ins->dst[0].reg.idx[0].offset, compiler->colours.reset); shader_print_bool_literal(compiler, " = ", ins->src[0].reg.u.immconst_u32[0], ""); @@ -1989,9 +1668,14 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, default: shader_dump_instruction_flags(compiler, ins);
+ if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE) + vkd3d_string_buffer_printf(buffer, "_indexable"); + + shader_dump_precise_flags(compiler, ins->flags); + if (ins->resource_type != VKD3D_SHADER_RESOURCE_NONE) { - vkd3d_string_buffer_printf(buffer, "_indexable("); + vkd3d_string_buffer_printf(buffer, "("); if (ins->raw) vkd3d_string_buffer_printf(buffer, "raw_"); if (ins->structured) @@ -2009,10 +1693,10 @@ static void shader_dump_instruction(struct vkd3d_d3d_asm_compiler *compiler, shader_print_int_literal(compiler, ",", ins->texel_offset.w, ")"); }
- if (ins->resource_data_type[0] != VKD3D_DATA_FLOAT - || ins->resource_data_type[1] != VKD3D_DATA_FLOAT - || ins->resource_data_type[2] != VKD3D_DATA_FLOAT - || ins->resource_data_type[3] != VKD3D_DATA_FLOAT) + if (ins->resource_data_type[0] != VSIR_DATA_F32 + || ins->resource_data_type[1] != VSIR_DATA_F32 + || ins->resource_data_type[2] != VSIR_DATA_F32 + || ins->resource_data_type[3] != VSIR_DATA_F32) shader_dump_resource_data_type(compiler, ins->resource_data_type);
for (i = 0; i < ins->dst_count; ++i) @@ -2276,9 +1960,8 @@ static void shader_print_descriptors(struct vkd3d_d3d_asm_compiler *compiler, } }
-enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, - const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, enum vsir_asm_flags flags) +enum vkd3d_result d3d_asm_compile(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context) { const struct vkd3d_shader_version *shader_version = &program->shader_version; enum vkd3d_shader_compile_option_formatting_flags formatting; @@ -2286,8 +1969,10 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, { .flags = flags, }; + struct vkd3d_shader_instruction *ins; enum vkd3d_result result = VKD3D_OK; struct vkd3d_string_buffer *buffer; + struct vsir_program_iterator it; unsigned int indent, i, j; const char *indent_str;
@@ -2344,6 +2029,14 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, if (formatting & VKD3D_SHADER_COMPILE_OPTION_FORMATTING_IO_SIGNATURES && shader_version->major >= 4) compiler.flags |= VSIR_ASM_FLAG_DUMP_SIGNATURES;
+ if (compiler.flags & VSIR_ASM_FLAG_ALLOCATE_TEMPS) + { + if ((result = vsir_allocate_temp_registers(program, message_context)) < 0) + return result; + if ((result = vsir_update_dcl_temps(program, message_context))) + return result; + } + buffer = &compiler.buffer; vkd3d_string_buffer_init(buffer);
@@ -2367,25 +2060,25 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, vkd3d_string_buffer_printf(buffer, "%s.text%s\n", compiler.colours.opcode, compiler.colours.reset);
indent = 0; - for (i = 0; i < program->instructions.count; ++i) - { - struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
+ it = vsir_program_iterator(&program->instructions); + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { switch (ins->opcode) { - case VKD3DSIH_ELSE: - case VKD3DSIH_ENDIF: - case VKD3DSIH_ENDLOOP: - case VKD3DSIH_ENDSWITCH: + case VSIR_OP_ELSE: + case VSIR_OP_ENDIF: + case VSIR_OP_ENDLOOP: + case VSIR_OP_ENDSWITCH: if (indent) --indent; break;
- case VKD3DSIH_LABEL: - case VKD3DSIH_HS_DECLS: - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_LABEL: + case VSIR_OP_HS_DECLS: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: indent = 0; break;
@@ -2402,12 +2095,12 @@ enum vkd3d_result d3d_asm_compile(const struct vsir_program *program,
switch (ins->opcode) { - case VKD3DSIH_ELSE: - case VKD3DSIH_IF: - case VKD3DSIH_IFC: - case VKD3DSIH_LOOP: - case VKD3DSIH_SWITCH: - case VKD3DSIH_LABEL: + case VSIR_OP_ELSE: + case VSIR_OP_IF: + case VSIR_OP_IFC: + case VSIR_OP_LOOP: + case VSIR_OP_SWITCH: + case VSIR_OP_LABEL: ++indent; break;
@@ -2561,21 +2254,26 @@ static void trace_io_declarations(const struct vsir_program *program) vkd3d_string_buffer_cleanup(&buffer); }
-void vsir_program_trace(const struct vsir_program *program) +void vsir_program_trace(struct vsir_program *program) { const unsigned int flags = VSIR_ASM_FLAG_DUMP_TYPES | VSIR_ASM_FLAG_DUMP_ALL_INDICES | VSIR_ASM_FLAG_DUMP_SIGNATURES | VSIR_ASM_FLAG_DUMP_DESCRIPTORS; + struct vkd3d_shader_message_context message_context; struct vkd3d_shader_code code; const char *p, *q, *end;
+ vkd3d_shader_message_context_init(&message_context, VKD3D_SHADER_LOG_NONE); + trace_signature(&program->input_signature, "Input"); trace_signature(&program->output_signature, "Output"); trace_signature(&program->patch_constant_signature, "Patch-constant"); trace_io_declarations(program);
- if (d3d_asm_compile(program, NULL, &code, flags) != VKD3D_OK) + if (d3d_asm_compile(program, NULL, &code, flags, &message_context) != VKD3D_OK) return;
+ vkd3d_shader_message_context_cleanup(&message_context); + end = (const char *)code.code + code.size; for (p = code.code; p < end; p = q) { diff --git a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c index 57d874efe37..751e5578276 100644 --- a/libs/vkd3d/libs/vkd3d-shader/d3dbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/d3dbc.c @@ -259,159 +259,159 @@ struct vkd3d_shader_sm1_parser static const struct vkd3d_sm1_opcode_info vs_opcode_table[] = { /* Arithmetic */ - {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP}, - {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV}, - {VKD3D_SM1_OP_MOVA, 1, 1, VKD3DSIH_MOVA, {2, 0}}, - {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD}, - {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB}, - {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD}, - {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL}, - {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP}, - {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ}, - {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3}, - {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4}, - {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN}, - {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX}, - {VKD3D_SM1_OP_SLT, 1, 2, VKD3DSIH_SLT}, - {VKD3D_SM1_OP_SGE, 1, 2, VKD3DSIH_SGE}, - {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}}, - {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP}, - {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG}, - {VKD3D_SM1_OP_EXPP, 1, 1, VKD3DSIH_EXPP}, - {VKD3D_SM1_OP_LOGP, 1, 1, VKD3DSIH_LOGP}, - {VKD3D_SM1_OP_LIT, 1, 1, VKD3DSIH_LIT}, - {VKD3D_SM1_OP_DST, 1, 2, VKD3DSIH_DST}, - {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP, {2, 0}}, - {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC}, - {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}}, - {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}}, - {VKD3D_SM1_OP_SGN, 1, 3, VKD3DSIH_SGN, {2, 0}, {2, 1}}, - {VKD3D_SM1_OP_SGN, 1, 1, VKD3DSIH_SGN, {3, 0}}, - {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}}, - {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}}, - {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}}, + {VKD3D_SM1_OP_NOP, 0, 0, VSIR_OP_NOP}, + {VKD3D_SM1_OP_MOV, 1, 1, VSIR_OP_MOV}, + {VKD3D_SM1_OP_MOVA, 1, 1, VSIR_OP_MOVA, {2, 0}}, + {VKD3D_SM1_OP_ADD, 1, 2, VSIR_OP_ADD}, + {VKD3D_SM1_OP_SUB, 1, 2, VSIR_OP_SUB}, + {VKD3D_SM1_OP_MAD, 1, 3, VSIR_OP_MAD}, + {VKD3D_SM1_OP_MUL, 1, 2, VSIR_OP_MUL}, + {VKD3D_SM1_OP_RCP, 1, 1, VSIR_OP_RCP}, + {VKD3D_SM1_OP_RSQ, 1, 1, VSIR_OP_RSQ}, + {VKD3D_SM1_OP_DP3, 1, 2, VSIR_OP_DP3}, + {VKD3D_SM1_OP_DP4, 1, 2, VSIR_OP_DP4}, + {VKD3D_SM1_OP_MIN, 1, 2, VSIR_OP_MIN}, + {VKD3D_SM1_OP_MAX, 1, 2, VSIR_OP_MAX}, + {VKD3D_SM1_OP_SLT, 1, 2, VSIR_OP_SLT}, + {VKD3D_SM1_OP_SGE, 1, 2, VSIR_OP_SGE}, + {VKD3D_SM1_OP_ABS, 1, 1, VSIR_OP_ABS, {2, 0}}, + {VKD3D_SM1_OP_EXP, 1, 1, VSIR_OP_EXP}, + {VKD3D_SM1_OP_LOG, 1, 1, VSIR_OP_LOG}, + {VKD3D_SM1_OP_EXPP, 1, 1, VSIR_OP_EXPP}, + {VKD3D_SM1_OP_LOGP, 1, 1, VSIR_OP_LOGP}, + {VKD3D_SM1_OP_LIT, 1, 1, VSIR_OP_LIT}, + {VKD3D_SM1_OP_DST, 1, 2, VSIR_OP_DST}, + {VKD3D_SM1_OP_LRP, 1, 3, VSIR_OP_LRP, {2, 0}}, + {VKD3D_SM1_OP_FRC, 1, 1, VSIR_OP_FRC}, + {VKD3D_SM1_OP_POW, 1, 2, VSIR_OP_POW, {2, 0}}, + {VKD3D_SM1_OP_CRS, 1, 2, VSIR_OP_CRS, {2, 0}}, + {VKD3D_SM1_OP_SGN, 1, 3, VSIR_OP_SGN, {2, 0}, {2, 1}}, + {VKD3D_SM1_OP_SGN, 1, 1, VSIR_OP_SGN, {3, 0}}, + {VKD3D_SM1_OP_NRM, 1, 1, VSIR_OP_NRM, {2, 0}}, + {VKD3D_SM1_OP_SINCOS, 1, 3, VSIR_OP_SINCOS, {2, 0}, {2, 1}}, + {VKD3D_SM1_OP_SINCOS, 1, 1, VSIR_OP_SINCOS, {3, 0}}, /* Matrix */ - {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4}, - {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3}, - {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4}, - {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3}, - {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2}, + {VKD3D_SM1_OP_M4x4, 1, 2, VSIR_OP_M4x4}, + {VKD3D_SM1_OP_M4x3, 1, 2, VSIR_OP_M4x3}, + {VKD3D_SM1_OP_M3x4, 1, 2, VSIR_OP_M3x4}, + {VKD3D_SM1_OP_M3x3, 1, 2, VSIR_OP_M3x3}, + {VKD3D_SM1_OP_M3x2, 1, 2, VSIR_OP_M3x2}, /* Declarations */ - {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL}, + {VKD3D_SM1_OP_DCL, 0, 0, VSIR_OP_DCL}, /* Constant definitions */ - {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, - {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}}, - {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 0}}, + {VKD3D_SM1_OP_DEF, 1, 1, VSIR_OP_DEF}, + {VKD3D_SM1_OP_DEFB, 1, 1, VSIR_OP_DEFB, {2, 0}}, + {VKD3D_SM1_OP_DEFI, 1, 1, VSIR_OP_DEFI, {2, 0}}, /* Control flow */ - {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 0}}, - {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 0}}, - {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 0}}, - {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}}, - {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 0}}, - {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 0}}, - {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}}, - {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}}, - {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}}, - {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 0}}, - {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 0}}, - {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {2, 0}}, - {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 0}}, - {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {2, 0}}, - {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 0}}, - - {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}}, - {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}}, - {0, 0, 0, VKD3DSIH_INVALID}, + {VKD3D_SM1_OP_REP, 0, 1, VSIR_OP_REP, {2, 0}}, + {VKD3D_SM1_OP_ENDREP, 0, 0, VSIR_OP_ENDREP, {2, 0}}, + {VKD3D_SM1_OP_IF, 0, 1, VSIR_OP_IF, {2, 0}}, + {VKD3D_SM1_OP_IFC, 0, 2, VSIR_OP_IFC, {2, 1}}, + {VKD3D_SM1_OP_ELSE, 0, 0, VSIR_OP_ELSE, {2, 0}}, + {VKD3D_SM1_OP_ENDIF, 0, 0, VSIR_OP_ENDIF, {2, 0}}, + {VKD3D_SM1_OP_BREAK, 0, 0, VSIR_OP_BREAK, {2, 1}}, + {VKD3D_SM1_OP_BREAKC, 0, 2, VSIR_OP_BREAKC, {2, 1}}, + {VKD3D_SM1_OP_BREAKP, 0, 1, VSIR_OP_BREAKP, {2, 1}}, + {VKD3D_SM1_OP_CALL, 0, 1, VSIR_OP_CALL, {2, 0}}, + {VKD3D_SM1_OP_CALLNZ, 0, 2, VSIR_OP_CALLNZ, {2, 0}}, + {VKD3D_SM1_OP_LOOP, 0, 2, VSIR_OP_LOOP, {2, 0}}, + {VKD3D_SM1_OP_RET, 0, 0, VSIR_OP_RET, {2, 0}}, + {VKD3D_SM1_OP_ENDLOOP, 0, 0, VSIR_OP_ENDLOOP, {2, 0}}, + {VKD3D_SM1_OP_LABEL, 0, 1, VSIR_OP_LABEL, {2, 0}}, + + {VKD3D_SM1_OP_SETP, 1, 2, VSIR_OP_SETP, {2, 1}}, + {VKD3D_SM1_OP_TEXLDL, 1, 2, VSIR_OP_TEXLDL, {3, 0}}, + {0, 0, 0, VSIR_OP_INVALID}, };
static const struct vkd3d_sm1_opcode_info ps_opcode_table[] = { /* Arithmetic */ - {VKD3D_SM1_OP_NOP, 0, 0, VKD3DSIH_NOP}, - {VKD3D_SM1_OP_MOV, 1, 1, VKD3DSIH_MOV}, - {VKD3D_SM1_OP_ADD, 1, 2, VKD3DSIH_ADD}, - {VKD3D_SM1_OP_SUB, 1, 2, VKD3DSIH_SUB}, - {VKD3D_SM1_OP_MAD, 1, 3, VKD3DSIH_MAD}, - {VKD3D_SM1_OP_MUL, 1, 2, VKD3DSIH_MUL}, - {VKD3D_SM1_OP_RCP, 1, 1, VKD3DSIH_RCP, {2, 0}}, - {VKD3D_SM1_OP_RSQ, 1, 1, VKD3DSIH_RSQ, {2, 0}}, - {VKD3D_SM1_OP_DP3, 1, 2, VKD3DSIH_DP3}, - {VKD3D_SM1_OP_DP4, 1, 2, VKD3DSIH_DP4, {1, 2}}, - {VKD3D_SM1_OP_MIN, 1, 2, VKD3DSIH_MIN, {2, 0}}, - {VKD3D_SM1_OP_MAX, 1, 2, VKD3DSIH_MAX, {2, 0}}, - {VKD3D_SM1_OP_ABS, 1, 1, VKD3DSIH_ABS, {2, 0}}, - {VKD3D_SM1_OP_EXP, 1, 1, VKD3DSIH_EXP, {2, 0}}, - {VKD3D_SM1_OP_LOG, 1, 1, VKD3DSIH_LOG, {2, 0}}, - {VKD3D_SM1_OP_LRP, 1, 3, VKD3DSIH_LRP}, - {VKD3D_SM1_OP_FRC, 1, 1, VKD3DSIH_FRC, {2, 0}}, - {VKD3D_SM1_OP_CND, 1, 3, VKD3DSIH_CND, {1, 0}, {1, 4}}, - {VKD3D_SM1_OP_CMP, 1, 3, VKD3DSIH_CMP, {1, 2}}, - {VKD3D_SM1_OP_POW, 1, 2, VKD3DSIH_POW, {2, 0}}, - {VKD3D_SM1_OP_CRS, 1, 2, VKD3DSIH_CRS, {2, 0}}, - {VKD3D_SM1_OP_NRM, 1, 1, VKD3DSIH_NRM, {2, 0}}, - {VKD3D_SM1_OP_SINCOS, 1, 3, VKD3DSIH_SINCOS, {2, 0}, {2, 1}}, - {VKD3D_SM1_OP_SINCOS, 1, 1, VKD3DSIH_SINCOS, {3, 0}}, - {VKD3D_SM1_OP_DP2ADD, 1, 3, VKD3DSIH_DP2ADD, {2, 0}}, + {VKD3D_SM1_OP_NOP, 0, 0, VSIR_OP_NOP}, + {VKD3D_SM1_OP_MOV, 1, 1, VSIR_OP_MOV}, + {VKD3D_SM1_OP_ADD, 1, 2, VSIR_OP_ADD}, + {VKD3D_SM1_OP_SUB, 1, 2, VSIR_OP_SUB}, + {VKD3D_SM1_OP_MAD, 1, 3, VSIR_OP_MAD}, + {VKD3D_SM1_OP_MUL, 1, 2, VSIR_OP_MUL}, + {VKD3D_SM1_OP_RCP, 1, 1, VSIR_OP_RCP, {2, 0}}, + {VKD3D_SM1_OP_RSQ, 1, 1, VSIR_OP_RSQ, {2, 0}}, + {VKD3D_SM1_OP_DP3, 1, 2, VSIR_OP_DP3}, + {VKD3D_SM1_OP_DP4, 1, 2, VSIR_OP_DP4, {1, 2}}, + {VKD3D_SM1_OP_MIN, 1, 2, VSIR_OP_MIN, {2, 0}}, + {VKD3D_SM1_OP_MAX, 1, 2, VSIR_OP_MAX, {2, 0}}, + {VKD3D_SM1_OP_ABS, 1, 1, VSIR_OP_ABS, {2, 0}}, + {VKD3D_SM1_OP_EXP, 1, 1, VSIR_OP_EXP, {2, 0}}, + {VKD3D_SM1_OP_LOG, 1, 1, VSIR_OP_LOG, {2, 0}}, + {VKD3D_SM1_OP_LRP, 1, 3, VSIR_OP_LRP}, + {VKD3D_SM1_OP_FRC, 1, 1, VSIR_OP_FRC, {2, 0}}, + {VKD3D_SM1_OP_CND, 1, 3, VSIR_OP_CND, {1, 0}, {1, 4}}, + {VKD3D_SM1_OP_CMP, 1, 3, VSIR_OP_CMP, {1, 2}}, + {VKD3D_SM1_OP_POW, 1, 2, VSIR_OP_POW, {2, 0}}, + {VKD3D_SM1_OP_CRS, 1, 2, VSIR_OP_CRS, {2, 0}}, + {VKD3D_SM1_OP_NRM, 1, 1, VSIR_OP_NRM, {2, 0}}, + {VKD3D_SM1_OP_SINCOS, 1, 3, VSIR_OP_SINCOS, {2, 0}, {2, 1}}, + {VKD3D_SM1_OP_SINCOS, 1, 1, VSIR_OP_SINCOS, {3, 0}}, + {VKD3D_SM1_OP_DP2ADD, 1, 3, VSIR_OP_DP2ADD, {2, 0}}, /* Matrix */ - {VKD3D_SM1_OP_M4x4, 1, 2, VKD3DSIH_M4x4, {2, 0}}, - {VKD3D_SM1_OP_M4x3, 1, 2, VKD3DSIH_M4x3, {2, 0}}, - {VKD3D_SM1_OP_M3x4, 1, 2, VKD3DSIH_M3x4, {2, 0}}, - {VKD3D_SM1_OP_M3x3, 1, 2, VKD3DSIH_M3x3, {2, 0}}, - {VKD3D_SM1_OP_M3x2, 1, 2, VKD3DSIH_M3x2, {2, 0}}, + {VKD3D_SM1_OP_M4x4, 1, 2, VSIR_OP_M4x4, {2, 0}}, + {VKD3D_SM1_OP_M4x3, 1, 2, VSIR_OP_M4x3, {2, 0}}, + {VKD3D_SM1_OP_M3x4, 1, 2, VSIR_OP_M3x4, {2, 0}}, + {VKD3D_SM1_OP_M3x3, 1, 2, VSIR_OP_M3x3, {2, 0}}, + {VKD3D_SM1_OP_M3x2, 1, 2, VSIR_OP_M3x2, {2, 0}}, /* Declarations */ - {VKD3D_SM1_OP_DCL, 0, 0, VKD3DSIH_DCL, {2, 0}}, + {VKD3D_SM1_OP_DCL, 0, 0, VSIR_OP_DCL, {2, 0}}, /* Constant definitions */ - {VKD3D_SM1_OP_DEF, 1, 1, VKD3DSIH_DEF}, - {VKD3D_SM1_OP_DEFB, 1, 1, VKD3DSIH_DEFB, {2, 0}}, - {VKD3D_SM1_OP_DEFI, 1, 1, VKD3DSIH_DEFI, {2, 1}}, + {VKD3D_SM1_OP_DEF, 1, 1, VSIR_OP_DEF}, + {VKD3D_SM1_OP_DEFB, 1, 1, VSIR_OP_DEFB, {2, 0}}, + {VKD3D_SM1_OP_DEFI, 1, 1, VSIR_OP_DEFI, {2, 1}}, /* Control flow */ - {VKD3D_SM1_OP_REP, 0, 1, VKD3DSIH_REP, {2, 1}}, - {VKD3D_SM1_OP_ENDREP, 0, 0, VKD3DSIH_ENDREP, {2, 1}}, - {VKD3D_SM1_OP_IF, 0, 1, VKD3DSIH_IF, {2, 1}}, - {VKD3D_SM1_OP_IFC, 0, 2, VKD3DSIH_IFC, {2, 1}}, - {VKD3D_SM1_OP_ELSE, 0, 0, VKD3DSIH_ELSE, {2, 1}}, - {VKD3D_SM1_OP_ENDIF, 0, 0, VKD3DSIH_ENDIF, {2, 1}}, - {VKD3D_SM1_OP_BREAK, 0, 0, VKD3DSIH_BREAK, {2, 1}}, - {VKD3D_SM1_OP_BREAKC, 0, 2, VKD3DSIH_BREAKC, {2, 1}}, - {VKD3D_SM1_OP_BREAKP, 0, 1, VKD3DSIH_BREAKP, {2, 1}}, - {VKD3D_SM1_OP_CALL, 0, 1, VKD3DSIH_CALL, {2, 1}}, - {VKD3D_SM1_OP_CALLNZ, 0, 2, VKD3DSIH_CALLNZ, {2, 1}}, - {VKD3D_SM1_OP_LOOP, 0, 2, VKD3DSIH_LOOP, {3, 0}}, - {VKD3D_SM1_OP_RET, 0, 0, VKD3DSIH_RET, {2, 1}}, - {VKD3D_SM1_OP_ENDLOOP, 0, 0, VKD3DSIH_ENDLOOP, {3, 0}}, - {VKD3D_SM1_OP_LABEL, 0, 1, VKD3DSIH_LABEL, {2, 1}}, + {VKD3D_SM1_OP_REP, 0, 1, VSIR_OP_REP, {2, 1}}, + {VKD3D_SM1_OP_ENDREP, 0, 0, VSIR_OP_ENDREP, {2, 1}}, + {VKD3D_SM1_OP_IF, 0, 1, VSIR_OP_IF, {2, 1}}, + {VKD3D_SM1_OP_IFC, 0, 2, VSIR_OP_IFC, {2, 1}}, + {VKD3D_SM1_OP_ELSE, 0, 0, VSIR_OP_ELSE, {2, 1}}, + {VKD3D_SM1_OP_ENDIF, 0, 0, VSIR_OP_ENDIF, {2, 1}}, + {VKD3D_SM1_OP_BREAK, 0, 0, VSIR_OP_BREAK, {2, 1}}, + {VKD3D_SM1_OP_BREAKC, 0, 2, VSIR_OP_BREAKC, {2, 1}}, + {VKD3D_SM1_OP_BREAKP, 0, 1, VSIR_OP_BREAKP, {2, 1}}, + {VKD3D_SM1_OP_CALL, 0, 1, VSIR_OP_CALL, {2, 1}}, + {VKD3D_SM1_OP_CALLNZ, 0, 2, VSIR_OP_CALLNZ, {2, 1}}, + {VKD3D_SM1_OP_LOOP, 0, 2, VSIR_OP_LOOP, {3, 0}}, + {VKD3D_SM1_OP_RET, 0, 0, VSIR_OP_RET, {2, 1}}, + {VKD3D_SM1_OP_ENDLOOP, 0, 0, VSIR_OP_ENDLOOP, {3, 0}}, + {VKD3D_SM1_OP_LABEL, 0, 1, VSIR_OP_LABEL, {2, 1}}, /* Texture */ - {VKD3D_SM1_OP_TEXCOORD, 1, 0, VKD3DSIH_TEXCOORD, {0, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXCOORD, 1, 1, VKD3DSIH_TEXCOORD, {1, 4}, {1, 4}}, - {VKD3D_SM1_OP_TEXKILL, 1, 0, VKD3DSIH_TEXKILL, {1, 0}}, - {VKD3D_SM1_OP_TEX, 1, 0, VKD3DSIH_TEX, {0, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEX, 1, 1, VKD3DSIH_TEX, {1, 4}, {1, 4}}, - {VKD3D_SM1_OP_TEX, 1, 2, VKD3DSIH_TEX, {2, 0}}, - {VKD3D_SM1_OP_TEXBEM, 1, 1, VKD3DSIH_TEXBEM, {0, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXBEML, 1, 1, VKD3DSIH_TEXBEML, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VKD3DSIH_TEXREG2AR, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VKD3DSIH_TEXREG2GB, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VKD3DSIH_TEXREG2RGB, {1, 2}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VKD3DSIH_TEXM3x2PAD, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VKD3DSIH_TEXM3x2TEX, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VKD3DSIH_TEXM3x3PAD, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VKD3DSIH_TEXM3x3DIFF, {0, 0}, {0, 0}}, - {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VKD3DSIH_TEXM3x3SPEC, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VKD3DSIH_TEXM3x3VSPEC, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VKD3DSIH_TEXM3x3TEX, {1, 0}, {1, 3}}, - {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VKD3DSIH_TEXDP3TEX, {1, 2}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VKD3DSIH_TEXM3x2DEPTH, {1, 3}, {1, 3}}, - {VKD3D_SM1_OP_TEXDP3, 1, 1, VKD3DSIH_TEXDP3, {1, 2}, {1, 3}}, - {VKD3D_SM1_OP_TEXM3x3, 1, 1, VKD3DSIH_TEXM3x3, {1, 2}, {1, 3}}, - {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VKD3DSIH_TEXDEPTH, {1, 4}, {1, 4}}, - {VKD3D_SM1_OP_BEM, 1, 2, VKD3DSIH_BEM, {1, 4}, {1, 4}}, - {VKD3D_SM1_OP_DSX, 1, 1, VKD3DSIH_DSX, {2, 1}}, - {VKD3D_SM1_OP_DSY, 1, 1, VKD3DSIH_DSY, {2, 1}}, - {VKD3D_SM1_OP_TEXLDD, 1, 4, VKD3DSIH_TEXLDD, {2, 1}}, - {VKD3D_SM1_OP_SETP, 1, 2, VKD3DSIH_SETP, {2, 1}}, - {VKD3D_SM1_OP_TEXLDL, 1, 2, VKD3DSIH_TEXLDL, {3, 0}}, - {VKD3D_SM1_OP_PHASE, 0, 0, VKD3DSIH_PHASE, {1, 4}, {1, 4}}, - {0, 0, 0, VKD3DSIH_INVALID}, + {VKD3D_SM1_OP_TEXCOORD, 1, 0, VSIR_OP_TEXCOORD, {0, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXCOORD, 1, 1, VSIR_OP_TEXCRD, {1, 4}, {1, 4}}, + {VKD3D_SM1_OP_TEXKILL, 1, 0, VSIR_OP_TEXKILL, {1, 0}}, + {VKD3D_SM1_OP_TEX, 1, 0, VSIR_OP_TEX, {0, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEX, 1, 1, VSIR_OP_TEXLD, {1, 4}, {1, 4}}, + {VKD3D_SM1_OP_TEX, 1, 2, VSIR_OP_TEXLD, {2, 0}}, + {VKD3D_SM1_OP_TEXBEM, 1, 1, VSIR_OP_TEXBEM, {0, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXBEML, 1, 1, VSIR_OP_TEXBEML, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXREG2AR, 1, 1, VSIR_OP_TEXREG2AR, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXREG2GB, 1, 1, VSIR_OP_TEXREG2GB, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXREG2RGB, 1, 1, VSIR_OP_TEXREG2RGB, {1, 2}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x2PAD, 1, 1, VSIR_OP_TEXM3x2PAD, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x2TEX, 1, 1, VSIR_OP_TEXM3x2TEX, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x3PAD, 1, 1, VSIR_OP_TEXM3x3PAD, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x3DIFF, 1, 1, VSIR_OP_TEXM3x3DIFF, {0, 0}, {0, 0}}, + {VKD3D_SM1_OP_TEXM3x3SPEC, 1, 2, VSIR_OP_TEXM3x3SPEC, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x3VSPEC, 1, 1, VSIR_OP_TEXM3x3VSPEC, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x3TEX, 1, 1, VSIR_OP_TEXM3x3TEX, {1, 0}, {1, 3}}, + {VKD3D_SM1_OP_TEXDP3TEX, 1, 1, VSIR_OP_TEXDP3TEX, {1, 2}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x2DEPTH, 1, 1, VSIR_OP_TEXM3x2DEPTH, {1, 3}, {1, 3}}, + {VKD3D_SM1_OP_TEXDP3, 1, 1, VSIR_OP_TEXDP3, {1, 2}, {1, 3}}, + {VKD3D_SM1_OP_TEXM3x3, 1, 1, VSIR_OP_TEXM3x3, {1, 2}, {1, 3}}, + {VKD3D_SM1_OP_TEXDEPTH, 1, 0, VSIR_OP_TEXDEPTH, {1, 4}, {1, 4}}, + {VKD3D_SM1_OP_BEM, 1, 2, VSIR_OP_BEM, {1, 4}, {1, 4}}, + {VKD3D_SM1_OP_DSX, 1, 1, VSIR_OP_DSX, {2, 1}}, + {VKD3D_SM1_OP_DSY, 1, 1, VSIR_OP_DSY, {2, 1}}, + {VKD3D_SM1_OP_TEXLDD, 1, 4, VSIR_OP_TEXLDD, {2, 1}}, + {VKD3D_SM1_OP_SETP, 1, 2, VSIR_OP_SETP, {2, 1}}, + {VKD3D_SM1_OP_TEXLDL, 1, 2, VSIR_OP_TEXLDL, {3, 0}}, + {VKD3D_SM1_OP_PHASE, 0, 0, VSIR_OP_PHASE, {1, 4}, {1, 4}}, + {0, 0, 0, VSIR_OP_INVALID}, };
static const struct @@ -475,7 +475,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info( for (;;) { info = &sm1->opcode_table[i++]; - if (info->vkd3d_opcode == VKD3DSIH_INVALID) + if (info->vkd3d_opcode == VSIR_OP_INVALID) return NULL;
if (opcode == info->sm1_opcode @@ -563,7 +563,7 @@ static void d3dbc_parse_register(struct vkd3d_shader_sm1_parser *d3dbc,
reg_type = parse_register_type(d3dbc, param, &index_offset); idx_count = idx_count_from_reg_type(reg_type); - vsir_register_init(reg, reg_type, VKD3D_DATA_FLOAT, idx_count); + vsir_register_init(reg, reg_type, VSIR_DATA_F32, idx_count); reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; reg->non_uniform = false; if (idx_count == 1) @@ -994,7 +994,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co /* DCL instructions do not have sources or destinations, but they * read two tokens to a semantic. See * shader_sm1_read_semantic(). */ - if (opcode_info->vkd3d_opcode == VKD3DSIH_DCL) + if (opcode_info->vkd3d_opcode == VSIR_OP_DCL) { *ptr += 2; } @@ -1002,7 +1002,7 @@ static void shader_sm1_skip_opcode(const struct vkd3d_shader_sm1_parser *sm1, co * four tokens for that source. See shader_sm1_read_immconst(). * Technically shader model 1 doesn't have integer registers or DEFI; we * handle it here anyway because it's easy. */ - else if (opcode_info->vkd3d_opcode == VKD3DSIH_DEF || opcode_info->vkd3d_opcode == VKD3DSIH_DEFI) + else if (opcode_info->vkd3d_opcode == VSIR_OP_DEF || opcode_info->vkd3d_opcode == VSIR_OP_DEFI) { *ptr += 3; } @@ -1088,10 +1088,10 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, { semantic->resource_type = resource_type_table[resource_type]; } - semantic->resource_data_type[0] = VKD3D_DATA_FLOAT; - semantic->resource_data_type[1] = VKD3D_DATA_FLOAT; - semantic->resource_data_type[2] = VKD3D_DATA_FLOAT; - semantic->resource_data_type[3] = VKD3D_DATA_FLOAT; + semantic->resource_data_type[0] = VSIR_DATA_F32; + semantic->resource_data_type[1] = VSIR_DATA_F32; + semantic->resource_data_type[2] = VSIR_DATA_F32; + semantic->resource_data_type[3] = VSIR_DATA_F32; shader_sm1_parse_dst_param(sm1, dst_token, NULL, &semantic->resource.reg); range = &semantic->resource.range; range->space = 0; @@ -1101,7 +1101,7 @@ static void shader_sm1_read_semantic(struct vkd3d_shader_sm1_parser *sm1, }
static void shader_sm1_read_immconst(struct vkd3d_shader_sm1_parser *sm1, const uint32_t **ptr, - struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vkd3d_data_type data_type) + struct vkd3d_shader_src_param *src_param, enum vsir_dimension dimension, enum vsir_data_type data_type) { unsigned int count = dimension == VSIR_DIMENSION_VEC4 ? 4 : 1;
@@ -1194,7 +1194,7 @@ static void shader_sm1_read_comment(struct vkd3d_shader_sm1_parser *sm1)
static void shader_sm1_validate_instruction(struct vkd3d_shader_sm1_parser *sm1, struct vkd3d_shader_instruction *ins) { - if ((ins->opcode == VKD3DSIH_BREAKP || ins->opcode == VKD3DSIH_IF) && ins->flags) + if ((ins->opcode == VSIR_OP_BREAKP || ins->opcode == VSIR_OP_IF) && ins->flags) { vkd3d_shader_parser_warning(&sm1->p, VKD3D_SHADER_WARNING_D3DBC_IGNORED_INSTRUCTION_FLAGS, "Ignoring unexpected instruction flags %#x.", ins->flags); @@ -1242,7 +1242,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str goto fail; }
- if (opcode_info->vkd3d_opcode == VKD3DSIH_TEXKILL) + if (opcode_info->vkd3d_opcode == VSIR_OP_TEXKILL) { vsir_src_count = 1; vsir_dst_count = 0; @@ -1272,10 +1272,10 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str
ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; ins->resource_stride = 0; - ins->resource_data_type[0] = VKD3D_DATA_FLOAT; - ins->resource_data_type[1] = VKD3D_DATA_FLOAT; - ins->resource_data_type[2] = VKD3D_DATA_FLOAT; - ins->resource_data_type[3] = VKD3D_DATA_FLOAT; + ins->resource_data_type[0] = VSIR_DATA_F32; + ins->resource_data_type[1] = VSIR_DATA_F32; + ins->resource_data_type[2] = VSIR_DATA_F32; + ins->resource_data_type[3] = VSIR_DATA_F32; memset(&ins->texel_offset, 0, sizeof(ins->texel_offset));
p = *ptr; @@ -1288,29 +1288,29 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str goto fail; }
- if (ins->opcode == VKD3DSIH_DCL) + if (ins->opcode == VSIR_OP_DCL) { shader_sm1_read_semantic(sm1, &p, &ins->declaration.semantic); } - else if (ins->opcode == VKD3DSIH_DEF) + else if (ins->opcode == VSIR_OP_DEF) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_FLOAT); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_F32); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } - else if (ins->opcode == VKD3DSIH_DEFB) + else if (ins->opcode == VSIR_OP_DEFB) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VKD3D_DATA_UINT); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_SCALAR, VSIR_DATA_U32); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } - else if (ins->opcode == VKD3DSIH_DEFI) + else if (ins->opcode == VSIR_OP_DEFI) { shader_sm1_read_dst_param(sm1, &p, dst_param); - shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VKD3D_DATA_INT); + shader_sm1_read_immconst(sm1, &p, &src_params[0], VSIR_DIMENSION_VEC4, VSIR_DATA_I32); shader_sm1_scan_register(sm1, &dst_param->reg, dst_param->write_mask, true); } - else if (ins->opcode == VKD3DSIH_TEXKILL) + else if (ins->opcode == VSIR_OP_TEXKILL) { /* TEXKILL, uniquely, encodes its argument as a destination, when it is * semantically a source. Since we have multiple passes which operate @@ -1360,7 +1360,7 @@ static void shader_sm1_read_instruction(struct vkd3d_shader_sm1_parser *sm1, str return;
fail: - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; *ptr = sm1->end; }
@@ -1472,7 +1472,6 @@ static uint32_t get_external_constant_count(struct vkd3d_shader_sm1_parser *sm1, int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, struct vkd3d_shader_message_context *message_context, struct vsir_program *program) { - struct vkd3d_shader_instruction_array *instructions; struct vkd3d_shader_sm1_parser sm1 = {0}; struct vkd3d_shader_instruction *ins; unsigned int i; @@ -1484,26 +1483,22 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c return ret; }
- instructions = &program->instructions; while (!shader_sm1_is_end(&sm1)) { - if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) + if (!(ins = vsir_program_append(program))) { - ERR("Failed to allocate instructions.\n"); vkd3d_shader_parser_error(&sm1.p, VKD3D_SHADER_ERROR_D3DBC_OUT_OF_MEMORY, "Out of memory."); vsir_program_cleanup(program); return VKD3D_ERROR_OUT_OF_MEMORY; } - ins = &instructions->elements[instructions->count]; shader_sm1_read_instruction(&sm1, ins);
- if (ins->opcode == VKD3DSIH_INVALID) + if (ins->opcode == VSIR_OP_INVALID) { WARN("Encountered unrecognized or invalid instruction.\n"); vsir_program_cleanup(program); return VKD3D_ERROR_INVALID_SHADER; } - ++instructions->count; }
for (i = 0; i < ARRAY_SIZE(program->flat_constant_count); ++i) @@ -1518,7 +1513,10 @@ int d3dbc_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t c return ret; }
- return VKD3D_OK; + if (program->normalisation_level >= VSIR_NORMALISED_SM4) + ret = vsir_program_lower_d3dbc(program, config_flags, compile_info, message_context); + + return ret; }
bool sm1_register_from_semantic_name(const struct vkd3d_shader_version *version, const char *semantic_name, @@ -1662,7 +1660,7 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir( for (;;) { info = &d3dbc->opcode_table[i++]; - if (info->vkd3d_opcode == VKD3DSIH_INVALID) + if (info->vkd3d_opcode == VSIR_OP_INVALID) return NULL;
if (vkd3d_opcode == info->vkd3d_opcode @@ -1681,7 +1679,8 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ if (!(info = shader_sm1_get_opcode_info_from_vsir(d3dbc, ins->opcode))) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, - "Opcode %#x not supported for shader profile.", ins->opcode); + "Instruction "%s" (%#x) is not supported for the current target.", + vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode); d3dbc->failed = true; return NULL; } @@ -1689,16 +1688,16 @@ static const struct vkd3d_sm1_opcode_info *shader_sm1_get_opcode_info_from_vsir_ if (ins->dst_count != info->dst_count) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, - "Invalid destination count %u for vsir instruction %#x (expected %u).", - ins->dst_count, ins->opcode, info->dst_count); + "Invalid destination parameter count %zu for instruction "%s" (%#x); expected %u.", + ins->dst_count, vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode, info->dst_count); d3dbc->failed = true; return NULL; } if (ins->src_count != info->src_count) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_REGISTER_COUNT, - "Invalid source count %u for vsir instruction %#x (expected %u).", - ins->src_count, ins->opcode, info->src_count); + "Invalid source parameter count %zu for instruction "%s" (%#x); expected %u.", + ins->src_count, vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode, info->src_count); d3dbc->failed = true; return NULL; } @@ -1772,7 +1771,7 @@ static bool is_inconsequential_instr(const struct vkd3d_shader_instruction *ins) const struct vkd3d_shader_src_param *src = &ins->src[0]; unsigned int i;
- if (ins->opcode != VKD3DSIH_MOV) + if (ins->opcode != VSIR_OP_MOV) return false; if (dst->modifiers != VKD3DSPDM_NONE) return false; @@ -1829,6 +1828,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v struct vkd3d_bytecode_buffer *buffer = &d3dbc->buffer; const struct vkd3d_shader_src_param *src; const struct vkd3d_sm1_opcode_info *info; + size_t size, token_position; unsigned int i; uint32_t token;
@@ -1841,9 +1841,7 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v token = info->sm1_opcode; token |= VKD3D_SM1_INSTRUCTION_FLAGS_MASK & (ins->flags << VKD3D_SM1_INSTRUCTION_FLAGS_SHIFT);
- if (version->major > 1) - token |= (ins->dst_count + ins->src_count) << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT; - put_u32(buffer, token); + token_position = put_u32(buffer, 0);
for (i = 0; i < ins->dst_count; ++i) { @@ -1863,6 +1861,14 @@ static void d3dbc_write_instruction(struct d3dbc_compiler *d3dbc, const struct v if (src->reg.idx_count && src->reg.idx[0].rel_addr) write_sm1_src_register(buffer, src->reg.idx[0].rel_addr); } + + if (version->major > 1) + { + size = (bytecode_get_size(buffer) - token_position) / sizeof(uint32_t); + token |= ((size - 1) << VKD3D_SM1_INSTRUCTION_LENGTH_SHIFT); + } + + set_u32(buffer, token_position, token); };
static void d3dbc_write_texkill(struct d3dbc_compiler *d3dbc, const struct vkd3d_shader_instruction *ins) @@ -1982,55 +1988,56 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
switch (ins->opcode) { - case VKD3DSIH_DEF: + case VSIR_OP_DEF: d3dbc_write_vsir_def(d3dbc, ins); break;
- case VKD3DSIH_DCL: + case VSIR_OP_DCL: d3dbc_write_vsir_dcl(d3dbc, ins); break;
- case VKD3DSIH_TEXKILL: + case VSIR_OP_TEXKILL: d3dbc_write_texkill(d3dbc, ins); break;
- case VKD3DSIH_ABS: - case VKD3DSIH_ADD: - case VKD3DSIH_CMP: - case VKD3DSIH_DP2ADD: - case VKD3DSIH_DP3: - case VKD3DSIH_DP4: - case VKD3DSIH_DSX: - case VKD3DSIH_DSY: - case VKD3DSIH_ELSE: - case VKD3DSIH_ENDIF: - case VKD3DSIH_FRC: - case VKD3DSIH_IFC: - case VKD3DSIH_MAD: - case VKD3DSIH_MAX: - case VKD3DSIH_MIN: - case VKD3DSIH_MOV: - case VKD3DSIH_MOVA: - case VKD3DSIH_MUL: - case VKD3DSIH_SINCOS: - case VKD3DSIH_SLT: - case VKD3DSIH_TEX: - case VKD3DSIH_TEXLDD: + case VSIR_OP_ABS: + case VSIR_OP_ADD: + case VSIR_OP_CMP: + case VSIR_OP_DP2ADD: + case VSIR_OP_DP3: + case VSIR_OP_DP4: + case VSIR_OP_DSX: + case VSIR_OP_DSY: + case VSIR_OP_ELSE: + case VSIR_OP_ENDIF: + case VSIR_OP_FRC: + case VSIR_OP_IFC: + case VSIR_OP_MAD: + case VSIR_OP_MAX: + case VSIR_OP_MIN: + case VSIR_OP_MOV: + case VSIR_OP_MOVA: + case VSIR_OP_MUL: + case VSIR_OP_SINCOS: + case VSIR_OP_SLT: + case VSIR_OP_TEXLD: + case VSIR_OP_TEXLDL: + case VSIR_OP_TEXLDD: d3dbc_write_instruction(d3dbc, ins); break;
- case VKD3DSIH_EXP: - case VKD3DSIH_LOG: - case VKD3DSIH_RCP: - case VKD3DSIH_RSQ: + case VSIR_OP_EXP: + case VSIR_OP_LOG: + case VSIR_OP_RCP: + case VSIR_OP_RSQ: writemask = ins->dst->write_mask; if (writemask != VKD3DSP_WRITEMASK_0 && writemask != VKD3DSP_WRITEMASK_1 && writemask != VKD3DSP_WRITEMASK_2 && writemask != VKD3DSP_WRITEMASK_3) { vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_WRITEMASK, - "writemask %#x for vsir instruction with opcode %#x is not single component.", - writemask, ins->opcode); + "Writemask %#x for instruction "%s" (%#x) is not single component.", + writemask, vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode); d3dbc->failed = true; } d3dbc_write_instruction(d3dbc, ins); @@ -2038,7 +2045,8 @@ static void d3dbc_write_vsir_instruction(struct d3dbc_compiler *d3dbc, const str
default: vkd3d_shader_error(d3dbc->message_context, &ins->location, VKD3D_SHADER_ERROR_D3DBC_INVALID_OPCODE, - "vsir instruction with opcode %#x.", ins->opcode); + "Internal compiler error: Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode); d3dbc->failed = true; break; } @@ -2067,6 +2075,13 @@ static void d3dbc_write_semantic_dcl(struct d3dbc_compiler *d3dbc, VKD3D_ASSERT(ret); reg.reg.type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT; reg.reg.idx[0].offset = element->register_index; + if (!vkd3d_shader_ver_ge(version, 3, 0)) + { + if (reg.reg.idx[0].offset > SM1_RASTOUT_REGISTER_OFFSET) + reg.reg.idx[0].offset -= SM1_RASTOUT_REGISTER_OFFSET; + else if (reg.reg.idx[0].offset > SM1_COLOR_REGISTER_OFFSET) + reg.reg.idx[0].offset -= SM1_COLOR_REGISTER_OFFSET; + } }
token = VKD3D_SM1_OP_DCL; @@ -2112,11 +2127,13 @@ static void d3dbc_write_semantic_dcls(struct d3dbc_compiler *d3dbc)
static void d3dbc_write_program_instructions(struct d3dbc_compiler *d3dbc) { - struct vsir_program *program = d3dbc->program; - unsigned int i; + struct vsir_program_iterator it = vsir_program_iterator(&d3dbc->program->instructions); + struct vkd3d_shader_instruction *ins;
- for (i = 0; i < program->instructions.count; ++i) - d3dbc_write_vsir_instruction(d3dbc, &program->instructions.elements[i]); + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + d3dbc_write_vsir_instruction(d3dbc, ins); + } }
int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, @@ -2128,6 +2145,12 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, struct vkd3d_bytecode_buffer *buffer = &d3dbc.buffer; int result;
+ if ((result = vsir_allocate_temp_registers(program, message_context))) + return result; + + if ((result = vsir_update_dcl_temps(program, message_context))) + return result; + d3dbc.program = program; d3dbc.message_context = message_context; switch (version->type) @@ -2147,7 +2170,7 @@ int d3dbc_compile(struct vsir_program *program, uint64_t config_flags, }
put_u32(buffer, sm1_version(version->type, version->major, version->minor)); - d3dbc_write_comment(&d3dbc, VKD3D_MAKE_TAG('C','T','A','B'), ctab); + d3dbc_write_comment(&d3dbc, TAG_CTAB, ctab); d3dbc_write_semantic_dcls(&d3dbc); d3dbc_write_program_instructions(&d3dbc);
diff --git a/libs/vkd3d/libs/vkd3d-shader/dxbc.c b/libs/vkd3d/libs/vkd3d-shader/dxbc.c index 9e3a57132a1..45a45c3ad4a 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxbc.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxbc.c @@ -388,7 +388,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s { WARN("Invalid data size %#zx.\n", section->data.size); vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, - "Section size %zu is smaller than the minimum signature header size.\n", section->data.size); + "Section size %zu is smaller than the minimum signature header size.", section->data.size); return VKD3D_ERROR_INVALID_ARGUMENT; }
@@ -402,7 +402,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s { WARN("Invalid header size %#x.\n", header_size); vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_SIGNATURE, - "Signature header size %#x is invalid.\n", header_size); + "Signature header size %#x is invalid.", header_size); return VKD3D_ERROR_INVALID_ARGUMENT; } skip_dword_unknown(&ptr, i - 2); @@ -438,7 +438,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s || !(e[i].semantic_name = vkd3d_strdup(name))) { vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_STRING_REFERENCE, - "Element %u has invalid semantic name reference %#zx (data size %#zx).\n", + "Element %u has invalid semantic name reference %#zx (data size %#zx).", i, name_offset, section->data.size); fail = true; } @@ -447,7 +447,7 @@ static int shader_parse_signature(const struct vkd3d_shader_dxbc_section_desc *s if ((e[i].component_type = read_u32(&ptr)) > VKD3D_SHADER_COMPONENT_FLOAT) { vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_COMPONENT_TYPE, - "Element %u has invalid component type %#x.\n", i, e[i].component_type); + "Element %u has invalid component type %#x.", i, e[i].component_type); fail = true; } e[i].register_index = read_u32(&ptr); @@ -531,7 +531,7 @@ static int shdr_parse_features(const struct vkd3d_shader_dxbc_section_desc *sect { WARN("Invalid data size %#zx.\n", section->data.size); vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_DXBC_INVALID_CHUNK_SIZE, - "SFI0 section size %zu is too small to contain flags.\n", section->data.size); + "SFI0 section size %zu is too small to contain flags.", section->data.size); return VKD3D_ERROR_INVALID_ARGUMENT; } flags = read_u64(&ptr); diff --git a/libs/vkd3d/libs/vkd3d-shader/dxil.c b/libs/vkd3d/libs/vkd3d-shader/dxil.c index ca79939a39b..c448e000cf9 100644 --- a/libs/vkd3d/libs/vkd3d-shader/dxil.c +++ b/libs/vkd3d/libs/vkd3d-shader/dxil.c @@ -643,16 +643,22 @@ struct sm6_type
enum sm6_value_type { + VALUE_TYPE_INVALID, VALUE_TYPE_FUNCTION, - VALUE_TYPE_REG, VALUE_TYPE_DATA, VALUE_TYPE_HANDLE, VALUE_TYPE_SSA, VALUE_TYPE_ICB, VALUE_TYPE_IDXTEMP, VALUE_TYPE_GROUPSHAREDMEM, + VALUE_TYPE_CONSTANT, VALUE_TYPE_UNDEFINED, - VALUE_TYPE_INVALID, +}; + +struct sm6_index +{ + const struct sm6_value *index; + bool is_in_bounds; };
struct sm6_function_data @@ -678,16 +684,24 @@ struct sm6_icb_data { unsigned int data_id; unsigned int id; + struct sm6_index index; };
struct sm6_idxtemp_data { unsigned int id; + struct sm6_index index; };
struct sm6_groupsharedmem_data { unsigned int id; + struct sm6_index index; +}; + +struct sm6_constant_data +{ + union vsir_immediate_constant immconst; };
struct sm6_value @@ -696,6 +710,7 @@ struct sm6_value enum sm6_value_type value_type; unsigned int structure_stride; bool is_back_ref; + bool non_uniform; union { struct sm6_function_data function; @@ -705,8 +720,8 @@ struct sm6_value struct sm6_icb_data icb; struct sm6_idxtemp_data idxtemp; struct sm6_groupsharedmem_data groupsharedmem; + struct sm6_constant_data constant; } u; - struct vkd3d_shader_register reg; };
struct dxil_record @@ -731,7 +746,7 @@ struct incoming_value
struct sm6_phi { - struct vkd3d_shader_register reg; + struct sm6_value value; struct incoming_value *incoming; size_t incoming_capacity; size_t incoming_count; @@ -867,9 +882,9 @@ struct sm6_descriptor_info struct vkd3d_shader_register_range range; enum vkd3d_shader_resource_type resource_type; enum dxil_resource_kind kind; - enum vkd3d_data_type resource_data_type; + enum vsir_data_type resource_data_type; enum vkd3d_shader_register_type reg_type; - enum vkd3d_data_type reg_data_type; + enum vsir_data_type reg_data_type; };
struct sm6_parser @@ -2010,11 +2025,6 @@ static inline bool sm6_type_is_handle(const struct sm6_type *type) return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Handle"); }
-static inline const struct sm6_type *sm6_type_get_element_type(const struct sm6_type *type) -{ - return (type->class == TYPE_CLASS_ARRAY || type->class == TYPE_CLASS_VECTOR) ? type->u.array.elem_type : type; -} - static const struct sm6_type *sm6_type_get_pointer_to_type(const struct sm6_type *type, enum bitcode_address_space addr_space, struct sm6_parser *sm6) { @@ -2214,38 +2224,14 @@ static const char *sm6_parser_get_global_symbol_name(const struct sm6_parser *sm return NULL; }
-static unsigned int register_get_uint_value(const struct vkd3d_shader_register *reg) -{ - if (!register_is_constant(reg) || (!data_type_is_integer(reg->data_type) && !data_type_is_bool(reg->data_type))) - return UINT_MAX; - - if (reg->dimension == VSIR_DIMENSION_VEC4) - WARN("Returning vec4.x.\n"); - - if (reg->type == VKD3DSPR_IMMCONST64) - { - if (reg->u.immconst_u64[0] > UINT_MAX) - FIXME("Truncating 64-bit value.\n"); - return reg->u.immconst_u64[0]; - } - - return reg->u.immconst_u32[0]; -} - -static uint64_t register_get_uint64_value(const struct vkd3d_shader_register *reg) +static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) { - if (!register_is_constant(reg) || !data_type_is_integer(reg->data_type)) - return UINT64_MAX; - - if (reg->dimension == VSIR_DIMENSION_VEC4) - WARN("Returning vec4.x.\n"); - - return (reg->type == VKD3DSPR_IMMCONST64) ? reg->u.immconst_u64[0] : reg->u.immconst_u32[0]; + return value->value_type == VALUE_TYPE_FUNCTION; }
-static inline bool sm6_value_is_function_dcl(const struct sm6_value *value) +static bool sm6_value_is_invalid(const struct sm6_value *value) { - return value->value_type == VALUE_TYPE_FUNCTION; + return value->value_type == VALUE_TYPE_INVALID; }
static inline bool sm6_value_is_dx_intrinsic_dcl(const struct sm6_value *fn) @@ -2264,11 +2250,11 @@ static inline bool sm6_value_is_register(const struct sm6_value *value) { switch (value->value_type) { - case VALUE_TYPE_REG: case VALUE_TYPE_SSA: case VALUE_TYPE_ICB: case VALUE_TYPE_IDXTEMP: case VALUE_TYPE_GROUPSHAREDMEM: + case VALUE_TYPE_CONSTANT: case VALUE_TYPE_UNDEFINED: case VALUE_TYPE_INVALID: return true; @@ -2285,18 +2271,41 @@ static bool sm6_value_is_handle(const struct sm6_value *value)
static inline bool sm6_value_is_constant(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_constant(&value->reg); + return value->value_type == VALUE_TYPE_CONSTANT; }
static bool sm6_value_is_constant_zero(const struct sm6_value *value) { - /* Constant vectors do not occur. */ - return sm6_value_is_register(value) && register_is_scalar_constant_zero(&value->reg); + if (value->value_type != VALUE_TYPE_CONSTANT) + return false; + + switch (value->type->class) + { + case TYPE_CLASS_INTEGER: + case TYPE_CLASS_FLOAT: + break; + + default: + return false; + } + + if (value->type->u.width == 64) + return value->u.constant.immconst.immconst_u64[0] == 0; + else + return value->u.constant.immconst.immconst_u32[0] == 0; }
static inline bool sm6_value_is_undef(const struct sm6_value *value) { - return sm6_value_is_register(value) && value->reg.type == VKD3DSPR_UNDEF; + switch (value->value_type) + { + case VALUE_TYPE_UNDEFINED: + case VALUE_TYPE_INVALID: + return true; + + default: + return false; + } }
static bool sm6_value_vector_is_constant_or_undef(const struct sm6_value **values, unsigned int count) @@ -2315,26 +2324,98 @@ static bool sm6_value_is_data(const struct sm6_value *value)
static bool sm6_value_is_ssa(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_ssa(&value->reg); + return value->value_type == VALUE_TYPE_SSA; }
static bool sm6_value_is_numeric_array(const struct sm6_value *value) { - return sm6_value_is_register(value) && register_is_numeric_array(&value->reg); + switch (value->value_type) + { + case VALUE_TYPE_ICB: + case VALUE_TYPE_IDXTEMP: + case VALUE_TYPE_GROUPSHAREDMEM: + return true; + + default: + return false; + } }
-static inline unsigned int sm6_value_get_constant_uint(const struct sm6_value *value) +static unsigned int sm6_value_get_constant_uint(const struct sm6_value *value, struct sm6_parser *sm6) { if (!sm6_value_is_constant(value)) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-constant value."); return UINT_MAX; - return register_get_uint_value(&value->reg); + } + + if (value->type->class != TYPE_CLASS_INTEGER) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-integer constant value."); + return UINT_MAX; + } + + if (value->type->u.width == 64) + { + uint64_t val = value->u.constant.immconst.immconst_u64[0]; + if (val > UINT_MAX) + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid 64-bit constant %"PRIu64" will be truncated do %u.", val, (unsigned int)val); + return val; + } + + return value->u.constant.immconst.immconst_u32[0]; }
-static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value) +static uint64_t sm6_value_get_constant_uint64(const struct sm6_value *value, struct sm6_parser *sm6) { if (!sm6_value_is_constant(value)) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-constant value."); return UINT64_MAX; - return register_get_uint64_value(&value->reg); + } + + if (value->type->class != TYPE_CLASS_INTEGER) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-integer constant value."); + return UINT64_MAX; + } + + if (value->type->u.width == 64) + return value->u.constant.immconst.immconst_u64[0]; + else + return value->u.constant.immconst.immconst_u32[0]; +} + +static float sm6_value_get_constant_float(const struct sm6_value *value, struct sm6_parser *sm6) +{ + if (!sm6_value_is_constant(value)) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-constant value."); + return 0.0f; + } + + if (value->type->class != TYPE_CLASS_FLOAT) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid non-floating-point constant value."); + return 0.0f; + } + + if (value->type->u.width == 64) + { + double val = value->u.constant.immconst.immconst_f64[0]; + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT, + "Invalid double constant %lf will be truncated do float %f.", val, (float)val); + return val; + } + + return value->u.constant.immconst.immconst_f32[0]; }
static unsigned int sm6_parser_alloc_ssa_id(struct sm6_parser *sm6) @@ -2386,31 +2467,31 @@ static struct vkd3d_shader_dst_param *instruction_dst_params_alloc(struct vkd3d_ }
static void register_init_with_id(struct vkd3d_shader_register *reg, - enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id) + enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int id) { vsir_register_init(reg, reg_type, data_type, 1); reg->idx[0].offset = id; }
-static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type *type) +static enum vsir_data_type vsir_data_type_from_dxil(const struct sm6_type *type) { if (type->class == TYPE_CLASS_INTEGER) { switch (type->u.width) { case 1: - return VKD3D_DATA_BOOL; + return VSIR_DATA_BOOL; case 8: - return VKD3D_DATA_UINT8; + return VSIR_DATA_U8; case 16: - return VKD3D_DATA_UINT16; + return VSIR_DATA_U16; case 32: - return VKD3D_DATA_UINT; + return VSIR_DATA_U32; case 64: - return VKD3D_DATA_UINT64; + return VSIR_DATA_U64; default: FIXME("Unhandled width %u.\n", type->u.width); - return VKD3D_DATA_UINT; + return VSIR_DATA_U32; } } else if (type->class == TYPE_CLASS_FLOAT) @@ -2418,48 +2499,138 @@ static enum vkd3d_data_type vkd3d_data_type_from_sm6_type(const struct sm6_type switch (type->u.width) { case 16: - return VKD3D_DATA_HALF; + return VSIR_DATA_F16; case 32: - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; case 64: - return VKD3D_DATA_DOUBLE; + return VSIR_DATA_F64; default: FIXME("Unhandled width %u.\n", type->u.width); - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; } }
FIXME("Unhandled type %u.\n", type->class); - return VKD3D_DATA_UINT; + return VSIR_DATA_U32; }
-static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value) +/* Based on the implementation in the OpenGL Mathematics library. */ +static uint32_t half_to_float(uint16_t value) { - enum vkd3d_data_type data_type; + uint32_t s = (value & 0x8000u) << 16; + uint32_t e = (value >> 10) & 0x1fu; + uint32_t m = value & 0x3ffu;
- data_type = vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(value->type, 0)); + if (!e) + { + if (!m) + { + /* Plus or minus zero */ + return s; + } + else + { + /* Denormalized number -- renormalize it */ + while (!(m & 0x400u)) + { + m <<= 1; + --e; + }
- switch (value->value_type) + ++e; + m &= ~0x400u; + } + } + else if (e == 31u) { - case VALUE_TYPE_REG: - *reg = value->reg; + /* Positive or negative infinity for zero 'm'. + * Nan for non-zero 'm' -- preserve sign and significand bits */ + return s | 0x7f800000u | (m << 13); + } + + /* Normalized number */ + e += 127u - 15u; + m <<= 13; + + /* Assemble s, e and m. */ + return s | (e << 23) | m; +} + +static void register_convert_to_minimum_precision(struct vkd3d_shader_register *reg) +{ + unsigned int i; + + switch (reg->data_type) + { + case VSIR_DATA_F16: + reg->data_type = VSIR_DATA_F32; + reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_FLOAT_16; + if (reg->type == VKD3DSPR_IMMCONST) + { + for (i = 0; i < VSIR_DIMENSION_VEC4; ++i) + reg->u.immconst_u32[i] = half_to_float(reg->u.immconst_u32[i]); + } + break; + + case VSIR_DATA_U16: + reg->data_type = VSIR_DATA_U32; + reg->precision = VKD3D_SHADER_REGISTER_PRECISION_MIN_UINT_16; + if (reg->type == VKD3DSPR_IMMCONST) + { + for (i = 0; i < VSIR_DIMENSION_VEC4; ++i) + reg->u.immconst_u32[i] = (int16_t)reg->u.immconst_u32[i]; + } + break; + + default: break; + } +} + +static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, + struct sm6_parser *sm6);
+static void sm6_register_from_value(struct vkd3d_shader_register *reg, const struct sm6_value *value, + struct sm6_parser *sm6) +{ + const struct sm6_type *scalar_type; + 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); + + switch (value->value_type) + { case VALUE_TYPE_SSA: register_init_with_id(reg, VKD3DSPR_SSA, data_type, value->u.ssa.id); reg->dimension = sm6_type_is_scalar(value->type) ? VSIR_DIMENSION_SCALAR : VSIR_DIMENSION_VEC4; break;
case VALUE_TYPE_ICB: - register_init_with_id(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, value->u.icb.id); + vsir_register_init(reg, VKD3DSPR_IMMCONSTBUFFER, data_type, 2); + reg->idx[0].offset = value->u.icb.id; + register_index_address_init(®->idx[1], value->u.icb.index.index, sm6); + reg->idx[1].is_in_bounds = value->u.icb.index.is_in_bounds; break;
case VALUE_TYPE_IDXTEMP: - register_init_with_id(reg, VKD3DSPR_IDXTEMP, data_type, value->u.idxtemp.id); + vsir_register_init(reg, VKD3DSPR_IDXTEMP, data_type, 2); + reg->idx[0].offset = value->u.idxtemp.id; + register_index_address_init(®->idx[1], value->u.idxtemp.index.index, sm6); + reg->idx[1].is_in_bounds = value->u.idxtemp.index.is_in_bounds; break;
case VALUE_TYPE_GROUPSHAREDMEM: - register_init_with_id(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, value->u.groupsharedmem.id); + vsir_register_init(reg, VKD3DSPR_GROUPSHAREDMEM, data_type, 2); + reg->idx[0].offset = value->u.groupsharedmem.id; + register_index_address_init(®->idx[1], value->u.groupsharedmem.index.index, sm6); + reg->idx[1].is_in_bounds = value->u.groupsharedmem.index.is_in_bounds; + break; + + case VALUE_TYPE_CONSTANT: + vsir_register_init(reg, scalar_type->u.width == 64 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST, + data_type, 0); + reg->u = value->u.constant.immconst; break;
case VALUE_TYPE_UNDEFINED: @@ -2472,15 +2643,18 @@ static void sm6_register_from_value(struct vkd3d_shader_register *reg, const str case VALUE_TYPE_DATA: vkd3d_unreachable(); } + + register_convert_to_minimum_precision(reg); + reg->non_uniform = value->non_uniform; }
static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *value) { unsigned int id;
- if (register_is_ssa(&value->reg) && value->reg.idx[0].offset) + if (value->value_type == VALUE_TYPE_SSA && value->u.ssa.id) { - id = value->reg.idx[0].offset; + id = value->u.ssa.id; TRACE("Using forward-allocated id %u.\n", id); } else @@ -2490,12 +2664,11 @@ static void sm6_parser_init_ssa_value(struct sm6_parser *sm6, struct sm6_value *
value->value_type = VALUE_TYPE_SSA; value->u.ssa.id = id; - sm6_register_from_value(&value->reg, value); }
static void register_make_constant_uint(struct vkd3d_shader_register *reg, unsigned int value) { - vsir_register_init(reg, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); + vsir_register_init(reg, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); reg->u.immconst_u32[0] = value; }
@@ -2547,10 +2720,11 @@ static void src_param_init_vector(struct vkd3d_shader_src_param *param, unsigned param->modifiers = VKD3DSPSM_NONE; }
-static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src) +static void src_param_init_from_value(struct vkd3d_shader_src_param *param, const struct sm6_value *src, + struct sm6_parser *sm6) { src_param_init(param); - sm6_register_from_value(¶m->reg, src); + sm6_register_from_value(¶m->reg, src, sm6); }
static void src_param_init_vector_from_reg(struct vkd3d_shader_src_param *param, @@ -2570,12 +2744,12 @@ static void src_param_make_constant_uint(struct vkd3d_shader_src_param *param, u static void register_index_address_init(struct vkd3d_shader_register_index *idx, const struct sm6_value *address, struct sm6_parser *sm6) { - if (sm6_value_is_constant(address)) + if (address && sm6_value_is_constant(address)) { - idx->offset = sm6_value_get_constant_uint(address); + idx->offset = sm6_value_get_constant_uint(address, sm6); idx->rel_addr = NULL; } - else if (sm6_value_is_undef(address)) + else if (!address || sm6_value_is_undef(address)) { idx->offset = 0; idx->rel_addr = NULL; @@ -2584,7 +2758,7 @@ static void register_index_address_init(struct vkd3d_shader_register_index *idx, { struct vkd3d_shader_src_param *rel_addr = vsir_program_get_src_params(sm6->p.program, 1); if (rel_addr) - src_param_init_from_value(rel_addr, address); + src_param_init_from_value(rel_addr, address, sm6); idx->offset = 0; idx->rel_addr = rel_addr; } @@ -2619,7 +2793,7 @@ static bool instruction_dst_param_init_ssa_scalar(struct vkd3d_shader_instructio
dst_param_init(param); sm6_parser_init_ssa_value(sm6, dst); - sm6_register_from_value(¶m->reg, dst); + sm6_register_from_value(¶m->reg, dst, sm6); return true; }
@@ -2631,22 +2805,20 @@ static void instruction_dst_param_init_ssa_vector(struct vkd3d_shader_instructio
dst_param_init_vector(param, component_count); sm6_parser_init_ssa_value(sm6, dst); - sm6_register_from_value(¶m->reg, dst); + sm6_register_from_value(¶m->reg, dst, sm6); }
-static bool instruction_dst_param_init_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) +static bool instruction_dst_param_init_uint_temp_vector(struct vkd3d_shader_instruction *ins, struct sm6_parser *sm6) { - struct sm6_value *dst = sm6_parser_get_current_value(sm6); struct vkd3d_shader_dst_param *param;
if (!(param = instruction_dst_params_alloc(ins, 1, sm6))) return false;
- vsir_dst_param_init(param, VKD3DSPR_TEMP, vkd3d_data_type_from_sm6_type(sm6_type_get_scalar_type(dst->type, 0)), 1); + vsir_dst_param_init(param, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); param->write_mask = VKD3DSP_WRITEMASK_ALL; param->reg.idx[0].offset = 0; param->reg.dimension = VSIR_DIMENSION_VEC4; - dst->reg = param->reg;
return true; } @@ -2928,7 +3100,6 @@ static size_t sm6_parser_get_value_idx_by_ref(struct sm6_parser *sm6, const stru value->type = fwd_type; value->value_type = VALUE_TYPE_SSA; value->u.ssa.id = sm6_parser_alloc_ssa_id(sm6); - sm6_register_from_value(&value->reg, value); } }
@@ -3017,53 +3188,13 @@ static inline uint64_t decode_rotated_signed_value(uint64_t value) return value << 63; }
-static float bitcast_uint_to_float(unsigned int value) -{ - union - { - uint32_t uint32_value; - float float_value; - } u; - - u.uint32_value = value; - return u.float_value; -} - -static inline double bitcast_uint64_to_double(uint64_t value) -{ - union - { - uint64_t uint64_value; - double double_value; - } u; - - u.uint64_value = value; - return u.double_value; -} - -static float register_get_float_value(const struct vkd3d_shader_register *reg) -{ - if (!register_is_constant(reg) || !data_type_is_floating_point(reg->data_type)) - return 0.0; - - if (reg->dimension == VSIR_DIMENSION_VEC4) - WARN("Returning vec4.x.\n"); - - if (reg->type == VKD3DSPR_IMMCONST64) - { - WARN("Truncating double to float.\n"); - return bitcast_uint64_to_double(reg->u.immconst_u64[0]); - } - - return bitcast_uint_to_float(reg->u.immconst_u32[0]); -} - static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, const struct sm6_type *type, const uint64_t *operands, struct sm6_parser *sm6) { struct vkd3d_shader_immediate_constant_buffer *icb; const struct sm6_type *elem_type; unsigned int i, size, count; + uint64_t *data64;
elem_type = type->u.array.elem_type; /* Multidimensional arrays are emitted in flattened form. */ @@ -3106,7 +3237,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 = vkd3d_data_type_from_sm6_type(elem_type); + icb->data_type = vsir_data_type_from_dxil(elem_type); icb->element_count = type->u.array.count; icb->component_count = 1; icb->is_null = !operands; @@ -3115,28 +3246,70 @@ static enum vkd3d_result value_allocate_constant_array(struct sm6_value *dst, co return VKD3D_OK;
count = type->u.array.count; - if (size > sizeof(icb->data[0])) + switch (icb->data_type) { - uint64_t *data = (uint64_t *)icb->data; - for (i = 0; i < count; ++i) - data[i] = operands[i]; - } - else - { - for (i = 0; i < count; ++i) - icb->data[i] = operands[i]; + case VSIR_DATA_F16: + for (i = 0; i < count; ++i) + icb->data[i] = half_to_float(operands[i]); + icb->data_type = VSIR_DATA_F32; + break; + + case VSIR_DATA_U16: + for (i = 0; i < count; ++i) + icb->data[i] = (int16_t)operands[i]; + icb->data_type = VSIR_DATA_U32; + break; + + case VSIR_DATA_F32: + case VSIR_DATA_U32: + for (i = 0; i < count; ++i) + icb->data[i] = operands[i]; + break; + + case VSIR_DATA_F64: + case VSIR_DATA_U64: + data64 = (uint64_t *)icb->data; + for (i = 0; i < count; ++i) + data64[i] = operands[i]; + break; + + default: + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Invalid array of type %u.", icb->data_type); + return VKD3D_ERROR_INVALID_SHADER; }
return VKD3D_OK; }
+static struct sm6_index *sm6_get_value_index(struct sm6_parser *sm6, struct sm6_value *value) +{ + switch (value->value_type) + { + case VALUE_TYPE_ICB: + return &value->u.icb.index; + + case VALUE_TYPE_IDXTEMP: + return &value->u.idxtemp.index; + + case VALUE_TYPE_GROUPSHAREDMEM: + return &value->u.groupsharedmem.index; + + default: + WARN("Cannot index into value of type %#x.\n", value->value_type); + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Cannot index into value of type %#x.", value->value_type); + return NULL; + } +} + static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, const struct dxil_record *record, struct sm6_value *dst) { const struct sm6_type *elem_type, *pointee_type, *gep_type, *ptr_type; - struct vkd3d_shader_register reg; struct sm6_value *operands[3]; unsigned int i, j, offset; + struct sm6_index *index; uint64_t value;
i = 0; @@ -3178,9 +3351,13 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c } }
- sm6_register_from_value(®, operands[0]); + *dst = *operands[0]; + index = sm6_get_value_index(sm6, dst);
- if (reg.idx_count > 1) + if (!index) + return VKD3D_ERROR_INVALID_SHADER; + + if (index->index) { WARN("Unsupported stacked GEP.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -3203,8 +3380,6 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c return VKD3D_ERROR_INVALID_SHADER; }
- dst->structure_stride = operands[0]->structure_stride; - ptr_type = operands[0]->type; if (!sm6_type_is_pointer(ptr_type)) { @@ -3225,7 +3400,7 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c "Explicit pointee type for constexpr GEP does not match the element type."); }
- offset = sm6_value_get_constant_uint(operands[2]); + offset = sm6_value_get_constant_uint(operands[2], sm6); if (!(gep_type = sm6_type_get_element_type_at_index(pointee_type, offset))) { WARN("Failed to get element type.\n"); @@ -3241,20 +3416,17 @@ static enum vkd3d_result sm6_parser_init_constexpr_gep(struct sm6_parser *sm6, c "Module does not define a pointer type for a constexpr GEP result."); return VKD3D_ERROR_INVALID_SHADER; } - dst->reg = reg; - dst->reg.idx[1].offset = offset; - dst->reg.idx[1].is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP; - dst->reg.idx_count = 2; + + index->index = operands[2]; + index->is_in_bounds = record->code == CST_CODE_CE_INBOUNDS_GEP;
return VKD3D_OK; }
static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const struct dxil_block *block) { - enum vkd3d_shader_register_type reg_type = VKD3DSPR_INVALID; - const struct sm6_type *type, *elem_type, *ptr_type; + const struct sm6_type *type, *ptr_type; size_t i, base_value_idx, value_idx; - enum vkd3d_data_type reg_data_type; const struct dxil_record *record; const struct sm6_value *src; enum vkd3d_result ret; @@ -3275,18 +3447,6 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const if (!(type = sm6_parser_get_type(sm6, record->operands[0]))) return VKD3D_ERROR_INVALID_SHADER;
- elem_type = sm6_type_get_element_type(type); - if (sm6_type_is_numeric(elem_type)) - { - reg_data_type = vkd3d_data_type_from_sm6_type(elem_type); - reg_type = elem_type->u.width > 32 ? VKD3DSPR_IMMCONST64 : VKD3DSPR_IMMCONST; - } - else - { - reg_data_type = VKD3D_DATA_UNUSED; - reg_type = VKD3DSPR_INVALID; - } - if (i == block->record_count - 1) WARN("Unused SETTYPE record.\n");
@@ -3301,19 +3461,21 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const
dst = sm6_parser_get_current_value(sm6); dst->type = type; - dst->value_type = VALUE_TYPE_REG; dst->is_back_ref = true; - vsir_register_init(&dst->reg, reg_type, reg_data_type, 0);
switch (record->code) { case CST_CODE_NULL: - if (sm6_type_is_array(type) - && (ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) + if (sm6_type_is_array(type)) { - return ret; + if ((ret = value_allocate_constant_array(dst, type, NULL, sm6)) < 0) + return ret; + } + else + { + dst->value_type = VALUE_TYPE_CONSTANT; + memset(&dst->u.constant, 0, sizeof(dst->u.constant)); } - /* For non-aggregates, register constant data is already zero-filled. */ break;
case CST_CODE_INTEGER: @@ -3326,11 +3488,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; }
+ dst->value_type = VALUE_TYPE_CONSTANT; + value = decode_rotated_signed_value(record->operands[0]); if (type->u.width <= 32) - dst->reg.u.immconst_u32[0] = value & ((1ull << type->u.width) - 1); + dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1); else - dst->reg.u.immconst_u64[0] = value; + dst->u.constant.immconst.immconst_u64[0] = value;
break;
@@ -3344,14 +3508,13 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; }
- if (type->u.width == 16) - dst->reg.u.immconst_u32[0] = record->operands[0]; - else if (type->u.width == 32) - dst->reg.u.immconst_f32[0] = bitcast_uint_to_float(record->operands[0]); - else if (type->u.width == 64) - dst->reg.u.immconst_f64[0] = bitcast_uint64_to_double(record->operands[0]); + dst->value_type = VALUE_TYPE_CONSTANT; + + value = record->operands[0]; + if (type->u.width <= 32) + dst->u.constant.immconst.immconst_u32[0] = value & ((1ull << type->u.width) - 1); else - vkd3d_unreachable(); + dst->u.constant.immconst.immconst_u64[0] = value;
break;
@@ -3377,6 +3540,46 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const return ret; break;
+ case CST_CODE_CE_CAST: + /* Resolve later in case forward refs exist. */ + dst->type = type; + dst->value_type = VALUE_TYPE_INVALID; + break; + + case CST_CODE_UNDEF: + dxil_record_validate_operand_max_count(record, 0, sm6); + dst->value_type = VALUE_TYPE_UNDEFINED; + break; + + default: + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Constant code %u is unhandled.", record->code); + dst->value_type = VALUE_TYPE_INVALID; + break; + } + + if (record->attachment) + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, + "Ignoring a metadata attachment for a constant."); + + ++sm6->value_count; + } + + value_idx = base_value_idx; + + for (i = 0; i < block->record_count; ++i) + { + sm6->p.location.column = i; + record = block->records[i]; + + switch (record->code) + { + case CST_CODE_SETTYPE: + continue; + + default: + break; + case CST_CODE_CE_CAST: if (!dxil_record_validate_operand_count(record, 3, 3, sm6)) return VKD3D_ERROR_INVALID_SHADER; @@ -3413,59 +3616,26 @@ static enum vkd3d_result sm6_parser_constants_init(struct sm6_parser *sm6, const return VKD3D_ERROR_INVALID_SHADER; }
- /* Resolve later in case forward refs exist. */ - dst->type = type; - dst->reg.type = VKD3DSPR_COUNT; - dst->reg.idx[0].offset = value; - break; + dst = &sm6->values[value_idx]; + src = &sm6->values[value];
- case CST_CODE_UNDEF: - dxil_record_validate_operand_max_count(record, 0, sm6); - dst->value_type = VALUE_TYPE_UNDEFINED; - sm6_register_from_value(&dst->reg, dst); - break; + if (!sm6_value_is_numeric_array(src)) + { + vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Constexpr cast source value is not a global array element."); + return VKD3D_ERROR_INVALID_SHADER; + }
- default: - FIXME("Unhandled constant code %u.\n", record->code); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Constant code %u is unhandled.", record->code); - dst->value_type = VALUE_TYPE_INVALID; - sm6_register_from_value(&dst->reg, dst); + type = dst->type; + *dst = *src; + dst->type = type; break; }
- if (record->attachment) - { - WARN("Ignoring metadata attachment.\n"); - vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_IGNORING_ATTACHMENT, - "Ignoring a metadata attachment for a constant."); - } - - ++sm6->value_count; + ++value_idx; }
- /* Resolve cast forward refs. */ - for (i = base_value_idx; i < sm6->value_count; ++i) - { - dst = &sm6->values[i]; - if (dst->reg.type != VKD3DSPR_COUNT) - continue; - - type = dst->type; - - src = &sm6->values[dst->reg.idx[0].offset]; - if (!sm6_value_is_numeric_array(src)) - { - WARN("Value is not an array.\n"); - vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Constexpr cast source value is not a global array element."); - return VKD3D_ERROR_INVALID_SHADER; - } - - *dst = *src; - dst->type = type; - dst->reg.data_type = vkd3d_data_type_from_sm6_type(type->u.pointer.type); - } + VKD3D_ASSERT(value_idx == sm6->value_count);
return VKD3D_OK; } @@ -3509,7 +3679,7 @@ static void sm6_parser_declare_icb(struct sm6_parser *sm6, const struct sm6_type { struct vkd3d_shader_instruction *ins;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER); /* The icb value index will be resolved later so forward references can be handled. */ ins->declaration.icb = (void *)(intptr_t)init; dst->value_type = VALUE_TYPE_ICB; @@ -3520,12 +3690,12 @@ 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 vkd3d_data_type data_type = vkd3d_data_type_from_sm6_type(elem_type); + enum vsir_data_type data_type = vsir_data_type_from_dxil(elem_type);
if (ins) - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_INDEXABLE_TEMP); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_INDEXABLE_TEMP); else - ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_INDEXABLE_TEMP); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_INDEXABLE_TEMP); ins->declaration.indexable_temp.register_idx = sm6->indexable_temp_count++; ins->declaration.indexable_temp.register_size = count; ins->declaration.indexable_temp.alignment = alignment; @@ -3537,7 +3707,6 @@ static void sm6_parser_declare_indexable_temp(struct sm6_parser *sm6, const stru
dst->value_type = VALUE_TYPE_IDXTEMP; dst->u.idxtemp.id = ins->declaration.indexable_temp.register_idx; - sm6_register_from_value(&dst->reg, dst); }
static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6_type *elem_type, @@ -3546,15 +3715,17 @@ static void sm6_parser_declare_tgsm_raw(struct sm6_parser *sm6, const struct sm6 struct vkd3d_shader_instruction *ins; unsigned int byte_count;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_RAW); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TGSM_RAW); dst_param_init(&ins->declaration.tgsm_raw.reg); dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; dst->u.groupsharedmem.id = sm6->tgsm_count++; dst->structure_stride = 0; - sm6_register_from_value(&dst->reg, dst); - sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst); + sm6_register_from_value(&ins->declaration.tgsm_raw.reg.reg, dst, sm6); ins->declaration.tgsm_raw.alignment = alignment; - byte_count = elem_type->u.width / 8u; + byte_count = elem_type->u.width / CHAR_BIT; + /* Convert minimum precision types to their 32-bit equivalent. */ + if (byte_count == 2) + byte_count = 4; if (byte_count != 4) { FIXME("Unsupported byte count %u.\n", byte_count); @@ -3571,13 +3742,15 @@ static void sm6_parser_declare_tgsm_structured(struct sm6_parser *sm6, const str { struct vkd3d_shader_instruction *ins;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TGSM_STRUCTURED); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TGSM_STRUCTURED); dst_param_init(&ins->declaration.tgsm_structured.reg); dst->value_type = VALUE_TYPE_GROUPSHAREDMEM; dst->u.groupsharedmem.id = sm6->tgsm_count++; - dst->structure_stride = elem_type->u.width / 8u; - sm6_register_from_value(&dst->reg, dst); - sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst); + dst->structure_stride = elem_type->u.width / CHAR_BIT; + /* Convert minimum precision types to their 32-bit equivalent. */ + if (dst->structure_stride == 2) + dst->structure_stride = 4; + sm6_register_from_value(&ins->declaration.tgsm_structured.reg.reg, dst, sm6); if (dst->structure_stride != 4) { FIXME("Unsupported structure stride %u.\n", dst->structure_stride); @@ -3697,7 +3870,6 @@ static bool sm6_parser_declare_global(struct sm6_parser *sm6, const struct dxil_
dst = sm6_parser_get_current_value(sm6); dst->type = type; - dst->value_type = VALUE_TYPE_REG; dst->is_back_ref = true;
if (is_constant && !init) @@ -3797,6 +3969,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); size_t i, count, base_value_idx = sm6->value_count; const struct dxil_block *block = &sm6->root_block; struct vkd3d_shader_instruction *ins; @@ -3856,24 +4029,23 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) }
/* Resolve initialiser forward references. */ - for (i = 0; i < sm6->p.program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - ins = &sm6->p.program->instructions.elements[i]; - if (ins->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) + if (ins->opcode == VSIR_OP_DCL_INDEXABLE_TEMP && ins->declaration.indexable_temp.initialiser) { ins->declaration.indexable_temp.initialiser = resolve_forward_initialiser( (uintptr_t)ins->declaration.indexable_temp.initialiser, sm6); } - else if (ins->opcode == VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER) + else if (ins->opcode == VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER) { ins->declaration.icb = resolve_forward_initialiser((uintptr_t)ins->declaration.icb, sm6); } - else if (ins->opcode == VKD3DSIH_DCL_TGSM_RAW) + else if (ins->opcode == VSIR_OP_DCL_TGSM_RAW) { ins->declaration.tgsm_raw.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6); ins->flags = 0; } - else if (ins->opcode == VKD3DSIH_DCL_TGSM_STRUCTURED) + else if (ins->opcode == VSIR_OP_DCL_TGSM_STRUCTURED) { ins->declaration.tgsm_structured.zero_init = resolve_forward_zero_initialiser(ins->flags, sm6); ins->flags = 0; @@ -3891,14 +4063,13 @@ static enum vkd3d_result sm6_parser_globals_init(struct sm6_parser *sm6) value->u.icb.id = icb->register_idx; else value->u.icb.id = 0; - sm6_register_from_value(&value->reg, value); }
return VKD3D_OK; }
-static void dst_param_io_init(struct vkd3d_shader_dst_param *param, - const struct signature_element *e, enum vkd3d_shader_register_type reg_type) +static void dst_param_io_init(struct vkd3d_shader_dst_param *param, const struct signature_element *e, + enum vkd3d_shader_register_type reg_type, enum vsir_dimension dimension) { enum vkd3d_shader_component_type component_type;
@@ -3907,36 +4078,44 @@ static void dst_param_io_init(struct vkd3d_shader_dst_param *param, param->shift = 0; /* DXIL types do not have signedness. Load signed elements as unsigned. */ component_type = e->component_type == VKD3D_SHADER_COMPONENT_INT ? VKD3D_SHADER_COMPONENT_UINT : e->component_type; - vsir_register_init(¶m->reg, reg_type, vkd3d_data_type_from_component_type(component_type), 0); - param->reg.dimension = VSIR_DIMENSION_VEC4; + vsir_register_init(¶m->reg, reg_type, vsir_data_type_from_component_type(component_type), 0); + param->reg.dimension = dimension; }
static void src_params_init_from_operands(struct vkd3d_shader_src_param *src_params, - const struct sm6_value **operands, unsigned int count) + const struct sm6_value **operands, unsigned int count, struct sm6_parser *sm6) { unsigned int i;
for (i = 0; i < count; ++i) - src_param_init_from_value(&src_params[i], operands[i]); + src_param_init_from_value(&src_params[i], operands[i], sm6); }
static enum vkd3d_shader_register_type register_type_from_dxil_semantic_kind( - enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input) + enum vkd3d_shader_sysval_semantic sysval_semantic, bool is_input, enum vsir_dimension *dimension) { + *dimension = VSIR_DIMENSION_VEC4; + switch (sysval_semantic) { + case VKD3D_SHADER_SV_PRIMITIVE_ID: + return VKD3DSPR_PRIMID; /* VSIR does not use an I/O register for SV_SampleIndex, but its * signature element has a register index of UINT_MAX and it is * convenient to return a valid register type here to handle it. */ case VKD3D_SHADER_SV_SAMPLE_INDEX: return VKD3DSPR_NULL; case VKD3D_SHADER_SV_COVERAGE: + *dimension = is_input ? VSIR_DIMENSION_VEC4 : VSIR_DIMENSION_SCALAR; return is_input ? VKD3DSPR_COVERAGE : VKD3DSPR_SAMPLEMASK; case VKD3D_SHADER_SV_DEPTH: + *dimension = VSIR_DIMENSION_SCALAR; return VKD3DSPR_DEPTHOUT; case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: + *dimension = VSIR_DIMENSION_SCALAR; return VKD3DSPR_DEPTHOUTGE; case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: + *dimension = VSIR_DIMENSION_SCALAR; return VKD3DSPR_DEPTHOUTLE; default: return VKD3DSPR_INVALID; @@ -3976,18 +4155,21 @@ static void sm6_parser_init_signature(struct sm6_parser *sm6, const struct shade
for (i = 0; i < s->element_count; ++i) { + enum vsir_dimension dimension; + e = &s->elements[i];
param = ¶ms[i];
if (e->register_index == UINT_MAX - && (io_reg_type = register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input)) != VKD3DSPR_NULL) + && (io_reg_type = register_type_from_dxil_semantic_kind( + e->sysval_semantic, is_input, &dimension)) != VKD3DSPR_NULL) { - dst_param_io_init(param, e, io_reg_type); + dst_param_io_init(param, e, io_reg_type, dimension); continue; }
- dst_param_io_init(param, e, reg_type); + dst_param_io_init(param, e, reg_type, VSIR_DIMENSION_VEC4); count = 0;
if (is_control_point) @@ -4163,7 +4345,7 @@ static void sm6_parser_emit_alloca(struct sm6_parser *sm6, const struct dxil_rec if (!(size = sm6_parser_get_value_safe(sm6, record->operands[2]))) return; /* A size of 1 means one instance of type[0], i.e. one array. */ - if (sm6_value_get_constant_uint(size) != 1) + if (sm6_value_get_constant_uint(size, sm6) != 1) { FIXME("Allocation size is not 1.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -4186,26 +4368,26 @@ static enum vkd3d_shader_opcode map_dx_atomicrmw_op(uint64_t code) switch (code) { case RMW_ADD: - return VKD3DSIH_IMM_ATOMIC_IADD; + return VSIR_OP_IMM_ATOMIC_IADD; case RMW_AND: - return VKD3DSIH_IMM_ATOMIC_AND; + return VSIR_OP_IMM_ATOMIC_AND; case RMW_MAX: - return VKD3DSIH_IMM_ATOMIC_IMAX; + return VSIR_OP_IMM_ATOMIC_IMAX; case RMW_MIN: - return VKD3DSIH_IMM_ATOMIC_IMIN; + return VSIR_OP_IMM_ATOMIC_IMIN; case RMW_OR: - return VKD3DSIH_IMM_ATOMIC_OR; + return VSIR_OP_IMM_ATOMIC_OR; case RMW_UMAX: - return VKD3DSIH_IMM_ATOMIC_UMAX; + return VSIR_OP_IMM_ATOMIC_UMAX; case RMW_UMIN: - return VKD3DSIH_IMM_ATOMIC_UMIN; + return VSIR_OP_IMM_ATOMIC_UMIN; case RMW_XCHG: - return VKD3DSIH_IMM_ATOMIC_EXCH; + return VSIR_OP_IMM_ATOMIC_EXCH; case RMW_XOR: - return VKD3DSIH_IMM_ATOMIC_XOR; + return VSIR_OP_IMM_ATOMIC_XOR; default: /* DXIL currently doesn't use SUB and NAND. */ - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; } }
@@ -4228,7 +4410,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ || !sm6_value_validate_is_backward_ref(ptr, sm6)) return;
- sm6_register_from_value(®, ptr); + sm6_register_from_value(®, ptr, sm6);
if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { @@ -4246,7 +4428,7 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ if (!dxil_record_validate_operand_count(record, i + 4, i + 4, sm6)) return;
- if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VKD3DSIH_INVALID) + if ((op = map_dx_atomicrmw_op(code = record->operands[i++])) == VSIR_OP_INVALID) { FIXME("Unhandled atomicrmw op %"PRIu64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -4284,16 +4466,16 @@ static void sm6_parser_emit_atomicrmw(struct sm6_parser *sm6, const struct dxil_ src_param_init_vector_from_reg(&src_params[0], &coord); else src_param_make_constant_uint(&src_params[0], 0); - src_param_init_from_value(&src_params[1], src); + src_param_init_from_value(&src_params[1], src, sm6);
sm6_parser_init_ssa_value(sm6, dst);
dst_params = instruction_dst_params_alloc(ins, 2, sm6); - sm6_register_from_value(&dst_params[0].reg, dst); + sm6_register_from_value(&dst_params[0].reg, dst, sm6); dst_param_init(&dst_params[0]);
dst_params[1].reg = reg; - dst_params[1].reg.data_type = VKD3D_DATA_UNUSED; + dst_params[1].reg.data_type = VSIR_DATA_UNUSED; dst_params[1].reg.idx[1].rel_addr = NULL; dst_params[1].reg.idx[1].offset = ~0u; dst_params[1].reg.idx_count = 1; @@ -4314,7 +4496,7 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty WARN("Argument type %u is not bool, int16/32/64 or floating point.\n", type_a->class); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "An argument to a binary operation is not bool, int16/32/64 or floating point."); - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; } if (type_a != type_b) { @@ -4329,55 +4511,58 @@ static enum vkd3d_shader_opcode map_binary_op(uint64_t code, const struct sm6_ty case BINOP_ADD: case BINOP_SUB: /* NEG is applied later for subtraction. */ - op = is_int ? VKD3DSIH_IADD : (is_double ? VKD3DSIH_DADD : VKD3DSIH_ADD); + op = is_int ? VSIR_OP_IADD : (is_double ? VSIR_OP_DADD : VSIR_OP_ADD); is_valid = !is_bool; break; case BINOP_AND: - op = VKD3DSIH_AND; + op = VSIR_OP_AND; is_valid = is_int; break; case BINOP_ASHR: - op = VKD3DSIH_ISHR; + op = VSIR_OP_ISHR; is_valid = is_int && !is_bool; break; case BINOP_LSHR: - op = VKD3DSIH_USHR; + op = VSIR_OP_USHR; is_valid = is_int && !is_bool; break; case BINOP_MUL: - op = is_int ? VKD3DSIH_UMUL : (is_double ? VKD3DSIH_DMUL : VKD3DSIH_MUL); + op = is_int ? VSIR_OP_IMUL_LOW : (is_double ? VSIR_OP_DMUL : VSIR_OP_MUL); is_valid = !is_bool; break; case BINOP_OR: - op = VKD3DSIH_OR; + op = VSIR_OP_OR; is_valid = is_int; break; case BINOP_SDIV: - op = is_int ? VKD3DSIH_IDIV : (is_double ? VKD3DSIH_DDIV : VKD3DSIH_DIV); + op = is_int ? VSIR_OP_IDIV : (is_double ? VSIR_OP_DDIV : VSIR_OP_DIV); is_valid = !is_bool; break; case BINOP_SREM: - op = is_int ? VKD3DSIH_IDIV : VKD3DSIH_FREM; + op = is_int ? VSIR_OP_IREM : VSIR_OP_FREM; is_valid = !is_bool; break; case BINOP_SHL: - op = VKD3DSIH_ISHL; + op = VSIR_OP_ISHL; is_valid = is_int && !is_bool; break; case BINOP_UDIV: + op = VSIR_OP_UDIV_SIMPLE; + is_valid = is_int && !is_bool; + break; case BINOP_UREM: - op = VKD3DSIH_UDIV; + op = VSIR_OP_UREM; is_valid = is_int && !is_bool; break; case BINOP_XOR: - op = VKD3DSIH_XOR; + op = VSIR_OP_XOR; is_valid = is_int; break; default: FIXME("Unhandled binary op %#"PRIx64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Binary operation %#"PRIx64" is unhandled.", code); - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; }
if (!is_valid) @@ -4411,7 +4596,7 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco return;
code = record->operands[i++]; - if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VKD3DSIH_INVALID) + if ((handler_idx = map_binary_op(code, a->type, b->type, sm6)) == VSIR_OP_INVALID) return;
vsir_instruction_init(ins, &sm6->p.location, handler_idx); @@ -4421,25 +4606,27 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
switch (handler_idx) { - case VKD3DSIH_ADD: - case VKD3DSIH_MUL: - case VKD3DSIH_DIV: - case VKD3DSIH_FREM: + case VSIR_OP_ADD: + case VSIR_OP_MUL: + case VSIR_OP_DIV: + case VSIR_OP_FREM: if (!(flags & FP_ALLOW_UNSAFE_ALGEBRA)) ins->flags |= VKD3DSI_PRECISE_X; flags &= ~FP_ALLOW_UNSAFE_ALGEBRA; /* SPIR-V FPFastMathMode is only available in the Kernel execution model. */ silence_warning = !(flags & ~(FP_NO_NAN | FP_NO_INF | FP_NO_SIGNED_ZEROS | FP_ALLOW_RECIPROCAL)); break; - case VKD3DSIH_IADD: - case VKD3DSIH_UMUL: - case VKD3DSIH_ISHL: + case VSIR_OP_IADD: + case VSIR_OP_IMUL_LOW: + case VSIR_OP_ISHL: silence_warning = !(flags & ~(OB_NO_UNSIGNED_WRAP | OB_NO_SIGNED_WRAP)); break; - case VKD3DSIH_ISHR: - case VKD3DSIH_USHR: - case VKD3DSIH_IDIV: - case VKD3DSIH_UDIV: + case VSIR_OP_ISHR: + case VSIR_OP_USHR: + case VSIR_OP_IDIV: + case VSIR_OP_UDIV_SIMPLE: + case VSIR_OP_IREM: + case VSIR_OP_UREM: silence_warning = !(flags & ~PEB_EXACT); break; default: @@ -4459,34 +4646,21 @@ static void sm6_parser_emit_binop(struct sm6_parser *sm6, const struct dxil_reco
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; - src_param_init_from_value(&src_params[0], a); - src_param_init_from_value(&src_params[1], b); + src_param_init_from_value(&src_params[0], a, sm6); + src_param_init_from_value(&src_params[1], b, sm6); if (code == BINOP_SUB) src_params[1].modifiers = VKD3DSPSM_NEG;
dst->type = a->type;
- if (handler_idx == VKD3DSIH_UMUL || handler_idx == VKD3DSIH_UDIV || handler_idx == VKD3DSIH_IDIV) + if (handler_idx == VSIR_OP_ISHL || handler_idx == VSIR_OP_ISHR || handler_idx == VSIR_OP_USHR) { - struct vkd3d_shader_dst_param *dst_params = instruction_dst_params_alloc(ins, 2, sm6); - unsigned int index = code != BINOP_UDIV && code != BINOP_SDIV; - - dst_param_init(&dst_params[0]); - dst_param_init(&dst_params[1]); - sm6_parser_init_ssa_value(sm6, dst); - sm6_register_from_value(&dst_params[index].reg, dst); - vsir_dst_param_init_null(&dst_params[index ^ 1]); - } - else - { - if (handler_idx == VKD3DSIH_ISHL || handler_idx == VKD3DSIH_ISHR || handler_idx == VKD3DSIH_USHR) - { - /* DXC emits AND instructions where necessary to mask shift counts. Shift binops - * do not imply masking the shift as the TPF equivalents do. */ - ins->flags |= VKD3DSI_SHIFT_UNMASKED; - } - instruction_dst_param_init_ssa_scalar(ins, sm6); + /* DXC emits AND instructions where necessary to mask shift counts. + * Shift binops do not imply masking the shift as the TPF equivalents + * do. */ + ins->flags |= VKD3DSI_SHIFT_UNMASKED; } + instruction_dst_param_init_ssa_scalar(ins, sm6); }
static const struct sm6_block *sm6_function_get_block(const struct sm6_function *function, uint64_t index, @@ -4536,12 +4710,12 @@ static void sm6_parser_emit_br(struct sm6_parser *sm6, const struct dxil_record dxil_record_validate_operand_max_count(record, i, sm6);
code_block->terminator.type = TERMINATOR_COND_BR; - sm6_register_from_value(&code_block->terminator.conditional_reg, value); + sm6_register_from_value(&code_block->terminator.conditional_reg, value, sm6); code_block->terminator.true_block = sm6_function_get_block(function, record->operands[0], sm6); code_block->terminator.false_block = sm6_function_get_block(function, record->operands[1], sm6); }
- ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; }
static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6, @@ -4579,7 +4753,7 @@ static bool sm6_parser_emit_reg_composite_construct(struct sm6_parser *sm6,
for (i = 0; i < component_count; ++i, ++ins) { - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return false; @@ -4607,7 +4781,7 @@ static bool sm6_parser_emit_composite_construct(struct sm6_parser *sm6, const st unsigned int i;
for (i = 0; i < component_count; ++i) - sm6_register_from_value(&operand_regs[i], operands[i]); + sm6_register_from_value(&operand_regs[i], operands[i], sm6);
return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } @@ -4623,11 +4797,11 @@ static bool sm6_parser_emit_coordinate_construct(struct sm6_parser *sm6, const s { if (!z_operand && operands[component_count]->value_type == VALUE_TYPE_UNDEFINED) break; - sm6_register_from_value(&operand_regs[component_count], operands[component_count]); + sm6_register_from_value(&operand_regs[component_count], operands[component_count], sm6); }
if (z_operand) - sm6_register_from_value(&operand_regs[component_count++], z_operand); + sm6_register_from_value(&operand_regs[component_count++], z_operand, sm6);
return sm6_parser_emit_reg_composite_construct(sm6, operand_regs, component_count, state, reg); } @@ -4637,7 +4811,7 @@ static enum vkd3d_shader_opcode sm6_dx_map_void_op(enum dx_intrinsic_opcode op) switch (op) { case DX_WAVE_IS_FIRST_LANE: - return VKD3DSIH_WAVE_IS_FIRST_LANE; + return VSIR_OP_WAVE_IS_FIRST_LANE; default: vkd3d_unreachable(); } @@ -4656,77 +4830,81 @@ static enum vkd3d_shader_opcode map_dx_unary_op(enum dx_intrinsic_opcode op) switch (op) { case DX_ISNAN: - return VKD3DSIH_ISNAN; + return VSIR_OP_ISNAN; case DX_ISINF: - return VKD3DSIH_ISINF; + return VSIR_OP_ISINF; case DX_ISFINITE: - return VKD3DSIH_ISFINITE; + return VSIR_OP_ISFINITE; + case DX_COS: + return VSIR_OP_COS; + case DX_SIN: + return VSIR_OP_SIN; case DX_TAN: - return VKD3DSIH_TAN; + return VSIR_OP_TAN; case DX_ACOS: - return VKD3DSIH_ACOS; + return VSIR_OP_ACOS; case DX_ASIN: - return VKD3DSIH_ASIN; + return VSIR_OP_ASIN; case DX_ATAN: - return VKD3DSIH_ATAN; + return VSIR_OP_ATAN; case DX_HCOS: - return VKD3DSIH_HCOS; + return VSIR_OP_HCOS; case DX_HSIN: - return VKD3DSIH_HSIN; + return VSIR_OP_HSIN; case DX_HTAN: - return VKD3DSIH_HTAN; + return VSIR_OP_HTAN; case DX_EXP: - return VKD3DSIH_EXP; + return VSIR_OP_EXP; case DX_FRC: - return VKD3DSIH_FRC; + return VSIR_OP_FRC; case DX_LOG: - return VKD3DSIH_LOG; + return VSIR_OP_LOG; case DX_SQRT: - return VKD3DSIH_SQRT; + return VSIR_OP_SQRT; case DX_RSQRT: - return VKD3DSIH_RSQ; + return VSIR_OP_RSQ; case DX_ROUND_NE: - return VKD3DSIH_ROUND_NE; + return VSIR_OP_ROUND_NE; case DX_ROUND_NI: - return VKD3DSIH_ROUND_NI; + return VSIR_OP_ROUND_NI; case DX_ROUND_PI: - return VKD3DSIH_ROUND_PI; + return VSIR_OP_ROUND_PI; case DX_ROUND_Z: - return VKD3DSIH_ROUND_Z; + return VSIR_OP_ROUND_Z; case DX_BFREV: - return VKD3DSIH_BFREV; + return VSIR_OP_BFREV; case DX_COUNT_BITS: - return VKD3DSIH_COUNTBITS; + return VSIR_OP_COUNTBITS; case DX_FIRST_BIT_LO: - return VKD3DSIH_FIRSTBIT_LO; + return VSIR_OP_FIRSTBIT_LO; case DX_FIRST_BIT_HI: - return VKD3DSIH_FIRSTBIT_HI; + return VSIR_OP_FIRSTBIT_HI; case DX_FIRST_BIT_SHI: - return VKD3DSIH_FIRSTBIT_SHI; + return VSIR_OP_FIRSTBIT_SHI; case DX_DERIV_COARSEX: - return VKD3DSIH_DSX_COARSE; + return VSIR_OP_DSX_COARSE; case DX_DERIV_COARSEY: - return VKD3DSIH_DSY_COARSE; + return VSIR_OP_DSY_COARSE; case DX_DERIV_FINEX: - return VKD3DSIH_DSX_FINE; + return VSIR_OP_DSX_FINE; case DX_DERIV_FINEY: - return VKD3DSIH_DSY_FINE; + return VSIR_OP_DSY_FINE; case DX_LEGACY_F32TOF16: - return VKD3DSIH_F32TOF16; + return VSIR_OP_F32TOF16; case DX_LEGACY_F16TOF32: - return VKD3DSIH_F16TOF32; + return VSIR_OP_F16TOF32; case DX_WAVE_ACTIVE_ALL_EQUAL: - return VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL; + return VSIR_OP_WAVE_ACTIVE_ALL_EQUAL; case DX_WAVE_ALL_BIT_COUNT: - return VKD3DSIH_WAVE_ALL_BIT_COUNT; + return VSIR_OP_WAVE_ALL_BIT_COUNT; case DX_WAVE_ALL_TRUE: - return VKD3DSIH_WAVE_ALL_TRUE; + return VSIR_OP_WAVE_ALL_TRUE; case DX_WAVE_ANY_TRUE: - return VKD3DSIH_WAVE_ANY_TRUE; + return VSIR_OP_WAVE_ANY_TRUE; case DX_WAVE_PREFIX_BIT_COUNT: - return VKD3DSIH_WAVE_PREFIX_BIT_COUNT; + return VSIR_OP_WAVE_PREFIX_BIT_COUNT; case DX_WAVE_READ_LANE_FIRST: - return VKD3DSIH_WAVE_READ_LANE_FIRST; + return VSIR_OP_WAVE_READ_LANE_FIRST; default: vkd3d_unreachable(); } @@ -4741,7 +4919,7 @@ static void sm6_parser_emit_dx_unary(struct sm6_parser *sm6, enum dx_intrinsic_o vsir_instruction_init(ins, &sm6->p.location, map_dx_unary_op(op)); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -4751,21 +4929,21 @@ static enum vkd3d_shader_opcode map_dx_binary_op(enum dx_intrinsic_opcode op, co switch (op) { case DX_FMAX: - return type->u.width == 64 ? VKD3DSIH_DMAX : VKD3DSIH_MAX; + return type->u.width == 64 ? VSIR_OP_DMAX : VSIR_OP_MAX; case DX_FMIN: - return type->u.width == 64 ? VKD3DSIH_DMIN : VKD3DSIH_MIN; + return type->u.width == 64 ? VSIR_OP_DMIN : VSIR_OP_MIN; case DX_IMAX: - return VKD3DSIH_IMAX; + return VSIR_OP_IMAX; case DX_IMIN: - return VKD3DSIH_IMIN; + return VSIR_OP_IMIN; case DX_QUAD_READ_LANE_AT: - return VKD3DSIH_QUAD_READ_LANE_AT; + return VSIR_OP_QUAD_READ_LANE_AT; case DX_UMAX: - return VKD3DSIH_UMAX; + return VSIR_OP_UMAX; case DX_UMIN: - return VKD3DSIH_UMIN; + return VSIR_OP_UMIN; case DX_WAVE_READ_LANE_AT: - return VKD3DSIH_WAVE_READ_LANE_AT; + return VSIR_OP_WAVE_READ_LANE_AT; default: vkd3d_unreachable(); } @@ -4780,42 +4958,42 @@ static void sm6_parser_emit_dx_binary(struct sm6_parser *sm6, enum dx_intrinsic_ vsir_instruction_init(ins, &sm6->p.location, map_dx_binary_op(op, operands[0]->type)); if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; - src_param_init_from_value(&src_params[0], operands[0]); - src_param_init_from_value(&src_params[1], operands[1]); + src_param_init_from_value(&src_params[0], operands[0], sm6); + src_param_init_from_value(&src_params[1], operands[1], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); }
static enum vkd3d_shader_opcode map_dx_atomic_binop(const struct sm6_value *operand, struct sm6_parser *sm6) { - uint64_t code = sm6_value_get_constant_uint(operand); + uint64_t code = sm6_value_get_constant_uint(operand, sm6);
switch (code) { case ATOMIC_BINOP_ADD: - return VKD3DSIH_IMM_ATOMIC_IADD; + return VSIR_OP_IMM_ATOMIC_IADD; case ATOMIC_BINOP_AND: - return VKD3DSIH_IMM_ATOMIC_AND; + return VSIR_OP_IMM_ATOMIC_AND; case ATOMIC_BINOP_IMAX: - return VKD3DSIH_IMM_ATOMIC_IMAX; + return VSIR_OP_IMM_ATOMIC_IMAX; case ATOMIC_BINOP_IMIN: - return VKD3DSIH_IMM_ATOMIC_IMIN; + return VSIR_OP_IMM_ATOMIC_IMIN; case ATOMIC_BINOP_OR: - return VKD3DSIH_IMM_ATOMIC_OR; + return VSIR_OP_IMM_ATOMIC_OR; case ATOMIC_BINOP_UMAX: - return VKD3DSIH_IMM_ATOMIC_UMAX; + return VSIR_OP_IMM_ATOMIC_UMAX; case ATOMIC_BINOP_UMIN: - return VKD3DSIH_IMM_ATOMIC_UMIN; + return VSIR_OP_IMM_ATOMIC_UMIN; case ATOMIC_BINOP_XCHG: - return VKD3DSIH_IMM_ATOMIC_EXCH; + return VSIR_OP_IMM_ATOMIC_EXCH; case ATOMIC_BINOP_XOR: - return VKD3DSIH_IMM_ATOMIC_XOR; + return VSIR_OP_IMM_ATOMIC_XOR; /* DXIL currently doesn't use SUB and NAND. */ default: FIXME("Unhandled atomic binop %"PRIu64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Operation %"PRIu64" for an atomic binop instruction is unhandled.", code); - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; } }
@@ -4838,8 +5016,8 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr return;
if (is_cmp_xchg) - handler_idx = VKD3DSIH_IMM_ATOMIC_CMP_EXCH; - else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VKD3DSIH_INVALID) + handler_idx = VSIR_OP_IMM_ATOMIC_CMP_EXCH; + else if ((handler_idx = map_dx_atomic_binop(operands[1], sm6)) == VSIR_OP_INVALID) return;
coord_idx = 2 - is_cmp_xchg; @@ -4852,7 +5030,7 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr } else { - sm6_register_from_value(®, operands[coord_idx]); + sm6_register_from_value(®, operands[coord_idx], sm6); }
for (i = coord_idx + coord_count; i < coord_idx + 3; ++i) @@ -4873,14 +5051,14 @@ static void sm6_parser_emit_dx_atomic_binop(struct sm6_parser *sm6, enum dx_intr return; src_param_init_vector_from_reg(&src_params[0], ®); if (is_cmp_xchg) - src_param_init_from_value(&src_params[1], operands[4]); - src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5]); + src_param_init_from_value(&src_params[1], operands[4], sm6); + src_param_init_from_value(&src_params[1 + is_cmp_xchg], operands[5], sm6);
sm6_parser_init_ssa_value(sm6, dst);
dst_params = instruction_dst_params_alloc(ins, 2, sm6); dst_param_init(&dst_params[0]); - sm6_register_from_value(&dst_params[0].reg, dst); + sm6_register_from_value(&dst_params[0].reg, dst, sm6); dst_param_init(&dst_params[1]); sm6_register_from_handle(sm6, &resource->u.handle, &dst_params[1].reg); } @@ -4891,8 +5069,8 @@ static void sm6_parser_emit_dx_barrier(struct sm6_parser *sm6, enum dx_intrinsic struct vkd3d_shader_instruction *ins = state->ins; enum dxil_sync_flags flags;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SYNC); - flags = sm6_value_get_constant_uint(operands[0]); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SYNC); + flags = sm6_value_get_constant_uint(operands[0], sm6); ins->flags = flags & (SYNC_THREAD_GROUP | SYNC_THREAD_GROUP_UAV); if (flags & SYNC_GLOBAL_UAV) ins->flags |= VKD3DSSF_GLOBAL_UAV; @@ -4926,7 +5104,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu "A dynamic update value for a UAV counter operation is not supported."); return; } - i = sm6_value_get_constant_uint(operands[1]); + i = sm6_value_get_constant_uint(operands[1], sm6); if (i != 1 && i != 255) { WARN("Unexpected update value %#x.\n", i); @@ -4935,7 +5113,7 @@ static void sm6_parser_emit_dx_buffer_update_counter(struct sm6_parser *sm6, enu } inc = i;
- vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VKD3DSIH_IMM_ATOMIC_CONSUME : VKD3DSIH_IMM_ATOMIC_ALLOC); + vsir_instruction_init(ins, &sm6->p.location, (inc < 0) ? VSIR_OP_IMM_ATOMIC_CONSUME : VSIR_OP_IMM_ATOMIC_ALLOC); if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); @@ -4963,10 +5141,10 @@ static void sm6_parser_emit_dx_calculate_lod(struct sm6_parser *sm6, enum dx_int if (!sm6_parser_emit_coordinate_construct(sm6, &operands[2], 3, NULL, state, &coord)) return;
- clamp = sm6_value_get_constant_uint(operands[5]); + clamp = sm6_value_get_constant_uint(operands[5], sm6);
ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LOD); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_LOD); if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; src_param_init_vector_from_reg(&src_params[0], &coord); @@ -4990,7 +5168,7 @@ static void sm6_parser_emit_dx_cbuffer_load(struct sm6_parser *sm6, enum dx_intr if (!sm6_value_validate_is_handle(buffer, sm6)) return;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -5002,15 +5180,17 @@ 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 = vkd3d_data_type_from_sm6_type(type); + src_param->reg.data_type = vsir_data_type_from_dxil(type); if (data_type_is_64_bit(src_param->reg.data_type)) src_param->swizzle = vsir_swizzle_64_from_32(src_param->swizzle); + else + register_convert_to_minimum_precision(&src_param->reg);
instruction_dst_param_init_ssa_vector(ins, sm6_type_max_vector_size(type), sm6); }
static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_shader_opcode handler_idx, - enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int component_count) + enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, unsigned int component_count) { struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins; @@ -5025,17 +5205,19 @@ static void sm6_parser_dcl_register_builtin(struct sm6_parser *sm6, enum vkd3d_s } }
-static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, - struct vkd3d_shader_instruction *ins, enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type) +static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, + enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, bool scalar) { struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, reg_type, data_type, 1); + sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, data_type, 1); vsir_register_init(&src_param->reg, reg_type, data_type, 0); + if (!scalar) + src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init(src_param);
instruction_dst_param_init_ssa_scalar(ins, sm6); @@ -5044,7 +5226,7 @@ static void sm6_parser_emit_dx_input_register_mov(struct sm6_parser *sm6, static void sm6_parser_emit_dx_coverage(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { - sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VKD3D_DATA_UINT); + sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_COVERAGE, VSIR_DATA_U32, false); }
static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_parser *sm6, @@ -5064,7 +5246,7 @@ static const struct sm6_descriptor_info *sm6_parser_get_descriptor(struct sm6_pa if (!sm6_value_is_constant(address)) return d;
- register_index = sm6_value_get_constant_uint(address); + register_index = sm6_value_get_constant_uint(address, sm6); if (register_index >= d->range.first && register_index <= d->range.last) return d; } @@ -5081,8 +5263,8 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int struct sm6_value *dst; unsigned int id;
- type = sm6_value_get_constant_uint(operands[0]); - id = sm6_value_get_constant_uint(operands[1]); + type = sm6_value_get_constant_uint(operands[0], sm6); + id = sm6_value_get_constant_uint(operands[1], sm6); if (!(d = sm6_parser_get_descriptor(sm6, type, id, operands[2]))) { WARN("Failed to find resource type %#x, id %#x.\n", type, id); @@ -5095,10 +5277,10 @@ static void sm6_parser_emit_dx_create_handle(struct sm6_parser *sm6, enum dx_int dst->value_type = VALUE_TYPE_HANDLE; dst->u.handle.d = d; dst->u.handle.index = operands[2]; - dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3]); + dst->u.handle.non_uniform = !!sm6_value_get_constant_uint(operands[3], sm6);
/* NOP is used to flag no instruction emitted. */ - ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; }
static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -5108,12 +5290,12 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ struct vkd3d_shader_src_param *src_param; unsigned int i;
- vsir_instruction_init(ins, &sm6->p.location, (op == DX_CUT_STREAM) ? VKD3DSIH_CUT_STREAM : VKD3DSIH_EMIT_STREAM); + vsir_instruction_init(ins, &sm6->p.location, (op == DX_CUT_STREAM) ? VSIR_OP_CUT_STREAM : VSIR_OP_EMIT_STREAM);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return;
- i = sm6_value_get_constant_uint(operands[0]); + i = sm6_value_get_constant_uint(operands[0], sm6); if (i >= MAX_GS_OUTPUT_STREAMS) { WARN("Invalid stream index %u.\n", i); @@ -5121,8 +5303,7 @@ static void sm6_parser_emit_dx_stream(struct sm6_parser *sm6, enum dx_intrinsic_ "Output stream index %u is invalid.", i); }
- /* VKD3D_DATA_UNUSED would be more reasonable, but TPF uses data type 0 here. */ - register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, 0, i); + register_init_with_id(&src_param->reg, VKD3DSPR_STREAM, VSIR_DATA_UNUSED, i); src_param_init(src_param);
if (op == DX_EMIT_THEN_CUT_STREAM) @@ -5139,10 +5320,10 @@ static void sm6_parser_emit_dx_discard(struct sm6_parser *sm6, enum dx_intrinsic struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DISCARD); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DISCARD);
if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6); }
static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -5152,9 +5333,9 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i struct vkd3d_shader_src_param *src_param; unsigned int component_idx;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
- if ((component_idx = sm6_value_get_constant_uint(operands[0])) >= 3) + if ((component_idx = sm6_value_get_constant_uint(operands[0], sm6)) >= 3) { WARN("Invalid component index %u.\n", component_idx); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -5164,8 +5345,8 @@ static void sm6_parser_emit_dx_domain_location(struct sm6_parser *sm6, enum dx_i
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 3); - vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VKD3D_DATA_FLOAT, 0); + sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 3); + vsir_register_init(&src_param->reg, VKD3DSPR_TESSCOORD, VSIR_DATA_F32, 0); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init_scalar(src_param, component_idx);
@@ -5184,15 +5365,15 @@ static void sm6_parser_emit_dx_dot(struct sm6_parser *sm6, enum dx_intrinsic_opc switch (op) { case DX_DOT2: - handler_idx = VKD3DSIH_DP2; + handler_idx = VSIR_OP_DP2; component_count = 2; break; case DX_DOT3: - handler_idx = VKD3DSIH_DP3; + handler_idx = VSIR_OP_DP3; component_count = 3; break; case DX_DOT4: - handler_idx = VKD3DSIH_DP4; + handler_idx = VSIR_OP_DP4; component_count = 4; break; default: @@ -5223,8 +5404,8 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri unsigned int row_index, column_index; const struct signature_element *e;
- row_index = sm6_value_get_constant_uint(operands[0]); - column_index = sm6_value_get_constant_uint(operands[2]); + 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; if (row_index >= signature->element_count) @@ -5245,7 +5426,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri }
vsir_instruction_init(ins, &sm6->p.location, (op == DX_EVAL_CENTROID) - ? VKD3DSIH_EVAL_CENTROID : VKD3DSIH_EVAL_SAMPLE_INDEX); + ? VSIR_OP_EVAL_CENTROID : VSIR_OP_EVAL_SAMPLE_INDEX);
if (!(src_params = instruction_src_params_alloc(ins, 1 + (op == DX_EVAL_SAMPLE_INDEX), sm6))) return; @@ -5256,7 +5437,7 @@ static void sm6_parser_emit_dx_eval_attrib(struct sm6_parser *sm6, enum dx_intri register_index_address_init(&src_params[0].reg.idx[0], operands[1], sm6);
if (op == DX_EVAL_SAMPLE_INDEX) - src_param_init_from_value(&src_params[1], operands[3]); + src_param_init_from_value(&src_params[1], operands[3], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -5267,10 +5448,10 @@ static void sm6_parser_emit_dx_fabs(struct sm6_parser *sm6, enum dx_intrinsic_op struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6); src_param->modifiers = VKD3DSPSM_ABS;
instruction_dst_param_init_ssa_scalar(ins, sm6); @@ -5303,16 +5484,14 @@ static void sm6_parser_emit_dx_compute_builtin(struct sm6_parser *sm6, enum dx_i vkd3d_unreachable(); }
- sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_INPUT, reg_type, VKD3D_DATA_UINT, component_count); - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_INPUT, reg_type, VSIR_DATA_U32, component_count); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - vsir_register_init(&src_param->reg, reg_type, VKD3D_DATA_UINT, 0); + vsir_register_init(&src_param->reg, reg_type, VSIR_DATA_U32, 0); + src_param->reg.dimension = VSIR_DIMENSION_VEC4; if (component_count > 1) - { - src_param->reg.dimension = VSIR_DIMENSION_VEC4; - component_idx = sm6_value_get_constant_uint(operands[0]); - } + component_idx = sm6_value_get_constant_uint(operands[0], sm6); src_param_init_scalar(src_param, component_idx);
instruction_dst_param_init_ssa_scalar(ins, sm6); @@ -5323,12 +5502,12 @@ static enum vkd3d_shader_opcode sm6_dx_map_ma_op(enum dx_intrinsic_opcode op, co switch (op) { case DX_FMA: - return VKD3DSIH_DFMA; + return VSIR_OP_DFMA; case DX_FMAD: - return VKD3DSIH_MAD; + return VSIR_OP_MAD; case DX_IMAD: case DX_UMAD: - return VKD3DSIH_IMAD; + return VSIR_OP_IMAD; default: vkd3d_unreachable(); } @@ -5345,7 +5524,7 @@ static void sm6_parser_emit_dx_ma(struct sm6_parser *sm6, enum dx_intrinsic_opco if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; for (i = 0; i < 3; ++i) - src_param_init_from_value(&src_params[i], operands[i]); + src_param_init_from_value(&src_params[i], operands[i], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -5366,7 +5545,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in is_texture = resource->u.handle.d->resource_type != VKD3D_SHADER_RESOURCE_BUFFER; resource_kind = resource->u.handle.d->kind;
- instruction_init_with_resource(ins, is_texture ? VKD3DSIH_RESINFO : VKD3DSIH_BUFINFO, resource, sm6); + instruction_init_with_resource(ins, is_texture ? VSIR_OP_RESINFO : VSIR_OP_BUFINFO, resource, sm6);
if (!(src_params = instruction_src_params_alloc(ins, 1 + is_texture, sm6))) return; @@ -5375,17 +5554,17 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in if (is_texture) { ins->flags = VKD3DSI_RESINFO_UINT; - src_param_init_from_value(&src_params[0], operands[1]); + src_param_init_from_value(&src_params[0], operands[1], sm6); component_count = VKD3D_VEC4_SIZE;
if (resource_kind_is_multisampled(resource_kind)) { - instruction_dst_param_init_temp_vector(ins++, sm6); + instruction_dst_param_init_uint_temp_vector(ins++, sm6); state->temp_idx = 1;
/* DXIL does not have an intrinsic for sample info, and resinfo is expected to return * the sample count in .w for MS textures. The result is always a struct of 4 x uint32. */ - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_INFO); ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) @@ -5393,7 +5572,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); src_params[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X);
- if (!instruction_dst_param_init_temp_vector(ins, sm6)) + if (!instruction_dst_param_init_uint_temp_vector(ins, sm6)) return; dst = ins->dst; dst->write_mask = VKD3DSP_WRITEMASK_3; @@ -5401,7 +5580,7 @@ static void sm6_parser_emit_dx_get_dimensions(struct sm6_parser *sm6, enum dx_in /* Move the result to an SSA in case another instruction overwrites r0 before * the components are extracted for use. */ ++ins; - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; src_param_init_vector_from_reg(&src_params[0], &dst->reg); @@ -5429,9 +5608,9 @@ static enum vkd3d_shader_opcode sm6_dx_map_tertiary_op(enum dx_intrinsic_opcode switch (op) { case DX_IBFE: - return VKD3DSIH_IBFE; + return VSIR_OP_IBFE; case DX_UBFE: - return VKD3DSIH_UBFE; + return VSIR_OP_UBFE; default: vkd3d_unreachable(); } @@ -5448,7 +5627,7 @@ static void sm6_parser_emit_dx_tertiary(struct sm6_parser *sm6, enum dx_intrinsi if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; for (i = 0; i < 3; ++i) - src_param_init_from_value(&src_params[i], operands[i]); + src_param_init_from_value(&src_params[i], operands[i], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -5466,8 +5645,8 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin const struct shader_signature *signature; const struct signature_element *e;
- row_index = sm6_value_get_constant_uint(operands[0]); - column_index = sm6_value_get_constant_uint(operands[2]); + row_index = sm6_value_get_constant_uint(operands[0], sm6); + column_index = sm6_value_get_constant_uint(operands[2], sm6);
if (is_control_point && operands[3]->value_type == VALUE_TYPE_UNDEFINED) { @@ -5477,7 +5656,7 @@ static void sm6_parser_emit_dx_load_input(struct sm6_parser *sm6, enum dx_intrin "The index for a control point load is undefined."); }
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (is_patch_constant) { @@ -5532,7 +5711,7 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri return;
ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; src_params[0].reg = reg; @@ -5544,13 +5723,13 @@ static void sm6_parser_emit_dx_make_double(struct sm6_parser *sm6, enum dx_intri static void sm6_parser_emit_dx_output_control_point_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { - sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT); + sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, true); }
static void sm6_parser_emit_dx_primitive_id(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { - sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VKD3D_DATA_UINT); + sm6_parser_emit_dx_input_register_mov(sm6, state->ins, VKD3DSPR_PRIMID, VSIR_DATA_U32, true); }
static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) @@ -5558,13 +5737,13 @@ static enum vkd3d_shader_opcode dx_map_quad_op(enum dxil_quad_op_kind op) switch (op) { case QUAD_READ_ACROSS_X: - return VKD3DSIH_QUAD_READ_ACROSS_X; + return VSIR_OP_QUAD_READ_ACROSS_X; case QUAD_READ_ACROSS_Y: - return VKD3DSIH_QUAD_READ_ACROSS_Y; + return VSIR_OP_QUAD_READ_ACROSS_Y; case QUAD_READ_ACROSS_D: - return VKD3DSIH_QUAD_READ_ACROSS_D; + return VSIR_OP_QUAD_READ_ACROSS_D; default: - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; } }
@@ -5576,8 +5755,8 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic enum vkd3d_shader_opcode opcode; enum dxil_quad_op_kind quad_op;
- quad_op = sm6_value_get_constant_uint(operands[1]); - if ((opcode = dx_map_quad_op(quad_op)) == VKD3DSIH_INVALID) + quad_op = sm6_value_get_constant_uint(operands[1], sm6); + if ((opcode = dx_map_quad_op(quad_op)) == VSIR_OP_INVALID) { FIXME("Unhandled quad op kind %u.\n", quad_op); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, @@ -5589,7 +5768,7 @@ static void sm6_parser_emit_dx_quad_op(struct sm6_parser *sm6, enum dx_intrinsic
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -5610,7 +5789,7 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i
if (op == DX_RAW_BUFFER_LOAD) { - write_mask = sm6_value_get_constant_uint(operands[3]); + write_mask = sm6_value_get_constant_uint(operands[3], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -5627,11 +5806,11 @@ static void sm6_parser_emit_dx_raw_buffer_load(struct sm6_parser *sm6, enum dx_i component_count = vsir_write_mask_component_count(write_mask); }
- instruction_init_with_resource(ins, raw ? VKD3DSIH_LD_RAW : VKD3DSIH_LD_STRUCTURED, resource, sm6); + instruction_init_with_resource(ins, raw ? VSIR_OP_LD_RAW : VSIR_OP_LD_STRUCTURED, resource, sm6); operand_count = 2 + !raw; if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) return; - src_params_init_from_operands(src_params, &operands[1], operand_count - 1); + src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6); src_param_init_vector_from_handle(sm6, &src_params[operand_count - 1], &resource->u.handle);
instruction_dst_param_init_ssa_vector(ins, component_count, sm6); @@ -5653,7 +5832,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ return; raw = resource->u.handle.d->kind == RESOURCE_KIND_RAWBUFFER;
- write_mask = sm6_value_get_constant_uint(operands[7]); + write_mask = sm6_value_get_constant_uint(operands[7], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -5679,7 +5858,7 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ "Resource for a raw buffer store is not a raw or structured buffer."); }
- alignment = sm6_value_get_constant_uint(operands[8]); + alignment = sm6_value_get_constant_uint(operands[8], sm6); if (alignment & (alignment - 1)) { FIXME("Invalid alignment %#x.\n", alignment); @@ -5692,13 +5871,13 @@ static void sm6_parser_emit_dx_raw_buffer_store(struct sm6_parser *sm6, enum dx_ return;
ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, raw ? VKD3DSIH_STORE_RAW : VKD3DSIH_STORE_STRUCTURED); + vsir_instruction_init(ins, &sm6->p.location, raw ? VSIR_OP_STORE_RAW : VSIR_OP_STORE_STRUCTURED); operand_count = 2 + !raw;
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) return; - src_params_init_from_operands(src_params, &operands[1], operand_count - 1); - data.data_type = VKD3D_DATA_UINT; + src_params_init_from_operands(src_params, &operands[1], operand_count - 1, sm6); + data.data_type = VSIR_DATA_U32; src_param_init_vector_from_reg(&src_params[operand_count - 1], &data);
dst_param = instruction_dst_params_alloc(ins, 1, sm6); @@ -5732,11 +5911,11 @@ static void sm6_parser_emit_dx_buffer_load(struct sm6_parser *sm6, enum dx_intri }
instruction_init_with_resource(ins, (resource->u.handle.d->type == VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) - ? VKD3DSIH_LD_UAV_TYPED : VKD3DSIH_LD, resource, sm6); + ? VSIR_OP_LD_UAV_TYPED : VSIR_OP_LD, resource, sm6);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; - src_param_init_from_value(&src_params[0], operands[1]); + src_param_init_from_value(&src_params[0], operands[1], sm6); if (!sm6_value_is_undef(operands[2])) { /* Constant zero would be ok, but is not worth checking for unless it shows up. */ @@ -5776,7 +5955,7 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr "Resource for a typed buffer store is not a typed buffer."); }
- write_mask = sm6_value_get_constant_uint(operands[7]); + write_mask = sm6_value_get_constant_uint(operands[7], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -5797,11 +5976,11 @@ static void sm6_parser_emit_dx_buffer_store(struct sm6_parser *sm6, enum dx_intr return;
ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_UAV_TYPED);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; - src_param_init_from_value(&src_params[0], operands[1]); + src_param_init_from_value(&src_params[0], operands[1], sm6); if (!sm6_value_is_undef(operands[2])) { /* Constant zero would have no effect, but is not worth checking for unless it shows up. */ @@ -5822,17 +6001,17 @@ static void sm6_parser_emit_dx_get_sample_count(struct sm6_parser *sm6, enum dx_ struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_INFO); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_INFO); ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&src_param->reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param_init(src_param);
instruction_dst_param_init_ssa_scalar(ins, sm6); - ins->dst->reg.data_type = VKD3D_DATA_FLOAT; + ins->dst->reg.data_type = VSIR_DATA_U32; }
static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -5849,37 +6028,37 @@ static void sm6_parser_emit_dx_get_sample_pos(struct sm6_parser *sm6, enum dx_in return; }
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SAMPLE_POS); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_SAMPLE_POS);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; if (op == DX_TEX2DMS_GET_SAMPLE_POS) { src_param_init_vector_from_handle(sm6, &src_params[0], &resource->u.handle); - src_param_init_from_value(&src_params[1], operands[1]); + src_param_init_from_value(&src_params[1], operands[1], sm6); } else { src_param_init_vector(&src_params[0], 2); - vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&src_params[0].reg, VKD3DSPR_RASTERIZER, VSIR_DATA_F32, 0); src_params[0].reg.dimension = VSIR_DIMENSION_VEC4; - src_param_init_from_value(&src_params[1], operands[0]); + src_param_init_from_value(&src_params[1], operands[0], sm6); }
instruction_dst_param_init_ssa_vector(ins, 2, sm6); }
-static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value) +static unsigned int sm6_value_get_texel_offset(const struct sm6_value *value, struct sm6_parser *sm6) { - return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value); + return sm6_value_is_undef(value) ? 0 : sm6_value_get_constant_uint(value, sm6); }
static void instruction_set_texel_offset(struct vkd3d_shader_instruction *ins, const struct sm6_value **operands, struct sm6_parser *sm6) { - ins->texel_offset.u = sm6_value_get_texel_offset(operands[0]); - ins->texel_offset.v = sm6_value_get_texel_offset(operands[1]); - ins->texel_offset.w = sm6_value_get_texel_offset(operands[2]); + ins->texel_offset.u = sm6_value_get_texel_offset(operands[0], sm6); + ins->texel_offset.v = sm6_value_get_texel_offset(operands[1], sm6); + ins->texel_offset.w = sm6_value_get_texel_offset(operands[2], sm6); }
static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -5914,7 +6093,7 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ switch (op) { case DX_SAMPLE: - instruction_init_with_resource(ins, VKD3DSIH_SAMPLE, resource, sm6); + instruction_init_with_resource(ins, VSIR_OP_SAMPLE, resource, sm6); src_params = instruction_src_params_alloc(ins, 3, sm6); clamp_idx = 9; break; @@ -5922,23 +6101,23 @@ static void sm6_parser_emit_dx_sample(struct sm6_parser *sm6, enum dx_intrinsic_ clamp_idx = 10; /* fall through */ case DX_SAMPLE_LOD: - instruction_init_with_resource(ins, (op == DX_SAMPLE_B) ? VKD3DSIH_SAMPLE_B : VKD3DSIH_SAMPLE_LOD, + instruction_init_with_resource(ins, (op == DX_SAMPLE_B) ? VSIR_OP_SAMPLE_B : VSIR_OP_SAMPLE_LOD, resource, sm6); src_params = instruction_src_params_alloc(ins, 4, sm6); - src_param_init_from_value(&src_params[3], operands[9]); + src_param_init_from_value(&src_params[3], operands[9], sm6); break; case DX_SAMPLE_C: clamp_idx = 10; /* fall through */ case DX_SAMPLE_C_LZ: - instruction_init_with_resource(ins, (op == DX_SAMPLE_C_LZ) ? VKD3DSIH_SAMPLE_C_LZ : VKD3DSIH_SAMPLE_C, + instruction_init_with_resource(ins, (op == DX_SAMPLE_C_LZ) ? VSIR_OP_SAMPLE_C_LZ : VSIR_OP_SAMPLE_C, resource, sm6); src_params = instruction_src_params_alloc(ins, 4, sm6); - src_param_init_from_value(&src_params[3], operands[9]); + src_param_init_from_value(&src_params[3], operands[9], sm6); component_count = 1; break; case DX_SAMPLE_GRAD: - instruction_init_with_resource(ins, VKD3DSIH_SAMPLE_GRAD, resource, sm6); + instruction_init_with_resource(ins, VSIR_OP_SAMPLE_GRAD, resource, sm6); src_params = instruction_src_params_alloc(ins, 5, sm6); src_param_init_vector_from_reg(&src_params[3], &ddx); src_param_init_vector_from_reg(&src_params[4], &ddy); @@ -5974,7 +6153,7 @@ static void sm6_parser_emit_dx_sample_index(struct sm6_parser *sm6, enum dx_intr struct vkd3d_shader_src_param *src_param; unsigned int element_idx;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
/* SV_SampleIndex is identified in VSIR by its signature element index, * but the index is not supplied as a parameter to the DXIL intrinsic. */ @@ -6000,49 +6179,25 @@ static void sm6_parser_emit_dx_saturate(struct sm6_parser *sm6, enum dx_intrinsi struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6);
if (instruction_dst_param_init_ssa_scalar(ins, sm6)) ins->dst->modifiers = VKD3DSPDM_SATURATE; }
-static void sm6_parser_emit_dx_sincos(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, - const struct sm6_value **operands, struct function_emission_state *state) -{ - struct sm6_value *dst = sm6_parser_get_current_value(sm6); - struct vkd3d_shader_instruction *ins = state->ins; - struct vkd3d_shader_dst_param *dst_params; - struct vkd3d_shader_src_param *src_param; - unsigned int index; - - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_SINCOS); - if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) - return; - src_param_init_from_value(src_param, operands[0]); - - sm6_parser_init_ssa_value(sm6, dst); - - index = op == DX_COS; - dst_params = instruction_dst_params_alloc(ins, 2, sm6); - dst_param_init(&dst_params[0]); - dst_param_init(&dst_params[1]); - sm6_register_from_value(&dst_params[index].reg, dst); - vsir_dst_param_init_null(&dst_params[index ^ 1]); -} - static void sm6_parser_emit_dx_split_double(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, const struct sm6_value **operands, struct function_emission_state *state) { struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_vector(ins, 2, sm6); } @@ -6060,8 +6215,8 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr const struct signature_element *e; const struct sm6_value *value;
- row_index = sm6_value_get_constant_uint(operands[0]); - column_index = sm6_value_get_constant_uint(operands[2]); + row_index = sm6_value_get_constant_uint(operands[0], sm6); + column_index = sm6_value_get_constant_uint(operands[2], sm6);
signature = is_patch_constant ? &program->patch_constant_signature : &program->output_signature; if (row_index >= signature->element_count) @@ -6092,7 +6247,7 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr return; }
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) return; @@ -6103,12 +6258,12 @@ static void sm6_parser_emit_dx_store_output(struct sm6_parser *sm6, enum dx_intr
if (e->register_index == UINT_MAX) { - sm6_parser_dcl_register_builtin(sm6, VKD3DSIH_DCL_OUTPUT, dst_param->reg.type, + sm6_parser_dcl_register_builtin(sm6, VSIR_OP_DCL_OUTPUT, dst_param->reg.type, dst_param->reg.data_type, vsir_write_mask_component_count(e->mask)); }
if ((src_param = instruction_src_params_alloc(ins, 1, sm6))) - src_param_init_from_value(src_param, value); + src_param_init_from_value(src_param, value, sm6); }
static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -6138,19 +6293,23 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in return; }
+ /* DXIL doesn't know about signedness, but vsir expects the offset to be signed. */ + if (extended_offset) + offset.data_type = VSIR_DATA_I32; + ins = state->ins; if (op == DX_TEXTURE_GATHER) { - instruction_init_with_resource(ins, extended_offset ? VKD3DSIH_GATHER4_PO : VKD3DSIH_GATHER4, resource, sm6); + instruction_init_with_resource(ins, extended_offset ? VSIR_OP_GATHER4_PO : VSIR_OP_GATHER4, resource, sm6); if (!(src_params = instruction_src_params_alloc(ins, 3 + extended_offset, sm6))) return; } else { - instruction_init_with_resource(ins, extended_offset ? VKD3DSIH_GATHER4_PO_C : VKD3DSIH_GATHER4_C, resource, sm6); + instruction_init_with_resource(ins, extended_offset ? VSIR_OP_GATHER4_PO_C : VSIR_OP_GATHER4_C, resource, sm6); if (!(src_params = instruction_src_params_alloc(ins, 4 + extended_offset, sm6))) return; - src_param_init_from_value(&src_params[3 + extended_offset], operands[9]); + src_param_init_from_value(&src_params[3 + extended_offset], operands[9], sm6); }
src_param_init_vector_from_reg(&src_params[0], &coord); @@ -6161,7 +6320,7 @@ static void sm6_parser_emit_dx_texture_gather(struct sm6_parser *sm6, enum dx_in src_param_init_vector_from_handle(sm6, &src_params[1 + extended_offset], &resource->u.handle); src_param_init_vector_from_handle(sm6, &src_params[2 + extended_offset], &sampler->u.handle); /* Swizzle stored in the sampler parameter is the scalar component index to be gathered. */ - swizzle = sm6_value_get_constant_uint(operands[8]); + swizzle = sm6_value_get_constant_uint(operands[8], sm6); if (swizzle >= VKD3D_VEC4_SIZE) { WARN("Invalid swizzle %#x.\n", swizzle); @@ -6201,8 +6360,8 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr }
ins = state->ins; - instruction_init_with_resource(ins, is_uav ? VKD3DSIH_LD_UAV_TYPED - : is_multisample ? VKD3DSIH_LD2DMS : VKD3DSIH_LD, resource, sm6); + instruction_init_with_resource(ins, is_uav ? VSIR_OP_LD_UAV_TYPED + : is_multisample ? VSIR_OP_LD2DMS : VSIR_OP_LD, resource, sm6); instruction_set_texel_offset(ins, &operands[5], sm6);
for (i = 0; i < VKD3D_VEC4_SIZE; ++i) @@ -6213,7 +6372,7 @@ static void sm6_parser_emit_dx_texture_load(struct sm6_parser *sm6, enum dx_intr src_param_init_vector_from_reg(&src_params[0], &coord); src_param_init_vector_from_handle(sm6, &src_params[1], &resource->u.handle); if (is_multisample) - src_param_init_from_value(&src_params[2], mip_level_or_sample_count); + src_param_init_from_value(&src_params[2], mip_level_or_sample_count, sm6);
instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } @@ -6235,7 +6394,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int if (!sm6_parser_emit_coordinate_construct(sm6, &operands[1], 3, NULL, state, &coord)) return;
- write_mask = sm6_value_get_constant_uint(operands[8]); + write_mask = sm6_value_get_constant_uint(operands[8], sm6); if (!write_mask || write_mask > VKD3DSP_WRITEMASK_ALL) { WARN("Invalid write mask %#x.\n", write_mask); @@ -6256,7 +6415,7 @@ static void sm6_parser_emit_dx_texture_store(struct sm6_parser *sm6, enum dx_int return;
ins = state->ins; - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_UAV_TYPED); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_UAV_TYPED);
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; @@ -6274,10 +6433,10 @@ static void sm6_parser_emit_dx_wave_active_ballot(struct sm6_parser *sm6, enum d struct vkd3d_shader_instruction *ins = state->ins; struct vkd3d_shader_src_param *src_param;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_WAVE_ACTIVE_BALLOT); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_WAVE_ACTIVE_BALLOT); if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_vector(ins, VKD3D_VEC4_SIZE, sm6); } @@ -6288,16 +6447,16 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_bit_op(enum dxil_wave_bit_op_kin switch (op) { case WAVE_BIT_OP_AND: - return VKD3DSIH_WAVE_ACTIVE_BIT_AND; + return VSIR_OP_WAVE_ACTIVE_BIT_AND; case WAVE_BIT_OP_OR: - return VKD3DSIH_WAVE_ACTIVE_BIT_OR; + return VSIR_OP_WAVE_ACTIVE_BIT_OR; case WAVE_BIT_OP_XOR: - return VKD3DSIH_WAVE_ACTIVE_BIT_XOR; + return VSIR_OP_WAVE_ACTIVE_BIT_XOR; default: FIXME("Unhandled wave bit op %u.\n", op); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, - "Wave bit operation %u is unhandled.\n", op); - return VKD3DSIH_INVALID; + "Wave bit operation %u is unhandled.", op); + return VSIR_OP_INVALID; } }
@@ -6309,15 +6468,15 @@ static void sm6_parser_emit_dx_wave_active_bit(struct sm6_parser *sm6, enum dx_i enum dxil_wave_bit_op_kind wave_op; enum vkd3d_shader_opcode opcode;
- wave_op = sm6_value_get_constant_uint(operands[1]); + wave_op = sm6_value_get_constant_uint(operands[1], sm6);
- if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VKD3DSIH_INVALID) + if ((opcode = sm6_dx_map_wave_bit_op(wave_op, sm6)) == VSIR_OP_INVALID) return; vsir_instruction_init(ins, &sm6->p.location, opcode);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -6328,22 +6487,22 @@ static enum vkd3d_shader_opcode sm6_dx_map_wave_op(enum dxil_wave_op_kind op, bo switch (op) { case WAVE_OP_ADD: - return VKD3DSIH_WAVE_OP_ADD; + return VSIR_OP_WAVE_OP_ADD; case WAVE_OP_MUL: - return VKD3DSIH_WAVE_OP_MUL; + return VSIR_OP_WAVE_OP_MUL; case WAVE_OP_MIN: if (is_float) - return VKD3DSIH_WAVE_OP_MIN; - return is_signed ? VKD3DSIH_WAVE_OP_IMIN : VKD3DSIH_WAVE_OP_UMIN; + return VSIR_OP_WAVE_OP_MIN; + return is_signed ? VSIR_OP_WAVE_OP_IMIN : VSIR_OP_WAVE_OP_UMIN; case WAVE_OP_MAX: if (is_float) - return VKD3DSIH_WAVE_OP_MAX; - return is_signed ? VKD3DSIH_WAVE_OP_IMAX : VKD3DSIH_WAVE_OP_UMAX; + return VSIR_OP_WAVE_OP_MAX; + return is_signed ? VSIR_OP_WAVE_OP_IMAX : VSIR_OP_WAVE_OP_UMAX; default: FIXME("Unhandled wave op %u.\n", op); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_UNHANDLED_INTRINSIC, - "Wave operation %u is unhandled.\n", op); - return VKD3DSIH_INVALID; + "Wave operation %u is unhandled.", op); + return VSIR_OP_INVALID; } }
@@ -6356,11 +6515,11 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic enum dxil_wave_op_kind wave_op; bool is_signed;
- wave_op = sm6_value_get_constant_uint(operands[1]); - is_signed = !sm6_value_get_constant_uint(operands[2]); + wave_op = sm6_value_get_constant_uint(operands[1], sm6); + is_signed = !sm6_value_get_constant_uint(operands[2], sm6); opcode = sm6_dx_map_wave_op(wave_op, is_signed, sm6_type_is_floating_point(operands[0]->type), sm6);
- if (opcode == VKD3DSIH_INVALID) + if (opcode == VSIR_OP_INVALID) return;
vsir_instruction_init(ins, &sm6->p.location, opcode); @@ -6368,7 +6527,7 @@ static void sm6_parser_emit_dx_wave_op(struct sm6_parser *sm6, enum dx_intrinsic
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, operands[0]); + src_param_init_from_value(src_param, operands[0], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -6390,7 +6549,7 @@ static void sm6_parser_emit_dx_wave_builtin(struct sm6_parser *sm6, enum dx_intr vkd3d_unreachable(); }
- sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VKD3D_DATA_UINT); + sm6_parser_emit_dx_input_register_mov(sm6, state->ins, type, VSIR_DATA_U32, true); }
struct sm6_dx_opcode_info @@ -6436,7 +6595,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_BUFFER_UPDATE_COUNTER ] = {"i", "H8", sm6_parser_emit_dx_buffer_update_counter}, [DX_CALCULATE_LOD ] = {"f", "HHfffb", sm6_parser_emit_dx_calculate_lod}, [DX_CBUFFER_LOAD_LEGACY ] = {"o", "Hi", sm6_parser_emit_dx_cbuffer_load}, - [DX_COS ] = {"g", "R", sm6_parser_emit_dx_sincos}, + [DX_COS ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_COUNT_BITS ] = {"i", "m", sm6_parser_emit_dx_unary}, [DX_COVERAGE ] = {"i", "", sm6_parser_emit_dx_coverage}, [DX_CREATE_HANDLE ] = {"H", "ccib", sm6_parser_emit_dx_create_handle}, @@ -6505,7 +6664,7 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = [DX_SAMPLE_INDEX ] = {"i", "", sm6_parser_emit_dx_sample_index}, [DX_SAMPLE_LOD ] = {"o", "HHffffiiif", sm6_parser_emit_dx_sample}, [DX_SATURATE ] = {"g", "R", sm6_parser_emit_dx_saturate}, - [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_sincos}, + [DX_SIN ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_SPLIT_DOUBLE ] = {"S", "d", sm6_parser_emit_dx_split_double}, [DX_SQRT ] = {"g", "R", sm6_parser_emit_dx_unary}, [DX_STORE_OUTPUT ] = {"v", "ii8o", sm6_parser_emit_dx_store_output}, @@ -6539,11 +6698,13 @@ static const struct sm6_dx_opcode_info sm6_dx_op_table[] = };
static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struct sm6_value *value, char info_type, - const struct sm6_type *ret_type, bool is_return) + const struct sm6_type *ret_type) { const struct sm6_type *type = value->type;
- if (info_type != 'H' && !sm6_value_is_register(value)) + if (info_type != 'H' && info_type != 'v' && !sm6_value_is_register(value)) + return false; + if (!type && info_type != 'v') return false;
switch (info_type) @@ -6578,7 +6739,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 'g': return sm6_type_is_floating_point(type); case 'H': - return (is_return || sm6_value_is_handle(value)) && type == sm6->handle_type; + return sm6_value_is_handle(value) && type == sm6->handle_type; case 'D': return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.Dimensions"); case 'S': @@ -6586,7 +6747,7 @@ static bool sm6_parser_validate_operand_type(struct sm6_parser *sm6, const struc case 'V': return sm6_type_is_struct(type) && !strcmp(type->u.struc->name, "dx.types.fouri32"); case 'v': - return !type; + return sm6_value_is_invalid(value) && !type; case 'o': /* TODO: some type checking may be possible */ return true; @@ -6606,18 +6767,10 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_
info = &sm6_dx_op_table[op];
- VKD3D_ASSERT(info->ret_type[0]); - if (!sm6_parser_validate_operand_type(sm6, dst, info->ret_type[0], NULL, true)) - { - WARN("Failed to validate return type for dx intrinsic id %u, '%s'.\n", op, name); - /* Return type validation failure is not so critical. We only need to set - * a data type for the SSA result. */ - } - for (i = 0; i < operand_count; ++i) { const struct sm6_value *value = operands[i]; - if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], dst->type, false)) + if (!sm6_parser_validate_operand_type(sm6, value, info->operand_info[i], dst->type)) { WARN("Failed to validate operand %u for dx intrinsic id %u, '%s'.\n", i + 1, op, name); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -6639,13 +6792,12 @@ static bool sm6_parser_validate_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_ static void sm6_parser_emit_unhandled(struct sm6_parser *sm6, struct vkd3d_shader_instruction *ins, struct sm6_value *dst) { - ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP;
if (!dst->type) return;
dst->value_type = VALUE_TYPE_INVALID; - sm6_register_from_value(&dst->reg, dst); }
static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_opcode op, @@ -6661,10 +6813,22 @@ static void sm6_parser_decode_dx_op(struct sm6_parser *sm6, enum dx_intrinsic_op return; }
- if (sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst)) - sm6_dx_op_table[op].handler(sm6, op, operands, state); - else + if (!sm6_parser_validate_dx_op(sm6, op, name, operands, operand_count, dst)) + { sm6_parser_emit_unhandled(sm6, state->ins, dst); + return; + } + + sm6_dx_op_table[op].handler(sm6, op, operands, state); + + VKD3D_ASSERT(sm6_dx_op_table[op].ret_type[0]); + if (!sm6_parser_validate_operand_type(sm6, dst, sm6_dx_op_table[op].ret_type[0], NULL)) + { + vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, + "Failed to validate return type for dx intrinsic id %u, '%s'.", op, name); + /* Return type validation failure is not so critical. We only need to set + * a data type for the SSA result. */ + } }
static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_record *record, @@ -6750,15 +6914,16 @@ static void sm6_parser_emit_call(struct sm6_parser *sm6, const struct dxil_recor "Expected a constant integer dx intrinsic function id."); return; } - sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value), + sm6_parser_decode_dx_op(sm6, sm6_value_get_constant_uint(op_value, sm6), fn_value->u.function.name, &operands[1], operand_count - 1, state, dst); }
static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_type *from, const struct sm6_type *to, struct sm6_parser *sm6) { - enum vkd3d_shader_opcode op = VKD3DSIH_INVALID; + enum vkd3d_shader_opcode op = VSIR_OP_INVALID; bool from_int, to_int, from_fp, to_fp; + unsigned int from_width, to_width; bool is_valid = false;
from_int = sm6_type_is_integer(from); @@ -6772,92 +6937,98 @@ static enum vkd3d_shader_opcode sm6_map_cast_op(uint64_t code, const struct sm6_ FIXME("Unhandled cast of type class %u to type class %u.\n", from->class, to->class); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Cast of type class %u to type class %u is not implemented.", from->class, to->class); - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; } if (to->u.width == 8 || from->u.width == 8) { FIXME("Unhandled 8-bit value.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, "Cast to/from an 8-bit type is not implemented."); - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; }
- /* DXC emits minimum precision types as 16-bit. These must be emitted - * as 32-bit in VSIR, so all width extensions to 32 bits are no-ops. */ switch (code) { case CAST_TRUNC: - /* nop or min precision. TODO: native 16-bit */ - if (to->u.width == from->u.width || (to->u.width == 16 && from->u.width == 32)) - op = VKD3DSIH_NOP; - else - op = VKD3DSIH_UTOU; + op = VSIR_OP_UTOU; is_valid = from_int && to_int && to->u.width <= from->u.width; break; + case CAST_ZEXT: + op = VSIR_OP_UTOU; + is_valid = from_int && to_int && to->u.width >= from->u.width; + break; + case CAST_SEXT: - /* nop or min precision. TODO: native 16-bit. - * Extension instructions could be emitted for min precision, but in Windows - * the AMD RX 580 simply drops such instructions, which makes sense as no - * assumptions should be made about any behaviour which depends on bit width. */ - if (to->u.width == from->u.width || (to->u.width == 32 && from->u.width == 16)) - { - op = VKD3DSIH_NOP; - is_valid = from_int && to_int; - } - else if (to->u.width > from->u.width) - { - op = (code == CAST_ZEXT) ? VKD3DSIH_UTOU : VKD3DSIH_ITOI; - VKD3D_ASSERT(from->u.width == 1 || to->u.width == 64); - is_valid = from_int && to_int; - } + op = VSIR_OP_ITOI; + is_valid = from_int && to_int && to->u.width >= from->u.width; break; + case CAST_FPTOUI: - op = VKD3DSIH_FTOU; + op = VSIR_OP_FTOU; is_valid = from_fp && to_int && to->u.width > 1; break; + case CAST_FPTOSI: - op = VKD3DSIH_FTOI; + op = VSIR_OP_FTOI; is_valid = from_fp && to_int && to->u.width > 1; break; + case CAST_UITOFP: - op = VKD3DSIH_UTOF; + op = VSIR_OP_UTOF; is_valid = from_int && to_fp; break; + case CAST_SITOFP: - op = VKD3DSIH_ITOF; + op = VSIR_OP_ITOF; is_valid = from_int && to_fp; break; + case CAST_FPTRUNC: - /* TODO: native 16-bit */ - op = (from->u.width == 64) ? VKD3DSIH_DTOF : VKD3DSIH_NOP; - is_valid = from_fp && to_fp; + op = VSIR_OP_DTOF; + is_valid = from_fp && to_fp && to->u.width <= from->u.width; break; + case CAST_FPEXT: - /* TODO: native 16-bit */ - op = (to->u.width == 64) ? VKD3DSIH_FTOD : VKD3DSIH_NOP; - is_valid = from_fp && to_fp; + op = VSIR_OP_FTOD; + is_valid = from_fp && to_fp && to->u.width >= from->u.width; break; + case CAST_BITCAST: - op = VKD3DSIH_MOV; + op = VSIR_OP_MOV; is_valid = to->u.width == from->u.width; break; + default: FIXME("Unhandled cast op %"PRIu64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Cast operation %"PRIu64" is unhandled.\n", code); - return VKD3DSIH_INVALID; + "Cast operation %"PRIu64" is unhandled.", code); + return VSIR_OP_INVALID; }
if (!is_valid) { FIXME("Invalid types %u and/or %u for op %"PRIu64".\n", from->class, to->class, code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, - "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.\n", + "Cast operation %"PRIu64" from type class %u, width %u to type class %u, width %u is invalid.", code, from->class, from->u.width, to->class, to->u.width); - return VKD3DSIH_INVALID; + return VSIR_OP_INVALID; }
+ /* 16-bit values are currently treated as 32-bit, because 16-bit is + * interpreted as a minimum precision hint in SM 6.0, and we don't handle + * SM > 6.0 yet. */ + from_width = from->u.width; + if (from_width == 16) + from_width = 32; + + to_width = to->u.width; + if (to_width == 16) + to_width = 32; + + if (from->class == to->class && from_width == to_width) + op = VSIR_OP_NOP; + return op; }
@@ -6885,33 +7056,33 @@ static void sm6_parser_emit_cast(struct sm6_parser *sm6, const struct dxil_recor { *dst = *value; dst->type = type; - ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; return; }
- if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VKD3DSIH_INVALID) + if ((handler_idx = sm6_map_cast_op(record->operands[i], value->type, type, sm6)) == VSIR_OP_INVALID) return;
vsir_instruction_init(ins, &sm6->p.location, handler_idx);
- if (handler_idx == VKD3DSIH_NOP) + if (handler_idx == VSIR_OP_NOP) { - sm6_register_from_value(&dst->reg, value); - /* Set the result type for casts from 16-bit min precision. */ - if (type->u.width != 16) - dst->reg.data_type = vkd3d_data_type_from_sm6_type(type); + *dst = *value; + dst->type = type; return; }
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - src_param_init_from_value(src_param, value); + src_param_init_from_value(src_param, value, sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6);
- /* bitcast */ - if (handler_idx == VKD3DSIH_MOV) - src_param->reg.data_type = dst->reg.data_type; + /* VSIR bitcasts are represented by source registers with types different + * from the types they were written with, rather than with different types + * for the MOV source and destination. */ + if (handler_idx == VSIR_OP_MOV) + src_param->reg.data_type = ins->dst[0].reg.data_type; }
struct sm6_cmp_info @@ -6924,33 +7095,33 @@ static const struct sm6_cmp_info *sm6_map_cmp2_op(uint64_t code) { static const struct sm6_cmp_info cmp_op_table[] = { - [FCMP_FALSE] = {VKD3DSIH_INVALID}, - [FCMP_OEQ] = {VKD3DSIH_EQO}, - [FCMP_OGT] = {VKD3DSIH_LTO, true}, - [FCMP_OGE] = {VKD3DSIH_GEO}, - [FCMP_OLT] = {VKD3DSIH_LTO}, - [FCMP_OLE] = {VKD3DSIH_GEO, true}, - [FCMP_ONE] = {VKD3DSIH_NEO}, - [FCMP_ORD] = {VKD3DSIH_ORD}, - [FCMP_UNO] = {VKD3DSIH_UNO}, - [FCMP_UEQ] = {VKD3DSIH_EQU}, - [FCMP_UGT] = {VKD3DSIH_LTU, true}, - [FCMP_UGE] = {VKD3DSIH_GEU}, - [FCMP_ULT] = {VKD3DSIH_LTU}, - [FCMP_ULE] = {VKD3DSIH_GEU, true}, - [FCMP_UNE] = {VKD3DSIH_NEU}, - [FCMP_TRUE] = {VKD3DSIH_INVALID}, - - [ICMP_EQ] = {VKD3DSIH_IEQ}, - [ICMP_NE] = {VKD3DSIH_INE}, - [ICMP_UGT] = {VKD3DSIH_ULT, true}, - [ICMP_UGE] = {VKD3DSIH_UGE}, - [ICMP_ULT] = {VKD3DSIH_ULT}, - [ICMP_ULE] = {VKD3DSIH_UGE, true}, - [ICMP_SGT] = {VKD3DSIH_ILT, true}, - [ICMP_SGE] = {VKD3DSIH_IGE}, - [ICMP_SLT] = {VKD3DSIH_ILT}, - [ICMP_SLE] = {VKD3DSIH_IGE, true}, + [FCMP_FALSE] = {VSIR_OP_INVALID}, + [FCMP_OEQ] = {VSIR_OP_EQO}, + [FCMP_OGT] = {VSIR_OP_LTO, true}, + [FCMP_OGE] = {VSIR_OP_GEO}, + [FCMP_OLT] = {VSIR_OP_LTO}, + [FCMP_OLE] = {VSIR_OP_GEO, true}, + [FCMP_ONE] = {VSIR_OP_NEO}, + [FCMP_ORD] = {VSIR_OP_ORD}, + [FCMP_UNO] = {VSIR_OP_UNO}, + [FCMP_UEQ] = {VSIR_OP_EQU}, + [FCMP_UGT] = {VSIR_OP_LTU, true}, + [FCMP_UGE] = {VSIR_OP_GEU}, + [FCMP_ULT] = {VSIR_OP_LTU}, + [FCMP_ULE] = {VSIR_OP_GEU, true}, + [FCMP_UNE] = {VSIR_OP_NEU}, + [FCMP_TRUE] = {VSIR_OP_INVALID}, + + [ICMP_EQ] = {VSIR_OP_IEQ}, + [ICMP_NE] = {VSIR_OP_INE}, + [ICMP_UGT] = {VSIR_OP_ULT, true}, + [ICMP_UGE] = {VSIR_OP_UGE}, + [ICMP_ULT] = {VSIR_OP_ULT}, + [ICMP_ULE] = {VSIR_OP_UGE, true}, + [ICMP_SGT] = {VSIR_OP_ILT, true}, + [ICMP_SGE] = {VSIR_OP_IGE}, + [ICMP_SLT] = {VSIR_OP_ILT}, + [ICMP_SLE] = {VSIR_OP_IGE, true}, };
return (code < ARRAY_SIZE(cmp_op_table)) ? &cmp_op_table[code] : NULL; @@ -6996,7 +7167,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor * do not otherwise occur, so deleting these avoids the need for backend support. */ if (sm6_type_is_bool(type_a) && code == ICMP_NE && sm6_value_is_constant_zero(b)) { - ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; *dst = *a; return; } @@ -7017,7 +7188,7 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor "Type mismatch in comparison operation arguments."); }
- if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VKD3DSIH_INVALID) + if (!(cmp = sm6_map_cmp2_op(code)) || !cmp->handler_idx || cmp->handler_idx == VSIR_OP_INVALID) { FIXME("Unhandled operation %"PRIu64".\n", code); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -7051,8 +7222,8 @@ static void sm6_parser_emit_cmp2(struct sm6_parser *sm6, const struct dxil_recor
if (!(src_params = instruction_src_params_alloc(ins, 2, sm6))) return; - src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a); - src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b); + src_param_init_from_value(&src_params[0 ^ cmp->src_swap], a, sm6); + src_param_init_from_value(&src_params[1 ^ cmp->src_swap], b, sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -7074,7 +7245,7 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re || !sm6_value_validate_is_backward_ref(ptr, sm6)) return;
- sm6_register_from_value(®, ptr); + sm6_register_from_value(®, ptr, sm6);
if (reg.type != VKD3DSPR_GROUPSHAREDMEM) { @@ -7123,20 +7294,20 @@ static void sm6_parser_emit_cmpxchg(struct sm6_parser *sm6, const struct dxil_re if (record->operand_count > i && record->operands[i]) FIXME("Ignoring weak cmpxchg.\n");
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_IMM_ATOMIC_CMP_EXCH); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_IMM_ATOMIC_CMP_EXCH); ins->flags = is_volatile ? VKD3DARF_SEQ_CST | VKD3DARF_VOLATILE : VKD3DARF_SEQ_CST;
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; src_param_make_constant_uint(&src_params[0], 0); - src_param_init_from_value(&src_params[1], cmp); - src_param_init_from_value(&src_params[2], new); + src_param_init_from_value(&src_params[1], cmp, sm6); + src_param_init_from_value(&src_params[2], new, sm6);
sm6_parser_init_ssa_value(sm6, dst);
if (!(dst_params = instruction_dst_params_alloc(ins, 2, sm6))) return; - sm6_register_from_value(&dst_params[0].reg, dst); + sm6_register_from_value(&dst_params[0].reg, dst, sm6); dst_param_init(&dst_params[0]); dst_params[1].reg = reg; dst_param_init(&dst_params[1]); @@ -7191,11 +7362,11 @@ static void sm6_parser_emit_extractval(struct sm6_parser *sm6, const struct dxil } dst->type = type;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOV);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; - sm6_register_from_value(&src_param->reg, src); + sm6_register_from_value(&src_param->reg, src, sm6); src_param_init_scalar(src_param, elem_idx);
instruction_dst_param_init_ssa_scalar(ins, sm6); @@ -7208,9 +7379,8 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record unsigned int elem_idx, operand_idx = 2; enum bitcode_address_space addr_space; const struct sm6_value *elem_value; - struct vkd3d_shader_register reg; const struct sm6_value *src; - bool is_in_bounds; + struct sm6_index *index;
if (!dxil_record_validate_operand_min_count(record, 5, sm6) || !(type = sm6_parser_get_type(sm6, record->operands[1])) @@ -7222,9 +7392,13 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; }
- sm6_register_from_value(®, src); + *dst = *src; + index = sm6_get_value_index(sm6, dst);
- if (reg.idx_count > 1) + if (!index) + return; + + if (index->index) { WARN("Unsupported stacked GEP.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -7232,8 +7406,6 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; }
- is_in_bounds = record->operands[0]; - if ((pointee_type = src->type->u.pointer.type) != type) { WARN("Type mismatch, type %u width %u vs type %u width %u.\n", type->class, @@ -7247,7 +7419,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return;
/* The first index is always zero, to form a simple pointer dereference. */ - if (sm6_value_get_constant_uint(elem_value)) + if (sm6_value_get_constant_uint(elem_value, sm6)) { WARN("Expected constant zero.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_OPERAND, @@ -7267,7 +7439,7 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return;
/* If indexing is dynamic, just get the type at offset zero. */ - elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value) : 0; + elem_idx = sm6_value_is_constant(elem_value) ? sm6_value_get_constant_uint(elem_value, sm6) : 0; type = sm6_type_get_element_type_at_index(pointee_type, elem_idx); if (!type) { @@ -7293,15 +7465,10 @@ static void sm6_parser_emit_gep(struct sm6_parser *sm6, const struct dxil_record return; }
- reg.idx[1].offset = 0; - register_index_address_init(®.idx[1], elem_value, sm6); - reg.idx[1].is_in_bounds = is_in_bounds; - reg.idx_count = 2; - - dst->reg = reg; - dst->structure_stride = src->structure_stride; + index->index = elem_value; + index->is_in_bounds = record->operands[0];
- ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; }
static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_record *record, @@ -7348,12 +7515,12 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor if (record->operands[i]) WARN("Ignoring volatile modifier.\n");
- sm6_register_from_value(®, ptr); + sm6_register_from_value(®, ptr, sm6);
if (ptr->structure_stride) { VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_LD_STRUCTURED); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_LD_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; @@ -7363,7 +7530,7 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); /* Struct offset is always zero as there is no struct, just an array. */ src_param_make_constant_uint(&src_params[1], 0); - src_param_init_from_value(&src_params[2], ptr); + src_param_init_from_value(&src_params[2], ptr, sm6); src_params[2].reg.alignment = alignment; /* The offset is already in src_params[0]. */ src_params[2].reg.idx_count = 1; @@ -7371,13 +7538,13 @@ static void sm6_parser_emit_load(struct sm6_parser *sm6, const struct dxil_recor else { operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); - vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_LD_RAW : VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VSIR_OP_LD_RAW : VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) return; if (operand_count > 1) src_param_make_constant_uint(&src_params[0], 0); - src_param_init_from_value(&src_params[operand_count - 1], ptr); + src_param_init_from_value(&src_params[operand_count - 1], ptr, sm6); src_params[operand_count - 1].reg.alignment = alignment; }
@@ -7425,7 +7592,6 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record
if (!(phi = sm6_block_phi_require_space(code_block, sm6))) return; - sm6_register_from_value(&phi->reg, dst); phi->incoming_count = record->operand_count / 2u;
if (!vkd3d_array_reserve((void **)&phi->incoming, &phi->incoming_capacity, phi->incoming_count, @@ -7456,7 +7622,7 @@ static void sm6_parser_emit_phi(struct sm6_parser *sm6, const struct dxil_record incoming[j].block = sm6_function_get_block(function, record->operands[i + 1], sm6); }
- ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP;
qsort(incoming, phi->incoming_count, sizeof(*incoming), phi_incoming_compare);
@@ -7491,7 +7657,7 @@ static void sm6_parser_emit_ret(struct sm6_parser *sm6, const struct dxil_record
code_block->terminator.type = TERMINATOR_RET;
- ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; }
static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_record *record, @@ -7536,12 +7702,12 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco if (record->operands[i]) WARN("Ignoring volatile modifier.\n");
- sm6_register_from_value(®, ptr); + sm6_register_from_value(®, ptr, sm6);
if (ptr->structure_stride) { VKD3D_ASSERT(reg.type == VKD3DSPR_GROUPSHAREDMEM); - vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_STORE_STRUCTURED); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_STORE_STRUCTURED);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; @@ -7551,18 +7717,18 @@ static void sm6_parser_emit_store(struct sm6_parser *sm6, const struct dxil_reco src_param_make_constant_uint(&src_params[0], reg.idx[1].offset); /* Struct offset is always zero as there is no struct, just an array. */ src_param_make_constant_uint(&src_params[1], 0); - src_param_init_from_value(&src_params[2], src); + src_param_init_from_value(&src_params[2], src, sm6); } else { operand_count = 1 + (reg.type == VKD3DSPR_GROUPSHAREDMEM); - vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VKD3DSIH_STORE_RAW : VKD3DSIH_MOV); + vsir_instruction_init(ins, &sm6->p.location, (operand_count > 1) ? VSIR_OP_STORE_RAW : VSIR_OP_MOV);
if (!(src_params = instruction_src_params_alloc(ins, operand_count, sm6))) return; if (operand_count > 1) src_param_make_constant_uint(&src_params[0], 0); - src_param_init_from_value(&src_params[operand_count - 1], src); + src_param_init_from_value(&src_params[operand_count - 1], src, sm6); }
dst_param = instruction_dst_params_alloc(ins, 1, sm6); @@ -7612,7 +7778,7 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec return; }
- sm6_register_from_value(&terminator->conditional_reg, src); + sm6_register_from_value(&terminator->conditional_reg, src, sm6); terminator->type = TERMINATOR_SWITCH;
terminator->case_count = record->operand_count / 2u; @@ -7651,10 +7817,10 @@ static void sm6_parser_emit_switch(struct sm6_parser *sm6, const struct dxil_rec "A switch case value is not a constant."); }
- terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src); + terminator->cases[i / 2u].value = sm6_value_get_constant_uint64(src, sm6); }
- ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; }
static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_record *record, @@ -7683,12 +7849,12 @@ static void sm6_parser_emit_vselect(struct sm6_parser *sm6, const struct dxil_re if (!sm6_value_validate_is_bool(src[0], sm6)) return;
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_MOVC); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_MOVC);
if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; for (i = 0; i < 3; ++i) - src_param_init_from_value(&src_params[i], src[i]); + src_param_init_from_value(&src_params[i], src[i], sm6);
instruction_dst_param_init_ssa_scalar(ins, sm6); } @@ -7714,7 +7880,7 @@ static bool sm6_metadata_value_is_zero_or_undef(const struct sm6_metadata_value && (sm6_value_is_undef(m->u.value) || sm6_value_is_constant_zero(m->u.value)); }
-static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, +static bool sm6_metadata_get_uint_value(struct sm6_parser *sm6, const struct sm6_metadata_value *m, unsigned int *u) { const struct sm6_value *value; @@ -7728,12 +7894,12 @@ static bool sm6_metadata_get_uint_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false;
- *u = sm6_value_get_constant_uint(value); + *u = sm6_value_get_constant_uint(value, sm6);
return true; }
-static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, +static bool sm6_metadata_get_uint64_value(struct sm6_parser *sm6, const struct sm6_metadata_value *m, uint64_t *u) { const struct sm6_value *value; @@ -7747,12 +7913,12 @@ static bool sm6_metadata_get_uint64_value(const struct sm6_parser *sm6, if (!sm6_type_is_integer(value->type)) return false;
- *u = sm6_value_get_constant_uint(value); + *u = sm6_value_get_constant_uint(value, sm6);
return true; }
-static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, +static bool sm6_metadata_get_float_value(struct sm6_parser *sm6, const struct sm6_metadata_value *m, float *f) { const struct sm6_value *value; @@ -7766,7 +7932,7 @@ static bool sm6_metadata_get_float_value(const struct sm6_parser *sm6, if (!sm6_type_is_floating_point(value->type)) return false;
- *f = register_get_float_value(&value->reg); + *f = sm6_value_get_constant_float(value, sm6);
return true; } @@ -7951,7 +8117,7 @@ static void metadata_attachment_record_apply(const struct dxil_record *record, e } else if (metadata_node_get_unary_uint(node, &operand, sm6)) { - dst->reg.non_uniform = !!operand; + dst->non_uniform = !!operand; } } else @@ -8023,13 +8189,13 @@ static enum vkd3d_result sm6_function_resolve_phi_incomings(const struct sm6_fun "A PHI incoming value is not a constant or SSA register."); return VKD3D_ERROR_INVALID_SHADER; } - if (src->reg.data_type != phi->reg.data_type) + if (src->type != phi->value.type) { WARN("Type mismatch.\n"); vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, "The type of a phi incoming value does not match the result type."); } - sm6_register_from_value(&phi->incoming[j].reg, src); + sm6_register_from_value(&phi->incoming[j].reg, src, sm6); } } } @@ -8113,12 +8279,11 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const }
ins = &code_block->instructions[code_block->instruction_count]; - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID;
dst = sm6_parser_get_current_value(sm6); fwd_type = dst->type; dst->type = NULL; - dst->value_type = VALUE_TYPE_REG; dst->is_back_ref = true; is_terminator = false;
@@ -8196,13 +8361,17 @@ static enum vkd3d_result sm6_parser_function_init(struct sm6_parser *sm6, const if (record->attachment) metadata_attachment_record_apply(record->attachment, record->code, ins, dst, sm6);
+ /* This is specific for PHI nodes, but must happen after attachments have been applied. */ + if (record->code == FUNC_CODE_INST_PHI) + code_block->phi[code_block->phi_count - 1].value = *dst; + if (is_terminator) { ++block_idx; code_block = (block_idx < function->block_count) ? function->blocks[block_idx] : NULL; } if (code_block) - code_block->instruction_count += ins->opcode != VKD3DSIH_NOP; + code_block->instruction_count += ins->opcode != VSIR_OP_NOP;
if (dst->type && fwd_type && dst->type != fwd_type) { @@ -8234,7 +8403,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ case TERMINATOR_UNCOND_BR: if (!block->terminator.true_block) return; - ins = sm6_parser_add_instruction(sm6, VKD3DSIH_BRANCH); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH); if (!(src_params = instruction_src_params_alloc(ins, 1, sm6))) return; vsir_src_param_init_label(&src_params[0], block->terminator.true_block->id); @@ -8243,7 +8412,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ case TERMINATOR_COND_BR: if (!block->terminator.true_block || !block->terminator.false_block) return; - ins = sm6_parser_add_instruction(sm6, VKD3DSIH_BRANCH); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_BRANCH); if (!(src_params = instruction_src_params_alloc(ins, 3, sm6))) return; src_param_init(&src_params[0]); @@ -8253,7 +8422,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ break;
case TERMINATOR_SWITCH: - ins = sm6_parser_add_instruction(sm6, VKD3DSIH_SWITCH_MONOLITHIC); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_SWITCH_MONOLITHIC); if (!(src_params = instruction_src_params_alloc(ins, block->terminator.case_count * 2u + 1, sm6))) return; src_param_init(&src_params[0]); @@ -8278,9 +8447,9 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ continue; }
- if (src_params[0].reg.data_type == VKD3D_DATA_UINT64) + if (src_params[0].reg.data_type == VSIR_DATA_U64) { - vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VKD3D_DATA_UINT64, 0); + vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST64, VSIR_DATA_U64, 0); src_params[count++].reg.u.immconst_u64[0] = switch_case->value; } else @@ -8291,7 +8460,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ vkd3d_shader_parser_warning(&sm6->p, VKD3D_SHADER_WARNING_DXIL_TYPE_MISMATCH, "Truncating 64-bit switch case value %"PRIx64" to 32 bits.", switch_case->value); } - vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); + vsir_src_param_init(&src_params[count], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); src_params[count++].reg.u.immconst_u32[0] = switch_case->value; } vsir_src_param_init_label(&src_params[count++], case_block->id); @@ -8300,7 +8469,7 @@ static void sm6_block_emit_terminator(const struct sm6_block *block, struct sm6_ break;
case TERMINATOR_RET: - sm6_parser_add_instruction(sm6, VKD3DSIH_RET); + sm6_parser_add_instruction(sm6, VSIR_OP_RET); break;
default: @@ -8322,7 +8491,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser src_phi = &block->phi[i]; incoming_count = src_phi->incoming_count;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_PHI); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_PHI); if (!(src_params = instruction_src_params_alloc(ins, incoming_count * 2u, sm6))) return; if (!(dst_param = instruction_dst_params_alloc(ins, 1, sm6))) @@ -8342,7 +8511,7 @@ static void sm6_block_emit_phi(const struct sm6_block *block, struct sm6_parser }
dst_param_init(dst_param); - dst_param->reg = src_phi->reg; + sm6_register_from_value(&dst_param->reg, &src_phi->value, sm6); } }
@@ -8408,7 +8577,7 @@ static void sm6_parser_emit_label(struct sm6_parser *sm6, unsigned int label_id) struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_LABEL); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_LABEL);
if (!(src_param = instruction_src_params_alloc(ins, 1, sm6))) return; @@ -8738,6 +8907,7 @@ static const enum vkd3d_shader_sysval_semantic sysval_semantic_table[] = [SEMANTIC_KIND_INSTANCEID] = VKD3D_SHADER_SV_INSTANCE_ID, [SEMANTIC_KIND_POSITION] = VKD3D_SHADER_SV_POSITION, [SEMANTIC_KIND_RTARRAYINDEX] = VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX, + [SEMANTIC_KIND_VIEWPORTARRAYINDEX] = VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX, [SEMANTIC_KIND_CLIPDISTANCE] = VKD3D_SHADER_SV_CLIP_DISTANCE, [SEMANTIC_KIND_CULLDISTANCE] = VKD3D_SHADER_SV_CULL_DISTANCE, [SEMANTIC_KIND_PRIMITIVEID] = VKD3D_SHADER_SV_PRIMITIVE_ID, @@ -8876,40 +9046,39 @@ static enum vkd3d_shader_resource_type shader_resource_type_from_dxil_resource_k } }
-static const enum vkd3d_data_type data_type_table[] = -{ - [COMPONENT_TYPE_INVALID] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_I1] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_I16] = VKD3D_DATA_INT, - [COMPONENT_TYPE_U16] = VKD3D_DATA_UINT, - [COMPONENT_TYPE_I32] = VKD3D_DATA_INT, - [COMPONENT_TYPE_U32] = VKD3D_DATA_UINT, - [COMPONENT_TYPE_I64] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_U64] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_F16] = VKD3D_DATA_FLOAT, - [COMPONENT_TYPE_F32] = VKD3D_DATA_FLOAT, - [COMPONENT_TYPE_F64] = VKD3D_DATA_DOUBLE, - [COMPONENT_TYPE_SNORMF16] = VKD3D_DATA_SNORM, - [COMPONENT_TYPE_UNORMF16] = VKD3D_DATA_UNORM, - [COMPONENT_TYPE_SNORMF32] = VKD3D_DATA_SNORM, - [COMPONENT_TYPE_UNORMF32] = VKD3D_DATA_UNORM, - [COMPONENT_TYPE_SNORMF64] = VKD3D_DATA_DOUBLE, - [COMPONENT_TYPE_UNORMF64] = VKD3D_DATA_DOUBLE, - [COMPONENT_TYPE_PACKEDS8X32] = VKD3D_DATA_UNUSED, - [COMPONENT_TYPE_PACKEDU8X32] = VKD3D_DATA_UNUSED, +static const enum vsir_data_type data_type_table[] = +{ + [COMPONENT_TYPE_INVALID] = VSIR_DATA_UNUSED, + [COMPONENT_TYPE_I1] = VSIR_DATA_UNUSED, + [COMPONENT_TYPE_I16] = VSIR_DATA_I32, + [COMPONENT_TYPE_U16] = VSIR_DATA_U32, + [COMPONENT_TYPE_I32] = VSIR_DATA_I32, + [COMPONENT_TYPE_U32] = VSIR_DATA_U32, + [COMPONENT_TYPE_I64] = VSIR_DATA_UNUSED, + [COMPONENT_TYPE_U64] = VSIR_DATA_UNUSED, + [COMPONENT_TYPE_F16] = VSIR_DATA_F32, + [COMPONENT_TYPE_F32] = VSIR_DATA_F32, + [COMPONENT_TYPE_F64] = VSIR_DATA_F64, + [COMPONENT_TYPE_SNORMF16] = VSIR_DATA_SNORM, + [COMPONENT_TYPE_UNORMF16] = VSIR_DATA_UNORM, + [COMPONENT_TYPE_SNORMF32] = VSIR_DATA_SNORM, + [COMPONENT_TYPE_UNORMF32] = VSIR_DATA_UNORM, + [COMPONENT_TYPE_SNORMF64] = VSIR_DATA_F64, + [COMPONENT_TYPE_UNORMF64] = VSIR_DATA_F64, + [COMPONENT_TYPE_PACKEDS8X32] = VSIR_DATA_UNUSED, + [COMPONENT_TYPE_PACKEDU8X32] = VSIR_DATA_UNUSED, };
-static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_component_type type, +static enum vsir_data_type vsir_data_type_from_dxil_component_type(enum dxil_component_type type, struct sm6_parser *sm6) { - enum vkd3d_data_type data_type; + enum vsir_data_type data_type;
- if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VKD3D_DATA_UNUSED) + if (type >= ARRAY_SIZE(data_type_table) || (data_type = data_type_table[type]) == VSIR_DATA_UNUSED) { - FIXME("Unhandled component type %u.\n", type); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, "Resource descriptor component type %u is unhandled.", type); - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; }
return data_type; @@ -8917,7 +9086,7 @@ static enum vkd3d_data_type vkd3d_data_type_from_dxil_component_type(enum dxil_c
struct resource_additional_values { - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; unsigned int byte_stride; };
@@ -8926,7 +9095,7 @@ static bool resources_load_additional_values(struct resource_additional_values * { unsigned int i, operand_count, tag, value;
- info->data_type = VKD3D_DATA_UNUSED; + info->data_type = VSIR_DATA_UNUSED; info->byte_stride = 0;
if (node->operand_count & 1) @@ -8958,7 +9127,7 @@ static bool resources_load_additional_values(struct resource_additional_values * "An untyped resource has type %u.", value); return false; } - info->data_type = vkd3d_data_type_from_dxil_component_type(value, sm6); + info->data_type = vsir_data_type_from_dxil_component_type(value, sm6); break;
case RESOURCE_TAG_ELEMENT_STRIDE: @@ -9018,7 +9187,7 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
if (!m) { - ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; + ins->opcode = is_uav ? VSIR_OP_DCL_UAV_RAW : VSIR_OP_DCL_RESOURCE_RAW; ins->declaration.raw_resource.resource.reg.write_mask = 0; return &ins->declaration.raw_resource.resource; } @@ -9036,14 +9205,13 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc
if (kind == RESOURCE_KIND_TYPEDBUFFER || resource_kind_is_texture(kind)) { - if (resource_values.data_type == VKD3D_DATA_UNUSED) + if (resource_values.data_type == VSIR_DATA_UNUSED) { - WARN("No data type defined.\n"); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES, "A typed resource has no data type."); }
- ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_TYPED : VKD3DSIH_DCL; + ins->opcode = is_uav ? VSIR_OP_DCL_UAV_TYPED : VSIR_OP_DCL; for (i = 0; i < VKD3D_VEC4_SIZE; ++i) ins->declaration.semantic.resource_data_type[i] = resource_values.data_type; ins->declaration.semantic.resource_type = resource_type; @@ -9053,14 +9221,14 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc } else if (kind == RESOURCE_KIND_RAWBUFFER) { - ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_RAW : VKD3DSIH_DCL_RESOURCE_RAW; + ins->opcode = is_uav ? VSIR_OP_DCL_UAV_RAW : VSIR_OP_DCL_RESOURCE_RAW; ins->declaration.raw_resource.resource.reg.write_mask = 0;
return &ins->declaration.raw_resource.resource; } else if (kind == RESOURCE_KIND_STRUCTUREDBUFFER) { - ins->opcode = is_uav ? VKD3DSIH_DCL_UAV_STRUCTURED : VKD3DSIH_DCL_RESOURCE_STRUCTURED; + ins->opcode = is_uav ? VSIR_OP_DCL_UAV_STRUCTURED : VSIR_OP_DCL_RESOURCE_STRUCTURED; ins->declaration.structured_resource.byte_stride = resource_values.byte_stride; ins->declaration.structured_resource.resource.reg.write_mask = 0;
@@ -9086,8 +9254,8 @@ static struct vkd3d_shader_resource *sm6_parser_resources_load_common_info(struc }
static void init_resource_declaration(struct vkd3d_shader_resource *resource, - enum vkd3d_shader_register_type reg_type, enum vkd3d_data_type data_type, unsigned int id, - const struct vkd3d_shader_register_range *range) + enum vkd3d_shader_register_type reg_type, enum vsir_data_type data_type, + unsigned int id, const struct vkd3d_shader_register_range *range) { struct vkd3d_shader_dst_param *param = &resource->reg;
@@ -9129,7 +9297,7 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; }
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_INVALID);
if (!(resource = sm6_parser_resources_load_common_info(sm6, node->operands[1], false, kind, node->operands[8], ins))) @@ -9140,9 +9308,9 @@ static enum vkd3d_result sm6_parser_resources_load_srv(struct sm6_parser *sm6, d->resource_type = ins->resource_type; d->kind = kind; d->reg_type = VKD3DSPR_RESOURCE; - d->reg_data_type = VKD3D_DATA_UNUSED; - d->resource_data_type = (ins->opcode == VKD3DSIH_DCL) - ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; + d->reg_data_type = VSIR_DATA_UNUSED; + d->resource_data_type = (ins->opcode == VSIR_OP_DCL) + ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_RESOURCE, d->reg_data_type, d->id, &d->range);
@@ -9197,7 +9365,7 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, } }
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_INVALID); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_INVALID); if (values[1]) ins->flags = VKD3DSUF_GLOBALLY_COHERENT; if (values[2]) @@ -9214,9 +9382,9 @@ static enum vkd3d_result sm6_parser_resources_load_uav(struct sm6_parser *sm6, d->resource_type = ins->resource_type; d->kind = values[0]; d->reg_type = VKD3DSPR_UAV; - d->reg_data_type = VKD3D_DATA_UNUSED; - d->resource_data_type = (ins->opcode == VKD3DSIH_DCL_UAV_TYPED) - ? ins->declaration.semantic.resource_data_type[0] : VKD3D_DATA_UNUSED; + d->reg_data_type = VSIR_DATA_UNUSED; + d->resource_data_type = (ins->opcode == VSIR_OP_DCL_UAV_TYPED) + ? ins->declaration.semantic.resource_data_type[0] : VSIR_DATA_UNUSED;
init_resource_declaration(resource, VKD3DSPR_UAV, d->reg_data_type, d->id, &d->range);
@@ -9251,14 +9419,14 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, return VKD3D_ERROR_INVALID_SHADER; }
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_CONSTANT_BUFFER); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_CONSTANT_BUFFER); ins->resource_type = VKD3D_SHADER_RESOURCE_BUFFER; ins->declaration.cb.size = buffer_size; ins->declaration.cb.src.swizzle = VKD3D_SHADER_NO_SWIZZLE; ins->declaration.cb.src.modifiers = VKD3DSPSM_NONE;
reg = &ins->declaration.cb.src.reg; - vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); + vsir_register_init(reg, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3); reg->idx[0].offset = d->id; reg->idx[1].offset = d->range.first; reg->idx[2].offset = d->range.last; @@ -9266,8 +9434,8 @@ static enum vkd3d_result sm6_parser_resources_load_cbv(struct sm6_parser *sm6, ins->declaration.cb.range = d->range;
d->reg_type = VKD3DSPR_CONSTBUFFER; - d->reg_data_type = VKD3D_DATA_FLOAT; - d->resource_data_type = VKD3D_DATA_FLOAT; + d->reg_data_type = VSIR_DATA_F32; + d->resource_data_type = VSIR_DATA_F32;
return VKD3D_OK; } @@ -9292,7 +9460,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm "Ignoring %u extra operands for a sampler descriptor.", node->operand_count - 7); }
- vsir_instruction_init(ins, &sm6->p.location, VKD3DSIH_DCL_SAMPLER); + vsir_instruction_init(ins, &sm6->p.location, VSIR_OP_DCL_SAMPLER); ins->resource_type = VKD3D_SHADER_RESOURCE_NONE;
if (!sm6_metadata_get_uint_value(sm6, node->operands[6], &kind)) @@ -9320,7 +9488,7 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm ins->declaration.sampler.src.modifiers = VKD3DSPSM_NONE;
reg = &ins->declaration.sampler.src.reg; - vsir_register_init(reg, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 3); + vsir_register_init(reg, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 3); reg->idx[0].offset = d->id; reg->idx[1].offset = d->range.first; reg->idx[2].offset = d->range.last; @@ -9330,8 +9498,8 @@ static enum vkd3d_result sm6_parser_resources_load_sampler(struct sm6_parser *sm d->resource_type = ins->resource_type; d->kind = RESOURCE_KIND_SAMPLER; d->reg_type = VKD3DSPR_SAMPLER; - d->reg_data_type = VKD3D_DATA_UNUSED; - d->resource_data_type = VKD3D_DATA_UNUSED; + d->reg_data_type = VSIR_DATA_UNUSED; + d->resource_data_type = VSIR_DATA_UNUSED;
return VKD3D_OK; } @@ -9660,7 +9828,9 @@ static enum vkd3d_result sm6_parser_read_signature(struct sm6_parser *sm6, const
if ((is_register = e->register_index == UINT_MAX)) { - if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input) == VKD3DSPR_INVALID) + enum vsir_dimension dimension; + + if (register_type_from_dxil_semantic_kind(e->sysval_semantic, is_input, &dimension) == VKD3DSPR_INVALID) { WARN("Unhandled I/O register semantic kind %u.\n", j); vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_SIGNATURE, @@ -9813,7 +9983,7 @@ static void sm6_parser_emit_global_flags(struct sm6_parser *sm6, const struct sm rotated_flags = (rotated_flags >> 1) | ((rotated_flags & 1) << 4); global_flags = (global_flags & ~mask) | rotated_flags;
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_GLOBAL_FLAGS); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_GLOBAL_FLAGS); ins->declaration.global_flags = global_flags; sm6->p.program->global_flags = global_flags; } @@ -9870,7 +10040,7 @@ static enum vkd3d_result sm6_parser_emit_thread_group(struct sm6_parser *sm6, co } }
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_THREAD_GROUP); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_THREAD_GROUP); 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]; @@ -9910,7 +10080,7 @@ static void sm6_parser_emit_dcl_tessellator_domain(struct sm6_parser *sm6, "Domain shader tessellator domain %u is unhandled.", tessellator_domain); }
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_DOMAIN); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_DOMAIN); ins->declaration.tessellator_domain = tessellator_domain; sm6->p.program->tess_domain = tessellator_domain; } @@ -9938,7 +10108,7 @@ static void sm6_parser_emit_dcl_tessellator_partitioning(struct sm6_parser *sm6, "Hull shader tessellator partitioning %u is unhandled.", tessellator_partitioning); }
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_TESSELLATOR_PARTITIONING); ins->declaration.tessellator_partitioning = tessellator_partitioning;
sm6->p.program->tess_partitioning = tessellator_partitioning; @@ -9956,7 +10126,7 @@ static void sm6_parser_emit_dcl_tessellator_output_primitive(struct sm6_parser * "Hull shader tessellator output primitive %u is unhandled.", primitive); }
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE); + 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; @@ -9983,7 +10153,7 @@ static void sm6_parser_emit_dcl_max_tessellation_factor(struct sm6_parser *sm6, "Hull shader max tessellation factor %f is invalid.", max_tessellation_factor); }
- ins = sm6_parser_add_instruction(sm6, VKD3DSIH_DCL_HS_MAX_TESSFACTOR); + ins = sm6_parser_add_instruction(sm6, VSIR_OP_DCL_HS_MAX_TESSFACTOR); ins->declaration.max_tessellation_factor = max_tessellation_factor; }
@@ -10070,7 +10240,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s break; }
- sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_INPUT_PRIMITIVE, input_primitive, patch_vertex_count); + 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;
@@ -10082,7 +10252,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Geometry shader output vertex count %u is invalid.", i); } - sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_VERTICES_OUT, i); + sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_VERTICES_OUT, i); sm6->p.program->vertices_out_count = i;
if (operands[2] > 1) @@ -10100,7 +10270,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s "Geometry shader output primitive %u is unhandled.", output_primitive); output_primitive = VKD3D_PT_TRIANGLELIST; } - sm6_parser_emit_dcl_primitive_topology(sm6, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); + sm6_parser_emit_dcl_primitive_topology(sm6, VSIR_OP_DCL_OUTPUT_TOPOLOGY, output_primitive, 0); sm6->p.program->output_topology = output_primitive;
i = operands[4]; @@ -10110,7 +10280,7 @@ static void sm6_parser_gs_properties_init(struct sm6_parser *sm6, const struct s vkd3d_shader_parser_error(&sm6->p, VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES, "Geometry shader instance count %u is invalid.", i); } - sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_GS_INSTANCES, i); + sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_GS_INSTANCES, i); }
static enum vkd3d_tessellator_domain sm6_parser_ds_properties_init(struct sm6_parser *sm6, @@ -10217,7 +10387,7 @@ static enum vkd3d_tessellator_domain sm6_parser_hs_properties_init(struct sm6_pa sm6_parser_validate_control_point_count(sm6, operands[1], false, "Hull shader input"); program->input_control_point_count = operands[1]; sm6_parser_validate_control_point_count(sm6, operands[2], false, "Hull shader output"); - sm6_parser_emit_dcl_count(sm6, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]); + sm6_parser_emit_dcl_count(sm6, VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, operands[2]); program->output_control_point_count = operands[2]; sm6_parser_emit_dcl_tessellator_domain(sm6, operands[3]); sm6_parser_emit_dcl_tessellator_partitioning(sm6, operands[4]); @@ -10742,7 +10912,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro
if (version.type == VKD3D_SHADER_TYPE_HULL) { - sm6_parser_add_instruction(sm6, VKD3DSIH_HS_CONTROL_POINT_PHASE); + sm6_parser_add_instruction(sm6, VSIR_OP_HS_CONTROL_POINT_PHASE);
if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) goto fail; @@ -10757,7 +10927,7 @@ static enum vkd3d_result sm6_parser_init(struct sm6_parser *sm6, struct vsir_pro goto fail; }
- sm6_parser_add_instruction(sm6, VKD3DSIH_HS_FORK_PHASE); + sm6_parser_add_instruction(sm6, VSIR_OP_HS_FORK_PHASE); if ((ret = sm6_function_emit_blocks(fn, sm6)) < 0) goto fail;
diff --git a/libs/vkd3d/libs/vkd3d-shader/fx.c b/libs/vkd3d/libs/vkd3d-shader/fx.c index a4f1a371299..676c501bb08 100644 --- a/libs/vkd3d/libs/vkd3d-shader/fx.c +++ b/libs/vkd3d/libs/vkd3d-shader/fx.c @@ -20,6 +20,8 @@
#include "hlsl.h"
+#define TAG_FX20 0x46580200 + static inline size_t put_u32_unaligned(struct vkd3d_bytecode_buffer *buffer, uint32_t value) { return bytecode_put_bytes_unaligned(buffer, &value, sizeof(value)); @@ -54,6 +56,22 @@ enum state_property_component_type FX_COMPONENT_TYPE_COUNT, };
+enum fxlvm_constants +{ + FX_FXLC_COMP_COUNT_MASK = 0xffff, + FX_FXLC_OPCODE_MASK = 0x7ff, + FX_FXLC_OPCODE_SHIFT = 20, + FX_FXLC_IS_SCALAR_MASK = 0x80000000, + + FX_FXLC_REG_UNUSED = 0, + FX_FXLC_REG_LITERAL = 1, + FX_FXLC_REG_CB = 2, + FX_FXLC_REG_INPUT = 3, + FX_FXLC_REG_OUTPUT = 4, + FX_FXLC_REG_TEMP = 7, + FX_FXLC_REG_MAX = FX_FXLC_REG_TEMP, +}; + struct rhs_named_value { const char *name; @@ -237,6 +255,8 @@ struct fx_write_context_ops void (*write_technique)(struct hlsl_ir_var *var, struct fx_write_context *fx); void (*write_pass)(struct hlsl_ir_var *var, struct fx_write_context *fx); void (*write_annotation)(struct hlsl_ir_var *var, struct fx_write_context *fx); + void (*write_state_assignment)(const struct hlsl_ir_var *var, + struct hlsl_state_block_entry *entry, struct fx_write_context *fx); bool are_child_effects_supported; };
@@ -289,15 +309,6 @@ static void set_status(struct fx_write_context *fx, int status) fx->status = status; }
-static void fx_print_string(struct vkd3d_string_buffer *buffer, const char *prefix, - const char *s, size_t len) -{ - if (len) - --len; /* Trim terminating null. */ - vkd3d_string_buffer_printf(buffer, "%s", prefix); - vkd3d_string_buffer_print_string_escaped(buffer, s, len); -} - static uint32_t write_string(const char *string, struct fx_write_context *fx) { return fx->ops->write_string(string, fx); @@ -308,6 +319,15 @@ static void write_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) fx->ops->write_pass(var, fx); }
+static void write_state_assignment(const struct hlsl_ir_var *var, + struct hlsl_state_block_entry *entry, struct fx_write_context *fx) +{ + fx->ops->write_state_assignment(var, entry, fx); +} + +static uint32_t write_state_block(struct hlsl_ir_var *var, + unsigned int block_index, struct fx_write_context *fx); + static uint32_t write_annotations(struct hlsl_scope *scope, struct fx_write_context *fx) { struct hlsl_ctx *ctx = fx->ctx; @@ -343,8 +363,6 @@ static void write_fx_4_annotations(struct hlsl_scope *scope, struct fx_write_con static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_context *fx); static const char * get_fx_4_type_name(const struct hlsl_type *type); static void write_fx_4_annotation(struct hlsl_ir_var *var, struct fx_write_context *fx); -static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index, - uint32_t count_offset, struct fx_write_context *fx);
static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context *fx) { @@ -369,18 +387,23 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context name = get_fx_4_type_name(element_type); modifiers = element_type->modifiers & HLSL_MODIFIERS_MAJORITY_MASK;
- LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry) + /* We don't try to reuse nameless types; they will get the same + * "<unnamed>" name, but are not available for the type cache. */ + if (name) { - if (strcmp(type_entry->name, name)) - continue; + LIST_FOR_EACH_ENTRY(type_entry, &fx->types, struct type_entry, entry) + { + if (strcmp(type_entry->name, name)) + continue;
- if (type_entry->elements_count != elements_count) - continue; + if (type_entry->elements_count != elements_count) + continue;
- if (type_entry->modifiers != modifiers) - continue; + if (type_entry->modifiers != modifiers) + continue;
- return type_entry->offset; + return type_entry->offset; + } }
if (!(type_entry = hlsl_alloc(fx->ctx, sizeof(*type_entry)))) @@ -391,7 +414,8 @@ static uint32_t write_type(const struct hlsl_type *type, struct fx_write_context type_entry->elements_count = elements_count; type_entry->modifiers = modifiers;
- list_add_tail(&fx->types, &type_entry->entry); + if (name) + list_add_tail(&fx->types, &type_entry->entry);
return type_entry->offset; } @@ -491,17 +515,22 @@ static uint32_t write_fx_4_string(const char *string, struct fx_write_context *f return string_entry->offset; }
+static void fx_4_decompose_state_blocks(struct hlsl_ir_var *var, struct fx_write_context *fx); + static void write_fx_4_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) { struct vkd3d_bytecode_buffer *buffer = &fx->structured; - uint32_t name_offset, count_offset; + uint32_t name_offset, count_offset, count;
name_offset = write_string(var->name, fx); put_u32(buffer, name_offset); count_offset = put_u32(buffer, 0);
+ fx_4_decompose_state_blocks(var, fx); + write_fx_4_annotations(var->annotations, fx); - write_fx_4_state_block(var, 0, count_offset, fx); + count = write_state_block(var, 0, fx); + set_u32(buffer, count_offset, count); }
static void write_fx_2_annotations(struct hlsl_ir_var *var, uint32_t count_offset, struct fx_write_context *fx) @@ -764,208 +793,227 @@ static const struct rhs_named_value fx_2_filter_values[] = { NULL } };
-static const struct fx_2_state +struct fx_state { const char *name; + enum hlsl_type_class container; enum hlsl_type_class class; enum state_property_component_type type; unsigned int dimx; uint32_t array_size; uint32_t id; const struct rhs_named_value *values; -} -fx_2_states[] = -{ - { "ZEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values }, - { "FillMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values }, - { "ShadeMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 2, fx_2_shademode_values }, - { "ZWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 3 }, - { "AlphaTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 4 }, - { "LastPixel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 5 }, - { "SrcBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 6, fx_2_blendmode_values }, - { "DestBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 7, fx_2_blendmode_values }, - { "CullMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 8, fx_2_cullmode_values }, - { "ZFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9, fx_2_cmpfunc_values }, - { "AlphaRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 10 }, - { "AlphaFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11, fx_2_cmpfunc_values }, - { "DitherEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12 }, - { "AlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13 }, - { "FogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 14 }, - { "SpecularEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, - { "FogColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 16 }, - { "FogTableMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 17, fx_2_fogmode_values }, - { "FogStart", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 18 }, - { "FogEnd", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 19 }, - { "FogDensity", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 20 }, - { "RangeFogEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 21 }, - { "StencilEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 22 }, - { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, fx_2_stencilcaps_values }, - { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, fx_2_stencilcaps_values }, - { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 25, fx_2_stencilcaps_values }, - { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 26, fx_2_cmpfunc_values }, - { "StencilRef", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 27 }, - { "StencilMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28 }, - { "StencilWriteMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 29 }, - { "TextureFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 30 }, - { "Wrap0", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 31, fx_2_wrap_values }, - { "Wrap1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 32, fx_2_wrap_values }, - { "Wrap2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 33, fx_2_wrap_values }, - { "Wrap3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 34, fx_2_wrap_values }, - { "Wrap4", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 35, fx_2_wrap_values }, - { "Wrap5", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 36, fx_2_wrap_values }, - { "Wrap6", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 37, fx_2_wrap_values }, - { "Wrap7", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, fx_2_wrap_values }, - { "Wrap8", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, fx_2_wrap_values }, - { "Wrap9", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, fx_2_wrap_values }, - { "Wrap10", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, fx_2_wrap_values }, - { "Wrap11", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, fx_2_wrap_values }, - { "Wrap12", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, fx_2_wrap_values }, - { "Wrap13", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 44, fx_2_wrap_values }, - { "Wrap14", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 45, fx_2_wrap_values }, - { "Wrap15", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 46, fx_2_wrap_values }, - { "Clipping", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 47 }, - { "Lighting", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 48 }, - { "Ambient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 49 }, - { "FogVertexMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 50, fx_2_fogmode_values }, - { "ColorVertex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 51 }, - { "LocalViewer", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 52 }, - { "NormalizeNormals", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 53 }, - - { "DiffuseMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 54, fx_2_materialcolorsource_values }, - { "SpecularMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 55, fx_2_materialcolorsource_values }, - { "AmbientMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 56, fx_2_materialcolorsource_values }, - { "EmissiveMaterialSource", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 57, fx_2_materialcolorsource_values }, - - { "VertexBlend", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 58, fx_2_vertexblend_values }, - { "ClipPlaneEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 59, fx_2_clipplane_values }, - { "PointSize", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 60 }, - { "PointSize_Min", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 61 }, - { "PointSize_Max", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 62 }, - { "PointSpriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 63 }, - { "PointScaleEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 64 }, - { "PointScale_A", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 65 }, - { "PointScale_B", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 66 }, - { "PointScale_C", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 67 }, - - { "MultiSampleAntialias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 68 }, - { "MultiSampleMask", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 69 }, - { "PatchEdgeStyle", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 70, fx_2_patchedgestyle_values }, - { "DebugMonitorToken", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 71 }, - { "IndexedVertexBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 72 }, - { "ColorWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 73, fx_2_colorwriteenable_values }, - { "TweenFactor", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 74 }, - { "BlendOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 75, fx_2_blendop_values }, - { "PositionDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 76, fx_2_degree_values }, - { "NormalDegree", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 77, fx_2_degree_values }, - { "ScissorTestEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 78 }, - { "SlopeScaleDepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 79 }, - - { "AntialiasedLineEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 80 }, - { "MinTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 81 }, - { "MaxTessellationLevel", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 82 }, - { "AdaptiveTess_X", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 83 }, - { "AdaptiveTess_Y", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 }, - { "AdaptiveTess_Z", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 }, - { "AdaptiveTess_W", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 }, - { "EnableAdaptiveTesselation", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 }, - { "TwoSidedStencilMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 }, - { "StencilFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values }, - { "StencilZFail", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values }, - { "StencilPass", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 91, fx_2_stencilcaps_values }, - { "StencilFunc", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 92, fx_2_cmpfunc_values }, - - { "ColorWriteEnable1", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 93, fx_2_colorwriteenable_values }, - { "ColorWriteEnable2", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 94, fx_2_colorwriteenable_values }, - { "ColorWriteEnable3", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 95, fx_2_colorwriteenable_values }, - { "BlendFactor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 96 }, - { "SRGBWriteEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 97 }, - { "DepthBias", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 98 }, - { "SeparateAlphaBlendEnable", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 99 }, - { "SrcBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 100, fx_2_blendmode_values }, - { "DestBlendAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 101, fx_2_blendmode_values }, - { "BlendOpAlpha", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 102, fx_2_blendmode_values }, - - { "ColorOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 103, fx_2_textureop_values }, - { "ColorArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 104, fx_2_colorarg_values }, - { "ColorArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 105, fx_2_colorarg_values }, - { "ColorArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 106, fx_2_colorarg_values }, - { "AlphaOp", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 107, fx_2_textureop_values }, - { "AlphaArg0", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 108, fx_2_colorarg_values }, - { "AlphaArg1", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 109, fx_2_colorarg_values }, - { "AlphaArg2", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 110, fx_2_colorarg_values }, - { "ResultArg", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 111, fx_2_colorarg_values }, - { "BumpEnvMat00", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 112 }, - { "BumpEnvMat01", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 }, - { "BumpEnvMat10", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 }, - { "BumpEnvMat11", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 }, - { "TextCoordIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 }, - { "BumpEnvLScale", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 }, - { "BumpEnvLOffset", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 }, - { "TextureTransformFlags", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values }, - { "Constant", HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 }, - { "NPatchMode", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 }, - { "FVF", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 }, - - { "ProjectionTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 }, - { "ViewTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 }, - { "WorldTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 125 }, - { "TextureTransform", HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 }, - - { "MaterialAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 }, - { "MaterialDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 128 }, - { "MaterialSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 129 }, - { "MaterialEmissive", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 }, - { "MaterialPower", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 }, - - { "LightType", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 132, fx_2_lighttype_values }, - { "LightDiffuse", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 133 }, - { "LightSpecular", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 134 }, - { "LightAmbient", HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 135 }, - { "LightPosition", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 136 }, - { "LightDirection", HLSL_CLASS_VECTOR, FX_FLOAT, 3, 1, 137 }, - { "LightRange", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 138 }, - { "LightFalloff", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 139 }, - { "LightAttenuation0", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 140 }, - { "LightAttenuation1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 141 }, - { "LightAttenuation2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 142 }, - { "LightTheta", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 143 }, - { "LightPhi", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 144 }, - { "LightEnable", HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 145 }, - - { "VertexShader", HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 }, - { "PixelShader", HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 }, - - { "VertexShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 148 }, - { "VertexShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 149 }, - { "VertexShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 150 }, - { "VertexShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 151 }, - { "VertexShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 152 }, - { "VertexShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 153 }, - { "VertexShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 154 }, - { "VertexShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 155 }, - - { "PixelShaderConstantF", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 156 }, - { "PixelShaderConstantB", HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u-1, 157 }, - { "PixelShaderConstantI", HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u-1, 158 }, - { "PixelShaderConstant", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 159 }, - { "PixelShaderConstant1", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 160 }, - { "PixelShaderConstant2", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 161 }, - { "PixelShaderConstant3", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 162 }, - { "PixelShaderConstant4", HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u-1, 163 }, - - { "Texture", HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, - { "AddressU", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, - { "AddressV", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, - { "AddressW", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, - { "BorderColor", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, - { "MagFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, - { "MinFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, - { "MipFilter", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, - { "MipMapLodBias", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, - { "MaxMipLevel", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, - { "MaxAnisotropy", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, - { "SRBTexture", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, - { "ElementIndex", HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, +}; + +static const struct fx_state fx_2_pass_states[] = +{ + { "ZEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 0, fx_2_zenable_values }, + { "FillMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 1, fx_2_fillmode_values }, + { "ShadeMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 2, fx_2_shademode_values }, + { "ZWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 3 }, + { "AlphaTestEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 4 }, + { "LastPixel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 5 }, + { "SrcBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 6, fx_2_blendmode_values }, + { "DestBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 7, fx_2_blendmode_values }, + { "CullMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 8, fx_2_cullmode_values }, + { "ZFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 9, fx_2_cmpfunc_values }, + { "AlphaRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 10 }, + { "AlphaFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 11, fx_2_cmpfunc_values }, + { "DitherEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 12 }, + { "AlphaBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 13 }, + { "FogEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 14 }, + { "SpecularEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 15 }, + { "FogColor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 16 }, + { "FogTableMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 17, fx_2_fogmode_values }, + { "FogStart", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 18 }, + { "FogEnd", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 19 }, + { "FogDensity", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 20 }, + { "RangeFogEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 21 }, + { "StencilEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 22 }, + { "StencilFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 23, fx_2_stencilcaps_values }, + { "StencilZFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 24, fx_2_stencilcaps_values }, + { "StencilPass", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 25, fx_2_stencilcaps_values }, + { "StencilFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 26, fx_2_cmpfunc_values }, + { "StencilRef", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 27 }, + { "StencilMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 28 }, + { "StencilWriteMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 29 }, + { "TextureFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 30 }, + { "Wrap0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 31, fx_2_wrap_values }, + { "Wrap1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 32, fx_2_wrap_values }, + { "Wrap2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 33, fx_2_wrap_values }, + { "Wrap3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 34, fx_2_wrap_values }, + { "Wrap4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 35, fx_2_wrap_values }, + { "Wrap5", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 36, fx_2_wrap_values }, + { "Wrap6", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 37, fx_2_wrap_values }, + { "Wrap7", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 38, fx_2_wrap_values }, + { "Wrap8", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 39, fx_2_wrap_values }, + { "Wrap9", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 40, fx_2_wrap_values }, + { "Wrap10", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 41, fx_2_wrap_values }, + { "Wrap11", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 42, fx_2_wrap_values }, + { "Wrap12", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 43, fx_2_wrap_values }, + { "Wrap13", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 44, fx_2_wrap_values }, + { "Wrap14", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 45, fx_2_wrap_values }, + { "Wrap15", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 46, fx_2_wrap_values }, + { "Clipping", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 47 }, + { "Lighting", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 48 }, + { "Ambient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 49 }, + { "FogVertexMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 50, fx_2_fogmode_values }, + { "ColorVertex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 51 }, + { "LocalViewer", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 52 }, + { "NormalizeNormals", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 53 }, + + { "DiffuseMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 54, fx_2_materialcolorsource_values }, + { "SpecularMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 55, fx_2_materialcolorsource_values }, + { "AmbientMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 56, fx_2_materialcolorsource_values }, + { "EmissiveMaterialSource", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 57, fx_2_materialcolorsource_values }, + + { "VertexBlend", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 58, fx_2_vertexblend_values }, + { "ClipPlaneEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 59, fx_2_clipplane_values }, + { "PointSize", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 60 }, + { "PointSize_Min", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 61 }, + { "PointSize_Max", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 62 }, + { "PointSpriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 63 }, + { "PointScaleEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 64 }, + { "PointScale_A", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 65 }, + { "PointScale_B", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 66 }, + { "PointScale_C", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 67 }, + + { "MultiSampleAntialias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 68 }, + { "MultiSampleMask", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 69 }, + { "PatchEdgeStyle", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 70, fx_2_patchedgestyle_values }, + { "DebugMonitorToken", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 71 }, + { "IndexedVertexBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 72 }, + { "ColorWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 73, fx_2_colorwriteenable_values }, + { "TweenFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 74 }, + { "BlendOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 75, fx_2_blendop_values }, + { "PositionDegree", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 76, fx_2_degree_values }, + { "NormalDegree", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 77, fx_2_degree_values }, + { "ScissorTestEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 78 }, + { "SlopeScaleDepthBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 79 }, + + { "AntialiasedLineEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 80 }, + { "MinTessellationLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 81 }, + { "MaxTessellationLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 82 }, + { "AdaptiveTess_X", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 83 }, + { "AdaptiveTess_Y", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 84 }, + { "AdaptiveTess_Z", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 85 }, + { "AdaptiveTess_W", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 86 }, + { "EnableAdaptiveTessellation",HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 87 }, + { "TwoSidedStencilMode", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 88 }, + { "StencilFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 89, fx_2_stencilcaps_values }, + { "StencilZFail", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 90, fx_2_stencilcaps_values }, + { "StencilPass", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 91, fx_2_stencilcaps_values }, + { "StencilFunc", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 92, fx_2_cmpfunc_values }, + + { "ColorWriteEnable1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 93, fx_2_colorwriteenable_values }, + { "ColorWriteEnable2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 94, fx_2_colorwriteenable_values }, + { "ColorWriteEnable3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 95, fx_2_colorwriteenable_values }, + { "BlendFactor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 96 }, + { "SRGBWriteEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 97 }, + { "DepthBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 98 }, + { "SeparateAlphaBlendEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 99 }, + { "SrcBlendAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 100, fx_2_blendmode_values }, + { "DestBlendAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 101, fx_2_blendmode_values }, + { "BlendOpAlpha", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 102, fx_2_blendmode_values }, + + { "ColorOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 103, fx_2_textureop_values }, + { "ColorArg0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 104, fx_2_colorarg_values }, + { "ColorArg1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 105, fx_2_colorarg_values }, + { "ColorArg2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 106, fx_2_colorarg_values }, + { "AlphaOp", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 107, fx_2_textureop_values }, + { "AlphaArg0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 108, fx_2_colorarg_values }, + { "AlphaArg1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 109, fx_2_colorarg_values }, + { "AlphaArg2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 110, fx_2_colorarg_values }, + { "ResultArg", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 111, fx_2_colorarg_values }, + { "BumpEnvMat00", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 112 }, + { "BumpEnvMat01", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 113 }, + { "BumpEnvMat10", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 114 }, + { "BumpEnvMat11", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 115 }, + { "TexCoordIndex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 116 }, + { "BumpEnvLScale", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 117 }, + { "BumpEnvLOffset", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 8, 118 }, + { "TextureTransformFlags", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 119, fx_2_texturetransform_values }, + { "Constant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 8, 120 }, + { "PatchSegments", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 121 }, + { "FVF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 122 }, + + { "ProjectionTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 123 }, + { "ViewTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 1, 124 }, + { "WorldTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 256, 125 }, + { "TextureTransform", HLSL_CLASS_PASS, HLSL_CLASS_MATRIX, FX_FLOAT, 4, 8, 126 }, + + { "MaterialDiffuse", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 127 }, + { "MaterialAmbient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 128 }, + { "MaterialSpecular", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 129 }, + { "MaterialEmissive", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, 1, 130 }, + { "MaterialPower", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, 1, 131 }, + + { "LightType", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 132, fx_2_lighttype_values }, + { "LightDiffuse", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 133 }, + { "LightSpecular", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 134 }, + { "LightAmbient", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 4, ~0u, 135 }, + { "LightPosition", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 136 }, + { "LightDirection", HLSL_CLASS_PASS, HLSL_CLASS_VECTOR, FX_FLOAT, 3, ~0u, 137 }, + { "LightRange", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 138 }, + { "LightFalloff", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 139 }, + { "LightAttenuation0", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 140 }, + { "LightAttenuation1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 141 }, + { "LightAttenuation2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 142 }, + { "LightTheta", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 143 }, + { "LightPhi", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 144 }, + { "LightEnable", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 145 }, + + { "VertexShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_VERTEXSHADER, 1, 1, 146 }, + { "PixelShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_PIXELSHADER, 1, 1, 147 }, + + { "VertexShaderConstantF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 148 }, + { "VertexShaderConstantB", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 149 }, + { "VertexShaderConstantI", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 150 }, + { "VertexShaderConstant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 151 }, + { "VertexShaderConstant1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 152 }, + { "VertexShaderConstant2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 153 }, + { "VertexShaderConstant3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 154 }, + { "VertexShaderConstant4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 155 }, + + { "PixelShaderConstantF", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 156 }, + { "PixelShaderConstantB", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_BOOL, 1, ~0u, 157 }, + { "PixelShaderConstantI", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, ~0u, 158 }, + { "PixelShaderConstant", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 159 }, + { "PixelShaderConstant1", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 160 }, + { "PixelShaderConstant2", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 161 }, + { "PixelShaderConstant3", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 162 }, + { "PixelShaderConstant4", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_FLOAT, 1, ~0u, 163 }, + + { "Texture", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 261, 164 }, + { "AddressU", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 165, fx_2_address_values }, + { "AddressV", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 166, fx_2_address_values }, + { "AddressW", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 167, fx_2_address_values }, + { "BorderColor", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 168 }, + { "MagFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 169, fx_2_filter_values }, + { "MinFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 170, fx_2_filter_values }, + { "MipFilter", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 171, fx_2_filter_values }, + { "MipMapLodBias", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 172 }, + { "MaxMipLevel", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 173 }, + { "MaxAnisotropy", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 174 }, + { "SRGBTexture", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 175 }, + { "ElementIndex", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_UINT, 1, 261, 176 }, +}; + +static const struct fx_state fx_2_sampler_states[] = +{ + { "Texture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_TEXTURE, 1, 1, 164 }, + { "AddressU", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 165, fx_2_address_values }, + { "AddressV", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 166, fx_2_address_values }, + { "AddressW", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 167, fx_2_address_values }, + { "BorderColor", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 168 }, + { "MagFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 169, fx_2_filter_values }, + { "MinFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 170, fx_2_filter_values }, + { "MipFilter", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 171, fx_2_filter_values }, + { "MipMapLodBias", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 172 }, + { "MaxMipLevel", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 173 }, + { "MaxAnisotropy", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 174 }, + { "SRGBTexture", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 175 }, + { "ElementIndex", HLSL_CLASS_SAMPLER, HLSL_CLASS_SCALAR, FX_UINT, 1, 1, 176 }, };
static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx) @@ -988,16 +1036,6 @@ static void write_fx_2_pass(struct hlsl_ir_var *var, struct fx_write_context *fx fx->shader_count++; }
-static uint32_t get_fx_4_type_size(const struct hlsl_type *type) -{ - uint32_t elements_count; - - elements_count = hlsl_get_multiarray_size(type); - type = hlsl_get_multiarray_element_type(type); - - return type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float) * elements_count; -} - enum fx_4_type_constants { /* Numeric types encoding */ @@ -1015,6 +1053,9 @@ enum fx_4_type_constants FX_4_NUMERIC_COLUMNS_SHIFT = 11, FX_4_NUMERIC_COLUMN_MAJOR_MASK = 0x4000,
+ /* Variable flags */ + FX_4_HAS_EXPLICIT_BIND_POINT = 0x4, + /* Object types */ FX_4_OBJECT_TYPE_STRING = 0x1, FX_4_OBJECT_TYPE_BLEND_STATE = 0x2, @@ -1071,17 +1112,6 @@ enum fx_4_type_constants FX_4_ASSIGNMENT_VALUE_EXPRESSION = 0x6, FX_4_ASSIGNMENT_INLINE_SHADER = 0x7, FX_5_ASSIGNMENT_INLINE_SHADER = 0x8, - - /* FXLVM constants */ - FX_4_FXLC_COMP_COUNT_MASK = 0xffff, - FX_4_FXLC_OPCODE_MASK = 0x7ff, - FX_4_FXLC_OPCODE_SHIFT = 20, - FX_4_FXLC_IS_SCALAR_MASK = 0x80000000, - - FX_4_FXLC_REG_LITERAL = 1, - FX_4_FXLC_REG_CB = 2, - FX_4_FXLC_REG_OUTPUT = 4, - FX_4_FXLC_REG_TEMP = 7, };
static const uint32_t fx_4_numeric_base_types[] = @@ -1238,7 +1268,7 @@ static uint32_t write_fx_4_type(const struct hlsl_type *type, struct fx_write_co
name = get_fx_4_type_name(element_type);
- name_offset = write_string(name, fx); + name_offset = write_string(name ? name : "<unnamed>", fx); if (element_type->class == HLSL_CLASS_STRUCT) { if (!(field_offsets = hlsl_calloc(ctx, element_type->e.record.field_count, sizeof(*field_offsets)))) @@ -1541,12 +1571,33 @@ static uint32_t get_fx_2_type_class(const struct hlsl_type *type) return hlsl_sm1_class(type); }
-static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *name, - const struct hlsl_semantic *semantic, bool is_combined_sampler, struct fx_write_context *fx) +struct fx_2_write_type_context { - struct vkd3d_bytecode_buffer *buffer = &fx->unstructured; - uint32_t semantic_offset, offset, elements_count = 0, name_offset; - size_t i; + uint32_t *names; + uint32_t *semantics; + uint32_t count; + + uint32_t offset; + + bool is_combined_sampler; + struct fx_write_context *fx; +}; + +static void count_type_iter(const struct hlsl_type *type, const char *name, + const struct hlsl_semantic *semantic, void *context) +{ + struct fx_2_write_type_context *ctx = context; + + ++ctx->count; +} + +static void write_fx_2_type_iter(const struct hlsl_type *type, const char *name, + const struct hlsl_semantic *semantic, void *context) +{ + struct fx_2_write_type_context *ctx = context; + struct fx_write_context *fx = ctx->fx; + struct vkd3d_bytecode_buffer *buffer; + uint32_t offset, elements_count = 0;
/* Resolve arrays to element type and number of elements. */ if (type->class == HLSL_CLASS_ARRAY) @@ -1555,13 +1606,11 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n type = hlsl_get_multiarray_element_type(type); }
- name_offset = write_string(name, fx); - semantic_offset = semantic->raw_name ? write_string(semantic->raw_name, fx) : 0; - - offset = put_u32(buffer, hlsl_sm1_base_type(type, is_combined_sampler)); + buffer = &fx->unstructured; + offset = put_u32(buffer, hlsl_sm1_base_type(type, ctx->is_combined_sampler)); put_u32(buffer, get_fx_2_type_class(type)); - put_u32(buffer, name_offset); - put_u32(buffer, semantic_offset); + *ctx->names++ = put_u32(buffer, 0); + *ctx->semantics++ = put_u32(buffer, 0); put_u32(buffer, elements_count);
switch (type->class) @@ -1586,19 +1635,68 @@ static uint32_t write_fx_2_parameter(const struct hlsl_type *type, const char *n ; }
+ /* Save the offset of the top level type. */ + if (!ctx->offset) + ctx->offset = offset; +} + +static void write_fx_2_type_strings_iter(const struct hlsl_type *type, const char *name, + const struct hlsl_semantic *semantic, void *context) +{ + struct fx_2_write_type_context *ctx = context; + struct fx_write_context *fx = ctx->fx; + struct vkd3d_bytecode_buffer *buffer; + + buffer = &fx->unstructured; + set_u32(buffer, *ctx->names++, write_string(name, fx)); + set_u32(buffer, *ctx->semantics++, semantic->raw_name ? write_string(semantic->raw_name, fx) : 0); +} + +static void foreach_type(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, + void (*iter_func)(const struct hlsl_type *type, const char *name, const struct hlsl_semantic *semantic, void *context), + void *context) +{ + iter_func(type, name, semantic, context); + + type = hlsl_get_multiarray_element_type(type); if (type->class == HLSL_CLASS_STRUCT) { - for (i = 0; i < type->e.record.field_count; ++i) + for (size_t i = 0; i < type->e.record.field_count; ++i) { const struct hlsl_struct_field *field = &type->e.record.fields[i]; - - /* Validated in check_invalid_object_fields(). */ - VKD3D_ASSERT(hlsl_is_numeric_type(field->type)); - write_fx_2_parameter(field->type, field->name, &field->semantic, false, fx); + foreach_type(field->type, field->name, &field->semantic, iter_func, context); } } +}
- return offset; +static uint32_t write_fx_2_parameter(const struct hlsl_ir_var *var, struct fx_write_context *fx) +{ + struct fx_2_write_type_context ctx = { .fx = fx, .is_combined_sampler = var->is_combined_sampler }; + uint32_t *offsets; + + /* Parameter type information has to be stored in a contiguous segment, so + * that any structure fields come right after each other. To achieve that + * the variable length string data is written after the type data. */ + + /* Calculate the number of string entries needed for this type. */ + foreach_type(var->data_type, var->name, &var->semantic, count_type_iter, &ctx); + + if (!(offsets = calloc(ctx.count, 2 * sizeof(*offsets)))) + return 0; + + /* Writing type information also sets string offsets. */ + ctx.names = offsets; + ctx.semantics = &offsets[ctx.count]; + foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_iter, &ctx); + + /* Now the final pass to write the string data. */ + ctx.names = offsets; + ctx.semantics = &offsets[ctx.count]; + foreach_type(var->data_type, var->name, &var->semantic, write_fx_2_type_strings_iter, &ctx); + + free(offsets); + + return ctx.offset; }
static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_context *fx) @@ -1623,6 +1721,15 @@ static void write_fx_2_technique(struct hlsl_ir_var *var, struct fx_write_contex set_u32(buffer, pass_count_offset, count); }
+/* Effects represent bool values as 1/0, as opposed to ~0u/0 as used by + * Direct3D shader model 4+. */ +static uint32_t get_fx_default_numeric_value(const struct hlsl_type *type, uint32_t value) +{ + if (type->e.numeric.type == HLSL_TYPE_BOOL) + return !!value; + return value; +} + static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hlsl_default_value *value, struct fx_write_context *fx) { @@ -1656,7 +1763,7 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < comp_count; ++j) { - put_u32(buffer, value->number.u); + put_u32(buffer, get_fx_default_numeric_value(type, value->number.u)); value++; } break; @@ -1673,8 +1780,8 @@ static uint32_t write_fx_2_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < type->e.record.field_count; ++j) { - write_fx_2_default_value(fields[i].type, value, fx); - value += hlsl_type_component_count(fields[i].type); + write_fx_2_default_value(fields[j].type, value, fx); + value += hlsl_type_component_count(fields[j].type); } break; } @@ -1861,7 +1968,7 @@ static void write_fx_2_parameters(struct fx_write_context *fx) if (!is_type_supported_fx_2(ctx, var->data_type, &var->loc)) continue;
- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx); + desc_offset = write_fx_2_parameter(var, fx); value_offset = write_fx_2_initial_value(var, fx);
flags = 0; @@ -1884,19 +1991,28 @@ static void write_fx_2_annotation(struct hlsl_ir_var *var, struct fx_write_conte struct vkd3d_bytecode_buffer *buffer = &fx->structured; uint32_t desc_offset, value_offset;
- desc_offset = write_fx_2_parameter(var->data_type, var->name, &var->semantic, var->is_combined_sampler, fx); + desc_offset = write_fx_2_parameter(var, fx); value_offset = write_fx_2_initial_value(var, fx);
put_u32(buffer, desc_offset); put_u32(buffer, value_offset); }
+static void write_fx_2_state_assignment(const struct hlsl_ir_var *var, + struct hlsl_state_block_entry *entry, struct fx_write_context *fx) +{ + struct hlsl_ctx *ctx = fx->ctx; + + hlsl_fixme(ctx, &var->loc, "Writing fx_2_0 state assignments is not implemented."); +} + static const struct fx_write_context_ops fx_2_ops = { .write_string = write_fx_2_string, .write_technique = write_fx_2_technique, .write_pass = write_fx_2_pass, .write_annotation = write_fx_2_annotation, + .write_state_assignment = write_fx_2_state_assignment, };
static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) @@ -1959,12 +2075,16 @@ static int hlsl_fx_2_write(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out) return fx_write_context_cleanup(&fx); }
+static void write_fx_4_state_assignment(const struct hlsl_ir_var *var, + struct hlsl_state_block_entry *entry, struct fx_write_context *fx); + static const struct fx_write_context_ops fx_4_ops = { .write_string = write_fx_4_string, .write_technique = write_fx_4_technique, .write_pass = write_fx_4_pass, .write_annotation = write_fx_4_annotation, + .write_state_assignment = write_fx_4_state_assignment, .are_child_effects_supported = true, };
@@ -2001,7 +2121,7 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < comp_count; ++j) { - put_u32_unaligned(buffer, value->number.u); + put_u32_unaligned(buffer, get_fx_default_numeric_value(type, value->number.u)); value++; } break; @@ -2018,8 +2138,8 @@ static uint32_t write_fx_4_default_value(struct hlsl_type *value_type, struct hl
for (j = 0; j < type->e.record.field_count; ++j) { - write_fx_4_default_value(fields[i].type, value, fx); - value += hlsl_type_component_count(fields[i].type); + write_fx_4_default_value(fields[j].type, value, fx); + value += hlsl_type_component_count(fields[j].type); } break; } @@ -2057,13 +2177,9 @@ static void write_fx_4_numeric_variable(struct hlsl_ir_var *var, bool shared, st struct vkd3d_bytecode_buffer *buffer = &fx->structured; uint32_t name_offset, type_offset, value_offset; uint32_t semantic_offset, flags = 0; - enum fx_4_numeric_variable_flags - { - HAS_EXPLICIT_BIND_POINT = 0x4, - };
if (var->has_explicit_bind_point) - flags |= HAS_EXPLICIT_BIND_POINT; + flags |= FX_4_HAS_EXPLICIT_BIND_POINT;
type_offset = write_type(var->data_type, fx); name_offset = write_string(var->name, fx); @@ -2163,7 +2279,7 @@ static uint32_t write_fx_4_state_numeric_value(struct hlsl_ir_constant *value, s }
put_u32_unaligned(buffer, type); - put_u32_unaligned(buffer, value->value.u[i].u); + put_u32_unaligned(buffer, get_fx_default_numeric_value(data_type, value->value.u[i].u)); }
return offset; @@ -2576,18 +2692,7 @@ static const struct rhs_named_value null_values[] = { NULL } };
-static const struct fx_4_state -{ - const char *name; - enum hlsl_type_class container; - enum hlsl_type_class class; - enum state_property_component_type type; - unsigned int dimx; - unsigned int array_size; - int id; - const struct rhs_named_value *values; -} -fx_4_states[] = +static const struct fx_state fx_4_states[] = { { "RasterizerState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_RASTERIZER, 1, 1, 0 }, { "DepthStencilState", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_DEPTHSTENCIL, 1, 1, 1 }, @@ -2655,7 +2760,7 @@ fx_4_states[] = { "ComputeShader", HLSL_CLASS_PASS, HLSL_CLASS_SCALAR, FX_COMPUTESHADER, 1, 1, 58 }, };
-static const struct fx_4_state fx_5_blend_states[] = +static const struct fx_state fx_5_blend_states[] = { { "AlphaToCoverageEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 1, 36, bool_values }, { "BlendEnable", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_BOOL, 1, 8, 37, bool_values }, @@ -2668,45 +2773,61 @@ static const struct fx_4_state fx_5_blend_states[] = { "RenderTargetWriteMask", HLSL_CLASS_BLEND_STATE, HLSL_CLASS_SCALAR, FX_UINT8, 1, 8, 44 }, };
-struct fx_4_state_table +struct fx_state_table { - const struct fx_4_state *ptr; + const struct fx_state *ptr; unsigned int count; };
-static struct fx_4_state_table fx_4_get_state_table(enum hlsl_type_class type_class, +static struct fx_state_table fx_get_state_table(enum hlsl_type_class type_class, unsigned int major, unsigned int minor) { - struct fx_4_state_table table; + struct fx_state_table table;
- if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1))) + if (major == 2) { - table.ptr = fx_5_blend_states; - table.count = ARRAY_SIZE(fx_5_blend_states); + if (type_class == HLSL_CLASS_PASS) + { + table.ptr = fx_2_pass_states; + table.count = ARRAY_SIZE(fx_2_pass_states); + } + else + { + table.ptr = fx_2_sampler_states; + table.count = ARRAY_SIZE(fx_2_sampler_states); + } } else { - table.ptr = fx_4_states; - table.count = ARRAY_SIZE(fx_4_states); + if (type_class == HLSL_CLASS_BLEND_STATE && (major == 5 || (major == 4 && minor == 1))) + { + table.ptr = fx_5_blend_states; + table.count = ARRAY_SIZE(fx_5_blend_states); + } + else + { + table.ptr = fx_4_states; + table.count = ARRAY_SIZE(fx_4_states); + } }
return table; }
-static void resolve_fx_4_state_block_values(struct hlsl_ir_var *var, +static void resolve_fx_state_block_values(struct hlsl_ir_var *var, struct hlsl_state_block_entry *entry, struct fx_write_context *fx) { const struct hlsl_type *type = hlsl_get_multiarray_element_type(var->data_type); struct replace_state_context replace_context; - const struct fx_4_state *state = NULL; + const struct fx_state *state = NULL; struct hlsl_type *state_type = NULL; struct hlsl_ctx *ctx = fx->ctx; enum hlsl_base_type base_type; - struct fx_4_state_table table; + struct fx_state_table table; struct hlsl_ir_node *node; unsigned int i;
- table = fx_4_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version); + table = fx_get_state_table(type->class, ctx->profile->major_version, ctx->profile->minor_version);
for (i = 0; i < table.count; ++i) { @@ -2992,21 +3113,34 @@ static unsigned int decompose_fx_4_state_block(struct hlsl_ir_var *var, struct h return decompose_fx_4_state_block_expand_array(var, block, entry_index, fx); }
-static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_index, - uint32_t count_offset, struct fx_write_context *fx) +static void fx_4_decompose_state_blocks(struct hlsl_ir_var *var, struct fx_write_context *fx) { - struct vkd3d_bytecode_buffer *buffer = &fx->structured; + unsigned int block_count = hlsl_get_multiarray_size(var->data_type); struct hlsl_state_block *block; - uint32_t i, count = 0;
- if (var->state_blocks) + if (!var->state_blocks) + return; + + for (unsigned int i = 0; i < block_count; ++i) { - block = var->state_blocks[block_index]; + block = var->state_blocks[i];
- for (i = 0; i < block->count;) + for (unsigned int j = 0; j < block->count;) { - i += decompose_fx_4_state_block(var, block, i, fx); + j += decompose_fx_4_state_block(var, block, j, fx); } + } +} + +static uint32_t write_state_block(struct hlsl_ir_var *var, unsigned int block_index, + struct fx_write_context *fx) +{ + struct hlsl_state_block *block; + uint32_t i, count = 0; + + if (var->state_blocks) + { + block = var->state_blocks[block_index];
for (i = 0; i < block->count; ++i) { @@ -3017,27 +3151,29 @@ static void write_fx_4_state_block(struct hlsl_ir_var *var, unsigned int block_i continue;
/* Resolve special constant names and property names. */ - resolve_fx_4_state_block_values(var, entry, fx); + resolve_fx_state_block_values(var, entry, fx);
- write_fx_4_state_assignment(var, entry, fx); + write_state_assignment(var, entry, fx); ++count; } }
- set_u32(buffer, count_offset, count); + return count; }
static void write_fx_4_state_object_initializer(struct hlsl_ir_var *var, struct fx_write_context *fx) { uint32_t elements_count = hlsl_get_multiarray_size(var->data_type), i; struct vkd3d_bytecode_buffer *buffer = &fx->structured; - uint32_t count_offset; + uint32_t count_offset, count; + + fx_4_decompose_state_blocks(var, fx);
for (i = 0; i < elements_count; ++i) { count_offset = put_u32(buffer, 0); - - write_fx_4_state_block(var, i, count_offset, fx); + count = write_state_block(var, i, fx); + set_u32(buffer, count_offset, count); } }
@@ -3212,6 +3348,8 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx size = 0; LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) { + uint32_t unpacked_size; + if (!is_numeric_fx_4_type(var->data_type)) continue;
@@ -3219,7 +3357,9 @@ static void write_fx_4_buffer(struct hlsl_buffer *b, struct fx_write_context *fx continue;
write_fx_4_numeric_variable(var, shared, fx); - size += get_fx_4_type_size(var->data_type); + + unpacked_size = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * sizeof(float); + size = max(size, unpacked_size + var->buffer_offset * 4); ++count; }
@@ -3446,6 +3586,7 @@ int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out)
struct fx_parser { + enum vkd3d_shader_source_type source_type; const uint8_t *ptr, *start, *end; struct vkd3d_shader_message_context *message_context; struct vkd3d_string_buffer buffer; @@ -3572,20 +3713,43 @@ static void parse_fx_print_indent(struct fx_parser *parser) vkd3d_string_buffer_printf(&parser->buffer, "%*s", 4 * parser->indent, ""); }
-static const char *fx_2_get_string(struct fx_parser *parser, uint32_t offset, uint32_t *size) +static void fx_2_print_string_literal(struct fx_parser *parser, const char *prefix, + const char *s, uint32_t max_len, const char *suffix) { - const char *ptr; + uint32_t len;
- fx_parser_read_unstructured(parser, size, offset, sizeof(*size)); - ptr = fx_parser_get_unstructured_ptr(parser, offset + 4, *size); + if (s) + len = strnlen(s, max_len); + if (!s || len == max_len) + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to parse a string entry."); + return; + }
- if (!ptr) + vkd3d_string_buffer_printf(&parser->buffer, "%s", prefix); + vkd3d_string_buffer_print_string_escaped(&parser->buffer, s, len); + vkd3d_string_buffer_printf(&parser->buffer, "%s", suffix); +} + +static void fx_2_parse_string_literal(struct fx_parser *parser, uint32_t offset, + bool unstructured, const char *prefix, const char *suffix) +{ + uint32_t max_len; + const char *s; + + if (unstructured) { - parser->failed = true; - return "<invalid>"; + fx_parser_read_unstructured(parser, &max_len, offset, sizeof(max_len)); + s = fx_parser_get_unstructured_ptr(parser, offset + 4, max_len); + } + else + { + max_len = fx_parser_read_u32(parser); + s = fx_parser_get_ptr(parser, max_len); + fx_parser_skip(parser, align(max_len, 4)); }
- return ptr; + fx_2_print_string_literal(parser, prefix, s, max_len, suffix); }
static unsigned int fx_get_fx_2_type_size(struct fx_parser *parser, uint32_t *offset) @@ -3742,15 +3906,12 @@ static void fx_parse_fx_2_parameter(struct fx_parser *parser, uint32_t offset) uint32_t semantic; uint32_t element_count; } var; - const char *name; - uint32_t size;
fx_parser_read_unstructured(parser, &var, offset, sizeof(var));
fx_parse_fx_2_type(parser, offset);
- name = fx_2_get_string(parser, var.name, &size); - fx_print_string(&parser->buffer, " ", name, size); + fx_2_parse_string_literal(parser, var.name, true, " ", ""); if (var.element_count) vkd3d_string_buffer_printf(&parser->buffer, "[%u]", var.element_count); } @@ -3764,7 +3925,8 @@ static bool is_fx_2_sampler(uint32_t type) || type == D3DXPT_SAMPLERCUBE; }
-static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry); +static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, + const struct fx_assignment *entry);
static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, uint32_t offset) @@ -3789,7 +3951,7 @@ static void parse_fx_2_sampler(struct fx_parser *parser, uint32_t element_count, fx_parser_read_unstructured(parser, &entry, offset, sizeof(entry));
parse_fx_print_indent(parser); - fx_parse_fx_2_assignment(parser, &entry); + fx_parse_fx_2_assignment(parser, HLSL_CLASS_SAMPLER, &entry); } parse_fx_end_indent(parser); parse_fx_print_indent(parser); @@ -3867,15 +4029,25 @@ static void fx_parse_fx_2_annotations(struct fx_parser *parser, uint32_t count) vkd3d_string_buffer_printf(&parser->buffer, ">"); }
-static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_assignment *entry) +static const struct fx_state *fx_2_get_state_by_id(enum hlsl_type_class container, uint32_t id) +{ + struct fx_state_table table = fx_get_state_table(container, 2, 0); + + /* State identifiers are sequential, no gaps */ + if (id >= table.ptr[0].id && id <= table.ptr[table.count - 1].id) + return &table.ptr[id - table.ptr[0].id]; + + return NULL; +} + +static void fx_parse_fx_2_assignment(struct fx_parser *parser, enum hlsl_type_class container, + const struct fx_assignment *entry) { const struct rhs_named_value *named_value = NULL; - const struct fx_2_state *state = NULL; + const struct fx_state *state;
- if (entry->id <= ARRAY_SIZE(fx_2_states)) + if ((state = fx_2_get_state_by_id(container, entry->id))) { - state = &fx_2_states[entry->id]; - vkd3d_string_buffer_printf(&parser->buffer, "%s", state->name); if (state->array_size > 1) vkd3d_string_buffer_printf(&parser->buffer, "[%u]", entry->lhs_index); @@ -3886,7 +4058,7 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a } vkd3d_string_buffer_printf(&parser->buffer, " = ");
- if (state && state->type == FX_UINT) + if (state && state->type == FX_UINT && state->values) { const struct rhs_named_value *ptr = state->values; uint32_t value; @@ -3910,13 +4082,14 @@ static void fx_parse_fx_2_assignment(struct fx_parser *parser, const struct fx_a } else if (state) { - if (state->type == FX_UINT || state->type == FX_FLOAT) + if (state->type == FX_UINT || state->type == FX_FLOAT || state->type == FX_BOOL) { - uint32_t offset = entry->type; + uint32_t offset = entry->type, base_type; unsigned int size;
size = fx_get_fx_2_type_size(parser, &offset); - parse_fx_2_numeric_value(parser, entry->value, size, entry->type); + fx_parser_read_unstructured(parser, &base_type, entry->type, sizeof(base_type)); + parse_fx_2_numeric_value(parser, entry->value, size, base_type); } else if (state->type == FX_VERTEXSHADER || state->type == FX_PIXELSHADER) { @@ -3951,18 +4124,14 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) uint32_t annotation_count; uint32_t assignment_count; } pass; - const char *name; - uint32_t size;
if (parser->failed) return;
fx_parser_read_u32s(parser, &technique, sizeof(technique));
- name = fx_2_get_string(parser, technique.name, &size); - parse_fx_print_indent(parser); - fx_print_string(&parser->buffer, "technique ", name, size); + fx_2_parse_string_literal(parser, technique.name, true, "technique ", ""); fx_parse_fx_2_annotations(parser, technique.annotation_count);
vkd3d_string_buffer_printf(&parser->buffer, "\n"); @@ -3973,10 +4142,9 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser) for (uint32_t i = 0; i < technique.pass_count; ++i) { fx_parser_read_u32s(parser, &pass, sizeof(pass)); - name = fx_2_get_string(parser, pass.name, &size);
parse_fx_print_indent(parser); - fx_print_string(&parser->buffer, "pass ", name, size); + fx_2_parse_string_literal(parser, pass.name, true, "pass ", ""); fx_parse_fx_2_annotations(parser, pass.annotation_count);
vkd3d_string_buffer_printf(&parser->buffer, "\n"); @@ -3990,7 +4158,7 @@ static void fx_parse_fx_2_technique(struct fx_parser *parser)
parse_fx_print_indent(parser); fx_parser_read_u32s(parser, &entry, sizeof(entry)); - fx_parse_fx_2_assignment(parser, &entry); + fx_parse_fx_2_assignment(parser, HLSL_CLASS_PASS, &entry); } parse_fx_end_indent(parser);
@@ -4037,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_16}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, };
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; @@ -4112,8 +4280,7 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) { parse_fx_start_indent(parser); parse_fx_print_indent(parser); - fx_print_string(&parser->buffer, """, (const char *)data, size); - vkd3d_string_buffer_printf(&parser->buffer, """); + fx_2_print_string_literal(parser, """, (const char *)data, size, """); parse_fx_end_indent(parser); } else if (type == D3DXPT_PIXELSHADER || type == D3DXPT_VERTEXSHADER) @@ -4135,38 +4302,18 @@ static void fx_parse_fx_2_data_blob(struct fx_parser *parser) fx_parser_skip(parser, align(size, 4)); }
-static void fx_dump_blob(struct fx_parser *parser, const void *blob, uint32_t size) -{ - const uint32_t *data = blob; - unsigned int i, j, n; +static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size);
- size /= sizeof(*data); - i = 0; - while (i < size) - { - parse_fx_print_indent(parser); - n = min(size - i, 8); - for (j = 0; j < n; ++j) - vkd3d_string_buffer_printf(&parser->buffer, "0x%08x,", data[i + j]); - i += n; - vkd3d_string_buffer_printf(&parser->buffer, "\n"); - } -} - -static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size) +static void fx_parse_fx_2_array_selector(struct fx_parser *parser) { - const uint8_t *end = parser->ptr + size; - uint32_t name_size, blob_size = 0; + uint32_t size, blob_size = 0; const void *blob = NULL; - const char *name; + const uint8_t *end;
- name_size = fx_parser_read_u32(parser); - name = fx_parser_get_ptr(parser, name_size); - fx_parser_skip(parser, name_size); + size = fx_parser_read_u32(parser); + end = parser->ptr + size;
- if (!name || (uint8_t *)name >= end) - fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, - "Malformed name entry in the array selector."); + fx_2_parse_string_literal(parser, 0, false, "array "", ""\n");
if (parser->ptr <= end) { @@ -4180,17 +4327,38 @@ static void fx_parse_fx_2_array_selector(struct fx_parser *parser, uint32_t size "Malformed blob entry in the array selector."); }
- if (name) - { - fx_print_string(&parser->buffer, "array "", name, name_size); - vkd3d_string_buffer_printf(&parser->buffer, ""\n"); - } if (blob) { parse_fx_print_indent(parser); vkd3d_string_buffer_printf(&parser->buffer, "selector blob size %u\n", blob_size); - fx_dump_blob(parser, blob, blob_size); + fx_2_parse_fxlvm_expression(parser, blob, blob_size); + } +} + +static void fx_2_parse_code_blob(struct fx_parser *parser, const uint32_t *blob, uint32_t size) +{ + uint32_t tag; + + if (size < sizeof(tag)) + return; + + tag = *blob; + + if (tag == TAG_FX20) + { + fx_2_parse_fxlvm_expression(parser, blob, size); + return; } + + tag >>= 16; + if (tag == 0xfffe || tag == 0xffff) + { + fx_parse_shader_blob(parser, VKD3D_SHADER_SOURCE_D3D_BYTECODE, blob, size); + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + return; + } + + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Unrecognized code blob type, tag 0x%08x.", *blob); }
static void fx_parse_fx_2_complex_state(struct fx_parser *parser) @@ -4203,7 +4371,7 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) uint32_t state; uint32_t assignment_type; } state; - const char *data; + const uint32_t *data; uint32_t size;
fx_parser_read_u32s(parser, &state, sizeof(state)); @@ -4219,28 +4387,29 @@ static void fx_parse_fx_2_complex_state(struct fx_parser *parser) state.technique, state.index, state.state); }
- size = fx_parser_read_u32(parser); - parse_fx_print_indent(parser);
if (state.assignment_type == FX_2_ASSIGNMENT_PARAMETER) { - data = fx_parser_get_ptr(parser, size); - fx_print_string(&parser->buffer, "parameter "", data, size); - vkd3d_string_buffer_printf(&parser->buffer, ""\n"); - fx_parser_skip(parser, align(size, 4)); + fx_2_parse_string_literal(parser, 0, false, "parameter "", ""\n"); } else if (state.assignment_type == FX_2_ASSIGNMENT_ARRAY_SELECTOR) { - fx_parse_fx_2_array_selector(parser, size); + fx_parse_fx_2_array_selector(parser); } - else + else if (state.assignment_type == FX_2_ASSIGNMENT_CODE_BLOB) { - vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); + size = fx_parser_read_u32(parser); data = fx_parser_get_ptr(parser, size); - fx_dump_blob(parser, data, size); + vkd3d_string_buffer_printf(&parser->buffer, "blob size %u\n", size); + fx_2_parse_code_blob(parser, data, size); fx_parser_skip(parser, align(size, 4)); } + else + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Unknown state assignment type %u.", state.assignment_type); + } }
static void fx_2_parse(struct fx_parser *parser) @@ -4457,6 +4626,11 @@ static void fx_parse_fx_4_numeric_variables(struct fx_parser *parser, uint32_t c semantic = fx_4_get_string(parser, var.semantic); vkd3d_string_buffer_printf(&parser->buffer, " : %s", semantic); } + if (var.flags & FX_4_HAS_EXPLICIT_BIND_POINT) + { + vkd3d_string_buffer_printf(&parser->buffer, " : packoffset(c%u.%c)", + var.offset / 16, "xyzw"[(var.offset % 16) / 4]); + } fx_parse_fx_4_annotations(parser);
if (var.value) @@ -4492,6 +4666,8 @@ static void fx_parse_buffers(struct fx_parser *parser) name = fx_4_get_string(parser, buffer.name);
vkd3d_string_buffer_printf(&parser->buffer, "cbuffer %s", name); + if (buffer.bind_point != ~0u) + vkd3d_string_buffer_printf(&parser->buffer, " : register(b%u)", buffer.bind_point); fx_parse_fx_4_annotations(parser);
vkd3d_string_buffer_printf(&parser->buffer, "\n{\n"); @@ -4598,7 +4774,7 @@ static bool fx_4_object_has_initializer(const struct fx_4_binary_type *type)
static int fx_4_state_id_compare(const void *a, const void *b) { - const struct fx_4_state *state = b; + const struct fx_state *state = b; int id = *(int *)a;
return id - state->id; @@ -4609,7 +4785,7 @@ static const struct uint32_t opcode; const char *name; } -fx_4_fxlc_opcodes[] = +fxlc_opcodes[] = { { 0x100, "mov" }, { 0x101, "neg" }, @@ -4634,6 +4810,8 @@ fx_4_fxlc_opcodes[] = { 0x13a, "ceil" }, { 0x200, "min" }, { 0x201, "max" }, + { 0x202, "lt" }, + { 0x203, "ge" }, { 0x204, "add" }, { 0x205, "mul" }, { 0x206, "atan2" }, @@ -4659,29 +4837,24 @@ fx_4_fxlc_opcodes[] = { 0x236, "ushr" }, { 0x301, "movc" }, { 0x500, "dot" }, + { 0x502, "noise" }, { 0x70e, "d3ds_dotswiz" }, + { 0x711, "d3ds_noiseswiz" }, };
-static const char *fx_4_get_fxlc_opcode_name(uint32_t opcode) +static const char *get_fxlc_opcode_name(uint32_t opcode) { size_t i;
- for (i = 0; i < ARRAY_SIZE(fx_4_fxlc_opcodes); ++i) + for (i = 0; i < ARRAY_SIZE(fxlc_opcodes); ++i) { - if (fx_4_fxlc_opcodes[i].opcode == opcode) - return fx_4_fxlc_opcodes[i].name; + if (fxlc_opcodes[i].opcode == opcode) + return fxlc_opcodes[i].name; }
return "<unrecognized>"; }
-struct fx_4_fxlc_argument -{ - uint32_t flags; - uint32_t reg_type; - uint32_t address; -}; - struct fx_4_ctab_entry { uint32_t name; @@ -4693,10 +4866,29 @@ struct fx_4_ctab_entry uint32_t default_value; };
+struct fxlc_arg +{ + uint32_t reg_type; + uint32_t address; + bool indexed; + struct + { + uint32_t reg_type; + uint32_t address; + } index; +}; + struct fxlvm_code { - const float *cli4; - uint32_t cli4_count; + const uint32_t *ptr, *end; + bool failed; + + union + { + const float *_4; + const double *_8; + } cli; + uint32_t cli_count;
const struct fx_4_ctab_entry *constants; uint32_t ctab_offset; @@ -4707,7 +4899,45 @@ struct fxlvm_code bool scalar; };
-static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) +static uint32_t fxlvm_read_u32(struct fxlvm_code *code) +{ + if (code->end == code->ptr) + { + code->failed = true; + return 0; + } + + return *code->ptr++; +} + +static const uint32_t *find_d3dbc_section(const uint32_t *ptr, uint32_t count, uint32_t tag, uint32_t *size) +{ + if (!count) + return NULL; + + /* Skip version tag */ + ptr++; + count--; + + while (count > 2 && (*ptr & 0xffff) == 0xfffe) + { + unsigned int section_size; + + section_size = (*ptr >> 16); + if (!section_size || section_size + 1 > count) + break; + if (*(ptr + 1) == tag) + { + *size = section_size; + return ptr + 2; + } + count -= section_size + 1; + ptr += section_size + 1; + } + return NULL; +} + +static void fx_parse_print_swizzle(struct fx_parser *parser, const struct fxlvm_code *code, unsigned int addr) { unsigned int comp_count = code->scalar ? 1 : code->comp_count; static const char comp[] = "xyzw"; @@ -4716,44 +4946,137 @@ static void fx_4_parse_print_swizzle(struct fx_parser *parser, const struct fxlv vkd3d_string_buffer_printf(&parser->buffer, ".%.*s", comp_count, &comp[addr % 4]); }
-static void fx_4_parse_fxlc_constant_argument(struct fx_parser *parser, - const struct fx_4_fxlc_argument *arg, const struct fxlvm_code *code) +static void fx_print_fxlc_register(struct fx_parser *parser, uint32_t reg_type, + uint32_t address, uint32_t index_type, uint32_t index_address, struct fxlvm_code *code) +{ + static const char *table_names[FX_FXLC_REG_MAX + 1] = + { + [FX_FXLC_REG_LITERAL] = "imm", + [FX_FXLC_REG_CB] = "c", + [FX_FXLC_REG_INPUT] = "i", + [FX_FXLC_REG_OUTPUT] = "expr", + [FX_FXLC_REG_TEMP] = "r", + }; + uint32_t reg_index = address / 4; + + if (parser->source_type == VKD3D_SHADER_SOURCE_TX + && (reg_type == FX_FXLC_REG_INPUT || reg_type == FX_FXLC_REG_OUTPUT)) + { + if (reg_type == FX_FXLC_REG_INPUT) + { + if (reg_index == 0) + vkd3d_string_buffer_printf(&parser->buffer, "vPos"); + else if (reg_index == 1) + vkd3d_string_buffer_printf(&parser->buffer, "vPSize"); + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "oC%u", reg_index); + } + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "%s%u", table_names[reg_type], reg_index); + } + if (index_type != FX_FXLC_REG_UNUSED) + { + vkd3d_string_buffer_printf(&parser->buffer, "[%s%u.%c]", table_names[index_type], + index_address / 4, "xyzw"[index_address % 4]); + } + fx_parse_print_swizzle(parser, code, address); +} + +static void fx_parse_fxlc_constant_argument(struct fx_parser *parser, + const struct fxlc_arg *arg, const struct fxlvm_code *code) { - uint32_t i, offset, register_index = arg->address / 4; /* Address counts in components. */ + uint32_t register_index = arg->address / 4; /* Address counts in components. */
- for (i = 0; i < code->ctab_count; ++i) + if (code->ctab_count) { - const struct fx_4_ctab_entry *c = &code->constants[i]; + uint32_t i, offset;
- if (register_index < c->register_index || register_index - c->register_index >= c->register_count) - continue; + for (i = 0; i < code->ctab_count; ++i) + { + const struct fx_4_ctab_entry *c = &code->constants[i];
- vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]); + if (register_index < c->register_index || register_index - c->register_index >= c->register_count) + continue;
- /* Register offset within variable */ - offset = arg->address - c->register_index * 4; + vkd3d_string_buffer_printf(&parser->buffer, "%s", &code->ctab[c->name]);
- if (offset / 4) - vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); - fx_4_parse_print_swizzle(parser, code, offset); - return; + /* Register offset within variable */ + offset = arg->address - c->register_index * 4; + + if (offset / 4) + vkd3d_string_buffer_printf(&parser->buffer, "[%u]", offset / 4); + fx_parse_print_swizzle(parser, code, offset); + return; + } + + vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); + } + else + { + vkd3d_string_buffer_printf(&parser->buffer, "c%u", register_index); + fx_parse_print_swizzle(parser, code, arg->address); + } +} + +static void fx_parse_fxlc_argument(struct fx_parser *parser, struct fxlc_arg *arg, struct fxlvm_code *code) +{ + uint32_t flags; + + memset(arg, 0, sizeof(*arg)); + + flags = fxlvm_read_u32(code); + if (flags) + { + arg->indexed = true; + arg->index.reg_type = fxlvm_read_u32(code); + arg->index.address = fxlvm_read_u32(code); } + arg->reg_type = fxlvm_read_u32(code); + arg->address = fxlvm_read_u32(code); +}
- vkd3d_string_buffer_printf(&parser->buffer, "(var-not-found)"); +static void fx_print_fxlc_literal(struct fx_parser *parser, uint32_t address, struct fxlvm_code *code) +{ + if (parser->version.major >= 4) + vkd3d_string_buffer_print_f32(&parser->buffer, code->cli._4[address]); + else + vkd3d_string_buffer_print_f64(&parser->buffer, code->cli._8[address]); }
-static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, const struct fxlvm_code *code) +static void fx_print_fxlc_argument(struct fx_parser *parser, const struct fxlc_arg *arg, struct fxlvm_code *code) { - struct fx_4_fxlc_argument arg; uint32_t count;
- fx_parser_read_unstructured(parser, &arg, offset, sizeof(arg)); + if (arg->reg_type > FX_FXLC_REG_MAX) + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Unexpected register type %u.", arg->reg_type); + return; + }
- switch (arg.reg_type) + if (arg->index.reg_type > FX_FXLC_REG_MAX) { - case FX_4_FXLC_REG_LITERAL: + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Unexpected index register type %u.", arg->index.reg_type); + return; + } + + if (arg->indexed) + { + fx_print_fxlc_register(parser, arg->reg_type, arg->address, arg->index.reg_type, + arg->index.address, code); + return; + } + + switch (arg->reg_type) + { + case FX_FXLC_REG_LITERAL: count = code->scalar ? 1 : code->comp_count; - if (arg.address >= code->cli4_count || count > code->cli4_count - arg.address) + if (arg->address >= code->cli_count || count > code->cli_count - arg->address) { vkd3d_string_buffer_printf(&parser->buffer, "(<out-of-bounds>)"); parser->failed = true; @@ -4761,42 +5084,131 @@ static void fx_4_parse_fxlc_argument(struct fx_parser *parser, uint32_t offset, }
vkd3d_string_buffer_printf(&parser->buffer, "("); - vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address]); + fx_print_fxlc_literal(parser, arg->address, code); for (unsigned int i = 1; i < code->comp_count; ++i) { vkd3d_string_buffer_printf(&parser->buffer, ", "); - vkd3d_string_buffer_print_f32(&parser->buffer, code->cli4[arg.address + (code->scalar ? 0 : i)]); + fx_print_fxlc_literal(parser, arg->address + (code->scalar ? 0 : i), code); } vkd3d_string_buffer_printf(&parser->buffer, ")"); break;
- case FX_4_FXLC_REG_CB: - fx_4_parse_fxlc_constant_argument(parser, &arg, code); + case FX_FXLC_REG_CB: + fx_parse_fxlc_constant_argument(parser, arg, code); break;
- case FX_4_FXLC_REG_OUTPUT: - case FX_4_FXLC_REG_TEMP: - if (arg.reg_type == FX_4_FXLC_REG_OUTPUT) - vkd3d_string_buffer_printf(&parser->buffer, "expr"); - else - vkd3d_string_buffer_printf(&parser->buffer, "r%u", arg.address / 4); - fx_4_parse_print_swizzle(parser, code, arg.address); + case FX_FXLC_REG_INPUT: + case FX_FXLC_REG_OUTPUT: + case FX_FXLC_REG_TEMP: + fx_print_fxlc_register(parser, arg->reg_type, arg->address, FX_FXLC_REG_UNUSED, 0, code); break;
default: - vkd3d_string_buffer_printf(&parser->buffer, "<unknown register %u>", arg.reg_type); + vkd3d_string_buffer_printf(&parser->buffer, "<unknown register %u>", arg->reg_type); break; } }
+static void fx_parse_fxlvm_expression(struct fx_parser *parser, struct fxlvm_code *code) +{ + struct fxlc_arg args[9]; + uint32_t ins_count; + size_t i, j; + + parse_fx_start_indent(parser); + if (parser->source_type == VKD3D_SHADER_SOURCE_TX) + { + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "tx_1_0\n"); + } + + ins_count = fxlvm_read_u32(code); + + for (i = 0; i < ins_count; ++i) + { + uint32_t instr, opcode, src_count; + + instr = fxlvm_read_u32(code); + src_count = fxlvm_read_u32(code); + + if (src_count >= ARRAY_SIZE(args)) + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, + "Unexpected instruction source count %u.", src_count); + break; + } + + /* Sources entries are followed by the destination, first read them all. + Output format is "opcode dst, src[0]...src[n]". */ + for (j = 0; j < src_count; ++j) + fx_parse_fxlc_argument(parser, &args[j], code); + fx_parse_fxlc_argument(parser, &args[src_count], code); + + opcode = (instr >> FX_FXLC_OPCODE_SHIFT) & FX_FXLC_OPCODE_MASK; + code->comp_count = instr & FX_FXLC_COMP_COUNT_MASK; + + parse_fx_print_indent(parser); + vkd3d_string_buffer_printf(&parser->buffer, "%s ", get_fxlc_opcode_name(opcode)); + + code->scalar = false; + fx_print_fxlc_argument(parser, &args[src_count], code); + vkd3d_string_buffer_printf(&parser->buffer, ", "); + + for (j = 0; j < src_count; ++j) + { + /* Scalar modifier applies only to the first source. */ + code->scalar = j == 0 && !!(instr & FX_FXLC_IS_SCALAR_MASK); + fx_print_fxlc_argument(parser, &args[j], code); + if (j < src_count - 1) + vkd3d_string_buffer_printf(&parser->buffer, ", "); + } + + vkd3d_string_buffer_printf(&parser->buffer, "\n"); + } + + parse_fx_end_indent(parser); +} + +static void fx_2_parse_fxlvm_expression(struct fx_parser *parser, const uint32_t *blob, uint32_t size) +{ + uint32_t count = size / sizeof(uint32_t); + struct fxlvm_code code = { 0 }; + uint32_t section_size; + const uint32_t *data; + + if (!blob) + return; + + /* Literal constants, using 64-bit floats. */ + if ((data = find_d3dbc_section(blob, count, TAG_CLIT, §ion_size))) + { + code.cli_count = *data++; + code.cli._8 = (const double *)data; + } + + /* CTAB does not contain variable names */ + + /* Code blob */ + code.ptr = find_d3dbc_section(blob, count, TAG_FXLC, &count); + code.end = code.ptr + count; + + if (!code.ptr) + { + fx_parser_error(parser, VKD3D_SHADER_ERROR_FX_INVALID_DATA, "Failed to locate expression code section."); + return; + } + + fx_parse_fxlvm_expression(parser, &code); +} + static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offset) { struct vkd3d_shader_dxbc_section_desc *section, fxlc, cli4, ctab; struct vkd3d_shader_dxbc_desc dxbc_desc; + struct fxlvm_code code = { 0 }; struct vkd3d_shader_code dxbc; - uint32_t size, ins_count; - struct fxlvm_code code; - size_t i, j; + uint32_t size; + size_t i;
offset = fx_parser_read_unstructured(parser, &size, offset, sizeof(size));
@@ -4832,8 +5244,8 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse { uint32_t cli4_offset = offset + (size_t)cli4.data.code - (size_t)dxbc.code;
- fx_parser_read_unstructured(parser, &code.cli4_count, cli4_offset, sizeof(code.cli4_count)); - code.cli4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli4_count * sizeof(float)); + fx_parser_read_unstructured(parser, &code.cli_count, cli4_offset, sizeof(code.cli_count)); + code.cli._4 = fx_parser_get_unstructured_ptr(parser, cli4_offset + 4, code.cli_count * sizeof(float)); }
if (ctab.data.code) @@ -4849,47 +5261,10 @@ static void fx_4_parse_fxlvm_expression(struct fx_parser *parser, uint32_t offse ctab_offset + consts_offset, code.ctab_count * sizeof(*code.constants)); }
- offset += (size_t)fxlc.data.code - (size_t)dxbc.code; - offset = fx_parser_read_unstructured(parser, &ins_count, offset, sizeof(ins_count)); - - parse_fx_start_indent(parser); + code.ptr = fxlc.data.code; + code.end = (uint32_t *)((uint8_t *)fxlc.data.code + fxlc.data.size);
- for (i = 0; i < ins_count; ++i) - { - uint32_t instr, opcode, src_count; - struct fx_4_fxlc_argument arg; - - offset = fx_parser_read_unstructured(parser, &instr, offset, sizeof(instr)); - offset = fx_parser_read_unstructured(parser, &src_count, offset, sizeof(src_count)); - - opcode = (instr >> FX_4_FXLC_OPCODE_SHIFT) & FX_4_FXLC_OPCODE_MASK; - code.comp_count = instr & FX_4_FXLC_COMP_COUNT_MASK; - code.scalar = false; - - parse_fx_print_indent(parser); - vkd3d_string_buffer_printf(&parser->buffer, "%s ", fx_4_get_fxlc_opcode_name(opcode)); - - /* Destination first. */ - fx_4_parse_fxlc_argument(parser, offset + sizeof(arg) * src_count, &code); - - for (j = 0; j < src_count; ++j) - { - vkd3d_string_buffer_printf(&parser->buffer, ", "); - - /* Scalar modifier applies only to first source. */ - code.scalar = j == 0 && !!(instr & FX_4_FXLC_IS_SCALAR_MASK); - fx_4_parse_fxlc_argument(parser, offset, &code); - - offset += sizeof(arg); - } - - /* Destination */ - offset += sizeof(arg); - - vkd3d_string_buffer_printf(&parser->buffer, "\n"); - } - - parse_fx_end_indent(parser); + fx_parse_fxlvm_expression(parser, &code); }
static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32_t count, @@ -4919,12 +5294,12 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 }; const struct rhs_named_value *named_value; struct fx_5_shader shader = { 0 }; - struct fx_4_state_table table; + struct fx_state_table table; unsigned int shader_type = 0; uint32_t i, j, comp_count; - struct fx_4_state *state; + struct fx_state *state;
- table = fx_4_get_state_table(type_class, parser->version.major, parser->version.minor); + table = fx_get_state_table(type_class, parser->version.major, parser->version.minor);
for (i = 0; i < count; ++i) { @@ -4995,6 +5370,8 @@ static void fx_4_parse_state_object_initializer(struct fx_parser *parser, uint32 vkd3d_string_buffer_printf(&parser->buffer, "0x%.2x", value.u); else if (state->type == FX_UINT) vkd3d_string_buffer_printf(&parser->buffer, "%u", value.u); + else if (state->type == FX_BOOL) + vkd3d_string_buffer_printf(&parser->buffer, "%s", value.u ? "true" : "false"); else if (state->type == FX_FLOAT) vkd3d_string_buffer_printf(&parser->buffer, "%g", value.f);
@@ -5374,6 +5751,7 @@ static void fx_parser_init(struct fx_parser *parser, const struct vkd3d_shader_c struct vkd3d_shader_message_context *message_context) { memset(parser, 0, sizeof(*parser)); + parser->source_type = compile_info->source_type; parser->start = compile_info->source.code; parser->ptr = compile_info->source.code; parser->end = (uint8_t *)compile_info->source.code + compile_info->source.size; @@ -5434,3 +5812,38 @@ int fx_parse(const struct vkd3d_shader_compile_info *compile_info, return VKD3D_ERROR_INVALID_SHADER; return VKD3D_OK; } + +int tx_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) +{ + struct fx_parser parser; + uint32_t version; + + fx_parser_init(&parser, compile_info, message_context); + + if (parser.end - parser.start < sizeof(version)) + { + fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_SIZE, + "Source size %zu is smaller than the TX header size.", compile_info->source.size); + return VKD3D_ERROR_INVALID_SHADER; + } + version = *(uint32_t *)parser.ptr; + + switch (version) + { + case 0x54580100: + fx_2_parse_fxlvm_expression(&parser, (const uint32_t *)parser.ptr, parser.end - parser.ptr); + break; + default: + fx_parser_error(&parser, VKD3D_SHADER_ERROR_FX_INVALID_VERSION, + "Invalid texture shader binary version value 0x%08x.", version); + break; + } + + vkd3d_shader_code_from_string_buffer(out, &parser.buffer); + fx_parser_cleanup(&parser); + + if (parser.failed) + return VKD3D_ERROR_INVALID_SHADER; + return VKD3D_OK; +} diff --git a/libs/vkd3d/libs/vkd3d-shader/glsl.c b/libs/vkd3d/libs/vkd3d-shader/glsl.c index e4497b9ac5b..dfe0a40ddf0 100644 --- a/libs/vkd3d/libs/vkd3d-shader/glsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/glsl.c @@ -328,12 +328,12 @@ static void glsl_src_cleanup(struct glsl_src *src, struct vkd3d_string_buffer_ca }
static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vkd3d_glsl_generator *gen, - const char *src, enum vkd3d_data_type dst_data_type, enum vkd3d_data_type src_data_type, unsigned int size) + const char *src, enum vsir_data_type dst_data_type, enum vsir_data_type src_data_type, unsigned int size) { - if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) - dst_data_type = VKD3D_DATA_FLOAT; - if (src_data_type == VKD3D_DATA_UNORM || src_data_type == VKD3D_DATA_SNORM) - src_data_type = VKD3D_DATA_FLOAT; + if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM) + dst_data_type = VSIR_DATA_F32; + if (src_data_type == VSIR_DATA_UNORM || src_data_type == VSIR_DATA_SNORM) + src_data_type = VSIR_DATA_F32;
if (dst_data_type == src_data_type) { @@ -341,14 +341,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk return; }
- if (src_data_type == VKD3D_DATA_FLOAT) + if (src_data_type == VSIR_DATA_F32) { switch (dst_data_type) { - case VKD3D_DATA_INT: + case VSIR_DATA_I32: vkd3d_string_buffer_printf(dst, "floatBitsToInt(%s)", src); return; - case VKD3D_DATA_UINT: + case VSIR_DATA_U32: vkd3d_string_buffer_printf(dst, "floatBitsToUint(%s)", src); return; default: @@ -356,14 +356,14 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk } }
- if (src_data_type == VKD3D_DATA_UINT) + if (src_data_type == VSIR_DATA_U32) { switch (dst_data_type) { - case VKD3D_DATA_FLOAT: + case VSIR_DATA_F32: vkd3d_string_buffer_printf(dst, "uintBitsToFloat(%s)", src); return; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: if (size == 1) vkd3d_string_buffer_printf(dst, "int(%s)", src); else @@ -381,11 +381,11 @@ static void shader_glsl_print_bitcast(struct vkd3d_string_buffer *dst, struct vk }
static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, - const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) + const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type) { const struct vkd3d_shader_register *reg = &vsir_src->reg; struct vkd3d_string_buffer *register_name, *str; - enum vkd3d_data_type src_data_type; + enum vsir_data_type src_data_type; unsigned int size;
register_name = vkd3d_string_buffer_get(&gen->string_buffers); @@ -395,9 +395,9 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd "Internal compiler error: Unhandled 'non-uniform' modifier.");
if (reg->type == VKD3DSPR_IMMCONST || reg->type == VKD3DSPR_THREADID) - src_data_type = VKD3D_DATA_UINT; + src_data_type = VSIR_DATA_U32; else - src_data_type = VKD3D_DATA_FLOAT; + src_data_type = VSIR_DATA_F32;
shader_glsl_print_register_name(register_name, gen, reg);
@@ -421,6 +421,9 @@ static void shader_glsl_print_src(struct vkd3d_string_buffer *buffer, struct vkd case VKD3DSPSM_ABS: vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); break; + case VKD3DSPSM_ABSNEG: + vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); + break; default: vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)", vsir_src->modifiers, str->buffer); @@ -489,12 +492,15 @@ static void shader_glsl_print_subscript(struct vkd3d_string_buffer *buffer, stru }
static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_glsl_generator *gen, - struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, va_list args) + struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, va_list args) { struct vkd3d_string_buffer *buffer = gen->buffer; uint32_t modifiers = dst->vsir->modifiers; bool close = true;
+ /* It is always legitimate to ignore _pp. */ + modifiers &= ~VKD3DSPDM_PARTIALPRECISION; + if (dst->vsir->shift) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); @@ -513,13 +519,13 @@ static void VKD3D_PRINTF_FUNC(4, 0) shader_glsl_vprint_assignment(struct vkd3d_g vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled destination register data type %#x.", data_type); /* fall through */ - case VKD3D_DATA_FLOAT: + case VSIR_DATA_F32: close = false; break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: vkd3d_string_buffer_printf(buffer, "intBitsToFloat("); break; - case VKD3D_DATA_UINT: + case VSIR_DATA_U32: vkd3d_string_buffer_printf(buffer, "uintBitsToFloat("); break; } @@ -544,7 +550,7 @@ static void VKD3D_PRINTF_FUNC(3, 4) shader_glsl_print_assignment( }
static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3d_glsl_generator *gen, - struct glsl_dst *dst, enum vkd3d_data_type data_type, const char *format, ...) + struct glsl_dst *dst, enum vsir_data_type data_type, const char *format, ...) { va_list args;
@@ -555,10 +561,12 @@ static void VKD3D_PRINTF_FUNC(4, 5) shader_glsl_print_assignment_ext(struct vkd3
static void shader_glsl_unhandled(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) { + const char *name = vsir_opcode_get_name(ins->opcode, "<unknown>"); + shader_glsl_print_indent(gen->buffer, gen->indent); - vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction %#x> */\n", ins->opcode); + vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction "%s" (%#x)> */\n", name, ins->opcode); vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled instruction %#x.", ins->opcode); + "Internal compiler error: Unhandled instruction "%s" (%#x).", name, ins->opcode); }
static void shader_glsl_binop(struct vkd3d_glsl_generator *gen, @@ -789,7 +797,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ const struct vkd3d_shader_descriptor_info1 *d; enum vkd3d_shader_resource_type resource_type; struct vkd3d_string_buffer *fetch; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; struct glsl_src coord; struct glsl_dst dst; uint32_t coord_mask; @@ -818,7 +826,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ resource_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; sample_count = 1; - data_type = VKD3D_DATA_FLOAT; + data_type = VSIR_DATA_F32; }
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -843,7 +851,7 @@ static void shader_glsl_ld(struct vkd3d_glsl_generator *gen, const struct vkd3d_ if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) { vkd3d_string_buffer_printf(fetch, ", "); - if (ins->opcode != VKD3DSIH_LD2DMS) + if (ins->opcode != VSIR_OP_LD2DMS) shader_glsl_print_src(fetch, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, ins->src[0].reg.data_type); else if (sample_count == 1) /* If the resource isn't a true multisample resource, this is the @@ -904,17 +912,17 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk enum vkd3d_shader_resource_type resource_type; unsigned int component_idx, coord_size; struct vkd3d_string_buffer *sample; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; struct glsl_dst dst;
- bias = ins->opcode == VKD3DSIH_SAMPLE_B; - dynamic_offset = ins->opcode == VKD3DSIH_GATHER4_PO; - gather = ins->opcode == VKD3DSIH_GATHER4 || ins->opcode == VKD3DSIH_GATHER4_PO; - grad = ins->opcode == VKD3DSIH_SAMPLE_GRAD; - lod = ins->opcode == VKD3DSIH_SAMPLE_LOD || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; - lod_zero = ins->opcode == VKD3DSIH_SAMPLE_C_LZ; + bias = ins->opcode == VSIR_OP_SAMPLE_B; + dynamic_offset = ins->opcode == VSIR_OP_GATHER4_PO; + gather = ins->opcode == VSIR_OP_GATHER4 || ins->opcode == VSIR_OP_GATHER4_PO; + grad = ins->opcode == VSIR_OP_SAMPLE_GRAD; + lod = ins->opcode == VSIR_OP_SAMPLE_LOD || ins->opcode == VSIR_OP_SAMPLE_C_LZ; + lod_zero = ins->opcode == VSIR_OP_SAMPLE_C_LZ; offset = dynamic_offset || vkd3d_shader_instruction_has_texel_offset(ins); - shadow = ins->opcode == VKD3DSIH_SAMPLE_C || ins->opcode == VKD3DSIH_SAMPLE_C_LZ; + shadow = ins->opcode == VSIR_OP_SAMPLE_C || ins->opcode == VSIR_OP_SAMPLE_C_LZ;
resource = &ins->src[1 + dynamic_offset]; sampler = &ins->src[2 + dynamic_offset]; @@ -938,7 +946,7 @@ static void shader_glsl_sample(struct vkd3d_glsl_generator *gen, const struct vk "Internal compiler error: Undeclared resource descriptor %u.", resource_id); resource_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - data_type = VKD3D_DATA_FLOAT; + data_type = VSIR_DATA_F32; }
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -1053,7 +1061,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s enum vkd3d_shader_resource_type resource_type; unsigned int uav_id, uav_idx, uav_space; struct vkd3d_string_buffer *load; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; struct glsl_src coord; struct glsl_dst dst; uint32_t coord_mask; @@ -1076,7 +1084,7 @@ static void shader_glsl_load_uav_typed(struct vkd3d_glsl_generator *gen, const s "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); uav_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - data_type = VKD3D_DATA_FLOAT; + data_type = VSIR_DATA_F32; }
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -1113,7 +1121,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const enum vkd3d_shader_resource_type resource_type; unsigned int uav_id, uav_idx, uav_space; struct vkd3d_string_buffer *image_data; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; struct glsl_src image_coord; uint32_t coord_mask;
@@ -1135,7 +1143,7 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); uav_space = 0; resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; - data_type = VKD3D_DATA_FLOAT; + data_type = VSIR_DATA_F32; }
if ((resource_type_info = shader_glsl_get_resource_type_info(resource_type))) @@ -1156,19 +1164,19 @@ static void shader_glsl_store_uav_typed(struct vkd3d_glsl_generator *gen, const { switch (data_type) { - case VKD3D_DATA_UINT: - vkd3d_string_buffer_printf(image_data, "uvec4("); - break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: vkd3d_string_buffer_printf(image_data, "ivec4("); break; + case VSIR_DATA_U32: + vkd3d_string_buffer_printf(image_data, "uvec4("); + break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled data type %#x.", data_type); /* fall through */ - case VKD3D_DATA_FLOAT: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: + case VSIR_DATA_F32: + case VSIR_DATA_SNORM: + case VSIR_DATA_UNORM: vkd3d_string_buffer_printf(image_data, "vec4("); break; } @@ -1242,37 +1250,6 @@ static void shader_glsl_movc(struct vkd3d_glsl_generator *gen, const struct vkd3 glsl_dst_cleanup(&dst, &gen->string_buffers); }
-static void shader_glsl_mul_extended(struct vkd3d_glsl_generator *gen, const struct vkd3d_shader_instruction *ins) -{ - struct glsl_src src[2]; - struct glsl_dst dst; - uint32_t mask; - - if (ins->dst[0].reg.type != VKD3DSPR_NULL) - { - /* FIXME: imulExtended()/umulExtended() from ARB_gpu_shader5/GLSL 4.00+. */ - mask = glsl_dst_init(&dst, gen, ins, &ins->dst[0]); - shader_glsl_print_assignment(gen, &dst, "<unhandled 64-bit multiplication>"); - glsl_dst_cleanup(&dst, &gen->string_buffers); - - vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, - "Internal compiler error: Unhandled 64-bit integer multiplication."); - } - - if (ins->dst[1].reg.type != VKD3DSPR_NULL) - { - mask = glsl_dst_init(&dst, gen, ins, &ins->dst[1]); - glsl_src_init(&src[0], gen, &ins->src[0], mask); - glsl_src_init(&src[1], gen, &ins->src[1], mask); - - shader_glsl_print_assignment(gen, &dst, "%s * %s", src[0].str->buffer, src[1].str->buffer); - - glsl_src_cleanup(&src[1], &gen->string_buffers); - glsl_src_cleanup(&src[0], &gen->string_buffers); - glsl_dst_cleanup(&dst, &gen->string_buffers); - } -} - static void shader_glsl_print_sysval_name(struct vkd3d_string_buffer *buffer, struct vkd3d_glsl_generator *gen, enum vkd3d_shader_sysval_semantic sysval, unsigned int idx) { @@ -1482,177 +1459,177 @@ static void vkd3d_glsl_handle_instruction(struct vkd3d_glsl_generator *gen,
switch (ins->opcode) { - case VKD3DSIH_ADD: - case VKD3DSIH_IADD: + case VSIR_OP_ADD: + case VSIR_OP_IADD: shader_glsl_binop(gen, ins, "+"); break; - case VKD3DSIH_AND: + case VSIR_OP_AND: shader_glsl_binop(gen, ins, "&"); break; - case VKD3DSIH_BREAK: + case VSIR_OP_BREAK: shader_glsl_break(gen); break; - case VKD3DSIH_CASE: + case VSIR_OP_CASE: shader_glsl_case(gen, ins); break; - case VKD3DSIH_CONTINUE: + case VSIR_OP_CONTINUE: shader_glsl_continue(gen); break; - case VKD3DSIH_DCL_INDEXABLE_TEMP: + case VSIR_OP_DCL_INDEXABLE_TEMP: shader_glsl_dcl_indexable_temp(gen, ins); break; - case VKD3DSIH_NOP: + case VSIR_OP_NOP: break; - case VKD3DSIH_DEFAULT: + case VSIR_OP_DEFAULT: shader_glsl_default(gen); break; - case VKD3DSIH_DIV: + case VSIR_OP_DIV: shader_glsl_binop(gen, ins, "/"); break; - case VKD3DSIH_DP2: + case VSIR_OP_DP2: shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(2)); break; - case VKD3DSIH_DP3: + case VSIR_OP_DP3: shader_glsl_dot(gen, ins, vkd3d_write_mask_from_component_count(3)); break; - case VKD3DSIH_DP4: + case VSIR_OP_DP4: shader_glsl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); break; - case VKD3DSIH_ELSE: + case VSIR_OP_ELSE: shader_glsl_else(gen, ins); break; - case VKD3DSIH_ENDIF: - case VKD3DSIH_ENDLOOP: - case VKD3DSIH_ENDSWITCH: + case VSIR_OP_ENDIF: + case VSIR_OP_ENDLOOP: + case VSIR_OP_ENDSWITCH: shader_glsl_end_block(gen); break; - case VKD3DSIH_EQO: - case VKD3DSIH_IEQ: + case VSIR_OP_EQO: + case VSIR_OP_IEQ: shader_glsl_relop(gen, ins, "==", "equal"); break; - case VKD3DSIH_EXP: + case VSIR_OP_EXP: shader_glsl_intrinsic(gen, ins, "exp2"); break; - case VKD3DSIH_FRC: + case VSIR_OP_FRC: shader_glsl_intrinsic(gen, ins, "fract"); break; - case VKD3DSIH_FTOI: + case VSIR_OP_FTOI: shader_glsl_cast(gen, ins, "int", "ivec"); break; - case VKD3DSIH_FTOU: + case VSIR_OP_FTOU: shader_glsl_cast(gen, ins, "uint", "uvec"); break; - case VKD3DSIH_GATHER4: - case VKD3DSIH_GATHER4_PO: - case VKD3DSIH_SAMPLE: - case VKD3DSIH_SAMPLE_B: - case VKD3DSIH_SAMPLE_C: - case VKD3DSIH_SAMPLE_C_LZ: - case VKD3DSIH_SAMPLE_GRAD: - case VKD3DSIH_SAMPLE_LOD: + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_PO: + case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: + case VSIR_OP_SAMPLE_GRAD: + case VSIR_OP_SAMPLE_LOD: shader_glsl_sample(gen, ins); break; - case VKD3DSIH_GEO: - case VKD3DSIH_IGE: + case VSIR_OP_GEO: + case VSIR_OP_IGE: shader_glsl_relop(gen, ins, ">=", "greaterThanEqual"); break; - case VKD3DSIH_IF: + case VSIR_OP_IF: shader_glsl_if(gen, ins); break; - case VKD3DSIH_MAD: + case VSIR_OP_MAD: shader_glsl_intrinsic(gen, ins, "fma"); break; - case VKD3DSIH_ILT: - case VKD3DSIH_LTO: - case VKD3DSIH_ULT: + case VSIR_OP_ILT: + case VSIR_OP_LTO: + case VSIR_OP_ULT: shader_glsl_relop(gen, ins, "<", "lessThan"); break; - case VKD3DSIH_IMAX: - case VKD3DSIH_MAX: - case VKD3DSIH_UMAX: + case VSIR_OP_IMAX: + case VSIR_OP_MAX: + case VSIR_OP_UMAX: shader_glsl_intrinsic(gen, ins, "max"); break; - case VKD3DSIH_MIN: - case VKD3DSIH_UMIN: + case VSIR_OP_MIN: + case VSIR_OP_UMIN: shader_glsl_intrinsic(gen, ins, "min"); break; - case VKD3DSIH_IMUL: - shader_glsl_mul_extended(gen, ins); + case VSIR_OP_IMUL_LOW: + shader_glsl_binop(gen, ins, "*"); break; - case VKD3DSIH_INE: - case VKD3DSIH_NEU: + case VSIR_OP_INE: + case VSIR_OP_NEU: shader_glsl_relop(gen, ins, "!=", "notEqual"); break; - case VKD3DSIH_INEG: + case VSIR_OP_INEG: shader_glsl_unary_op(gen, ins, "-"); break; - case VKD3DSIH_ISHL: + case VSIR_OP_ISHL: shader_glsl_binop(gen, ins, "<<"); break; - case VKD3DSIH_ISHR: - case VKD3DSIH_USHR: + case VSIR_OP_ISHR: + case VSIR_OP_USHR: shader_glsl_binop(gen, ins, ">>"); break; - case VKD3DSIH_ITOF: - case VKD3DSIH_UTOF: + case VSIR_OP_ITOF: + case VSIR_OP_UTOF: shader_glsl_cast(gen, ins, "float", "vec"); break; - case VKD3DSIH_LD: - case VKD3DSIH_LD2DMS: + case VSIR_OP_LD: + case VSIR_OP_LD2DMS: shader_glsl_ld(gen, ins); break; - case VKD3DSIH_LD_UAV_TYPED: + case VSIR_OP_LD_UAV_TYPED: shader_glsl_load_uav_typed(gen, ins); break; - case VKD3DSIH_LOG: + case VSIR_OP_LOG: shader_glsl_intrinsic(gen, ins, "log2"); break; - case VKD3DSIH_LOOP: + case VSIR_OP_LOOP: shader_glsl_loop(gen); break; - case VKD3DSIH_MOV: + case VSIR_OP_MOV: shader_glsl_mov(gen, ins); break; - case VKD3DSIH_MOVC: + case VSIR_OP_MOVC: shader_glsl_movc(gen, ins); break; - case VKD3DSIH_MUL: + case VSIR_OP_MUL: shader_glsl_binop(gen, ins, "*"); break; - case VKD3DSIH_NOT: + case VSIR_OP_NOT: shader_glsl_unary_op(gen, ins, "~"); break; - case VKD3DSIH_OR: + case VSIR_OP_OR: shader_glsl_binop(gen, ins, "|"); break; - case VKD3DSIH_RET: + case VSIR_OP_RET: shader_glsl_ret(gen, ins); break; - case VKD3DSIH_ROUND_NE: + case VSIR_OP_ROUND_NE: shader_glsl_intrinsic(gen, ins, "roundEven"); break; - case VKD3DSIH_ROUND_NI: + case VSIR_OP_ROUND_NI: shader_glsl_intrinsic(gen, ins, "floor"); break; - case VKD3DSIH_ROUND_PI: + case VSIR_OP_ROUND_PI: shader_glsl_intrinsic(gen, ins, "ceil"); break; - case VKD3DSIH_ROUND_Z: + case VSIR_OP_ROUND_Z: shader_glsl_intrinsic(gen, ins, "trunc"); break; - case VKD3DSIH_RSQ: + case VSIR_OP_RSQ: shader_glsl_intrinsic(gen, ins, "inversesqrt"); break; - case VKD3DSIH_SQRT: + case VSIR_OP_SQRT: shader_glsl_intrinsic(gen, ins, "sqrt"); break; - case VKD3DSIH_STORE_UAV_TYPED: + case VSIR_OP_STORE_UAV_TYPED: shader_glsl_store_uav_typed(gen, ins); break; - case VKD3DSIH_SWITCH: + case VSIR_OP_SWITCH: shader_glsl_switch(gen, ins); break; - case VKD3DSIH_XOR: + case VSIR_OP_XOR: shader_glsl_binop(gen, ins, "^"); break; default: @@ -1789,22 +1766,22 @@ static void shader_glsl_generate_uav_declaration(struct vkd3d_glsl_generator *ge
switch (uav->resource_data_type) { - case VKD3D_DATA_UINT: - image_type_prefix = "u"; - read_format = "r32ui"; - break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: image_type_prefix = "i"; read_format = "r32i"; break; + case VSIR_DATA_U32: + image_type_prefix = "u"; + read_format = "r32ui"; + break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled data type %#x for UAV %u.", uav->resource_data_type, uav->register_id); /* fall through */ - case VKD3D_DATA_FLOAT: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: + case VSIR_DATA_F32: + case VSIR_DATA_SNORM: + case VSIR_DATA_UNORM: image_type_prefix = ""; read_format = "r32f"; break; @@ -2018,16 +1995,16 @@ static void shader_glsl_generate_sampler_declaration(struct vkd3d_glsl_generator
switch (srv->resource_data_type) { - case VKD3D_DATA_UINT: - sampler_type_prefix = "u"; + case VSIR_DATA_F32: + case VSIR_DATA_SNORM: + case VSIR_DATA_UNORM: + sampler_type_prefix = ""; break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: sampler_type_prefix = "i"; break; - case VKD3D_DATA_FLOAT: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: - sampler_type_prefix = ""; + case VSIR_DATA_U32: + sampler_type_prefix = "u"; break; default: vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, @@ -2313,7 +2290,7 @@ static void shader_glsl_handle_global_flags(struct vkd3d_string_buffer *buffer, flags &= ~VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL; }
- if (flags) + if (flags & ~VKD3DSGF_REFACTORING_ALLOWED) vkd3d_glsl_compiler_error(gen, VKD3D_SHADER_ERROR_GLSL_INTERNAL, "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)flags); } @@ -2348,9 +2325,9 @@ static void shader_glsl_generate_declarations(struct vkd3d_glsl_generator *gen)
static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struct vkd3d_shader_code *out) { - const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions; struct vkd3d_string_buffer *buffer = gen->buffer; - unsigned int i; + 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"); @@ -2365,9 +2342,11 @@ static int vkd3d_glsl_generator_generate(struct vkd3d_glsl_generator *gen, struc
++gen->indent; shader_glsl_shader_prologue(gen); - for (i = 0; i < instructions->count; ++i) + + it = vsir_program_iterator(&gen->program->instructions); + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - vkd3d_glsl_handle_instruction(gen, &instructions->elements[i]); + vkd3d_glsl_handle_instruction(gen, ins); }
vkd3d_string_buffer_printf(buffer, "}\n"); @@ -2465,6 +2444,9 @@ int glsl_compile(struct vsir_program *program, uint64_t config_flags, if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) return ret;
+ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0) + return ret; + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); VKD3D_ASSERT(program->has_descriptor_info);
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.c b/libs/vkd3d/libs/vkd3d-shader/hlsl.c index 653ddd2e8be..62335086e20 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.c @@ -2062,7 +2062,7 @@ struct hlsl_ir_node *hlsl_block_add_load_component(struct hlsl_ctx *ctx, struct return &load->node; }
-static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, +static struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_load *load; @@ -2098,18 +2098,23 @@ static struct hlsl_ir_node *hlsl_new_resource_load(struct hlsl_ctx *ctx, load->sampling_dim = params->sampling_dim; if (load->sampling_dim == HLSL_SAMPLER_DIM_GENERIC) load->sampling_dim = hlsl_deref_get_type(ctx, &load->resource)->sampler_dim; - return &load->node; + return load; }
struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc) { - return append_new_instr(ctx, block, hlsl_new_resource_load(ctx, params, loc)); + struct hlsl_ir_resource_load *load = hlsl_new_resource_load(ctx, params, loc); + + if (load && load->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + hlsl_src_from_node(&load->byte_offset, hlsl_block_add_uint_constant(ctx, block, 0, loc)); + + return append_new_instr(ctx, block, &load->node); }
-static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum hlsl_resource_store_type type, - const struct hlsl_deref *resource, struct hlsl_ir_node *coords, struct hlsl_ir_node *value, - const struct vkd3d_shader_location *loc) +static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, + enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, + struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) { struct hlsl_ir_resource_store *store;
@@ -2117,6 +2122,7 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h return NULL; init_node(&store->node, HLSL_IR_RESOURCE_STORE, NULL, loc); store->store_type = type; + store->writemask = writemask;
hlsl_copy_deref(ctx, &store->resource, resource); hlsl_src_from_node(&store->coords, coords); @@ -2126,9 +2132,9 @@ static struct hlsl_ir_node *hlsl_new_resource_store(struct hlsl_ctx *ctx, enum h
void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, - struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc) + struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc) { - append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, loc)); + append_new_instr(ctx, block, hlsl_new_resource_store(ctx, type, resource, coords, value, writemask, loc)); }
struct hlsl_ir_node *hlsl_new_swizzle(struct hlsl_ctx *ctx, uint32_t s, unsigned int component_count, @@ -2377,6 +2383,19 @@ bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index) return false; }
+bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index) +{ + if (index->val.node->type == HLSL_IR_LOAD) + { + struct hlsl_ir_load *load = hlsl_ir_load(index->val.node); + return load->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED; + } + + if (index->val.node->type == HLSL_IR_INDEX) + return hlsl_index_chain_has_tgsm_access(hlsl_ir_index(index->val.node)); + return false; +} + static struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) { @@ -2648,6 +2667,7 @@ static struct hlsl_ir_node *clone_resource_load(struct hlsl_ctx *ctx, vkd3d_free(dst); return NULL; } + clone_src(map, &dst->byte_offset, &src->byte_offset); clone_src(map, &dst->coords, &src->coords); clone_src(map, &dst->lod, &src->lod); clone_src(map, &dst->ddx, &src->ddx); @@ -2668,6 +2688,7 @@ static struct hlsl_ir_node *clone_resource_store(struct hlsl_ctx *ctx, return NULL; init_node(&dst->node, HLSL_IR_RESOURCE_STORE, NULL, &src->node.loc); dst->store_type = src->store_type; + dst->writemask = src->writemask; if (!clone_deref(ctx, map, &dst->resource, &src->resource)) { vkd3d_free(dst); @@ -2985,6 +3006,17 @@ bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const return ret; }
+struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) +{ + struct clone_instr_map map = {0}; + struct hlsl_ir_node *ret; + + ret = clone_instr(ctx, &map, instr); + vkd3d_free(map.instrs); + + return ret; +} + struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, struct hlsl_type *return_type, const struct hlsl_func_parameters *parameters, const struct hlsl_semantic *semantic, const struct vkd3d_shader_location *loc) @@ -2998,7 +3030,6 @@ struct hlsl_ir_function_decl *hlsl_new_func_decl(struct hlsl_ctx *ctx, decl->return_type = return_type; decl->parameters = *parameters; decl->loc = *loc; - list_init(&decl->extern_vars);
if (!hlsl_types_are_equal(return_type, ctx->builtin_types.Void)) { @@ -3220,12 +3251,14 @@ static void hlsl_dump_type(struct vkd3d_string_buffer *buffer, const struct hlsl return; }
- VKD3D_ASSERT(hlsl_is_numeric_type(type->e.resource.format)); - VKD3D_ASSERT(type->e.resource.format->e.numeric.type < ARRAY_SIZE(base_types)); if (type->sampler_dim == HLSL_SAMPLER_DIM_BUFFER) { vkd3d_string_buffer_printf(buffer, "Buffer<"); } + else if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + { + vkd3d_string_buffer_printf(buffer, "StructuredBuffer<"); + } else { VKD3D_ASSERT(type->sampler_dim < ARRAY_SIZE(dimensions)); @@ -3531,21 +3564,7 @@ static void dump_deref(struct vkd3d_string_buffer *buffer, const struct hlsl_der
const char *debug_hlsl_writemask(unsigned int writemask) { - static const char components[] = {'x', 'y', 'z', 'w'}; - char string[5]; - unsigned int i = 0, pos = 0; - - VKD3D_ASSERT(!(writemask & ~VKD3DSP_WRITEMASK_ALL)); - - while (writemask) - { - if (writemask & 1) - string[pos++] = components[i]; - writemask >>= 1; - i++; - } - string[pos] = '\0'; - return vkd3d_dbg_sprintf(".%s", string); + return debug_vsir_writemask(writemask); }
const char *debug_hlsl_swizzle(uint32_t swizzle, unsigned int size) @@ -3652,6 +3671,7 @@ const char *debug_hlsl_expr_op(enum hlsl_ir_expr_op op) [HLSL_OP1_LOG2] = "log2", [HLSL_OP1_LOGIC_NOT] = "!", [HLSL_OP1_NEG] = "-", + [HLSL_OP1_NOISE] = "noise", [HLSL_OP1_RCP] = "rcp", [HLSL_OP1_REINTERPRET] = "reinterpret", [HLSL_OP1_ROUND] = "round", @@ -3776,6 +3796,11 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru dump_deref(buffer, &load->resource); vkd3d_string_buffer_printf(buffer, ", sampler = "); dump_deref(buffer, &load->sampler); + if (load->byte_offset.node) + { + vkd3d_string_buffer_printf(buffer, ", byte_offset = "); + dump_src(buffer, &load->byte_offset); + } if (load->coords.node) { vkd3d_string_buffer_printf(buffer, ", coords = "); @@ -3814,7 +3839,8 @@ static void dump_ir_resource_load(struct vkd3d_string_buffer *buffer, const stru vkd3d_string_buffer_printf(buffer, ")"); }
-static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) +static void dump_ir_resource_store(struct hlsl_ctx *ctx, + struct vkd3d_string_buffer *buffer, const struct hlsl_ir_resource_store *store) { static const char *const type_names[] = { @@ -3826,6 +3852,8 @@ static void dump_ir_resource_store(struct vkd3d_string_buffer *buffer, const str VKD3D_ASSERT(store->store_type < ARRAY_SIZE(type_names)); vkd3d_string_buffer_printf(buffer, "%s(resource = ", type_names[store->store_type]); dump_deref(buffer, &store->resource); + if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->resource))) + vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); if (store->coords.node) { vkd3d_string_buffer_printf(buffer, ", coords = "); @@ -3844,11 +3872,11 @@ static void dump_ir_string(struct vkd3d_string_buffer *buffer, const struct hlsl vkd3d_string_buffer_printf(buffer, ""%s"", debugstr_a(string->string)); }
-static void dump_ir_store(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store) +static void dump_ir_store(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_store *store) { vkd3d_string_buffer_printf(buffer, "= ("); dump_deref(buffer, &store->lhs); - if (store->writemask != VKD3DSP_WRITEMASK_ALL) + if (store->writemask != VKD3DSP_WRITEMASK_ALL && type_is_single_reg(hlsl_deref_get_type(ctx, &store->lhs))) vkd3d_string_buffer_printf(buffer, "%s", debug_hlsl_writemask(store->writemask)); vkd3d_string_buffer_printf(buffer, " "); dump_src(buffer, &store->rhs); @@ -4038,7 +4066,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, break;
case HLSL_IR_RESOURCE_STORE: - dump_ir_resource_store(buffer, hlsl_ir_resource_store(instr)); + dump_ir_resource_store(ctx, buffer, hlsl_ir_resource_store(instr)); break;
case HLSL_IR_STRING_CONSTANT: @@ -4046,7 +4074,7 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, break;
case HLSL_IR_STORE: - dump_ir_store(buffer, hlsl_ir_store(instr)); + dump_ir_store(ctx, buffer, hlsl_ir_store(instr)); break;
case HLSL_IR_SWITCH: @@ -4079,20 +4107,23 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, } }
-void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func) +void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, + const char *description, const struct hlsl_block *processed_block) { struct vkd3d_string_buffer buffer; size_t i;
vkd3d_string_buffer_init(&buffer); - vkd3d_string_buffer_printf(&buffer, "Dumping function %s.\n", func->func->name); + vkd3d_string_buffer_printf(&buffer, "Dumping %s "%s".\n", description, func->func->name); vkd3d_string_buffer_printf(&buffer, "Function parameters:\n"); for (i = 0; i < func->parameters.count; ++i) { dump_ir_var(ctx, &buffer, func->parameters.vars[i]); vkd3d_string_buffer_printf(&buffer, "\n"); } - if (func->has_body) + if (processed_block) + dump_block(ctx, &buffer, processed_block); + else if (func->has_body) dump_block(ctx, &buffer, &func->body);
vkd3d_string_buffer_trace(&buffer); @@ -4137,7 +4168,7 @@ void hlsl_replace_node(struct hlsl_ir_node *old, struct hlsl_ir_node *new) const struct hlsl_type *old_type = old->data_type, *new_type = new->data_type; struct hlsl_src *src, *next;
- if (hlsl_is_numeric_type(old_type)) + if (old_type && hlsl_is_numeric_type(old_type)) { VKD3D_ASSERT(hlsl_is_numeric_type(new_type)); VKD3D_ASSERT(old_type->e.numeric.dimx == new_type->e.numeric.dimx); @@ -4241,6 +4272,7 @@ static void free_ir_resource_load(struct hlsl_ir_resource_load *load) { hlsl_cleanup_deref(&load->sampler); hlsl_cleanup_deref(&load->resource); + hlsl_src_remove(&load->byte_offset); hlsl_src_remove(&load->coords); hlsl_src_remove(&load->lod); hlsl_src_remove(&load->ddx); @@ -4865,8 +4897,9 @@ static void declare_predefined_types(struct hlsl_ctx *ctx) hlsl_release_string_buffer(ctx, name); }
-static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, - const struct hlsl_profile_info *profile, struct vkd3d_shader_message_context *message_context) +static bool hlsl_ctx_init(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_files, + const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, + struct vkd3d_shader_message_context *message_context) { unsigned int i;
@@ -4876,15 +4909,12 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
ctx->message_context = message_context;
- if (!(ctx->source_files = hlsl_alloc(ctx, sizeof(*ctx->source_files)))) - return false; - if (!(ctx->source_files[0] = hlsl_strdup(ctx, compile_info->source_name ? compile_info->source_name : "<anonymous>"))) - { - vkd3d_free(ctx->source_files); + ctx->source_files = source_files; + if (!vkd3d_shader_source_list_append(source_files, + compile_info->source_name ? compile_info->source_name : "<anonymous>")) return false; - } - ctx->source_files_count = 1; - ctx->location.source_name = ctx->source_files[0]; + + ctx->location.source_name = source_files->sources[0]; ctx->location.line = ctx->location.column = 1; vkd3d_string_buffer_cache_init(&ctx->string_buffers);
@@ -4892,8 +4922,7 @@ static bool hlsl_ctx_init(struct hlsl_ctx *ctx, const struct vkd3d_shader_compil
if (!(ctx->dummy_scope = hlsl_new_scope(ctx, NULL))) { - vkd3d_free((void *)ctx->source_files[0]); - vkd3d_free(ctx->source_files); + vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers); return false; } hlsl_push_scope(ctx); @@ -4978,9 +5007,6 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) struct hlsl_type *type, *next_type; unsigned int i;
- for (i = 0; i < ctx->source_files_count; ++i) - vkd3d_free((void *)ctx->source_files[i]); - vkd3d_free(ctx->source_files); vkd3d_string_buffer_cache_cleanup(&ctx->string_buffers);
rb_destroy(&ctx->functions, free_function_rb, NULL); @@ -5022,31 +5048,13 @@ static void hlsl_ctx_cleanup(struct hlsl_ctx *ctx) vkd3d_free(ctx->constant_defs.regs); }
-int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) +static int hlsl_ctx_parse(struct hlsl_ctx *ctx, struct vkd3d_shader_source_list *source_list, + const struct vkd3d_shader_compile_info *compile_info, const struct hlsl_profile_info *profile, + struct vkd3d_shader_message_context *message_context) { enum vkd3d_shader_target_type target_type = compile_info->target_type; - const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; - struct hlsl_ir_function_decl *decl, *entry_func = NULL; - const struct hlsl_profile_info *profile; - struct hlsl_ir_function *func; - const char *entry_point; - struct hlsl_ctx ctx; int ret;
- if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) - { - ERR("No HLSL source info given.\n"); - return VKD3D_ERROR_INVALID_ARGUMENT; - } - entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; - - if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) - { - FIXME("Unknown compilation target %s.\n", debugstr_a(hlsl_source_info->profile)); - return VKD3D_ERROR_NOT_IMPLEMENTED; - } - if (target_type != VKD3D_SHADER_TARGET_FX && profile->type == VKD3D_SHADER_TYPE_EFFECT) { vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, @@ -5072,37 +5080,115 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d return VKD3D_ERROR_INVALID_ARGUMENT; }
- if (!hlsl_ctx_init(&ctx, compile_info, profile, message_context)) + if (!hlsl_ctx_init(ctx, source_list, compile_info, profile, message_context)) return VKD3D_ERROR_OUT_OF_MEMORY;
- if ((ret = hlsl_lexer_compile(&ctx, hlsl)) == 2) + if ((ret = hlsl_lexer_compile(ctx, &compile_info->source)) == 2) { - hlsl_ctx_cleanup(&ctx); + hlsl_ctx_cleanup(ctx); return VKD3D_ERROR_OUT_OF_MEMORY; }
- if (ctx.result) + if (ctx->result) { - hlsl_ctx_cleanup(&ctx); - return ctx.result; + hlsl_ctx_cleanup(ctx); + return ctx->result; }
/* If parsing failed without an error condition being recorded, we * plausibly hit some unimplemented feature. */ if (ret) { - hlsl_ctx_cleanup(&ctx); + hlsl_ctx_cleanup(ctx); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + + return VKD3D_OK; +} + +int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out) +{ + const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; + struct vkd3d_shader_source_list source_list; + const struct hlsl_profile_info *profile; + struct hlsl_ctx ctx; + int ret; + + if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) + { + WARN("No HLSL source info given.\n"); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + + if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, + "Unknown target profile '%s'.", hlsl_source_info->profile); return VKD3D_ERROR_NOT_IMPLEMENTED; }
- if (ctx.profile->type == VKD3D_SHADER_TYPE_EFFECT) + vkd3d_shader_source_list_init(&source_list); + if ((ret = hlsl_ctx_parse(&ctx, &source_list, compile_info, profile, message_context)) < 0) { - ret = hlsl_emit_effect_binary(&ctx, out); + vkd3d_shader_source_list_cleanup(&source_list); + return ret; + }
- hlsl_ctx_cleanup(&ctx); + ret = hlsl_emit_effect_binary(&ctx, out); + hlsl_ctx_cleanup(&ctx); + vkd3d_shader_source_list_cleanup(&source_list); + + return ret; +} + +int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, + struct vsir_program *program, struct vkd3d_shader_code *reflection_data) +{ + const struct vkd3d_shader_hlsl_source_info *hlsl_source_info; + struct hlsl_ir_function_decl *decl, *entry_func = NULL; + enum vsir_normalisation_level normalisation_level; + const struct hlsl_profile_info *profile; + struct vkd3d_shader_version version; + struct hlsl_ir_function *func; + const char *entry_point; + struct hlsl_ctx ctx; + int ret; + + if (!(hlsl_source_info = vkd3d_find_struct(compile_info->next, HLSL_SOURCE_INFO))) + { + WARN("No HLSL source info given.\n"); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + + if (!(profile = hlsl_get_target_info(hlsl_source_info->profile))) + { + vkd3d_shader_error(message_context, NULL, VKD3D_SHADER_ERROR_HLSL_INVALID_PROFILE, + "Unknown target profile '%s'.", hlsl_source_info->profile); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + + version = (struct vkd3d_shader_version) + { + .type = profile->type, + .major = profile->major_version, + .minor = profile->minor_version, + }; + normalisation_level = VSIR_NORMALISED_SM4; + if (version.major < 4 && (compile_info->target_type == VKD3D_SHADER_TARGET_D3D_ASM + || compile_info->target_type == VKD3D_SHADER_TARGET_D3D_BYTECODE)) + normalisation_level = VSIR_NORMALISED_SM1; + if (!vsir_program_init(program, compile_info, &version, 0, VSIR_CF_STRUCTURED, normalisation_level)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + if ((ret = hlsl_ctx_parse(&ctx, &program->source_files, compile_info, profile, message_context)) < 0) + { + vsir_program_cleanup(program); return ret; }
+ entry_point = hlsl_source_info->entry_point ? hlsl_source_info->entry_point : "main"; if ((func = hlsl_get_function(&ctx, entry_point))) { LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) @@ -5126,46 +5212,17 @@ int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d hlsl_error(&ctx, &loc, VKD3D_SHADER_ERROR_HLSL_NOT_DEFINED, "Entry point "%s" is not defined.", entry_point); hlsl_ctx_cleanup(&ctx); + vsir_program_cleanup(program); return VKD3D_ERROR_INVALID_SHADER; }
- if (target_type == VKD3D_SHADER_TARGET_SPIRV_BINARY - || target_type == VKD3D_SHADER_TARGET_SPIRV_TEXT - || target_type == VKD3D_SHADER_TARGET_GLSL - || target_type == VKD3D_SHADER_TARGET_D3D_ASM) - { - uint64_t config_flags = vkd3d_shader_init_config_flags(); - struct vkd3d_shader_compile_info info = *compile_info; - struct vsir_program program; - - if (profile->major_version < 4) - { - if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_D3D_BYTECODE, &info.source)) < 0) - goto done; - info.source_type = VKD3D_SHADER_SOURCE_D3D_BYTECODE; - ret = d3dbc_parse(&info, config_flags, message_context, &program); - } - else - { - if ((ret = hlsl_emit_bytecode(&ctx, entry_func, VKD3D_SHADER_TARGET_DXBC_TPF, &info.source)) < 0) - goto done; - info.source_type = VKD3D_SHADER_SOURCE_DXBC_TPF; - ret = tpf_parse(&info, config_flags, message_context, &program); - } - if (ret >= 0) - { - ret = vsir_program_compile(&program, config_flags, &info, out, message_context); - vsir_program_cleanup(&program); - } - vkd3d_shader_free_shader_code(&info.source); - } + ret = hlsl_emit_vsir(&ctx, compile_info, entry_func, program, reflection_data); + hlsl_ctx_cleanup(&ctx); + if (ret < 0) + vsir_program_cleanup(program); else - { - ret = hlsl_emit_bytecode(&ctx, entry_func, target_type, out); - } + vsir_program_trace(program);
-done: - hlsl_ctx_cleanup(&ctx); return ret; }
diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.h b/libs/vkd3d/libs/vkd3d-shader/hlsl.h index 58f579cd9f9..d67f820fe8b 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.h @@ -59,8 +59,7 @@ static inline unsigned int hlsl_swizzle_get_component(uint32_t swizzle, unsigned
static inline void hlsl_swizzle_set_component(uint32_t *swizzle, unsigned int idx, unsigned int component) { - *swizzle &= ~(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(idx)); - *swizzle |= component << VKD3D_SHADER_SWIZZLE_SHIFT(idx); + vsir_swizzle_set_component(swizzle, idx, component); }
enum hlsl_type_class @@ -126,7 +125,7 @@ enum hlsl_sampler_dim HLSL_SAMPLER_DIM_STRUCTURED_BUFFER, HLSL_SAMPLER_DIM_RAW_BUFFER, HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_RAW_BUFFER, - /* NOTE: Remember to update object_methods[] in hlsl.y if this enum is modified. */ + /* NOTE: Remember to update texture_methods[] and uav_methods[] in hlsl.y if this is modified. */ };
enum hlsl_so_object_type @@ -245,6 +244,7 @@ struct hlsl_semantic { const char *name; uint32_t index; + uint32_t stream_index;
/* Name exactly as it appears in the sources. */ const char *raw_name; @@ -278,11 +278,12 @@ struct hlsl_struct_field size_t name_bytecode_offset; };
-/* Information of the register(s) allocated for an instruction node or variable. - * These values are initialized at the end of hlsl_emit_bytecode(), after the compilation passes, - * just before writing the bytecode. - * The type of register (register class) is implied from its use, so it is not stored in this - * struct. */ +/* Information about the register(s) allocated for an instruction node or + * variable. These values are initialised at the end of hlsl_emit_vsir(), + * after the compilation passes, as vsir starts being generated from HLSL IR. + * + * The type of register (register class) is implied by its usage, so it is not + * stored in this structure. */ struct hlsl_reg { /* Register number of the first register allocated. */ @@ -308,6 +309,8 @@ struct hlsl_reg unsigned int writemask; /* Whether the register has been allocated. */ bool allocated; + /* Currently only used for numeric registers. */ + enum vkd3d_shader_register_type type; };
/* Types of instruction nodes for the IR. @@ -551,6 +554,7 @@ struct hlsl_ir_var uint32_t is_param : 1; uint32_t is_separated_resource : 1; uint32_t is_synthetic : 1; + uint32_t is_tgsm : 1; uint32_t has_explicit_bind_point : 1; };
@@ -643,12 +647,6 @@ struct hlsl_ir_function_decl * executed. Needed to deal with return statements in non-uniform control * flow, since some backends can't handle them. */ struct hlsl_ir_var *early_return_var; - - /* List of all the extern semantic variables; linked by the - * hlsl_ir_var.extern_entry fields. This exists as a convenience because - * it is often necessary to iterate all extern variables and these can be - * declared in as function parameters, or as the function return value. */ - struct list extern_vars; };
struct hlsl_ir_call @@ -733,6 +731,7 @@ enum hlsl_ir_expr_op HLSL_OP1_ISINF, HLSL_OP1_LOG2, HLSL_OP1_LOGIC_NOT, + HLSL_OP1_NOISE, HLSL_OP1_NEG, HLSL_OP1_RCP, HLSL_OP1_REINTERPRET, @@ -895,7 +894,7 @@ struct hlsl_ir_resource_load struct hlsl_ir_node node; enum hlsl_resource_load_type load_type; struct hlsl_deref resource, sampler; - struct hlsl_src coords, lod, ddx, ddy, cmp, sample_index, texel_offset; + struct hlsl_src byte_offset, coords, lod, ddx, ddy, cmp, sample_index, texel_offset; enum hlsl_sampler_dim sampling_dim; };
@@ -912,6 +911,7 @@ struct hlsl_ir_resource_store enum hlsl_resource_store_type store_type; struct hlsl_deref resource; struct hlsl_src coords, value; + uint8_t writemask; };
struct hlsl_ir_store @@ -1093,8 +1093,7 @@ struct hlsl_ctx { const struct hlsl_profile_info *profile;
- const char **source_files; - unsigned int source_files_count; + struct vkd3d_shader_source_list *source_files; /* Current location being read in the HLSL source, updated while parsing. */ struct vkd3d_shader_location location; /* Stores the logging messages and logging configuration. */ @@ -1185,6 +1184,8 @@ struct hlsl_ctx } constant_defs; /* 'c' registers where the constants expected by SM2 sincos are stored. */ struct hlsl_reg d3dsincosconst1, d3dsincosconst2; + /* Number of allocated SSA IDs, used in translation to vsir. */ + unsigned int ssa_count;
/* Number of 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. */ @@ -1586,7 +1587,7 @@ struct hlsl_ir_node *hlsl_block_add_resource_load(struct hlsl_ctx *ctx, struct h const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); void hlsl_block_add_resource_store(struct hlsl_ctx *ctx, struct hlsl_block *block, enum hlsl_resource_store_type type, const struct hlsl_deref *resource, struct hlsl_ir_node *coords, - struct hlsl_ir_node *value, const struct vkd3d_shader_location *loc); + struct hlsl_ir_node *value, uint32_t writemask, const struct vkd3d_shader_location *loc); struct hlsl_ir_node *hlsl_block_add_simple_load(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_var *var, const struct vkd3d_shader_location *loc); void hlsl_block_add_simple_store(struct hlsl_ctx *ctx, struct hlsl_block *block, @@ -1609,8 +1610,10 @@ struct hlsl_ir_node *hlsl_block_add_unary_expr(struct hlsl_ctx *ctx, struct hlsl enum hlsl_ir_expr_op op, struct hlsl_ir_node *arg, const struct vkd3d_shader_location *loc); void hlsl_block_cleanup(struct hlsl_block *block); bool hlsl_clone_block(struct hlsl_ctx *ctx, struct hlsl_block *dst_block, const struct hlsl_block *src_block); +struct hlsl_ir_node *hlsl_clone_instr(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr);
-void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func); +void hlsl_dump_function(struct hlsl_ctx *ctx, const struct hlsl_ir_function_decl *func, + const char *description, const struct hlsl_block *processed_block); void hlsl_dump_ir_function_decl(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_function_decl *f); void hlsl_dump_var_default_values(const struct hlsl_ir_var *var); @@ -1625,9 +1628,10 @@ struct hlsl_state_block_entry *clone_stateblock_entry(struct hlsl_ctx *ctx,
void hlsl_lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_block *body); void hlsl_run_const_passes(struct hlsl_ctx *ctx, struct hlsl_block *body); -int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out); int hlsl_emit_effect_binary(struct hlsl_ctx *ctx, struct vkd3d_shader_code *out); +int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, + struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, + struct vkd3d_shader_code *reflection_data);
bool hlsl_init_deref(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_var *var, unsigned int path_len); bool hlsl_init_deref_from_index_chain(struct hlsl_ctx *ctx, struct hlsl_deref *deref, struct hlsl_ir_node *chain); @@ -1707,6 +1711,7 @@ struct hlsl_ir_node *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hls bool hlsl_index_is_noncontiguous(struct hlsl_ir_index *index); bool hlsl_index_is_resource_access(struct hlsl_ir_index *index); bool hlsl_index_chain_has_resource_access(struct hlsl_ir_index *index); +bool hlsl_index_chain_has_tgsm_access(struct hlsl_ir_index *index);
struct hlsl_ir_node *hlsl_new_compile(struct hlsl_ctx *ctx, enum hlsl_compile_type compile_type, const char *profile_name, struct hlsl_ir_node **args, unsigned int args_count, diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.l b/libs/vkd3d/libs/vkd3d-shader/hlsl.l index d9fd43b5e78..0cdebb8a657 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.l +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.l @@ -158,6 +158,7 @@ static {return KW_STATIC; } string {return KW_STRING; } String {return KW_STRING; } struct {return KW_STRUCT; } +StructuredBuffer {return KW_STRUCTUREDBUFFER; } switch {return KW_SWITCH; } tbuffer {return KW_TBUFFER; } (?i:technique) {return KW_TECHNIQUE; } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl.y b/libs/vkd3d/libs/vkd3d-shader/hlsl.y index 5aee1e701cd..024d96c5663 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl.y @@ -2117,7 +2117,8 @@ static bool add_assignment(struct hlsl_ctx *ctx, struct hlsl_block *block, struc VKD3D_ASSERT(coords->data_type->e.numeric.type == HLSL_TYPE_UINT); VKD3D_ASSERT(coords->data_type->e.numeric.dimx == dim_count);
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, coords, rhs, &lhs->loc); + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, + &resource_deref, coords, rhs, writemask, &lhs->loc); hlsl_cleanup_deref(&resource_deref); } else if (matrix_writemask) @@ -2559,10 +2560,17 @@ static void declare_var(struct hlsl_ctx *ctx, struct parse_variable_def *v) hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Variable '%s' is declared as both "uniform" and "static".", var->name);
+ if ((modifiers & HLSL_STORAGE_GROUPSHARED) && ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE) + { + modifiers &= ~HLSL_STORAGE_GROUPSHARED; + hlsl_warning(ctx, &var->loc, VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER, + "Ignoring the 'groupshared' modifier in a non-compute shader."); + } + /* Mark it as uniform. We need to do this here since synthetic * variables also get put in the global scope, but shouldn't be * considered uniforms, and we have no way of telling otherwise. */ - if (!(modifiers & HLSL_STORAGE_STATIC)) + if (!(modifiers & (HLSL_STORAGE_STATIC | HLSL_STORAGE_GROUPSHARED))) var->storage_modifiers |= HLSL_STORAGE_UNIFORM;
if (stream_output) @@ -4291,6 +4299,28 @@ static bool intrinsic_mul(struct hlsl_ctx *ctx, return true; }
+static bool intrinsic_noise(struct hlsl_ctx *ctx, + const struct parse_initializer *params, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = params->args[0]->data_type, *ret_type; + struct hlsl_ir_node *args[HLSL_MAX_OPERANDS] = {0}; + + type = params->args[0]->data_type; + if (type->class == HLSL_CLASS_MATRIX) + { + struct vkd3d_string_buffer *string; + if ((string = hlsl_type_to_string(ctx, type))) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Wrong argument type for noise(): expected vector or scalar, but got '%s'.", string->buffer); + hlsl_release_string_buffer(ctx, string); + } + + args[0] = intrinsic_float_convert_arg(ctx, params, params->args[0], loc); + ret_type = hlsl_get_scalar_type(ctx, args[0]->data_type->e.numeric.type); + + return !!add_expr(ctx, params->instrs, HLSL_OP1_NOISE, args, ret_type, loc); +} + static bool intrinsic_normalize(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { @@ -5033,13 +5063,25 @@ static bool intrinsic_interlocked(struct hlsl_ctx *ctx, enum hlsl_interlocked_op
if (hlsl_deref_get_type(ctx, &dst_deref)->class != HLSL_CLASS_UAV) { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Interlocked targets must be UAV or groupshared elements."); return false; } } + else if (lhs->type == HLSL_IR_INDEX && hlsl_index_chain_has_tgsm_access(hlsl_ir_index(lhs))) + { + hlsl_fixme(ctx, loc, "Interlocked operations on indexed groupshared elements."); + return false; + } + else if (lhs->type == HLSL_IR_LOAD && (hlsl_ir_load(lhs)->src.var->storage_modifiers & HLSL_STORAGE_GROUPSHARED)) + { + hlsl_init_simple_deref_from_var(&dst_deref, hlsl_ir_load(lhs)->src.var); + coords = hlsl_block_add_uint_constant(ctx, params->instrs, 0, loc); + } else { - hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Interlocked targets must be UAV elements."); + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Interlocked targets must be UAV or groupshared elements."); return false; }
@@ -5119,10 +5161,10 @@ static bool intrinsic_InterlockedXor(struct hlsl_ctx *ctx,
static void validate_group_barrier_profile(struct hlsl_ctx *ctx, const struct vkd3d_shader_location *loc) { - if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE || hlsl_version_lt(ctx, 5, 0)) + if (ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, - "Group barriers can only be used in compute shaders 5.0 or higher."); + "Group barriers can only be used in compute shaders."); } }
@@ -5146,10 +5188,10 @@ static bool intrinsic_DeviceMemoryBarrier(struct hlsl_ctx *ctx, const struct parse_initializer *params, const struct vkd3d_shader_location *loc) { if ((ctx->profile->type != VKD3D_SHADER_TYPE_COMPUTE && ctx->profile->type != VKD3D_SHADER_TYPE_PIXEL) - || hlsl_version_lt(ctx, 5, 0)) + || hlsl_version_lt(ctx, 4, 0)) { hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, - "DeviceMemoryBarrier() can only be used in pixel and compute shaders 5.0 or higher."); + "DeviceMemoryBarrier() can only be used in compute and pixel shaders 4.0 or higher."); } return !!hlsl_block_add_sync(ctx, params->instrs, VKD3DSSF_GLOBAL_UAV, loc); } @@ -5255,6 +5297,7 @@ intrinsic_functions[] = {"min", 2, true, intrinsic_min}, {"modf", 2, true, intrinsic_modf}, {"mul", 2, true, intrinsic_mul}, + {"noise", 1, true, intrinsic_noise}, {"normalize", 1, true, intrinsic_normalize}, {"pow", 2, true, intrinsic_pow}, {"radians", 1, true, intrinsic_radians}, @@ -5604,6 +5647,7 @@ static unsigned int hlsl_offset_dim_count(enum hlsl_sampler_dim dim) case HLSL_SAMPLER_DIM_CUBEARRAY: case HLSL_SAMPLER_DIM_BUFFER: case HLSL_SAMPLER_DIM_RAW_BUFFER: + case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: /* Offset parameters not supported for these types. */ return 0; default: @@ -6269,6 +6313,7 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block struct hlsl_ir_node *offset, *rhs; struct hlsl_deref resource_deref; unsigned int value_dim; + uint32_t writemask;
if (params->args_count != 2) { @@ -6290,11 +6335,12 @@ static bool add_store_method_call(struct hlsl_ctx *ctx, struct hlsl_block *block hlsl_get_scalar_type(ctx, HLSL_TYPE_UINT), loc); rhs = add_implicit_conversion(ctx, block, params->args[1], hlsl_get_vector_type(ctx, HLSL_TYPE_UINT, value_dim), loc); + writemask = vkd3d_write_mask_from_component_count(value_dim);
if (!hlsl_init_deref_from_index_chain(ctx, &resource_deref, object)) return false;
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, loc); + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &resource_deref, offset, rhs, writemask, loc); hlsl_cleanup_deref(&resource_deref);
return true; @@ -6319,7 +6365,7 @@ static bool add_so_append_method_call(struct hlsl_ctx *ctx, struct hlsl_block *b if (!(rhs = add_implicit_conversion(ctx, block, params->args[0], object->data_type->e.so.type, loc))) return false;
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, loc); + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_APPEND, &so_deref, NULL, rhs, 0, loc); hlsl_cleanup_deref(&so_deref);
return true; @@ -6340,7 +6386,7 @@ static bool add_so_restartstrip_method_call(struct hlsl_ctx *ctx, struct hlsl_bl if (!hlsl_init_deref_from_index_chain(ctx, &so_deref, object)) return false;
- hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, loc); + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STREAM_RESTART, &so_deref, NULL, NULL, 0, loc); hlsl_cleanup_deref(&so_deref);
return true; @@ -6521,19 +6567,25 @@ static bool add_object_property_access(struct hlsl_ctx *ctx, return false; }
-static void validate_texture_format_type(struct hlsl_ctx *ctx, struct hlsl_type *format, - const struct vkd3d_shader_location *loc) +static void validate_texture_format_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, + struct hlsl_type *format, const struct vkd3d_shader_location *loc) { - if (format->class > HLSL_CLASS_VECTOR) - { - struct vkd3d_string_buffer *string; + struct vkd3d_string_buffer *string;
- string = hlsl_type_to_string(ctx, format); - if (string) + if (!(string = hlsl_type_to_string(ctx, format))) + return; + + if (dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + { + if (!type_contains_only_numerics(format)) hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, - "Texture data type %s is not scalar or vector.", string->buffer); - hlsl_release_string_buffer(ctx, string); + "SRV type %s is not numeric.", string->buffer); } + else if (format->class > HLSL_CLASS_VECTOR) + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Texture data type %s is not scalar or vector.", string->buffer); + + hlsl_release_string_buffer(ctx, string); }
static bool check_continue(struct hlsl_ctx *ctx, const struct hlsl_scope *scope, const struct vkd3d_shader_location *loc) @@ -6801,6 +6853,7 @@ static void validate_uav_type(struct hlsl_ctx *ctx, enum hlsl_sampler_dim dim, %token KW_STATIC %token KW_STRING %token KW_STRUCT +%token KW_STRUCTUREDBUFFER %token KW_SWITCH %token KW_TBUFFER %token KW_TECHNIQUE @@ -7137,23 +7190,19 @@ declaration_statement_list: preproc_directive: PRE_LINE STRING { - const char **new_array = NULL; - - ctx->location.line = $1; if (strcmp($2, ctx->location.source_name)) - new_array = hlsl_realloc(ctx, ctx->source_files, - sizeof(*ctx->source_files) * (ctx->source_files_count + 1)); - - if (new_array) { - ctx->source_files = new_array; - ctx->source_files[ctx->source_files_count++] = $2; - ctx->location.source_name = $2; - } - else - { - vkd3d_free($2); + if (!vkd3d_shader_source_list_append(ctx->source_files, $2)) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + } + else + { + ctx->location.line = $1; + ctx->location.source_name = ctx->source_files->sources[ctx->source_files->count - 1]; + } } + vkd3d_free($2); }
struct_declaration_without_vars: @@ -7888,6 +7937,10 @@ texture_type: { $$ = HLSL_SAMPLER_DIM_BUFFER; } + | KW_STRUCTUREDBUFFER + { + $$ = HLSL_SAMPLER_DIM_STRUCTURED_BUFFER; + } | KW_TEXTURE1D { $$ = HLSL_SAMPLER_DIM_1D; @@ -8111,16 +8164,19 @@ type_no_void: } | texture_type { + if ($1 == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + hlsl_error(ctx, &@1, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, + "Structured buffer type requires an explicit format."); $$ = hlsl_new_texture_type(ctx, $1, hlsl_get_vector_type(ctx, HLSL_TYPE_FLOAT, 4), 0); } | texture_type '<' resource_format '>' { - validate_texture_format_type(ctx, $3, &@3); + validate_texture_format_type(ctx, $1, $3, &@3); $$ = hlsl_new_texture_type(ctx, $1, $3, 0); } | texture_ms_type '<' resource_format '>' { - validate_texture_format_type(ctx, $3, &@3); + validate_texture_format_type(ctx, $1, $3, &@3);
$$ = hlsl_new_texture_type(ctx, $1, $3, 0); } diff --git a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c index 38d5c55c26b..0b3dee4d2ce 100644 --- a/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d/libs/vkd3d-shader/hlsl_codegen.c @@ -94,6 +94,134 @@ static struct hlsl_ir_node *new_offset_from_path_index(struct hlsl_ctx *ctx, str return base_offset; }
+static unsigned int base_type_get_byte_size(enum hlsl_base_type t) +{ + switch (t) + { + case HLSL_TYPE_HALF: + case HLSL_TYPE_MIN16UINT: + case HLSL_TYPE_FLOAT: + case HLSL_TYPE_INT: + case HLSL_TYPE_UINT: + case HLSL_TYPE_BOOL: + return 4; + + case HLSL_TYPE_DOUBLE: + return 8; + } + + return 0; +} + +static unsigned int hlsl_type_get_packed_alignment(const struct hlsl_type *type) +{ + unsigned int max_align, i; + + switch (type->class) + { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + case HLSL_CLASS_MATRIX: + return base_type_get_byte_size(type->e.numeric.type); + + case HLSL_CLASS_ARRAY: + return hlsl_type_get_packed_alignment(type->e.array.type); + + case HLSL_CLASS_STRUCT: + for (i = 0, max_align = 0; i < type->e.record.field_count; ++i) + { + struct hlsl_struct_field *field = &type->e.record.fields[i]; + + max_align = max(max_align, hlsl_type_get_packed_alignment(field->type)); + } + + return max_align; + + default: + vkd3d_unreachable(); + } +} + +static unsigned int hlsl_type_get_packed_size(const struct hlsl_type *type) +{ + unsigned int size, i; + + switch (type->class) + { + case HLSL_CLASS_SCALAR: + case HLSL_CLASS_VECTOR: + return type->e.numeric.dimx * base_type_get_byte_size(type->e.numeric.type); + + case HLSL_CLASS_MATRIX: + return type->e.numeric.dimx * type->e.numeric.dimy * base_type_get_byte_size(type->e.numeric.type); + + case HLSL_CLASS_ARRAY: + return type->e.array.elements_count * hlsl_type_get_packed_size(type->e.array.type); + + case HLSL_CLASS_STRUCT: + for (i = 0, size = 0; i < type->e.record.field_count; ++i) + { + struct hlsl_struct_field *field = &type->e.record.fields[i]; + + size = align(size, hlsl_type_get_packed_alignment(field->type)) + + hlsl_type_get_packed_size(field->type); + } + size = align(size, hlsl_type_get_packed_alignment(type)); + + return size; + + default: + vkd3d_unreachable(); + } +} + +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; + + switch (type->class) + { + case HLSL_CLASS_VECTOR: + c = hlsl_block_add_uint_constant(ctx, block, base_type_get_byte_size(type->e.numeric.type), loc); + idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); + break; + + case HLSL_CLASS_MATRIX: + size = base_type_get_byte_size(type->e.numeric.type) * hlsl_type_minor_size(type); + c = hlsl_block_add_uint_constant(ctx, block, size, loc); + idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); + break; + + case HLSL_CLASS_ARRAY: + size = hlsl_type_get_packed_size(type->e.array.type); + c = hlsl_block_add_uint_constant(ctx, block, size, loc); + idx_offset = hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_MUL, c, idx); + break; + + 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)); + idx_offset = hlsl_block_add_uint_constant(ctx, block, offset, loc); + break; + + default: + vkd3d_unreachable(); + } + + return hlsl_block_add_binary_expr(ctx, block, HLSL_OP2_ADD, idx_offset, prev_offset); +} + /* TODO: remove when no longer needed, only used for replace_deref_path_with_offset() */ static struct hlsl_ir_node *new_offset_instr_from_deref(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *deref, unsigned int *offset_component, const struct vkd3d_shader_location *loc) @@ -186,30 +314,34 @@ static void prepend_uniform_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, { struct hlsl_ir_node *store; struct hlsl_ir_load *load; - struct hlsl_ir_var *temp; - char *new_name;
uniform->is_uniform = 1; list_add_tail(&ctx->extern_vars, &uniform->extern_entry);
- if (!(new_name = hlsl_sprintf_alloc(ctx, "<temp-%s>", uniform->name))) - return; - - if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type, - &uniform->loc, NULL, uniform->storage_modifiers, NULL))) + if (!uniform->temp_copy) { - vkd3d_free(new_name); - return; - } - list_add_before(&uniform->scope_entry, &temp->scope_entry); + struct hlsl_ir_var *temp; + char *new_name;
- uniform->temp_copy = temp; + if (!(new_name = hlsl_sprintf_alloc(ctx, "<temp-%s>", uniform->name))) + return; + + if (!(temp = hlsl_new_var(ctx, new_name, uniform->data_type, + &uniform->loc, NULL, uniform->storage_modifiers, NULL))) + { + vkd3d_free(new_name); + return; + } + list_add_tail(&ctx->dummy_scope->vars, &temp->scope_entry); + + uniform->temp_copy = temp; + }
if (!(load = hlsl_new_var_load(ctx, uniform, &uniform->loc))) return; list_add_head(&block->instrs, &load->node.entry);
- if (!(store = hlsl_new_simple_store(ctx, temp, &load->node))) + if (!(store = hlsl_new_simple_store(ctx, uniform->temp_copy, &load->node))) return; list_add_after(&load->node.entry, &store->entry); } @@ -233,6 +365,20 @@ static bool divert_written_uniform_derefs_to_temp(struct hlsl_ctx *ctx, struct h return true; }
+static void warn_on_field_semantic(struct hlsl_ctx *ctx, + const struct hlsl_struct_field *field, const struct hlsl_semantic *outer) +{ + if (!field->semantic.name) + return; + + if (!ascii_strcasecmp(field->semantic.name, outer->name) && field->semantic.index == outer->index) + return; + + hlsl_warning(ctx, &field->loc, VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC, + "Field semantic %s%u is overridden by outer semantic %s%u.\n", + field->semantic.name, field->semantic.index, outer->name, outer->index); +} + static void validate_field_semantic(struct hlsl_ctx *ctx, struct hlsl_struct_field *field) { if (!field->semantic.name && hlsl_is_numeric_type(hlsl_get_multiarray_element_type(field->type)) @@ -286,11 +432,12 @@ static bool types_are_semantic_equivalent(struct hlsl_ctx *ctx, const struct hls == base_type_get_semantic_equivalent(type2->e.numeric.type); }
-static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - struct hlsl_ir_var *var, struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, - uint32_t index, bool output, bool force_align, bool create, const struct vkd3d_shader_location *loc) +static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_ir_var *var, + struct hlsl_type *type, uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t stream_index, bool output, + bool force_align, bool create, const struct vkd3d_shader_location *loc) { struct hlsl_semantic new_semantic; + uint32_t index = semantic->index; struct hlsl_ir_var *ext_var; const char *prefix; char *new_name; @@ -300,10 +447,15 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir else prefix = output ? "output" : "input";
- if (!(new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index))) + if (stream_index) + new_name = hlsl_sprintf_alloc(ctx, "<%s-m%u:%s%u>", prefix, stream_index, semantic->name, index); + else + new_name = hlsl_sprintf_alloc(ctx, "<%s-%s%u>", prefix, semantic->name, index); + + if (!new_name) return NULL;
- LIST_FOR_EACH_ENTRY(ext_var, &func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(ext_var, semantic_vars, struct hlsl_ir_var, extern_entry) { if (!ascii_strcasecmp(ext_var->name, new_name)) { @@ -353,6 +505,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir return NULL; } new_semantic.index = index; + new_semantic.stream_index = stream_index; if (!(ext_var = hlsl_new_var(ctx, new_name, type, loc, &new_semantic, modifiers, NULL))) { vkd3d_free(new_name); @@ -366,7 +519,7 @@ static struct hlsl_ir_var *add_semantic_var(struct hlsl_ctx *ctx, struct hlsl_ir ext_var->is_param = var->is_param; ext_var->force_align = force_align; list_add_before(&var->scope_entry, &ext_var->scope_entry); - list_add_tail(&func->extern_vars, &ext_var->extern_entry); + list_add_tail(semantic_vars, &ext_var->extern_entry);
return ext_var; } @@ -388,9 +541,9 @@ static uint32_t combine_field_storage_modifiers(uint32_t modifiers, uint32_t fie return field_modifiers; }
-static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, +static void prepend_input_copy(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, - uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) + uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) { struct hlsl_type *type = lhs->node.data_type, *vector_type_src, *vector_type_dst; struct vkd3d_shader_location *loc = &lhs->node.loc; @@ -434,9 +587,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec return; prim_type_src->modifiers = var->data_type->modifiers & HLSL_PRIMITIVE_MODIFIERS_MASK;
- if (!(input = add_semantic_var(ctx, func, var, prim_type_src, - modifiers, semantic, semantic_index + i, false, force_align, true, loc))) + if (!(input = add_semantic_var(ctx, semantic_vars, var, prim_type_src, + modifiers, semantic, 0, false, force_align, true, loc))) return; + ++semantic->index; hlsl_init_simple_deref_from_var(&prim_deref, input);
idx = hlsl_block_add_uint_constant(ctx, block, prim_index, &var->loc); @@ -447,9 +601,10 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec } else { - if (!(input = add_semantic_var(ctx, func, var, vector_type_src, - modifiers, semantic, semantic_index + i, false, force_align, true, loc))) + if (!(input = add_semantic_var(ctx, semantic_vars, var, vector_type_src, + modifiers, semantic, 0, false, force_align, true, loc))) return; + ++semantic->index;
if (!(load = hlsl_new_var_load(ctx, input, &var->loc))) return; @@ -473,9 +628,9 @@ static void prepend_input_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_dec } }
-static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, +static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *block, uint32_t prim_index, struct hlsl_ir_load *lhs, - uint32_t modifiers, struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align) + uint32_t modifiers, struct hlsl_semantic *semantic, bool force_align) { struct vkd3d_shader_location *loc = &lhs->node.loc; struct hlsl_type *type = lhs->node.data_type; @@ -487,21 +642,31 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func { struct hlsl_ir_load *element_load; struct hlsl_struct_field *field; - uint32_t elem_semantic_index;
for (i = 0; i < hlsl_type_element_count(type); ++i) { uint32_t element_modifiers;
+ if (type->class == HLSL_CLASS_STRUCT) + loc = &type->e.record.fields[i].loc; + + c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); + + /* This redundant load is expected to be deleted later by DCE. */ + if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc))) + return; + hlsl_block_add_instr(block, &element_load->node); + if (type->class == HLSL_CLASS_ARRAY) { - elem_semantic_index = semantic_index - + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; element_modifiers = modifiers; force_align = true;
if (hlsl_type_is_primitive_array(type)) prim_index = i; + + prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, + element_load, element_modifiers, semantic, force_align); } else { @@ -511,35 +676,42 @@ static void prepend_input_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_ir_func hlsl_fixme(ctx, &field->loc, "Prepend uniform copies for resource components within structs."); continue; } - validate_field_semantic(ctx, field); - semantic = &field->semantic; - elem_semantic_index = semantic->index; - loc = &field->loc; element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); force_align = (i == 0); - }
- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); + if (semantic->name) + { + warn_on_field_semantic(ctx, field, semantic); + prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, + element_load, element_modifiers, semantic, force_align); + } + else + { + struct hlsl_semantic semantic_copy;
- /* This redundant load is expected to be deleted later by DCE. */ - if (!(element_load = hlsl_new_load_index(ctx, &lhs->src, c, loc))) - return; - hlsl_block_add_instr(block, &element_load->node); + validate_field_semantic(ctx, field);
- prepend_input_copy_recurse(ctx, func, block, prim_index, element_load, - element_modifiers, semantic, elem_semantic_index, force_align); + if (!(hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic))) + return; + prepend_input_copy_recurse(ctx, semantic_vars, block, prim_index, + element_load, element_modifiers, &semantic_copy, force_align); + hlsl_cleanup_semantic(&semantic_copy); + } + } } } else { - prepend_input_copy(ctx, func, block, prim_index, lhs, modifiers, semantic, semantic_index, force_align); + prepend_input_copy(ctx, semantic_vars, block, prim_index, lhs, modifiers, semantic, force_align); } }
/* Split inputs into two variables representing the semantic and temp registers, * and copy the former to the latter, so that writes to input variables work. */ -static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) +static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body, + struct list *semantic_vars, struct hlsl_ir_var *var) { + struct hlsl_semantic semantic_copy; struct hlsl_ir_load *load; struct hlsl_block block;
@@ -550,15 +722,20 @@ static void prepend_input_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function return; hlsl_block_add_instr(&block, &load->node);
- prepend_input_copy_recurse(ctx, func, &block, 0, load, var->storage_modifiers, - &var->semantic, var->semantic.index, false); + if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) + { + hlsl_block_cleanup(&block); + return; + } + prepend_input_copy_recurse(ctx, semantic_vars, &block, 0, load, var->storage_modifiers, &semantic_copy, false); + hlsl_cleanup_semantic(&semantic_copy);
- list_move_head(&func->body.instrs, &block.instrs); + list_move_head(&body->instrs, &block.instrs); }
static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_function_decl *func, struct hlsl_ir_load *rhs, uint32_t modifiers, - struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) + struct list *semantic_vars, struct hlsl_ir_load *rhs, uint32_t modifiers, + struct hlsl_semantic *semantic, uint32_t stream_index, bool force_align, bool create) { struct hlsl_type *type = rhs->node.data_type, *vector_type; struct vkd3d_shader_location *loc = &rhs->node.loc; @@ -587,9 +764,10 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, struct hlsl_ir_var *output; struct hlsl_ir_node *load;
- if (!(output = add_semantic_var(ctx, func, var, vector_type, - modifiers, semantic, semantic_index + i, true, force_align, create, loc))) + if (!(output = add_semantic_var(ctx, semantic_vars, var, vector_type, modifiers, + semantic, stream_index, true, force_align, create, loc))) return; + ++semantic->index;
if (type->class == HLSL_CLASS_MATRIX) { @@ -607,9 +785,9 @@ static void append_output_copy(struct hlsl_ctx *ctx, struct hlsl_block *block, } }
-static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, - struct hlsl_ir_function_decl *func, const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, - struct hlsl_semantic *semantic, uint32_t semantic_index, bool force_align, bool create) +static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block *block, struct list *semantic_vars, + const struct hlsl_type *type, struct hlsl_ir_load *rhs, uint32_t modifiers, struct hlsl_semantic *semantic, + uint32_t stream_index, bool force_align, bool create) { struct vkd3d_shader_location *loc = &rhs->node.loc; struct hlsl_ir_var *var = rhs->src.var; @@ -620,63 +798,84 @@ static void append_output_copy_recurse(struct hlsl_ctx *ctx, struct hlsl_block * { for (i = 0; i < hlsl_type_element_count(type); ++i) { - uint32_t element_modifiers, elem_semantic_index; const struct hlsl_type *element_type; struct hlsl_ir_load *element_load; struct hlsl_struct_field *field; + uint32_t element_modifiers; + + if (type->class == HLSL_CLASS_STRUCT) + loc = &type->e.record.fields[i].loc; + + c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); + if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) + return; + hlsl_block_add_instr(block, &element_load->node);
if (type->class == HLSL_CLASS_ARRAY) { - elem_semantic_index = semantic_index - + i * hlsl_type_get_array_element_reg_size(type->e.array.type, HLSL_REGSET_NUMERIC) / 4; element_type = type->e.array.type; element_modifiers = modifiers; force_align = true; + + append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, + element_modifiers, semantic, stream_index, force_align, create); } else { field = &type->e.record.fields[i]; if (hlsl_type_is_resource(field->type)) continue; - validate_field_semantic(ctx, field); - semantic = &field->semantic; - elem_semantic_index = semantic->index; - loc = &field->loc; element_type = field->type; element_modifiers = combine_field_storage_modifiers(modifiers, field->storage_modifiers); force_align = (i == 0); - }
- c = hlsl_block_add_uint_constant(ctx, block, i, &var->loc); + if (semantic->name) + { + warn_on_field_semantic(ctx, field, semantic);
- if (!(element_load = hlsl_new_load_index(ctx, &rhs->src, c, loc))) - return; - hlsl_block_add_instr(block, &element_load->node); + append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, + element_modifiers, semantic, stream_index, force_align, create); + } + else + { + struct hlsl_semantic semantic_copy; + + validate_field_semantic(ctx, field);
- append_output_copy_recurse(ctx, block, func, element_type, element_load, element_modifiers, semantic, - elem_semantic_index, force_align, create); + if (!hlsl_clone_semantic(ctx, &semantic_copy, &field->semantic)) + continue; + append_output_copy_recurse(ctx, block, semantic_vars, element_type, element_load, + element_modifiers, &semantic_copy, stream_index, force_align, create); + hlsl_cleanup_semantic(&semantic_copy); + } + } } } else { - append_output_copy(ctx, block, func, rhs, modifiers, semantic, semantic_index, force_align, create); + append_output_copy(ctx, block, semantic_vars, rhs, modifiers, semantic, stream_index, force_align, create); } }
/* Split outputs into two variables representing the temp and semantic * registers, and copy the former to the latter, so that reads from output * variables work. */ -static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, struct hlsl_ir_var *var) +static void append_output_var_copy(struct hlsl_ctx *ctx, struct hlsl_block *body, + struct list *semantic_vars, struct hlsl_ir_var *var) { + struct hlsl_semantic semantic_copy; struct hlsl_ir_load *load;
/* This redundant load is expected to be deleted later by DCE. */ if (!(load = hlsl_new_var_load(ctx, var, &var->loc))) return; - hlsl_block_add_instr(&func->body, &load->node); + hlsl_block_add_instr(body, &load->node);
- append_output_copy_recurse(ctx, &func->body, func, var->data_type, load, var->storage_modifiers, - &var->semantic, var->semantic.index, false, true); + if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) + return; + append_output_copy_recurse(ctx, body, semantic_vars, var->data_type, + load, var->storage_modifiers, &semantic_copy, 0, false, true); + hlsl_cleanup_semantic(&semantic_copy); }
bool hlsl_transform_ir(struct hlsl_ctx *ctx, bool (*func)(struct hlsl_ctx *ctx, struct hlsl_ir_node *, void *), @@ -1237,6 +1436,73 @@ static bool lower_index_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, return true; }
+ if (val->type == HLSL_IR_RESOURCE_LOAD) + { + struct hlsl_ir_resource_load *parent = hlsl_ir_resource_load(index->val.node); + + if (parent->sampling_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + { + if (hlsl_index_is_noncontiguous(index)) + { + /* For column major matrices, since we have to output a row, + * we need to emit dimx loads. */ + struct hlsl_ir_node *mat = index->val.node; + struct hlsl_deref row_deref; + + if (!(var = hlsl_new_synthetic_var(ctx, "row", instr->data_type, &instr->loc))) + return false; + hlsl_init_simple_deref_from_var(&row_deref, var); + + for (unsigned int i = 0; i < mat->data_type->e.numeric.dimx; ++i) + { + struct hlsl_type *type = parent->node.data_type; + struct hlsl_ir_node *c, *c_offset, *idx_offset; + struct hlsl_ir_resource_load *column_load; + + c = hlsl_block_add_uint_constant(ctx, block, i, &instr->loc); + c_offset = hlsl_block_add_packed_index_offset_append(ctx, + block, parent->byte_offset.node, c, type, &instr->loc); + type = hlsl_get_element_type_from_path_index(ctx, type, c); + + idx_offset = hlsl_block_add_packed_index_offset_append(ctx, + block, c_offset, index->idx.node, type, &instr->loc); + type = hlsl_get_element_type_from_path_index(ctx, type, c_offset); + + column_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); + + hlsl_src_remove(&column_load->byte_offset); + hlsl_src_from_node(&column_load->byte_offset, idx_offset); + column_load->node.data_type = type; + + hlsl_block_add_instr(block, &column_load->node); + + hlsl_block_add_store_component(ctx, block, &row_deref, i, &column_load->node); + } + + hlsl_block_add_simple_load(ctx, block, var, &instr->loc); + } + else + { + struct hlsl_type *type = parent->node.data_type; + struct hlsl_ir_resource_load *appended_load; + struct hlsl_ir_node *idx_offset; + + idx_offset = hlsl_block_add_packed_index_offset_append(ctx, block, + parent->byte_offset.node, index->idx.node, type, &instr->loc); + appended_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &parent->node)); + type = hlsl_get_element_type_from_path_index(ctx, type, index->idx.node); + + hlsl_src_remove(&appended_load->byte_offset); + hlsl_src_from_node(&appended_load->byte_offset, idx_offset); + appended_load->node.data_type = type; + + hlsl_block_add_instr(block, &appended_load->node); + } + + return true; + } + } + if (!(var = hlsl_new_synthetic_var(ctx, "index-val", val->data_type, &instr->loc))) return false; hlsl_init_simple_deref_from_var(&var_deref, var); @@ -1315,6 +1581,67 @@ static bool lower_broadcasts(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, s return false; }
+/* Lowers loads from TGSMs to resource loads. */ +static bool lower_tgsm_loads(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_resource_load_params params = {.type = HLSL_RESOURCE_LOAD}; + const struct vkd3d_shader_location *loc = &instr->loc; + struct hlsl_ir_load *load; + struct hlsl_deref *deref; + + if (instr->type != HLSL_IR_LOAD || !hlsl_is_numeric_type(instr->data_type)) + return false; + load = hlsl_ir_load(instr); + deref = &load->src; + + if (!deref->var->is_tgsm) + return false; + + if (deref->path_len) + { + hlsl_fixme(ctx, &instr->loc, "Load from indexed TGSM."); + return false; + } + + params.resource = hlsl_block_add_simple_load(ctx, block, deref->var, loc); + params.format = instr->data_type; + params.coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); + hlsl_block_add_resource_load(ctx, block, ¶ms, loc); + + return true; +} + +/* Lowers stores to TGSMs to resource stores. */ +static bool lower_tgsm_stores(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct hlsl_block *block) +{ + struct hlsl_ir_store *store; + struct hlsl_ir_node *coords; + struct hlsl_deref res_deref; + struct hlsl_deref *deref; + + if (instr->type != HLSL_IR_STORE) + return false; + store = hlsl_ir_store(instr); + deref = &store->lhs; + + if (!deref->var->is_tgsm) + return false; + + if (deref->path_len) + { + hlsl_fixme(ctx, &instr->loc, "Store to indexed TGSM."); + return false; + } + + hlsl_init_simple_deref_from_var(&res_deref, deref->var); + coords = hlsl_block_add_uint_constant(ctx, block, 0, &instr->loc); + + hlsl_block_add_resource_store(ctx, block, HLSL_RESOURCE_STORE, &res_deref, + coords, store->rhs.node, store->writemask, &instr->loc); + + return true; +} + /* Allocate a unique, ordered index to each instruction, which will be used for * copy propagation and computing liveness ranges. * Index 0 means unused, so start at 1. */ @@ -3146,10 +3473,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins { struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(instr);
- if (!load->resource.var->is_uniform) + if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, - "Loaded resource must have a single uniform source."); + "Loaded resource must have a single uniform or groupshared source."); } else if (validate_component_index_range_from_deref(ctx, &load->resource) == DEREF_VALIDATION_NOT_CONSTANT) { @@ -3180,10 +3507,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins { struct hlsl_ir_resource_store *store = hlsl_ir_resource_store(instr);
- if (!store->resource.var->is_uniform) + if (!store->resource.var->is_uniform && !store->resource.var->is_tgsm) { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, - "Accessed resource must have a single uniform source."); + "Accessed resource must have a single uniform or groupshared source."); } else if (validate_component_index_range_from_deref(ctx, &store->resource) == DEREF_VALIDATION_NOT_CONSTANT) { @@ -3210,10 +3537,10 @@ static bool validate_dereferences(struct hlsl_ctx *ctx, struct hlsl_ir_node *ins { struct hlsl_ir_interlocked *interlocked = hlsl_ir_interlocked(instr);
- if (!interlocked->dst.var->is_uniform) + if (!interlocked->dst.var->is_uniform && !interlocked->dst.var->is_tgsm) { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_NON_STATIC_OBJECT_REF, - "Accessed resource must have a single uniform source."); + "Accessed resource must have a single uniform or groupshared source."); } else if (validate_component_index_range_from_deref(ctx, &interlocked->dst) == DEREF_VALIDATION_NOT_CONSTANT) { @@ -3359,18 +3686,20 @@ static bool split_struct_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr
struct stream_append_ctx { - struct hlsl_ir_function_decl *func; - bool created; + struct list *semantic_vars; + bool created[VKD3D_MAX_STREAM_COUNT]; };
static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { struct stream_append_ctx *append_ctx = context; struct hlsl_ir_resource_store *store; + struct hlsl_semantic semantic_copy; const struct hlsl_ir_node *rhs; const struct hlsl_type *type; struct hlsl_ir_var *var; struct hlsl_block block; + uint32_t stream_index;
if (instr->type != HLSL_IR_RESOURCE_STORE) return false; @@ -3390,24 +3719,49 @@ static bool lower_stream_appends(struct hlsl_ctx *ctx, struct hlsl_ir_node *inst }
VKD3D_ASSERT(var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated); + stream_index = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index;
- if (var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) - { - hlsl_fixme(ctx, &instr->loc, "Append to an output stream with a nonzero stream index."); - return false; - } + VKD3D_ASSERT(stream_index < ARRAY_SIZE(append_ctx->created));
hlsl_block_init(&block);
- append_output_copy_recurse(ctx, &block, append_ctx->func, type->e.so.type, hlsl_ir_load(rhs), var->storage_modifiers, - &var->semantic, var->semantic.index, false, !append_ctx->created); - append_ctx->created = true; + if (!hlsl_clone_semantic(ctx, &semantic_copy, &var->semantic)) + return false; + append_output_copy_recurse(ctx, &block, append_ctx->semantic_vars, type->e.so.type, hlsl_ir_load(rhs), + var->storage_modifiers, &semantic_copy, var->regs[HLSL_REGSET_STREAM_OUTPUTS].index, + false, !append_ctx->created[stream_index]); + hlsl_cleanup_semantic(&semantic_copy); + + append_ctx->created[stream_index] = true;
list_move_before(&instr->entry, &block.instrs); hlsl_src_remove(&store->value);
return true; +} + +static void split_resource_load(struct hlsl_ctx *ctx, struct hlsl_ir_store *store, + struct hlsl_ir_resource_load *load, const unsigned int idx, struct hlsl_type *type) +{ + struct hlsl_ir_resource_load *vector_load; + struct hlsl_ir_node *c, *idx_offset; + struct hlsl_block block; + + hlsl_block_init(&block);
+ c = hlsl_block_add_uint_constant(ctx, &block, idx, &store->node.loc); + idx_offset = hlsl_block_add_packed_index_offset_append(ctx, &block, + load->byte_offset.node, c, load->node.data_type, &store->node.loc); + + vector_load = hlsl_ir_resource_load(hlsl_clone_instr(ctx, &load->node)); + hlsl_src_remove(&vector_load->byte_offset); + hlsl_src_from_node(&vector_load->byte_offset, idx_offset); + vector_load->node.data_type = type; + hlsl_block_add_instr(&block, &vector_load->node); + + hlsl_block_add_store_index(ctx, &block, &store->lhs, c, &vector_load->node, 0, &store->node.loc); + + list_move_before(&store->node.entry, &block.instrs); }
static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -3428,16 +3782,32 @@ static bool split_matrix_copies(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr return false; element_type = hlsl_get_vector_type(ctx, type->e.numeric.type, hlsl_type_minor_size(type));
- if (rhs->type != HLSL_IR_LOAD) + if (rhs->type != HLSL_IR_LOAD && rhs->type != HLSL_IR_RESOURCE_LOAD) { hlsl_fixme(ctx, &instr->loc, "Copying from unsupported node type."); return false; }
- for (i = 0; i < hlsl_type_major_size(type); ++i) + if (rhs->type == HLSL_IR_RESOURCE_LOAD) { - if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) - return false; + /* As we forbid non-scalar or vector types in non-structured resource + * loads, this is specific to structured buffer loads. */ + struct hlsl_ir_resource_load *load = hlsl_ir_resource_load(rhs); + + VKD3D_ASSERT(hlsl_deref_get_type(ctx, &load->resource)->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER); + + for (i = 0; i < hlsl_type_major_size(type); ++i) + { + split_resource_load(ctx, store, load, i, element_type); + } + } + else + { + for (i = 0; i < hlsl_type_major_size(type); ++i) + { + if (!split_copy(ctx, store, hlsl_ir_load(rhs), i, element_type)) + return false; + } }
list_remove(&store->node.entry); @@ -3919,7 +4289,7 @@ static bool lower_separate_samples(struct hlsl_ctx *ctx, struct hlsl_ir_node *in if (load->texel_offset.node) { hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, - "Texel offsets are not supported on profiles lower than 4.0.\n"); + "Texel offsets are not supported on profiles lower than 4.0."); return false; }
@@ -5223,7 +5593,7 @@ static void dump_function(struct rb_entry *entry, void *context) LIST_FOR_EACH_ENTRY(decl, &func->overloads, struct hlsl_ir_function_decl, entry) { if (decl->has_body) - hlsl_dump_function(ctx, decl); + hlsl_dump_function(ctx, decl, "function", NULL); } }
@@ -5240,7 +5610,7 @@ static bool mark_indexable_var(struct hlsl_ctx *ctx, struct hlsl_deref *deref, return true; }
-static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) +static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_block *body) { struct hlsl_scope *scope; struct hlsl_ir_var *var; @@ -5251,7 +5621,7 @@ static void mark_indexable_vars(struct hlsl_ctx *ctx, struct hlsl_ir_function_de var->indexable = false; }
- transform_derefs(ctx, mark_indexable_var, &entry_func->body); + transform_derefs(ctx, mark_indexable_var, body); }
static char get_regset_name(enum hlsl_regset regset) @@ -5411,6 +5781,8 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop deref_mark_last_read(&load->sampler, last_read); }
+ if (load->byte_offset.node) + load->byte_offset.node->last_read = last_read; if (load->coords.node) load->coords.node->last_read = last_read; if (load->texel_offset.node) @@ -5498,7 +5870,7 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop } }
-static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func) +static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_block *body) { struct hlsl_scope *scope; struct hlsl_ir_var *var; @@ -5506,7 +5878,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl if (ctx->result) return;
- index_instructions(&entry_func->body, 1); + index_instructions(body, 1);
LIST_FOR_EACH_ENTRY(scope, &ctx->scopes, struct hlsl_scope, entry) { @@ -5514,7 +5886,7 @@ static void compute_liveness(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl var->first_write = var->last_read = 0; }
- compute_liveness_recurse(&entry_func->body, 0, 0); + compute_liveness_recurse(body, 0, 0); }
static void mark_vars_usage(struct hlsl_ctx *ctx) @@ -5648,6 +6020,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a unsigned int writemask = hlsl_combine_writemasks(available_writemask, vkd3d_write_mask_from_component_count(reg_size));
+ ret.type = VKD3DSPR_TEMP; ret.id = reg_idx; ret.writemask = hlsl_combine_writemasks(writemask, vkd3d_write_mask_from_component_count(component_count)); @@ -5658,6 +6031,7 @@ static struct hlsl_reg allocate_register(struct hlsl_ctx *ctx, struct register_a } }
+ ret.type = VKD3DSPR_TEMP; ret.id = allocator->reg_count; ret.writemask = vkd3d_write_mask_from_component_count(component_count); record_allocation(ctx, allocator, allocator->reg_count, @@ -5684,6 +6058,7 @@ static struct hlsl_reg allocate_register_with_masks(struct hlsl_ctx *ctx,
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; @@ -5729,6 +6104,7 @@ static struct hlsl_reg allocate_range(struct hlsl_ctx *ctx, struct register_allo record_allocation(ctx, allocator, reg_idx + (reg_size / 4), (1u << (reg_size % 4)) - 1, first_write, last_read, mode, vip);
+ ret.type = VKD3DSPR_TEMP; ret.id = reg_idx; ret.allocation_size = align(reg_size, 4) / 4; ret.allocated = true; @@ -5749,20 +6125,30 @@ static struct hlsl_reg allocate_numeric_registers_for_type(struct hlsl_ctx *ctx, return allocate_range(ctx, allocator, first_write, last_read, reg_size, 0, false); }
-static const char *debug_register(char class, struct hlsl_reg reg, const struct hlsl_type *type) +static const char *debug_register(struct hlsl_reg reg, const struct hlsl_type *type) { static const char writemask_offset[] = {'w','x','y','z'}; unsigned int reg_size = type->reg_size[HLSL_REGSET_NUMERIC]; + const char *class = "r";
- if (reg_size > 4) + if (reg.type == VKD3DSPR_CONST) + class = "c"; + else if (reg.type == VKD3DSPR_INPUT) + class = "v"; + else if (reg.type == VKD3DSPR_OUTPUT) + class = "o"; + else if (reg.type == VKD3DSPR_SSA) + class = "sr"; + + if (reg_size > 4 && !hlsl_type_is_patch_array(type)) { if (reg_size & 3) - return vkd3d_dbg_sprintf("%c%u-%c%u.%c", class, reg.id, class, reg.id + (reg_size / 4), + return vkd3d_dbg_sprintf("%s%u-%s%u.%c", class, reg.id, class, reg.id + (reg_size / 4), writemask_offset[reg_size & 3]);
- return vkd3d_dbg_sprintf("%c%u-%c%u", class, reg.id, class, reg.id + (reg_size / 4) - 1); + return vkd3d_dbg_sprintf("%s%u-%s%u", class, reg.id, class, reg.id + (reg_size / 4) - 1); } - return vkd3d_dbg_sprintf("%c%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); + return vkd3d_dbg_sprintf("%s%u%s", class, reg.id, debug_hlsl_writemask(reg.writemask)); }
static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) @@ -5778,6 +6164,9 @@ static bool track_object_components_sampler_dim(struct hlsl_ctx *ctx, struct hls load = hlsl_ir_resource_load(instr); var = load->resource.var;
+ if (var->is_tgsm) + return false; + regset = hlsl_deref_get_regset(ctx, &load->resource); if (!hlsl_regset_index_from_deref(ctx, &load->resource, regset, &index)) return false; @@ -5846,7 +6235,7 @@ static bool track_components_usage(struct hlsl_ctx *ctx, struct hlsl_ir_node *in { struct hlsl_ir_load *load = hlsl_ir_load(instr);
- if (!load->src.var->is_uniform) + if (!load->src.var->is_uniform && !load->src.var->is_tgsm) return false;
/* These will are handled by validate_static_object_references(). */ @@ -5902,11 +6291,12 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, struct register_allocator *allocator) { unsigned int reg_writemask = 0, dst_writemask = 0; + bool is_per_component = false;
if (instr->reg.allocated || !instr->last_read) return;
- if (instr->type == HLSL_IR_EXPR) + if (instr->type == HLSL_IR_EXPR && ctx->profile->major_version < 4) { switch (hlsl_ir_expr(instr)->op) { @@ -5920,20 +6310,42 @@ static void allocate_instr_temp_register(struct hlsl_ctx *ctx, reg_writemask = ctx->profile->major_version < 3 ? (1 << 3) - 1 : VKD3DSP_WRITEMASK_1; break;
+ case HLSL_OP1_EXP2: + case HLSL_OP1_LOG2: + case HLSL_OP1_RCP: + case HLSL_OP1_RSQ: + /* These ops can only be written one component at a time in sm1, + * so it'll take more than one instruction to fill the variable + * and thus we can't use an SSA. + * FIXME: We should probably handle this by splitting at the vsir + * level instead. */ + is_per_component = true; + break; + default: break; } }
+ 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); - else + instr->reg = allocate_register_with_masks(ctx, allocator, + instr->index, instr->last_read, reg_writemask, dst_writemask, 0, false); + else if (is_per_component) instr->reg = allocate_numeric_registers_for_type(ctx, allocator, instr->index, instr->last_read, instr->data_type); + else + { + 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_SSA; + instr->reg.id = ctx->ssa_count++; + }
TRACE("Allocated anonymous expression @%u to %s (liveness %u-%u).\n", instr->index, - debug_register('r', instr->reg, instr->data_type), instr->index, instr->last_read); + debug_register(instr->reg, instr->data_type), instr->index, instr->last_read); }
static void allocate_variable_temp_register(struct hlsl_ctx *ctx, @@ -5958,8 +6370,8 @@ static void allocate_variable_temp_register(struct hlsl_ctx *ctx, var->regs[HLSL_REGSET_NUMERIC] = allocate_numeric_registers_for_type(ctx, allocator, var->first_write, var->last_read, var->data_type);
- TRACE("Allocated %s to %s (liveness %u-%u).\n", var->name, debug_register('r', - var->regs[HLSL_REGSET_NUMERIC], var->data_type), var->first_write, var->last_read); + 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); } } } @@ -6043,6 +6455,7 @@ static bool find_constant(struct hlsl_ctx *ctx, const float *f, unsigned int cou if ((reg->allocated_mask & writemask) == writemask && !memcmp(f, ®->value.f[j], count * sizeof(float))) { + ret->type = VKD3DSPR_CONST; ret->id = reg->index; ret->allocation_size = 1; ret->writemask = writemask; @@ -6136,12 +6549,13 @@ static void allocate_const_registers_recurse(struct hlsl_ctx *ctx, if (find_constant(ctx, f, type->e.numeric.dimx, &constant->reg)) { TRACE("Reusing already allocated constant %s for @%u.\n", - debug_register('c', constant->reg, type), instr->index); + debug_register(constant->reg, type), instr->index); break; }
constant->reg = allocate_numeric_registers_for_type(ctx, allocator, 1, UINT_MAX, type); - TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register('c', constant->reg, type)); + constant->reg.type = VKD3DSPR_CONST; + TRACE("Allocated constant @%u to %s.\n", instr->index, debug_register(constant->reg, type));
for (unsigned int x = 0, i = 0; x < 4; ++x) { @@ -6238,14 +6652,16 @@ 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); - TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register('c', ctx->d3dsincosconst1, type)); + ctx->d3dsincosconst1.type = VKD3DSPR_CONST; + TRACE("Allocated D3DSINCOSCONST1 to %s.\n", debug_register(ctx->d3dsincosconst1, type)); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 0, -1.55009923e-06f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst1.id * 4 + 1, -2.17013894e-05f, &instr->loc); 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); - TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register('c', ctx->d3dsincosconst2, type)); + ctx->d3dsincosconst2.type = VKD3DSPR_CONST; + TRACE("Allocated D3DSINCOSCONST2 to %s.\n", debug_register(ctx->d3dsincosconst2, type)); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 0, -2.08333340e-02f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 1, -1.25000000e-01f, &instr->loc); record_constant(ctx, ctx->d3dsincosconst2.id * 4 + 2, 1.00000000e+00f, &instr->loc); @@ -6256,7 +6672,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_ir_function_decl *entry_func) +static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_block *body) { struct register_allocator allocator_used = {0}; struct register_allocator allocator = {0}; @@ -6293,12 +6709,13 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi record_allocation(ctx, &allocator, reg_idx + i, VKD3DSP_WRITEMASK_ALL, 1, UINT_MAX, 0, false); }
+ var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; var->regs[HLSL_REGSET_NUMERIC].id = reg_idx; var->regs[HLSL_REGSET_NUMERIC].allocation_size = reg_size / 4; var->regs[HLSL_REGSET_NUMERIC].writemask = VKD3DSP_WRITEMASK_ALL; var->regs[HLSL_REGSET_NUMERIC].allocated = true; TRACE("Allocated reserved %s to %s.\n", var->name, - debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); + debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); } }
@@ -6314,14 +6731,15 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi if (!var->regs[HLSL_REGSET_NUMERIC].allocated) { var->regs[HLSL_REGSET_NUMERIC] = allocate_range(ctx, &allocator, 1, UINT_MAX, alloc_size, 0, false); + var->regs[HLSL_REGSET_NUMERIC].type = VKD3DSPR_CONST; TRACE("Allocated %s to %s.\n", var->name, - debug_register('c', var->regs[HLSL_REGSET_NUMERIC], var->data_type)); + debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type)); } }
- allocate_const_registers_recurse(ctx, &entry_func->body, &allocator); + allocate_const_registers_recurse(ctx, body, &allocator);
- allocate_sincos_const_registers(ctx, &entry_func->body, &allocator); + allocate_sincos_const_registers(ctx, body, &allocator);
vkd3d_free(allocator.allocations); } @@ -6330,7 +6748,7 @@ static void allocate_const_registers(struct hlsl_ctx *ctx, struct hlsl_ir_functi * 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_ir_function_decl *entry_func) +static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_block *body, struct list *semantic_vars) { struct register_allocator allocator = {0}; struct hlsl_scope *scope; @@ -6341,7 +6759,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun { LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) { - if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform)) + if (!(var->is_input_semantic || var->is_output_semantic || var->is_uniform || var->is_tgsm)) memset(var->regs, 0, sizeof(var->regs)); } } @@ -6349,7 +6767,7 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun /* ps_1_* outputs are special and go in temp register 0. */ if (ctx->profile->major_version == 1 && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) { - LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { if (var->is_output_semantic) { @@ -6360,15 +6778,16 @@ static uint32_t allocate_temp_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun } }
- allocate_temp_registers_recurse(ctx, &entry_func->body, &allocator); + allocate_temp_registers_recurse(ctx, body, &allocator); vkd3d_free(allocator.allocations);
if (allocator.indexable_count) - TRACE("Declaration of function "%s" required %u temp registers, and %u indexable temps.\n", - entry_func->func->name, allocator.reg_count, allocator.indexable_count); + 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 function "%s" required %u temp registers.\n", - entry_func->func->name, allocator.reg_count); + 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; } @@ -6456,6 +6875,8 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
if ((!output && !var->last_read) || (output && !var->first_write)) return; + + optimize = false; } else { @@ -6509,17 +6930,17 @@ static void allocate_semantic_register(struct hlsl_ctx *ctx, struct hlsl_ir_var
var->regs[HLSL_REGSET_NUMERIC] = allocate_register(ctx, allocator, 1, UINT_MAX, reg_size, component_count, mode, var->force_align, vip_allocation); + var->regs[HLSL_REGSET_NUMERIC].type = output ? VKD3DSPR_OUTPUT : VKD3DSPR_INPUT;
- TRACE("Allocated %s to %s (mode %d).\n", var->name, debug_register(output ? 'o' : 'v', - var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); + TRACE("Allocated %s to %s (mode %d).\n", var->name, + debug_register(var->regs[HLSL_REGSET_NUMERIC], var->data_type), mode); } }
-static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - uint32_t *output_reg_count) +static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct list *semantic_vars, uint32_t *output_reg_count) { + struct register_allocator input_allocator = {0}, output_allocators[VKD3D_MAX_STREAM_COUNT] = {{0}}; struct register_allocator in_prim_allocator = {0}, patch_constant_out_patch_allocator = {0}; - struct register_allocator input_allocator = {0}, output_allocator = {0}; bool is_vertex_shader = ctx->profile->type == VKD3D_SHADER_TYPE_VERTEX; bool is_pixel_shader = ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL; struct hlsl_ir_var *var; @@ -6527,9 +6948,10 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun in_prim_allocator.prioritize_smaller_writemasks = true; patch_constant_out_patch_allocator.prioritize_smaller_writemasks = true; input_allocator.prioritize_smaller_writemasks = true; - output_allocator.prioritize_smaller_writemasks = true; + for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) + output_allocators[i].prioritize_smaller_writemasks = true;
- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { if (var->is_input_semantic) { @@ -6550,15 +6972,22 @@ static void allocate_semantic_registers(struct hlsl_ctx *ctx, struct hlsl_ir_fun }
if (var->is_output_semantic) - allocate_semantic_register(ctx, var, &output_allocator, true, !is_pixel_shader); + { + VKD3D_ASSERT(var->semantic.stream_index < ARRAY_SIZE(output_allocators)); + allocate_semantic_register(ctx, var, &output_allocators[var->semantic.stream_index], + true, !is_pixel_shader); + } }
- *output_reg_count = output_allocator.reg_count; + *output_reg_count = output_allocators[0].reg_count; + for (unsigned int i = 1; i < ARRAY_SIZE(output_allocators); ++i) + *output_reg_count = max(*output_reg_count, output_allocators[i].reg_count);
vkd3d_free(in_prim_allocator.allocations); vkd3d_free(patch_constant_out_patch_allocator.allocations); vkd3d_free(input_allocator.allocations); - vkd3d_free(output_allocator.allocations); + for (unsigned int i = 0; i < ARRAY_SIZE(output_allocators); ++i) + vkd3d_free(output_allocators[i].allocations); }
static const struct hlsl_buffer *get_reserved_buffer(struct hlsl_ctx *ctx, @@ -6863,7 +7292,7 @@ static const struct hlsl_ir_var *get_allocated_object(struct hlsl_ctx *ctx, enum return NULL; }
-static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, enum hlsl_regset regset) +static void allocate_objects(struct hlsl_ctx *ctx, struct list *semantic_vars, enum hlsl_regset regset) { char regset_name = get_regset_name(regset); uint32_t min_index = 0, id = 0; @@ -6871,7 +7300,7 @@ static void allocate_objects(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl
if (regset == HLSL_REGSET_UAVS && ctx->profile->type == VKD3D_SHADER_TYPE_PIXEL) { - LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { if (var->semantic.name && (!ascii_strcasecmp(var->semantic.name, "color") || !ascii_strcasecmp(var->semantic.name, "sv_target"))) @@ -6980,6 +7409,27 @@ static void allocate_stream_outputs(struct hlsl_ctx *ctx) } }
+static void allocate_tgsms(struct hlsl_ctx *ctx) +{ + struct hlsl_ir_var *var; + struct hlsl_reg *reg; + uint32_t index = 0; + + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (!var->is_tgsm || !var->bind_count[HLSL_REGSET_NUMERIC]) + continue; + + reg = &var->regs[HLSL_REGSET_NUMERIC]; + reg->space = 0; + reg->index = index; + reg->id = index; + reg->allocated = true; + + ++index; + } +} + bool hlsl_component_index_range_from_deref(struct hlsl_ctx *ctx, const struct hlsl_deref *deref, unsigned int *start, unsigned int *count) { @@ -7420,6 +7870,8 @@ static void parse_entry_function_attributes(struct hlsl_ctx *ctx, struct hlsl_ir entry_func->early_depth_test = true; else if (!strcmp(attr->name, "maxvertexcount") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY) parse_maxvertexcount_attribute(ctx, attr); + else if (!strcmp(attr->name, "instance") && profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + hlsl_fixme(ctx, &entry_func->attrs[i]->loc, "Geometry shader instance count"); else hlsl_warning(ctx, &entry_func->attrs[i]->loc, VKD3D_SHADER_WARNING_HLSL_UNKNOWN_ATTRIBUTE, "Ignoring unknown attribute "%s".", entry_func->attrs[i]->name); @@ -7715,12 +8167,10 @@ static void validate_and_record_stream_outputs(struct hlsl_ctx *ctx) reported_invalid_index = true; } } - - /* TODO: check that maxvertexcount * outputdatasize <= 1024. */ }
-static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - uint32_t output_reg_count) +static void validate_max_output_size(struct hlsl_ctx *ctx, struct list *semantic_vars, + uint32_t output_reg_count, const struct vkd3d_shader_location *loc) { unsigned int max_output_size, comp_count = 0; unsigned int *reg_comp_count; @@ -7733,7 +8183,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi if (!(reg_comp_count = hlsl_calloc(ctx, output_reg_count, sizeof(*reg_comp_count)))) return;
- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { if (!var->is_output_semantic) continue; @@ -7748,7 +8198,7 @@ static void validate_max_output_size(struct hlsl_ctx *ctx, struct hlsl_ir_functi
max_output_size = ctx->max_vertex_count * comp_count; if (max_output_size > 1024) - hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, + hlsl_error(ctx, loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT, "Max vertex count (%u) * output data component count (%u) = %u, which is greater than 1024.", ctx->max_vertex_count, comp_count, max_output_size);
@@ -7960,8 +8410,19 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog if ((!output && !var->last_read) || (output && !var->first_write)) return;
- if (!sm1_register_from_semantic_name(&program->shader_version, + if (sm1_register_from_semantic_name(&program->shader_version, var->semantic.name, var->semantic.index, output, &sysval, &type, ®ister_index)) + { + if (!vkd3d_shader_ver_ge(&program->shader_version, 3, 0)) + { + if (type == VKD3DSPR_RASTOUT) + register_index += SM1_RASTOUT_REGISTER_OFFSET; + else if (type == VKD3DSPR_ATTROUT + || (type == VKD3DSPR_INPUT && program->shader_version.type == VKD3D_SHADER_TYPE_PIXEL)) + register_index += SM1_COLOR_REGISTER_OFFSET; + } + } + else { enum vkd3d_decl_usage usage; unsigned int usage_idx; @@ -8018,6 +8479,7 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog return; } element->semantic_index = var->semantic.index; + element->stream_index = var->semantic.stream_index; element->sysval_semantic = sysval; element->component_type = component_type; element->register_index = register_index; @@ -8050,15 +8512,15 @@ static void generate_vsir_signature_entry(struct hlsl_ctx *ctx, struct vsir_prog } }
-static void generate_vsir_signature(struct hlsl_ctx *ctx, - struct vsir_program *program, struct hlsl_ir_function_decl *func) +static void generate_vsir_signature(struct hlsl_ctx *ctx, struct vsir_program *program, + struct hlsl_ir_function_decl *func, struct list *semantic_vars) { bool is_domain = program->shader_version.type == VKD3D_SHADER_TYPE_DOMAIN; struct hlsl_ir_var *var;
ctx->is_patch_constant_func = func == ctx->patch_constant_func;
- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { if (var->is_input_semantic) { @@ -8092,38 +8554,38 @@ static void generate_vsir_signature(struct hlsl_ctx *ctx, } }
-static enum vkd3d_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type) +static enum vsir_data_type vsir_data_type_from_hlsl_type(struct hlsl_ctx *ctx, const struct hlsl_type *type) { if (hlsl_version_lt(ctx, 4, 0)) - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32;
if (type->class == HLSL_CLASS_ARRAY) return vsir_data_type_from_hlsl_type(ctx, type->e.array.type); if (type->class == HLSL_CLASS_STRUCT) - return VKD3D_DATA_MIXED; + return VSIR_DATA_MIXED; if (type->class <= HLSL_CLASS_LAST_NUMERIC) { switch (type->e.numeric.type) { case HLSL_TYPE_DOUBLE: - return VKD3D_DATA_DOUBLE; + return VSIR_DATA_F64; case HLSL_TYPE_FLOAT: - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; case HLSL_TYPE_HALF: - return VKD3D_DATA_HALF; + return VSIR_DATA_F16; case HLSL_TYPE_INT: - return VKD3D_DATA_INT; + return VSIR_DATA_I32; case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: case HLSL_TYPE_MIN16UINT: - return VKD3D_DATA_UINT; + return VSIR_DATA_U32; } }
- vkd3d_unreachable(); + return VSIR_DATA_UNUSED; }
-static enum vkd3d_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, +static enum vsir_data_type vsir_data_type_from_hlsl_instruction(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) { return vsir_data_type_from_hlsl_type(ctx, instr->data_type); @@ -8141,7 +8603,6 @@ static uint32_t generate_vsir_get_src_swizzle(uint32_t src_writemask, uint32_t d static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_block *block) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins; @@ -8151,32 +8612,30 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr { const struct hlsl_constant_register *constant_reg = &ctx->constant_defs.regs[i];
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) + if (!(ins = vsir_program_append(program))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; } - - ins = &instructions->elements[instructions->count]; - if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VKD3DSIH_DEF, 1, 1)) + if (!vsir_instruction_init_with_params(program, ins, &constant_reg->loc, VSIR_OP_DEF, 1, 1)) { + vsir_instruction_init(ins, &constant_reg->loc, VSIR_OP_NOP); ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; } - ++instructions->count;
dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&dst_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].reg.idx[0].offset = constant_reg->index; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
src_param = &ins->src[0]; - vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&src_param->reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); src_param->reg.type = VKD3DSPR_IMMCONST; src_param->reg.precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; src_param->reg.non_uniform = false; - src_param->reg.data_type = VKD3D_DATA_FLOAT; + src_param->reg.data_type = VSIR_DATA_F32; src_param->reg.dimension = VSIR_DIMENSION_VEC4; for (x = 0; x < 4; ++x) src_param->reg.u.immconst_f32[x] = constant_reg->value.f[x]; @@ -8187,7 +8646,6 @@ static void sm1_generate_vsir_constant_defs(struct hlsl_ctx *ctx, struct vsir_pr static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_block *block) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; enum vkd3d_shader_resource_type resource_type; struct vkd3d_shader_register_range *range; struct vkd3d_shader_dst_param *dst_param; @@ -8234,25 +8692,18 @@ static void sm1_generate_vsir_sampler_dcls(struct hlsl_ctx *ctx, break; }
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; - } - - ins = &instructions->elements[instructions->count]; - if (!vsir_instruction_init_with_params(program, ins, &var->loc, VKD3DSIH_DCL, 0, 0)) + if (!(ins = vsir_program_append(program))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; } - ++instructions->count;
+ vsir_instruction_init(ins, &var->loc, VSIR_OP_DCL); semantic = &ins->declaration.semantic; semantic->resource_type = resource_type;
dst_param = &semantic->resource.reg; - vsir_register_init(&dst_param->reg, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&dst_param->reg, VKD3DSPR_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; @@ -8297,32 +8748,31 @@ static enum vkd3d_shader_register_type sm4_get_semantic_register_type(enum vkd3d return VKD3DSPR_INPUT; }
-static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction( - struct hlsl_ctx *ctx, struct vsir_program *program, - const struct vkd3d_shader_location *loc, enum vkd3d_shader_opcode opcode, - unsigned int dst_count, unsigned int src_count) +static struct vkd3d_shader_instruction *generate_vsir_add_program_instruction(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct vkd3d_shader_location *loc, + enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; struct vkd3d_shader_instruction *ins;
- if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) + if (!(ins = vsir_program_append(program))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return NULL; } - ins = &instructions->elements[instructions->count]; + if (!vsir_instruction_init_with_params(program, ins, loc, opcode, dst_count, src_count)) { + vsir_instruction_init(ins, loc, VSIR_OP_NOP); ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return NULL; } - ++instructions->count; + return ins; }
static void vsir_src_from_hlsl_constant_value(struct vkd3d_shader_src_param *src, struct hlsl_ctx *ctx, const struct hlsl_constant_value *value, - enum vkd3d_data_type type, unsigned int width, unsigned int map_writemask) + enum vsir_data_type type, unsigned int width, unsigned int map_writemask) { unsigned int i, j;
@@ -8357,7 +8807,7 @@ static void vsir_src_from_hlsl_node(struct vkd3d_shader_src_param *src, } else { - vsir_register_init(&src->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); + vsir_register_init(&src->reg, instr->reg.type, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); src->reg.idx[0].offset = instr->reg.id; src->reg.dimension = VSIR_DIMENSION_VEC4; src->swizzle = generate_vsir_get_src_swizzle(instr->reg.writemask, map_writemask); @@ -8424,6 +8874,8 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p const struct hlsl_type *data_type = hlsl_deref_get_type(ctx, deref); const struct hlsl_ir_var *var = deref->var;
+ reg->data_type = vsir_data_type_from_hlsl_type(ctx, data_type); + if (var->is_uniform) { enum hlsl_regset regset = hlsl_deref_get_regset(ctx, deref); @@ -8432,18 +8884,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p { reg->type = VKD3DSPR_RESOURCE; reg->dimension = VSIR_DIMENSION_VEC4; - if (vkd3d_shader_ver_ge(version, 5, 1)) - { - reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; - reg->idx[1].offset = var->regs[HLSL_REGSET_TEXTURES].index; /* FIXME: array index */ - reg->idx_count = 2; - } - else - { - reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].index; - reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); - reg->idx_count = 1; - } + reg->idx[0].offset = var->regs[HLSL_REGSET_TEXTURES].id; + reg->idx[1].offset = var->regs[HLSL_REGSET_TEXTURES].index; + reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref); + reg->idx_count = 2; VKD3D_ASSERT(regset == HLSL_REGSET_TEXTURES); *writemask = VKD3DSP_WRITEMASK_ALL; } @@ -8451,18 +8895,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p { reg->type = VKD3DSPR_UAV; reg->dimension = VSIR_DIMENSION_VEC4; - if (vkd3d_shader_ver_ge(version, 5, 1)) - { - reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; - reg->idx[1].offset = var->regs[HLSL_REGSET_UAVS].index; /* FIXME: array index */ - reg->idx_count = 2; - } - else - { - reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].index; - reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); - reg->idx_count = 1; - } + reg->idx[0].offset = var->regs[HLSL_REGSET_UAVS].id; + reg->idx[1].offset = var->regs[HLSL_REGSET_UAVS].index; + reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref); + reg->idx_count = 2; VKD3D_ASSERT(regset == HLSL_REGSET_UAVS); *writemask = VKD3DSP_WRITEMASK_ALL; } @@ -8470,21 +8906,21 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p { reg->type = VKD3DSPR_SAMPLER; reg->dimension = VSIR_DIMENSION_NONE; - if (vkd3d_shader_ver_ge(version, 5, 1)) - { - reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; - reg->idx[1].offset = var->regs[HLSL_REGSET_SAMPLERS].index; /* FIXME: array index */ - reg->idx_count = 2; - } - else - { - reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].index; - reg->idx[0].offset += hlsl_offset_from_deref_safe(ctx, deref); - reg->idx_count = 1; - } + reg->idx[0].offset = var->regs[HLSL_REGSET_SAMPLERS].id; + reg->idx[1].offset = var->regs[HLSL_REGSET_SAMPLERS].index; + reg->idx[1].offset += hlsl_offset_from_deref_safe(ctx, deref); + reg->idx_count = 2; VKD3D_ASSERT(regset == HLSL_REGSET_SAMPLERS); *writemask = VKD3DSP_WRITEMASK_ALL; } + else if (regset == HLSL_REGSET_STREAM_OUTPUTS) + { + reg->type = VKD3DSPR_STREAM; + reg->dimension = VSIR_DIMENSION_NONE; + reg->idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; + reg->idx_count = 1; + *writemask = VKD3DSP_WRITEMASK_ALL; + } else { unsigned int offset = deref->const_offset + var->buffer_offset; @@ -8492,19 +8928,10 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p VKD3D_ASSERT(data_type->class <= HLSL_CLASS_VECTOR); reg->type = VKD3DSPR_CONSTBUFFER; reg->dimension = VSIR_DIMENSION_VEC4; - if (vkd3d_shader_ver_ge(version, 5, 1)) - { - reg->idx[0].offset = var->buffer->reg.id; - reg->idx[1].offset = var->buffer->reg.index; /* FIXME: array index */ - reg->idx[2].offset = offset / 4; - reg->idx_count = 3; - } - else - { - reg->idx[0].offset = var->buffer->reg.index; - reg->idx[1].offset = offset / 4; - reg->idx_count = 2; - } + reg->idx[0].offset = var->buffer->reg.id; + reg->idx[1].offset = var->buffer->reg.index; /* FIXME: array index */ + reg->idx[2].offset = offset / 4; + reg->idx_count = 3;
if (deref->rel_offset.node) { @@ -8594,6 +9021,15 @@ static bool sm4_generate_vsir_reg_from_deref(struct hlsl_ctx *ctx, struct vsir_p *writemask = hlsl_reg.writemask; } } + else if (var->is_tgsm) + { + VKD3D_ASSERT(var->regs[HLSL_REGSET_NUMERIC].allocated); + reg->type = VKD3DSPR_GROUPSHAREDMEM; + reg->dimension = VSIR_DIMENSION_VEC4; + reg->idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; + reg->idx_count = 1; + *writemask = (1u << data_type->e.numeric.dimx) - 1; + } else { return sm4_generate_vsir_numeric_reg_from_deref(ctx, program, reg, writemask, deref); @@ -8630,7 +9066,7 @@ static void vsir_dst_from_hlsl_node(struct vkd3d_shader_dst_param *dst, struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr) { VKD3D_ASSERT(instr->reg.allocated); - vsir_dst_param_init(dst, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); + vsir_dst_param_init(dst, instr->reg.type, vsir_data_type_from_hlsl_instruction(ctx, instr), 1); dst->reg.idx[0].offset = instr->reg.id; dst->reg.dimension = VSIR_DIMENSION_VEC4; dst->write_mask = instr->reg.writemask; @@ -8646,11 +9082,11 @@ static void sm1_generate_vsir_instr_constant(struct hlsl_ctx *ctx, VKD3D_ASSERT(instr->reg.allocated); VKD3D_ASSERT(constant->reg.allocated);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) return;
src_param = &ins->src[0]; - vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = constant->reg.id; src_param->swizzle = generate_vsir_get_src_swizzle(constant->reg.writemask, instr->reg.writemask); @@ -8665,14 +9101,14 @@ static void sm4_generate_vsir_rasterizer_sample_count(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr = &expr->node; struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SAMPLE_INFO, 1, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SAMPLE_INFO, 1, 1))) return; ins->flags = VKD3DSI_SAMPLE_INFO_UINT;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
src_param = &ins->src[0]; - vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VKD3D_DATA_UNUSED, 0); + vsir_src_param_init(src_param, VKD3DSPR_RASTERIZER, VSIR_DATA_UNUSED, 0); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); } @@ -8740,13 +9176,13 @@ static void sm1_generate_vsir_instr_expr_per_component_instr_op(struct hlsl_ctx return;
dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&dst_param->reg, instr->reg.type, VSIR_DATA_F32, 1); dst_param->reg.idx[0].offset = instr->reg.id; dst_param->reg.dimension = VSIR_DIMENSION_VEC4; dst_param->write_mask = 1u << i;
src_param = &ins->src[0]; - vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&src_param->reg, operand->reg.type, VSIR_DATA_F32, 1); src_param->reg.idx[0].offset = operand->reg.id; src_param->reg.dimension = VSIR_DIMENSION_VEC4; c = vsir_swizzle_get_component(src_swizzle, i); @@ -8767,7 +9203,7 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi VKD3D_ASSERT(instr->reg.allocated); src_count = (ctx->profile->major_version < 3) ? 3 : 1;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SINCOS, 1, src_count))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SINCOS, 1, src_count))) return;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); @@ -8776,13 +9212,13 @@ static void sm1_generate_vsir_instr_expr_sincos(struct hlsl_ctx *ctx, struct vsi if (ctx->profile->major_version < 3) { src_param = &ins->src[1]; - vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = ctx->d3dsincosconst1.id; src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
src_param = &ins->src[2]; - vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&src_param->reg, VKD3DSPR_CONST, VSIR_DATA_F32, 1); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = ctx->d3dsincosconst2.id; src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE; @@ -8816,13 +9252,13 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, /* Integrals are internally represented as floats, so no change is necessary.*/ case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true;
case HLSL_TYPE_DOUBLE: if (ctx->double_as_float_alias) { - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true; } hlsl_error(ctx, &instr->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, @@ -8847,7 +9283,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: case HLSL_TYPE_BOOL: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true;
case HLSL_TYPE_DOUBLE: @@ -8860,7 +9296,7 @@ static bool sm1_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true; break;
@@ -8899,7 +9335,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr switch (expr->op) { case HLSL_OP1_ABS: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ABS, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ABS, 0, 0, true); break;
case HLSL_OP1_CAST: @@ -8915,53 +9351,53 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr case HLSL_OP1_DSX: if (!hlsl_type_is_floating_point(type)) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX, 0, 0, true); break;
case HLSL_OP1_DSY: if (!hlsl_type_is_floating_point(type)) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY, 0, 0, true); break;
case HLSL_OP1_EXP2: if (!hlsl_type_is_floating_point(type)) goto err; - sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_EXP); + sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_EXP); break;
case HLSL_OP1_LOG2: if (!hlsl_type_is_floating_point(type)) goto err; - sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_LOG); + sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_LOG); break;
case HLSL_OP1_NEG: if (type->e.numeric.type == HLSL_TYPE_BOOL) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_NEG, 0, true); break;
case HLSL_OP1_RCP: if (!hlsl_type_is_floating_point(type)) goto err; - sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RCP); + sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_RCP); break;
case HLSL_OP1_REINTERPRET: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); break;
case HLSL_OP1_RSQ: if (!hlsl_type_is_floating_point(type)) goto err; - sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VKD3DSIH_RSQ); + sm1_generate_vsir_instr_expr_per_component_instr_op(ctx, program, expr, VSIR_OP_RSQ); break;
case HLSL_OP1_SAT: if (!hlsl_type_is_floating_point(type)) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, VKD3DSPDM_SATURATE, true); break;
case HLSL_OP1_SIN_REDUCED: @@ -8974,7 +9410,7 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr case HLSL_OP2_ADD: if (type->e.numeric.type == HLSL_TYPE_BOOL) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ADD, 0, 0, true); break;
case HLSL_OP2_DOT: @@ -8983,11 +9419,11 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr switch (expr->operands[0].node->data_type->e.numeric.dimx) { case 3: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP3, 0, 0, false); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP3, 0, 0, false); break;
case 4: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP4, 0, 0, false); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP4, 0, 0, false); break;
default: @@ -8997,55 +9433,55 @@ static bool sm1_generate_vsir_instr_expr(struct hlsl_ctx *ctx, struct vsir_progr break;
case HLSL_OP2_MAX: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true); break;
case HLSL_OP2_MIN: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true); break;
case HLSL_OP2_MUL: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MUL, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MUL, 0, 0, true); break;
case HLSL_OP1_FRACT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FRC, 0, 0, true); break;
case HLSL_OP2_LOGIC_AND: if (type->e.numeric.type != HLSL_TYPE_BOOL) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true); break;
case HLSL_OP2_LOGIC_OR: if (type->e.numeric.type != HLSL_TYPE_BOOL) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true); break;
case HLSL_OP2_SLT: if (!hlsl_type_is_floating_point(type)) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SLT, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_SLT, 0, 0, true); break;
case HLSL_OP3_CMP: if (!hlsl_type_is_floating_point(type)) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_CMP, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_CMP, 0, 0, true); break;
case HLSL_OP3_DP2ADD: if (!hlsl_type_is_floating_point(type)) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2ADD, 0, 0, false); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP2ADD, 0, 0, false); break;
case HLSL_OP3_MAD: if (!hlsl_type_is_floating_point(type)) goto err; - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAD, 0, 0, true); break;
default: @@ -9107,12 +9543,12 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx,
if (type == VKD3DSPR_DEPTHOUT) { - vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0); dst_param->reg.dimension = VSIR_DIMENSION_SCALAR; } else { - vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1); dst_param->reg.idx[0].offset = register_index; dst_param->reg.dimension = VSIR_DIMENSION_VEC4; } @@ -9125,7 +9561,7 @@ static void sm1_generate_vsir_init_dst_param_from_deref(struct hlsl_ctx *ctx, static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx, struct vsir_program *program, struct hlsl_ir_node *instr) { - enum vkd3d_shader_opcode opcode = hlsl_version_ge(ctx, 2, 0) ? VKD3DSIH_MOVA : VKD3DSIH_MOV; + enum vkd3d_shader_opcode opcode = hlsl_version_ge(ctx, 2, 0) ? VSIR_OP_MOVA : VSIR_OP_MOV; struct vkd3d_shader_dst_param *dst_param; struct vkd3d_shader_instruction *ins;
@@ -9135,7 +9571,7 @@ static void sm1_generate_vsir_instr_mova(struct hlsl_ctx *ctx, return;
dst_param = &ins->dst[0]; - vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&dst_param->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0); dst_param->write_mask = VKD3DSP_WRITEMASK_0;
VKD3D_ASSERT(instr->data_type->class <= HLSL_CLASS_VECTOR); @@ -9155,7 +9591,7 @@ static struct vkd3d_shader_src_param *sm1_generate_vsir_new_address_src(struct h }
memset(idx_src, 0, sizeof(*idx_src)); - vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&idx_src->reg, VKD3DSPR_ADDR, VSIR_DATA_F32, 0); idx_src->reg.dimension = VSIR_DIMENSION_VEC4; idx_src->swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); return idx_src; @@ -9234,7 +9670,7 @@ static void sm1_generate_vsir_init_src_param_from_deref(struct hlsl_ctx *ctx, writemask = reg.writemask; }
- vsir_register_init(&src_param->reg, type, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&src_param->reg, type, VSIR_DATA_F32, 1); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->reg.idx[0].offset = register_index; src_param->reg.idx[0].rel_addr = src_rel_addr; @@ -9252,7 +9688,7 @@ static void sm1_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr if (load->src.rel_offset.node) sm1_generate_vsir_instr_mova(ctx, program, load->src.rel_offset.node);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) return;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); @@ -9279,21 +9715,25 @@ static void sm1_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, switch (load->load_type) { case HLSL_RESOURCE_SAMPLE: - opcode = VKD3DSIH_TEX; + opcode = VSIR_OP_TEXLD; break;
case HLSL_RESOURCE_SAMPLE_PROJ: - opcode = VKD3DSIH_TEX; + opcode = VSIR_OP_TEXLD; flags |= VKD3DSI_TEXLD_PROJECT; break;
+ case HLSL_RESOURCE_SAMPLE_LOD: + opcode = VSIR_OP_TEXLDL; + break; + case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - opcode = VKD3DSIH_TEX; + opcode = VSIR_OP_TEXLD; flags |= VKD3DSI_TEXLD_BIAS; break;
case HLSL_RESOURCE_SAMPLE_GRAD: - opcode = VKD3DSIH_TEXLDD; + opcode = VSIR_OP_TEXLDD; src_count += 2; break;
@@ -9334,7 +9774,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx,
VKD3D_ASSERT(instr->reg.allocated);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) return;
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); @@ -9345,7 +9785,7 @@ static void generate_vsir_instr_swizzle(struct hlsl_ctx *ctx,
src_param = &ins->src[0]; VKD3D_ASSERT(val->type != HLSL_IR_CONSTANT); - vsir_register_init(&src_param->reg, VKD3DSPR_TEMP, vsir_data_type_from_hlsl_instruction(ctx, val), 1); + vsir_register_init(&src_param->reg, val->reg.type, vsir_data_type_from_hlsl_instruction(ctx, val), 1); src_param->reg.idx[0].offset = val->reg.id; src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->swizzle = swizzle; @@ -9359,7 +9799,7 @@ static void sm1_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vsir_prog struct vkd3d_shader_instruction *ins; struct vkd3d_shader_src_param *src_param;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) return;
sm1_generate_vsir_init_dst_param_from_deref(ctx, &ins->dst[0], &store->lhs, &ins->location, store->writemask); @@ -9377,7 +9817,7 @@ static void sm1_generate_vsir_instr_jump(struct hlsl_ctx *ctx,
if (jump->type == HLSL_IR_JUMP_DISCARD_NEG) { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_TEXKILL, 0, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_TEXKILL, 0, 1))) return;
vsir_src_from_hlsl_node(&ins->src[0], ctx, condition, VKD3DSP_WRITEMASK_ALL); @@ -9404,7 +9844,7 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program } VKD3D_ASSERT(condition->data_type->e.numeric.dimx == 1 && condition->data_type->e.numeric.dimy == 1);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IFC, 0, 2))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_IFC, 0, 2))) return; ins->flags = VKD3D_SHADER_REL_OP_NE;
@@ -9418,12 +9858,12 @@ static void sm1_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
sm1_generate_vsir_block(ctx, &iff->then_block, program);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ELSE, 0, 0))) return;
sm1_generate_vsir_block(ctx, &iff->else_block, program);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDIF, 0, 0))) return; }
@@ -9486,33 +9926,30 @@ static void sm1_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo } }
-static void sm1_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - uint64_t config_flags, struct vsir_program *program) +static void sm1_generate_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, + struct hlsl_ir_function_decl *func, struct list *semantic_vars, + struct hlsl_block *body, uint64_t config_flags, struct vsir_program *program) { - struct vkd3d_shader_version version = {0}; struct hlsl_block block;
- version.major = ctx->profile->major_version; - version.minor = ctx->profile->minor_version; - version.type = ctx->profile->type; - if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) - { - ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; - return; - } - - program->temp_count = allocate_temp_registers(ctx, entry_func); + program->ssa_count = 0; + program->temp_count = allocate_temp_registers(ctx, body, semantic_vars); if (ctx->result) return;
- generate_vsir_signature(ctx, program, entry_func); - hlsl_block_init(&block); sm1_generate_vsir_constant_defs(ctx, program, &block); sm1_generate_vsir_sampler_dcls(ctx, program, &block); - list_move_head(&entry_func->body.instrs, &block.instrs); + list_move_head(&body->instrs, &block.instrs); + + sm1_generate_vsir_block(ctx, body, program);
- sm1_generate_vsir_block(ctx, &entry_func->body, program); + program->ssa_count = ctx->ssa_count; + + if (ctx->result) + return; + if (program->normalisation_level >= VSIR_NORMALISED_SM4) + ctx->result = vsir_program_lower_d3dbc(program, config_flags, compile_info, ctx->message_context); }
D3DXPARAMETER_CLASS hlsl_sm1_class(const struct hlsl_type *type) @@ -9922,6 +10359,57 @@ static void sm1_generate_ctab(struct hlsl_ctx *ctx, struct vkd3d_shader_code *ct ctab->size = buffer.size; }
+static enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, + unsigned int index) +{ + switch (sysval) + { + case VKD3D_SHADER_SV_COVERAGE: + case VKD3D_SHADER_SV_DEPTH: + case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: + case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: + case VKD3D_SHADER_SV_NONE: + case VKD3D_SHADER_SV_STENCIL_REF: + case VKD3D_SHADER_SV_TARGET: + return VKD3D_SIV_NONE; + case VKD3D_SHADER_SV_POSITION: + return VKD3D_SIV_POSITION; + case VKD3D_SHADER_SV_CLIP_DISTANCE: + return VKD3D_SIV_CLIP_DISTANCE; + case VKD3D_SHADER_SV_CULL_DISTANCE: + return VKD3D_SIV_CULL_DISTANCE; + case VKD3D_SHADER_SV_INSTANCE_ID: + return VKD3D_SIV_INSTANCE_ID; + case VKD3D_SHADER_SV_IS_FRONT_FACE: + return VKD3D_SIV_IS_FRONT_FACE; + case VKD3D_SHADER_SV_PRIMITIVE_ID: + return VKD3D_SIV_PRIMITIVE_ID; + case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: + return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX; + case VKD3D_SHADER_SV_SAMPLE_INDEX: + return VKD3D_SIV_SAMPLE_INDEX; + case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: + return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index; + case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: + return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index; + case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: + return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index; + case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: + return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR; + case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: + return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR; + case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: + return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR; + case VKD3D_SHADER_SV_VERTEX_ID: + return VKD3D_SIV_VERTEX_ID; + case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: + return VKD3D_SIV_VIEWPORT_ARRAY_INDEX; + default: + FIXME("Unhandled sysval %#x, index %u.\n", sysval, index); + return VKD3D_SIV_NONE; + } +} + static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vsir_program *program, const struct hlsl_ir_var *var, struct hlsl_block *block, const struct vkd3d_shader_location *loc) { @@ -9948,16 +10436,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs { case VKD3D_SHADER_SV_NONE: opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) - ? VKD3DSIH_DCL_INPUT_PS : VKD3DSIH_DCL_INPUT; + ? VSIR_OP_DCL_INPUT_PS : VSIR_OP_DCL_INPUT; break;
case VKD3D_SHADER_SV_PRIMITIVE_ID: if (version->type == VKD3D_SHADER_TYPE_PIXEL) - opcode = VKD3DSIH_DCL_INPUT_PS_SGV; + opcode = VSIR_OP_DCL_INPUT_PS_SGV; else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY) - opcode = VKD3DSIH_DCL_INPUT; + opcode = VSIR_OP_DCL_INPUT; else - opcode = VKD3DSIH_DCL_INPUT_SGV; + opcode = VSIR_OP_DCL_INPUT_SGV; break;
case VKD3D_SHADER_SV_INSTANCE_ID: @@ -9965,16 +10453,16 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs case VKD3D_SHADER_SV_SAMPLE_INDEX: case VKD3D_SHADER_SV_VERTEX_ID: opcode = (version->type == VKD3D_SHADER_TYPE_PIXEL) - ? VKD3DSIH_DCL_INPUT_PS_SGV : VKD3DSIH_DCL_INPUT_SGV; + ? VSIR_OP_DCL_INPUT_PS_SGV : VSIR_OP_DCL_INPUT_SGV; break;
default: if (version->type == VKD3D_SHADER_TYPE_PIXEL) - opcode = VKD3DSIH_DCL_INPUT_PS_SIV; + opcode = VSIR_OP_DCL_INPUT_PS_SIV; else if (is_primitive && version->type != VKD3D_SHADER_TYPE_GEOMETRY) - opcode = VKD3DSIH_DCL_INPUT; + opcode = VSIR_OP_DCL_INPUT; else - opcode = VKD3DSIH_DCL_INPUT_SIV; + opcode = VSIR_OP_DCL_INPUT_SIV; break; } } @@ -9982,9 +10470,12 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs { if (semantic == VKD3D_SHADER_SV_NONE || version->type == VKD3D_SHADER_TYPE_PIXEL || (version->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func)) - opcode = VKD3DSIH_DCL_OUTPUT; + opcode = VSIR_OP_DCL_OUTPUT; + else if ((semantic == VKD3D_SHADER_SV_PRIMITIVE_ID || semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) + && version->type == VKD3D_SHADER_TYPE_GEOMETRY) + opcode = VSIR_OP_DCL_OUTPUT_SGV; else - opcode = VKD3DSIH_DCL_OUTPUT_SIV; + opcode = VSIR_OP_DCL_OUTPUT_SIV; }
if (sm4_register_from_semantic_name(version, var->semantic.name, output, &type, &has_idx)) @@ -10004,13 +10495,13 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, opcode, 0, 0))) return;
- if (opcode == VKD3DSIH_DCL_OUTPUT) + if (opcode == VSIR_OP_DCL_OUTPUT) { VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || semantic == VKD3D_SHADER_SV_TARGET || version->type == VKD3D_SHADER_TYPE_HULL || type != VKD3DSPR_OUTPUT); dst_param = &ins->declaration.dst; } - else if (opcode == VKD3DSIH_DCL_INPUT || opcode == VKD3DSIH_DCL_INPUT_PS) + else if (opcode == VSIR_OP_DCL_INPUT || opcode == VSIR_OP_DCL_INPUT_PS) { VKD3D_ASSERT(semantic == VKD3D_SHADER_SV_NONE || is_primitive || version->type == VKD3D_SHADER_TYPE_GEOMETRY); dst_param = &ins->declaration.dst; @@ -10026,18 +10517,18 @@ static void sm4_generate_vsir_instr_dcl_semantic(struct hlsl_ctx *ctx, struct vs if (is_primitive) { VKD3D_ASSERT(has_idx); - vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 2); + vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 2); dst_param->reg.idx[0].offset = var->data_type->e.array.elements_count; dst_param->reg.idx[1].offset = idx; } else if (has_idx) { - vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 1); dst_param->reg.idx[0].offset = idx; } else { - vsir_register_init(&dst_param->reg, type, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&dst_param->reg, type, VSIR_DATA_F32, 0); }
if (shader_sm4_is_scalar_register(&dst_param->reg)) @@ -10056,7 +10547,7 @@ static void sm4_generate_vsir_instr_dcl_temps(struct hlsl_ctx *ctx, struct vsir_ { struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_TEMPS, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VSIR_OP_DCL_TEMPS, 0, 0))) return;
ins->declaration.count = temp_count; @@ -10068,13 +10559,13 @@ static void sm4_generate_vsir_instr_dcl_indexable_temp(struct hlsl_ctx *ctx, { struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VKD3DSIH_DCL_INDEXABLE_TEMP, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, loc, VSIR_OP_DCL_INDEXABLE_TEMP, 0, 0))) return;
ins->declaration.indexable_temp.register_idx = idx; ins->declaration.indexable_temp.register_size = size; ins->declaration.indexable_temp.alignment = 0; - ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; + ins->declaration.indexable_temp.data_type = VSIR_DATA_F32; ins->declaration.indexable_temp.component_count = comp_count; ins->declaration.indexable_temp.has_function_scope = false; } @@ -10095,16 +10586,17 @@ static void sm4_generate_vsir_cast_from_bool(struct hlsl_ctx *ctx, struct vsir_p
VKD3D_ASSERT(instr->reg.allocated);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_AND, 1, 2))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_AND, 1, 2))) return;
dst_param = &ins->dst[0]; vsir_dst_from_hlsl_node(dst_param, ctx, instr); + ins->dst[0].reg.data_type = VSIR_DATA_U32;
vsir_src_from_hlsl_node(&ins->src[0], ctx, operand, dst_param->write_mask);
value.u[0].u = bits; - vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VKD3D_DATA_UINT, 1, 0); + vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, VSIR_DATA_U32, 1, 0); }
static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, @@ -10131,16 +10623,16 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true;
case HLSL_TYPE_INT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ITOF, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ITOF, 0, 0, true); return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UTOF, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UTOF, 0, 0, true); return true;
case HLSL_TYPE_BOOL: @@ -10158,13 +10650,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FTOI, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FTOI, 0, 0, true); return true;
case HLSL_TYPE_INT: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true;
case HLSL_TYPE_BOOL: @@ -10183,13 +10675,13 @@ static bool sm4_generate_vsir_instr_expr_cast(struct hlsl_ctx *ctx, { case HLSL_TYPE_HALF: case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FTOU, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FTOU, 0, 0, true); return true;
case HLSL_TYPE_INT: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true;
case HLSL_TYPE_BOOL: @@ -10253,7 +10745,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx,
VKD3D_ASSERT(type_is_float(expr->node.data_type));
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DIV, 1, 2))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DIV, 1, 2))) return;
dst_param = &ins->dst[0]; @@ -10264,7 +10756,7 @@ static void sm4_generate_vsir_rcp_using_div(struct hlsl_ctx *ctx, value.u[2].f = 1.0f; value.u[3].f = 1.0f; vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, - VKD3D_DATA_FLOAT, instr->data_type->e.numeric.dimx, dst_param->write_mask); + VSIR_DATA_F32, instr->data_type->e.numeric.dimx, dst_param->write_mask);
vsir_src_from_hlsl_node(&ins->src[1], ctx, operand, dst_param->write_mask); } @@ -10287,12 +10779,12 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP1_ABS: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_ABS, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_ABS, 0, true); return true;
case HLSL_OP1_BIT_NOT: VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NOT, 0, 0, true); return true;
case HLSL_OP1_CAST: @@ -10300,92 +10792,92 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP1_CEIL: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_PI, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_PI, 0, 0, true); return true;
case HLSL_OP1_COS: VKD3D_ASSERT(type_is_float(dst_type)); - sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_SINCOS, expr, 1); + sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_SINCOS, expr, 1); return true;
case HLSL_OP1_DSX: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX, 0, 0, true); return true;
case HLSL_OP1_DSX_COARSE: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_COARSE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX_COARSE, 0, 0, true); return true;
case HLSL_OP1_DSX_FINE: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSX_FINE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSX_FINE, 0, 0, true); return true;
case HLSL_OP1_DSY: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY, 0, 0, true); return true;
case HLSL_OP1_DSY_COARSE: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_COARSE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY_COARSE, 0, 0, true); return true;
case HLSL_OP1_DSY_FINE: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DSY_FINE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DSY_FINE, 0, 0, true); return true;
case HLSL_OP1_EXP2: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EXP, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_EXP, 0, 0, true); return true;
case HLSL_OP1_F16TOF32: VKD3D_ASSERT(type_is_float(dst_type)); VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F16TOF32, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_F16TOF32, 0, 0, true); return true;
case HLSL_OP1_F32TOF16: VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_UINT); VKD3D_ASSERT(hlsl_version_ge(ctx, 5, 0)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_F32TOF16, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_F32TOF16, 0, 0, true); return true;
case HLSL_OP1_FLOOR: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NI, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_NI, 0, 0, true); return true;
case HLSL_OP1_FRACT: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_FRC, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_FRC, 0, 0, true); return true;
case HLSL_OP1_LOG2: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LOG, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_LOG, 0, 0, true); return true;
case HLSL_OP1_LOGIC_NOT: VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NOT, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NOT, 0, 0, true); return true;
case HLSL_OP1_NEG: switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, VKD3DSPSM_NEG, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, VKD3DSPSM_NEG, 0, true); return true;
case HLSL_TYPE_INT: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INEG, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_INEG, 0, 0, true); return true;
default: @@ -10399,7 +10891,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_TYPE_FLOAT: /* SM5 comes with a RCP opcode */ if (hlsl_version_ge(ctx, 5, 0)) - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_RCP, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_RCP, 0, 0, true); else sm4_generate_vsir_rcp_using_div(ctx, program, expr); return true; @@ -10410,50 +10902,50 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, }
case HLSL_OP1_REINTERPRET: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, 0, true); return true;
case HLSL_OP1_ROUND: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_NE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_NE, 0, 0, true); return true;
case HLSL_OP1_RSQ: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_RSQ, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_RSQ, 0, 0, true); return true;
case HLSL_OP1_SAT: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOV, 0, VKD3DSPDM_SATURATE, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOV, 0, VKD3DSPDM_SATURATE, true); return true;
case HLSL_OP1_SIN: VKD3D_ASSERT(type_is_float(dst_type)); - sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_SINCOS, expr, 0); + sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_SINCOS, expr, 0); return true;
case HLSL_OP1_SQRT: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_SQRT, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_SQRT, 0, 0, true); return true;
case HLSL_OP1_TRUNC: VKD3D_ASSERT(type_is_float(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ROUND_Z, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ROUND_Z, 0, 0, true); return true;
case HLSL_OP2_ADD: switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ADD, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ADD, 0, 0, true); return true;
case HLSL_TYPE_INT: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IADD, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IADD, 0, 0, true); return true;
default: @@ -10463,29 +10955,29 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP2_BIT_AND: VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_AND, 0, 0, true); return true;
case HLSL_OP2_BIT_OR: VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_OR, 0, 0, true); return true;
case HLSL_OP2_BIT_XOR: VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_XOR, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_XOR, 0, 0, true); return true;
case HLSL_OP2_DIV: switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DIV, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DIV, 0, 0, true); return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 0); + sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_UDIV, expr, 0); return true;
default: @@ -10500,15 +10992,15 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (expr->operands[0].node->data_type->e.numeric.dimx) { case 4: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP4, 0, 0, false); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP4, 0, 0, false); return true;
case 3: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP3, 0, 0, false); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP3, 0, 0, false); return true;
case 2: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_DP2, 0, 0, false); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_DP2, 0, 0, false); return true;
case 1: @@ -10527,14 +11019,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_EQO, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_EQO, 0, 0, true); return true;
case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IEQ, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IEQ, 0, 0, true); return true;
default: @@ -10549,17 +11041,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_GEO, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_GEO, 0, 0, true); return true;
case HLSL_TYPE_INT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IGE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IGE, 0, 0, true); return true;
case HLSL_TYPE_BOOL: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UGE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UGE, 0, 0, true); return true;
default: @@ -10574,17 +11066,17 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_LTO, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_LTO, 0, 0, true); return true;
case HLSL_TYPE_INT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ILT, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ILT, 0, 0, true); return true;
case HLSL_TYPE_BOOL: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ULT, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ULT, 0, 0, true); return true;
default: @@ -10595,31 +11087,31 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx,
case HLSL_OP2_LOGIC_AND: VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_AND, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_AND, 0, 0, true); return true;
case HLSL_OP2_LOGIC_OR: VKD3D_ASSERT(dst_type->e.numeric.type == HLSL_TYPE_BOOL); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_OR, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_OR, 0, 0, true); return true;
case HLSL_OP2_LSHIFT: VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_ISHL, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_ISHL, 0, 0, true); return true;
case HLSL_OP3_MAD: switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAD, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAD, 0, 0, true); return true;
case HLSL_TYPE_INT: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAD, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMAD, 0, 0, true); return true;
default: @@ -10631,16 +11123,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MAX, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MAX, 0, 0, true); return true;
case HLSL_TYPE_INT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMAX, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMAX, 0, 0, true); return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMAX, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UMAX, 0, 0, true); return true;
default: @@ -10652,16 +11144,16 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MIN, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MIN, 0, 0, true); return true;
case HLSL_TYPE_INT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_IMIN, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_IMIN, 0, 0, true); return true;
case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_UMIN, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_UMIN, 0, 0, true); return true;
default: @@ -10674,7 +11166,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, { case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_UDIV, expr, 1); + sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_UDIV, expr, 1); return true;
default: @@ -10686,7 +11178,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (dst_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MUL, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MUL, 0, 0, true); return true;
case HLSL_TYPE_INT: @@ -10694,7 +11186,7 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, case HLSL_TYPE_UINT: /* Using IMUL instead of UMUL because we're taking the low * bits, and the native compiler generates IMUL. */ - sm4_generate_vsir_expr_with_two_destinations(ctx, program, VKD3DSIH_IMUL, expr, 1); + sm4_generate_vsir_expr_with_two_destinations(ctx, program, VSIR_OP_IMUL, expr, 1); return true;
default: @@ -10708,14 +11200,14 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, switch (src_type->e.numeric.type) { case HLSL_TYPE_FLOAT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_NEU, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_NEU, 0, 0, true); return true;
case HLSL_TYPE_BOOL: case HLSL_TYPE_INT: case HLSL_TYPE_MIN16UINT: /* FIXME: Needs minimum-precision annotations. */ case HLSL_TYPE_UINT: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_INE, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_INE, 0, 0, true); return true;
default: @@ -10728,11 +11220,11 @@ static bool sm4_generate_vsir_instr_expr(struct hlsl_ctx *ctx, VKD3D_ASSERT(hlsl_type_is_integer(dst_type)); VKD3D_ASSERT(dst_type->e.numeric.type != HLSL_TYPE_BOOL); generate_vsir_instr_expr_single_instr_op(ctx, program, expr, - dst_type->e.numeric.type == HLSL_TYPE_INT ? VKD3DSIH_ISHR : VKD3DSIH_USHR, 0, 0, true); + dst_type->e.numeric.type == HLSL_TYPE_INT ? VSIR_OP_ISHR : VSIR_OP_USHR, 0, 0, true); return true;
case HLSL_OP3_TERNARY: - generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VKD3DSIH_MOVC, 0, 0, true); + generate_vsir_instr_expr_single_instr_op(ctx, program, expr, VSIR_OP_MOVC, 0, 0, true); return true;
default: @@ -10749,7 +11241,9 @@ static bool sm4_generate_vsir_instr_store(struct hlsl_ctx *ctx, struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) + VKD3D_ASSERT(!store->lhs.var->is_tgsm); + + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) return false;
dst_param = &ins->dst[0]; @@ -10783,13 +11277,14 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr struct vkd3d_shader_instruction *ins; struct hlsl_constant_value value;
+ VKD3D_ASSERT(!load->src.var->is_tgsm); VKD3D_ASSERT(hlsl_is_numeric_type(type)); if (type->e.numeric.type == HLSL_TYPE_BOOL && var_is_user_input(version, load->src.var)) { /* Uniform bools can be specified as anything, but internal bools * always have 0 for false and ~0 for true. Normalise that here. */
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOVC, 1, 3))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOVC, 1, 3))) return false;
dst_param = &ins->dst[0]; @@ -10801,14 +11296,14 @@ static bool sm4_generate_vsir_instr_load(struct hlsl_ctx *ctx, struct vsir_progr
memset(&value, 0xff, sizeof(value)); vsir_src_from_hlsl_constant_value(&ins->src[1], ctx, &value, - VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask); + VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask); memset(&value, 0x00, sizeof(value)); vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, &value, - VKD3D_DATA_UINT, type->e.numeric.dimx, dst_param->write_mask); + VSIR_DATA_U32, type->e.numeric.dimx, dst_param->write_mask); } else { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_MOV, 1, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_MOV, 1, 1))) return false;
dst_param = &ins->dst[0]; @@ -10827,30 +11322,37 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &store->resource); struct hlsl_ir_node *coords = store->coords.node, *value = store->value.node; struct hlsl_ir_node *instr = &store->node; + bool tgsm = store->resource.var->is_tgsm; struct vkd3d_shader_instruction *ins; - unsigned int writemask;
if (store->store_type != HLSL_RESOURCE_STORE) { - enum vkd3d_shader_opcode opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND - ? VKD3DSIH_EMIT : VKD3DSIH_CUT; + enum vkd3d_shader_opcode opcode;
VKD3D_ASSERT(!store->value.node && !store->coords.node); VKD3D_ASSERT(store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].allocated);
- if (store->resource.var->regs[HLSL_REGSET_STREAM_OUTPUTS].index) + if (hlsl_version_lt(ctx, 5, 0)) { - hlsl_fixme(ctx, &instr->loc, "Stream output operation with a nonzero stream index."); - return false; + opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VSIR_OP_EMIT : VSIR_OP_CUT; + ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); + return !!ins; }
- ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 0); - return !!ins; + opcode = store->store_type == HLSL_RESOURCE_STREAM_APPEND ? VSIR_OP_EMIT_STREAM : VSIR_OP_CUT_STREAM; + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &store->node.loc, opcode, 0, 1))) + return false; + + if (!sm4_generate_vsir_init_src_param_from_deref(ctx, program, &ins->src[0], + &store->resource, VKD3DSP_WRITEMASK_ALL, &instr->loc)) + return false; + + return true; }
- if (!store->resource.var->is_uniform) + if (!store->resource.var->is_uniform && !tgsm) { - hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform resource variable."); + hlsl_fixme(ctx, &store->node.loc, "Store to non-uniform non-groupshared resource variable."); return false; }
@@ -10860,19 +11362,24 @@ static bool sm4_generate_vsir_instr_resource_store(struct hlsl_ctx *ctx, return false; }
- if (resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + if (tgsm && !hlsl_is_numeric_type(resource_type)) + { + hlsl_fixme(ctx, &store->node.loc, "Store to structured TGSM."); + return false; + } + + if (tgsm || resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_STORE_RAW, 1, 2))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_RAW, 1, 2))) return false;
- writemask = vkd3d_write_mask_from_component_count(value->data_type->e.numeric.dimx); - if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, - &ins->dst[0], &store->resource, &instr->loc, writemask)) + if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, &ins->dst[0], + &store->resource, &instr->loc, store->writemask)) return false; } else { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_STORE_UAV_TYPED, 1, 2))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_STORE_UAV_TYPED, 1, 2))) return false;
if (!sm4_generate_vsir_init_dst_param_from_deref(ctx, program, @@ -10928,7 +11435,6 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, const struct hlsl_type *resource_type = hlsl_deref_get_type(ctx, &load->resource); bool uav = (hlsl_deref_get_regset(ctx, &load->resource) == HLSL_REGSET_UAVS); const struct vkd3d_shader_version *version = &program->shader_version; - bool raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; 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 *coords = load->coords.node; @@ -10936,22 +11442,39 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, const struct hlsl_deref *resource = &load->resource; const struct hlsl_ir_node *instr = &load->node; enum hlsl_sampler_dim dim = load->sampling_dim; + bool tgsm = load->resource.var->is_tgsm; struct vkd3d_shader_instruction *ins; enum vkd3d_shader_opcode opcode; - bool multisampled; + 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);
+ if (!tgsm) + { + raw = resource_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER; + } + else if (!(raw = hlsl_is_numeric_type(resource_type))) + { + hlsl_fixme(ctx, &load->node.loc, "Load from structured TGSM."); + return false; + } + if (uav) - opcode = VKD3DSIH_LD_UAV_TYPED; + opcode = VSIR_OP_LD_UAV_TYPED; else if (raw) - opcode = VKD3DSIH_LD_RAW; + opcode = VSIR_OP_LD_RAW; else - opcode = multisampled ? VKD3DSIH_LD2DMS : VKD3DSIH_LD; + opcode = multisampled ? VSIR_OP_LD2DMS : VSIR_OP_LD;
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, 1, 2 + multisampled))) return false; @@ -10966,7 +11489,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx,
vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr);
- if (!uav) + if (!uav && !tgsm) { /* Mipmap level is in the last component in the IR, but needs to be in * the W component in the instruction. */ @@ -10988,7 +11511,7 @@ static bool sm4_generate_vsir_instr_ld(struct hlsl_ctx *ctx, { if (sample_index->type == HLSL_IR_CONSTANT) vsir_src_from_hlsl_constant_value(&ins->src[2], ctx, - &hlsl_ir_constant(sample_index)->value, VKD3D_DATA_INT, 1, 0); + &hlsl_ir_constant(sample_index)->value, VSIR_DATA_I32, 1, 0); else if (version->major == 4 && version->minor == 0) hlsl_error(ctx, &sample_index->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_TYPE, "Expected literal sample index."); else @@ -11012,32 +11535,32 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, switch (load->load_type) { case HLSL_RESOURCE_SAMPLE: - opcode = VKD3DSIH_SAMPLE; + opcode = VSIR_OP_SAMPLE; src_count = 3; break;
case HLSL_RESOURCE_SAMPLE_CMP: - opcode = VKD3DSIH_SAMPLE_C; + opcode = VSIR_OP_SAMPLE_C; src_count = 4; break;
case HLSL_RESOURCE_SAMPLE_CMP_LZ: - opcode = VKD3DSIH_SAMPLE_C_LZ; + opcode = VSIR_OP_SAMPLE_C_LZ; src_count = 4; break;
case HLSL_RESOURCE_SAMPLE_LOD: - opcode = VKD3DSIH_SAMPLE_LOD; + opcode = VSIR_OP_SAMPLE_LOD; src_count = 4; break;
case HLSL_RESOURCE_SAMPLE_LOD_BIAS: - opcode = VKD3DSIH_SAMPLE_B; + opcode = VSIR_OP_SAMPLE_B; src_count = 4; break;
case HLSL_RESOURCE_SAMPLE_GRAD: - opcode = VKD3DSIH_SAMPLE_GRAD; + opcode = VSIR_OP_SAMPLE_GRAD; src_count = 5; break;
@@ -11068,15 +11591,15 @@ static bool sm4_generate_vsir_instr_sample(struct hlsl_ctx *ctx, sampler, VKD3DSP_WRITEMASK_ALL, &instr->loc)) return false;
- if (opcode == VKD3DSIH_SAMPLE_LOD || opcode == VKD3DSIH_SAMPLE_B) + if (opcode == VSIR_OP_SAMPLE_LOD || opcode == VSIR_OP_SAMPLE_B) { vsir_src_from_hlsl_node(&ins->src[3], ctx, load->lod.node, VKD3DSP_WRITEMASK_ALL); } - else if (opcode == VKD3DSIH_SAMPLE_C || opcode == VKD3DSIH_SAMPLE_C_LZ) + else if (opcode == VSIR_OP_SAMPLE_C || opcode == VSIR_OP_SAMPLE_C_LZ) { vsir_src_from_hlsl_node(&ins->src[3], ctx, load->cmp.node, VKD3DSP_WRITEMASK_ALL); } - else if (opcode == VKD3DSIH_SAMPLE_GRAD) + else if (opcode == VSIR_OP_SAMPLE_GRAD) { vsir_src_from_hlsl_node(&ins->src[3], ctx, load->ddx.node, VKD3DSP_WRITEMASK_ALL); vsir_src_from_hlsl_node(&ins->src[4], ctx, load->ddy.node, VKD3DSP_WRITEMASK_ALL); @@ -11091,7 +11614,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro const struct hlsl_ir_node *texel_offset = load->texel_offset.node; const struct hlsl_ir_node *coords = load->coords.node; const struct hlsl_deref *resource = &load->resource; - enum vkd3d_shader_opcode opcode = VKD3DSIH_GATHER4; + enum vkd3d_shader_opcode opcode = VSIR_OP_GATHER4; const struct hlsl_deref *sampler = &load->sampler; const struct hlsl_ir_node *instr = &load->node; unsigned int src_count = 3, current_arg = 0; @@ -11105,13 +11628,13 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro "Offset must resolve to integer literal in the range -8 to 7 for profiles < 5."); return false; } - opcode = VKD3DSIH_GATHER4_PO; + opcode = VSIR_OP_GATHER4_PO; ++src_count; }
if (compare) { - opcode = opcode == VKD3DSIH_GATHER4 ? VKD3DSIH_GATHER4_C : VKD3DSIH_GATHER4_PO_C; + opcode = opcode == VSIR_OP_GATHER4 ? VSIR_OP_GATHER4_C : VSIR_OP_GATHER4_PO_C; ++src_count; }
@@ -11121,7 +11644,7 @@ static bool sm4_generate_vsir_instr_gather(struct hlsl_ctx *ctx, struct vsir_pro vsir_dst_from_hlsl_node(&ins->dst[0], ctx, instr); vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, coords, VKD3DSP_WRITEMASK_ALL);
- if (opcode == VKD3DSIH_GATHER4_PO || opcode == VKD3DSIH_GATHER4_PO_C) + if (opcode == VSIR_OP_GATHER4_PO || opcode == VSIR_OP_GATHER4_PO_C) vsir_src_from_hlsl_node(&ins->src[current_arg++], ctx, texel_offset, VKD3DSP_WRITEMASK_ALL); else sm4_generate_vsir_encode_texel_offset_as_aoffimmi(ins, texel_offset); @@ -11153,7 +11676,7 @@ static bool sm4_generate_vsir_instr_sample_info(struct hlsl_ctx *ctx,
VKD3D_ASSERT(type->e.numeric.type == HLSL_TYPE_UINT || type->e.numeric.type == HLSL_TYPE_FLOAT);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SAMPLE_INFO, 1, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SAMPLE_INFO, 1, 1))) return false;
if (type->e.numeric.type == HLSL_TYPE_UINT) @@ -11185,7 +11708,7 @@ static bool sm4_generate_vsir_instr_resinfo(struct hlsl_ctx *ctx,
VKD3D_ASSERT(type->e.numeric.type == HLSL_TYPE_UINT || type->e.numeric.type == HLSL_TYPE_FLOAT);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_RESINFO, 1, 2))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_RESINFO, 1, 2))) return false;
if (type->e.numeric.type == HLSL_TYPE_UINT) @@ -11237,7 +11760,7 @@ static bool sm4_generate_vsir_instr_resource_load(struct hlsl_ctx *ctx, return false; }
- if (!load->resource.var->is_uniform) + if (!load->resource.var->is_uniform && !load->resource.var->is_tgsm) { hlsl_fixme(ctx, &load->node.loc, "Load from non-uniform resource variable."); return false; @@ -11290,25 +11813,25 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx,
static const enum vkd3d_shader_opcode opcodes[] = { - [HLSL_INTERLOCKED_ADD] = VKD3DSIH_ATOMIC_IADD, - [HLSL_INTERLOCKED_AND] = VKD3DSIH_ATOMIC_AND, - [HLSL_INTERLOCKED_CMP_EXCH] = VKD3DSIH_ATOMIC_CMP_STORE, - [HLSL_INTERLOCKED_MAX] = VKD3DSIH_ATOMIC_UMAX, - [HLSL_INTERLOCKED_MIN] = VKD3DSIH_ATOMIC_UMIN, - [HLSL_INTERLOCKED_OR] = VKD3DSIH_ATOMIC_OR, - [HLSL_INTERLOCKED_XOR] = VKD3DSIH_ATOMIC_XOR, + [HLSL_INTERLOCKED_ADD] = VSIR_OP_ATOMIC_IADD, + [HLSL_INTERLOCKED_AND] = VSIR_OP_ATOMIC_AND, + [HLSL_INTERLOCKED_CMP_EXCH] = VSIR_OP_ATOMIC_CMP_STORE, + [HLSL_INTERLOCKED_MAX] = VSIR_OP_ATOMIC_UMAX, + [HLSL_INTERLOCKED_MIN] = VSIR_OP_ATOMIC_UMIN, + [HLSL_INTERLOCKED_OR] = VSIR_OP_ATOMIC_OR, + [HLSL_INTERLOCKED_XOR] = VSIR_OP_ATOMIC_XOR, };
static const enum vkd3d_shader_opcode imm_opcodes[] = { - [HLSL_INTERLOCKED_ADD] = VKD3DSIH_IMM_ATOMIC_IADD, - [HLSL_INTERLOCKED_AND] = VKD3DSIH_IMM_ATOMIC_AND, - [HLSL_INTERLOCKED_CMP_EXCH] = VKD3DSIH_IMM_ATOMIC_CMP_EXCH, - [HLSL_INTERLOCKED_EXCH] = VKD3DSIH_IMM_ATOMIC_EXCH, - [HLSL_INTERLOCKED_MAX] = VKD3DSIH_IMM_ATOMIC_UMAX, - [HLSL_INTERLOCKED_MIN] = VKD3DSIH_IMM_ATOMIC_UMIN, - [HLSL_INTERLOCKED_OR] = VKD3DSIH_IMM_ATOMIC_OR, - [HLSL_INTERLOCKED_XOR] = VKD3DSIH_IMM_ATOMIC_XOR, + [HLSL_INTERLOCKED_ADD] = VSIR_OP_IMM_ATOMIC_IADD, + [HLSL_INTERLOCKED_AND] = VSIR_OP_IMM_ATOMIC_AND, + [HLSL_INTERLOCKED_CMP_EXCH] = VSIR_OP_IMM_ATOMIC_CMP_EXCH, + [HLSL_INTERLOCKED_EXCH] = VSIR_OP_IMM_ATOMIC_EXCH, + [HLSL_INTERLOCKED_MAX] = VSIR_OP_IMM_ATOMIC_UMAX, + [HLSL_INTERLOCKED_MIN] = VSIR_OP_IMM_ATOMIC_UMIN, + [HLSL_INTERLOCKED_OR] = VSIR_OP_IMM_ATOMIC_OR, + [HLSL_INTERLOCKED_XOR] = VSIR_OP_IMM_ATOMIC_XOR, };
struct hlsl_ir_node *cmp_value = interlocked->cmp_value.node, *value = interlocked->value.node; @@ -11323,14 +11846,14 @@ static bool sm4_generate_vsir_instr_interlocked(struct hlsl_ctx *ctx,
if (value->data_type->e.numeric.type == HLSL_TYPE_INT) { - if (opcode == VKD3DSIH_ATOMIC_UMAX) - opcode = VKD3DSIH_ATOMIC_IMAX; - else if (opcode == VKD3DSIH_ATOMIC_UMIN) - opcode = VKD3DSIH_ATOMIC_IMIN; - else if (opcode == VKD3DSIH_IMM_ATOMIC_UMAX) - opcode = VKD3DSIH_IMM_ATOMIC_IMAX; - else if (opcode == VKD3DSIH_IMM_ATOMIC_UMIN) - opcode = VKD3DSIH_IMM_ATOMIC_IMIN; + if (opcode == VSIR_OP_ATOMIC_UMAX) + opcode = VSIR_OP_ATOMIC_IMAX; + else if (opcode == VSIR_OP_ATOMIC_UMIN) + opcode = VSIR_OP_ATOMIC_IMIN; + else if (opcode == VSIR_OP_IMM_ATOMIC_UMAX) + opcode = VSIR_OP_IMM_ATOMIC_IMAX; + else if (opcode == VSIR_OP_IMM_ATOMIC_UMIN) + opcode = VSIR_OP_IMM_ATOMIC_IMIN; }
if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, opcode, @@ -11368,13 +11891,13 @@ static bool sm4_generate_vsir_instr_jump(struct hlsl_ctx *ctx, switch (jump->type) { case HLSL_IR_JUMP_BREAK: - return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_BREAK, 0, 0); + return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_BREAK, 0, 0);
case HLSL_IR_JUMP_CONTINUE: - return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_CONTINUE, 0, 0); + return generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_CONTINUE, 0, 0);
case HLSL_IR_JUMP_DISCARD_NZ: - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DISCARD, 0, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DISCARD, 0, 1))) return false; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
@@ -11396,7 +11919,7 @@ static bool sm4_generate_vsir_instr_sync(struct hlsl_ctx *ctx, const struct hlsl_ir_node *instr = &sync->node; struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SYNC, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SYNC, 0, 0))) return false; ins->flags = sync->sync_flags;
@@ -11412,7 +11935,7 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
VKD3D_ASSERT(iff->condition.node->data_type->e.numeric.dimx == 1);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_IF, 0, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_IF, 0, 1))) return; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
@@ -11422,12 +11945,12 @@ static void sm4_generate_vsir_instr_if(struct hlsl_ctx *ctx, struct vsir_program
if (!list_empty(&iff->else_block.instrs)) { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ELSE, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ELSE, 0, 0))) return; sm4_generate_vsir_block(ctx, &iff->else_block, program); }
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDIF, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDIF, 0, 0))) return; }
@@ -11437,12 +11960,12 @@ static void sm4_generate_vsir_instr_loop(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr = &loop->node; struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_LOOP, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_LOOP, 0, 0))) return;
sm4_generate_vsir_block(ctx, &loop->body, program);
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDLOOP, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDLOOP, 0, 0))) return; }
@@ -11454,7 +11977,7 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, struct vkd3d_shader_instruction *ins; struct hlsl_ir_switch_case *cas;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_SWITCH, 0, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_SWITCH, 0, 1))) return; vsir_src_from_hlsl_node(&ins->src[0], ctx, selector, VKD3DSP_WRITEMASK_ALL);
@@ -11462,22 +11985,22 @@ static void sm4_generate_vsir_instr_switch(struct hlsl_ctx *ctx, { if (cas->is_default) { - if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_DEFAULT, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_DEFAULT, 0, 0))) return; } else { struct hlsl_constant_value value = {.u[0].u = cas->value};
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_CASE, 0, 1))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_CASE, 0, 1))) return; - vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VKD3D_DATA_UINT, 1, VKD3DSP_WRITEMASK_ALL); + vsir_src_from_hlsl_constant_value(&ins->src[0], ctx, &value, VSIR_DATA_U32, 1, VKD3DSP_WRITEMASK_ALL); }
sm4_generate_vsir_block(ctx, &cas->body, program); }
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VKD3DSIH_ENDSWITCH, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &instr->loc, VSIR_OP_ENDSWITCH, 0, 0))) return; }
@@ -11563,8 +12086,9 @@ static void sm4_generate_vsir_block(struct hlsl_ctx *ctx, struct hlsl_block *blo } }
-static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, - struct hlsl_ir_function_decl *func, uint64_t config_flags, struct vsir_program *program) +static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, struct list *semantic_vars, + struct hlsl_ir_function_decl *func, struct hlsl_block *body, uint64_t config_flags, + struct vsir_program *program) { struct hlsl_block block = {0}; struct hlsl_scope *scope; @@ -11573,16 +12097,16 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx,
ctx->is_patch_constant_func = func == ctx->patch_constant_func;
- compute_liveness(ctx, func); - mark_indexable_vars(ctx, func); - temp_count = allocate_temp_registers(ctx, func); + compute_liveness(ctx, body); + mark_indexable_vars(ctx, body); + temp_count = allocate_temp_registers(ctx, body, semantic_vars); if (ctx->result) return; program->temp_count = max(program->temp_count, temp_count);
hlsl_block_init(&block);
- LIST_FOR_EACH_ENTRY(var, &func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { if ((var->is_input_semantic && var->last_read) || (var->is_output_semantic && var->first_write)) @@ -11596,7 +12120,7 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, { LIST_FOR_EACH_ENTRY(var, &scope->vars, struct hlsl_ir_var, scope_entry) { - if (var->is_uniform || var->is_input_semantic || var->is_output_semantic) + if (var->is_uniform || var->is_tgsm || var->is_input_semantic || var->is_output_semantic) continue; if (!var->regs[HLSL_REGSET_NUMERIC].allocated) continue; @@ -11611,13 +12135,13 @@ static void sm4_generate_vsir_add_function(struct hlsl_ctx *ctx, } }
- list_move_head(&func->body.instrs, &block.instrs); + list_move_head(&body->instrs, &block.instrs);
hlsl_block_cleanup(&block);
- sm4_generate_vsir_block(ctx, &func->body, program); + sm4_generate_vsir_block(ctx, body, program);
- generate_vsir_add_program_instruction(ctx, program, &func->loc, VKD3DSIH_RET, 0, 0); + generate_vsir_add_program_instruction(ctx, program, &func->loc, VSIR_OP_RET, 0, 0); }
static int sm4_compare_extern_resources(const void *a, const void *b) @@ -11839,8 +12363,8 @@ static void generate_vsir_scan_required_features(struct hlsl_ctx *ctx, struct vs * STENCIL_REF, and TYPED_UAV_LOAD_ADDITIONAL_FORMATS. */ }
-static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, - struct vsir_program *program, const struct hlsl_ir_function_decl *entry_func) +static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx, struct vsir_program *program, + const struct list *semantic_vars, const struct hlsl_ir_function_decl *entry_func) { const struct vkd3d_shader_version *version = &program->shader_version; struct extern_resource *extern_resources; @@ -11866,7 +12390,7 @@ static void generate_vsir_scan_global_flags(struct hlsl_ctx *ctx,
sm4_free_extern_resources(extern_resources, extern_resources_count);
- LIST_FOR_EACH_ENTRY(var, &entry_func->extern_vars, struct hlsl_ir_var, extern_entry) + LIST_FOR_EACH_ENTRY(var, semantic_vars, struct hlsl_ir_var, extern_entry) { const struct hlsl_type *type = var->data_type;
@@ -11897,7 +12421,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, struct vkd3d_shader_src_param *src_param; struct vkd3d_shader_instruction *ins;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &cbuffer->loc, VKD3DSIH_DCL_CONSTANT_BUFFER, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &cbuffer->loc, VSIR_OP_DCL_CONSTANT_BUFFER, 0, 0))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; @@ -11906,7 +12430,7 @@ static void sm4_generate_vsir_add_dcl_constant_buffer(struct hlsl_ctx *ctx, ins->declaration.cb.size = cbuffer->size;
src_param = &ins->declaration.cb.src; - vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 0); + vsir_src_param_init(src_param, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 0); src_param->reg.dimension = VSIR_DIMENSION_VEC4; src_param->swizzle = VKD3D_SHADER_NO_SWIZZLE;
@@ -11938,7 +12462,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, if (resource->var && !resource->var->objects_usage[HLSL_REGSET_SAMPLERS][i].used) continue;
- if (!(ins = generate_vsir_add_program_instruction(ctx, program, &resource->loc, VKD3DSIH_DCL_SAMPLER, 0, 0))) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &resource->loc, VSIR_OP_DCL_SAMPLER, 0, 0))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; @@ -11948,7 +12472,7 @@ static void sm4_generate_vsir_add_dcl_sampler(struct hlsl_ctx *ctx, ins->flags |= VKD3DSI_SAMPLER_COMPARISON_MODE;
src_param = &ins->declaration.sampler.src; - vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 0); + vsir_src_param_init(src_param, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 0);
ins->declaration.sampler.range.first = array_first; ins->declaration.sampler.range.last = array_last; @@ -11992,30 +12516,33 @@ static enum vkd3d_shader_resource_type sm4_generate_vsir_get_resource_type(const } }
-static enum vkd3d_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) +static enum vsir_data_type sm4_generate_vsir_get_format_type(const struct hlsl_type *type) { const struct hlsl_type *format = type->e.resource.format;
+ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + return VSIR_DATA_MIXED; + switch (format->e.numeric.type) { case HLSL_TYPE_DOUBLE: - return VKD3D_DATA_DOUBLE; + return VSIR_DATA_F64;
case HLSL_TYPE_FLOAT: case HLSL_TYPE_HALF: if (format->modifiers & HLSL_MODIFIER_UNORM) - return VKD3D_DATA_UNORM; + return VSIR_DATA_UNORM; if (format->modifiers & HLSL_MODIFIER_SNORM) - return VKD3D_DATA_SNORM; - return VKD3D_DATA_FLOAT; + return VSIR_DATA_SNORM; + return VSIR_DATA_F32;
case HLSL_TYPE_INT: - return VKD3D_DATA_INT; + return VSIR_DATA_I32;
case HLSL_TYPE_BOOL: case HLSL_TYPE_MIN16UINT: case HLSL_TYPE_UINT: - return VKD3D_DATA_UINT; + return VSIR_DATA_U32; }
vkd3d_unreachable(); @@ -12026,14 +12553,11 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, bool uav) { enum hlsl_regset regset = uav ? HLSL_REGSET_UAVS : HLSL_REGSET_TEXTURES; - struct vkd3d_shader_structured_resource *structured_resource; - struct vkd3d_shader_dst_param *dst_param; - struct vkd3d_shader_semantic *semantic; struct vkd3d_shader_instruction *ins; struct hlsl_type *component_type; enum vkd3d_shader_opcode opcode; bool multisampled; - unsigned int i, j; + unsigned int i;
VKD3D_ASSERT(resource->regset == regset); VKD3D_ASSERT(hlsl_version_lt(ctx, 5, 1) || resource->bind_count == 1); @@ -12044,6 +12568,7 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, { unsigned int array_first = resource->index + i; unsigned int array_last = resource->index + i; /* FIXME: array end. */ + struct vkd3d_shader_resource *vsir_resource;
if (resource->var && !resource->var->objects_usage[regset][i].used) continue; @@ -12053,13 +12578,13 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, switch (component_type->sampler_dim) { case HLSL_SAMPLER_DIM_STRUCTURED_BUFFER: - opcode = VKD3DSIH_DCL_UAV_STRUCTURED; + opcode = VSIR_OP_DCL_UAV_STRUCTURED; break; case HLSL_SAMPLER_DIM_RAW_BUFFER: - opcode = VKD3DSIH_DCL_UAV_RAW; + opcode = VSIR_OP_DCL_UAV_RAW; break; default: - opcode = VKD3DSIH_DCL_UAV_TYPED; + opcode = VSIR_OP_DCL_UAV_TYPED; break; } } @@ -12068,10 +12593,10 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, switch (component_type->sampler_dim) { case HLSL_SAMPLER_DIM_RAW_BUFFER: - opcode = VKD3DSIH_DCL_RESOURCE_RAW; + opcode = VSIR_OP_DCL_RESOURCE_RAW; break; default: - opcode = VKD3DSIH_DCL; + opcode = VSIR_OP_DCL; break; } } @@ -12081,13 +12606,16 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; } - semantic = &ins->declaration.semantic; - structured_resource = &ins->declaration.structured_resource; - dst_param = &semantic->resource.reg; - vsir_dst_param_init(dst_param, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 0);
- if (uav && component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) - structured_resource->byte_stride = 4 * component_type->e.resource.format->reg_size[HLSL_REGSET_NUMERIC]; + if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + vsir_resource = &ins->declaration.raw_resource.resource; + else if (component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + vsir_resource = &ins->declaration.structured_resource.resource; + else + vsir_resource = &ins->declaration.semantic.resource; + + vsir_dst_param_init(&vsir_resource->reg, uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 0); + if (uav && component_type->e.resource.rasteriser_ordered) ins->flags = VKD3DSUF_RASTERISER_ORDERED_VIEW;
@@ -12101,64 +12629,103 @@ static void sm4_generate_vsir_add_dcl_texture(struct hlsl_ctx *ctx, ctx->profile->major_version, ctx->profile->minor_version); }
- for (j = 0; j < 4; ++j) - semantic->resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type); + vsir_resource->range.first = array_first; + vsir_resource->range.last = array_last; + vsir_resource->range.space = resource->space;
- semantic->resource.range.first = array_first; - semantic->resource.range.last = array_last; - semantic->resource.range.space = resource->space; - - dst_param->reg.idx[0].offset = resource->id; - dst_param->reg.idx[1].offset = array_first; - dst_param->reg.idx[2].offset = array_last; - dst_param->reg.idx_count = 3; + vsir_resource->reg.reg.idx[0].offset = resource->id; + vsir_resource->reg.reg.idx[1].offset = array_first; + vsir_resource->reg.reg.idx[2].offset = array_last; + vsir_resource->reg.reg.idx_count = 3;
ins->resource_type = sm4_generate_vsir_get_resource_type(resource->component_type); - if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + + if (component_type->sampler_dim == HLSL_SAMPLER_DIM_RAW_BUFFER) + { ins->raw = true; - if (resource->component_type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + } + 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->declaration.structured_resource.byte_stride = ins->resource_stride; } + else + { + for (unsigned int j = 0; j < 4; ++j) + ins->declaration.semantic.resource_data_type[j] = sm4_generate_vsir_get_format_type(component_type);
- if (multisampled) - semantic->sample_count = component_type->sample_count; + if (multisampled) + ins->declaration.semantic.sample_count = component_type->sample_count; + } } }
-/* OBJECTIVE: Translate all the information from ctx and entry_func to the - * vsir_program, so it can be used as input to tpf_compile() without relying - * on ctx and entry_func. */ -static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *func, - uint64_t config_flags, struct vsir_program *program) +static void sm4_generate_vsir_add_dcl_tgsm(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct hlsl_ir_var *var) { - struct vkd3d_shader_version version = {0}; - struct extern_resource *extern_resources; - unsigned int extern_resources_count; - const struct hlsl_buffer *cbuffer; + struct vkd3d_shader_dst_param *dst_param; + struct vkd3d_shader_instruction *ins;
- version.major = ctx->profile->major_version; - version.minor = ctx->profile->minor_version; - version.type = ctx->profile->type; + if (!hlsl_is_numeric_type(var->data_type)) + { + hlsl_fixme(ctx, &var->loc, "Structured TGSM declaration."); + return; + }
- if (!vsir_program_init(program, NULL, &version, 0, VSIR_CF_STRUCTURED, VSIR_NORMALISED_SM4)) + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_TGSM_RAW, 0, 0))) { ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; return; }
- generate_vsir_signature(ctx, program, func); - if (version.type == VKD3D_SHADER_TYPE_HULL) - generate_vsir_signature(ctx, program, ctx->patch_constant_func); + dst_param = &ins->declaration.tgsm_raw.reg; + + vsir_dst_param_init(dst_param, VKD3DSPR_GROUPSHAREDMEM, VSIR_DATA_F32, 1); + dst_param->reg.dimension = VSIR_DIMENSION_NONE; + dst_param->reg.idx[0].offset = var->regs[HLSL_REGSET_NUMERIC].id; + + ins->declaration.tgsm_raw.byte_count = var->data_type->reg_size[HLSL_REGSET_NUMERIC] * 4; + ins->declaration.tgsm_raw.zero_init = false; +}
- if (version.type == VKD3D_SHADER_TYPE_COMPUTE) +static void sm4_generate_vsir_add_dcl_stream(struct hlsl_ctx *ctx, + struct vsir_program *program, const struct hlsl_ir_var *var) +{ + struct vkd3d_shader_instruction *ins; + + if (!(ins = generate_vsir_add_program_instruction(ctx, program, &var->loc, VSIR_OP_DCL_STREAM, 0, 1))) + { + ctx->result = VKD3D_ERROR_OUT_OF_MEMORY; + return; + } + + vsir_src_param_init(&ins->src[0], VKD3DSPR_STREAM, VSIR_DATA_UNUSED, 1); + ins->src[0].reg.dimension = VSIR_DIMENSION_NONE; + ins->src[0].reg.idx[0].offset = var->regs[HLSL_REGSET_STREAM_OUTPUTS].index; +} + +/* OBJECTIVE: Translate all the information from ctx and entry_func to the + * vsir_program, so it can be used as input to tpf_compile() without relying + * on ctx and entry_func. */ +static void sm4_generate_vsir(struct hlsl_ctx *ctx, + const struct vkd3d_shader_compile_info *compile_info, struct hlsl_ir_function_decl *func, + struct list *semantic_vars, struct hlsl_block *body, struct list *patch_semantic_vars, + struct hlsl_block *patch_body, uint64_t config_flags, struct vsir_program *program) +{ + const struct vkd3d_shader_version *version = &program->shader_version; + struct extern_resource *extern_resources; + unsigned int extern_resources_count; + const struct hlsl_buffer *cbuffer; + const struct hlsl_ir_var *var; + + if (version->type == VKD3D_SHADER_TYPE_COMPUTE) { program->thread_group_size.x = ctx->thread_count[0]; program->thread_group_size.y = ctx->thread_count[1]; program->thread_group_size.z = ctx->thread_count[2]; } - else if (version.type == VKD3D_SHADER_TYPE_HULL) + else if (version->type == VKD3D_SHADER_TYPE_HULL) { program->input_control_point_count = ctx->input_control_point_count == UINT_MAX ? 1 : ctx->input_control_point_count; @@ -12167,13 +12734,13 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl program->tess_partitioning = ctx->partitioning; program->tess_output_primitive = ctx->output_primitive; } - else if (version.type == VKD3D_SHADER_TYPE_DOMAIN) + else if (version->type == VKD3D_SHADER_TYPE_DOMAIN) { program->input_control_point_count = ctx->input_control_point_count == UINT_MAX ? 0 : ctx->input_control_point_count; program->tess_domain = ctx->domain; } - else if (version.type == VKD3D_SHADER_TYPE_GEOMETRY) + else if (version->type == VKD3D_SHADER_TYPE_GEOMETRY) { program->input_control_point_count = ctx->input_control_point_count; program->input_primitive = ctx->input_primitive_type; @@ -12201,19 +12768,39 @@ static void sm4_generate_vsir(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl } sm4_free_extern_resources(extern_resources, extern_resources_count);
- if (version.type == VKD3D_SHADER_TYPE_HULL) + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->is_tgsm && var->regs[HLSL_REGSET_NUMERIC].allocated) + sm4_generate_vsir_add_dcl_tgsm(ctx, program, var); + } + + if (version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) + { + LIST_FOR_EACH_ENTRY(var, &ctx->extern_vars, struct hlsl_ir_var, extern_entry) + { + if (var->bind_count[HLSL_REGSET_STREAM_OUTPUTS]) + sm4_generate_vsir_add_dcl_stream(ctx, program, var); + } + } + + program->ssa_count = 0; + + if (version->type == VKD3D_SHADER_TYPE_HULL) generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VKD3DSIH_HS_CONTROL_POINT_PHASE, 0, 0); - sm4_generate_vsir_add_function(ctx, func, config_flags, program); - if (version.type == VKD3D_SHADER_TYPE_HULL) + &ctx->patch_constant_func->loc, VSIR_OP_HS_CONTROL_POINT_PHASE, 0, 0); + sm4_generate_vsir_add_function(ctx, semantic_vars, func, body, config_flags, program); + if (version->type == VKD3D_SHADER_TYPE_HULL) { generate_vsir_add_program_instruction(ctx, program, - &ctx->patch_constant_func->loc, VKD3DSIH_HS_FORK_PHASE, 0, 0); - sm4_generate_vsir_add_function(ctx, ctx->patch_constant_func, config_flags, program); + &ctx->patch_constant_func->loc, VSIR_OP_HS_FORK_PHASE, 0, 0); + sm4_generate_vsir_add_function(ctx, patch_semantic_vars, + ctx->patch_constant_func, patch_body, config_flags, program); }
generate_vsir_scan_required_features(ctx, program); - generate_vsir_scan_global_flags(ctx, program, func); + generate_vsir_scan_global_flags(ctx, program, semantic_vars, func); + + program->ssa_count = ctx->ssa_count; }
/* For some reason, for matrices, values from default value initializers end @@ -12297,6 +12884,9 @@ static enum D3D_RESOURCE_RETURN_TYPE sm4_data_type(const struct hlsl_type *type) { const struct hlsl_type *format = type->e.resource.format;
+ if (type->sampler_dim == HLSL_SAMPLER_DIM_STRUCTURED_BUFFER) + return D3D_RETURN_TYPE_MIXED; + switch (format->e.numeric.type) { case HLSL_TYPE_DOUBLE: @@ -13352,15 +13942,14 @@ static bool lower_isinf(struct hlsl_ctx *ctx, struct hlsl_ir_node *node, struct return true; }
-static void process_entry_function(struct hlsl_ctx *ctx, +static void process_entry_function(struct hlsl_ctx *ctx, struct list *semantic_vars, struct hlsl_block *body, const struct hlsl_block *global_uniform_block, struct hlsl_ir_function_decl *entry_func) { + struct stream_append_ctx stream_append_ctx = { .semantic_vars = semantic_vars }; const struct hlsl_ir_var *input_patch = NULL, *output_patch = NULL; const struct hlsl_profile_info *profile = ctx->profile; struct hlsl_block static_initializers, global_uniforms; - struct hlsl_block *const body = &entry_func->body; struct recursive_call_ctx recursive_call_ctx; - struct stream_append_ctx stream_append_ctx; uint32_t output_reg_count; struct hlsl_ir_var *var; unsigned int i; @@ -13368,6 +13957,8 @@ static void process_entry_function(struct hlsl_ctx *ctx,
ctx->is_patch_constant_func = entry_func == ctx->patch_constant_func;
+ hlsl_clone_block(ctx, body, &entry_func->body); + if (!hlsl_clone_block(ctx, &static_initializers, &ctx->static_initializers)) return; list_move_head(&body->instrs, &static_initializers.instrs); @@ -13401,6 +13992,22 @@ static void process_entry_function(struct hlsl_ctx *ctx, lower_ir(ctx, lower_matrix_swizzles, body); lower_ir(ctx, lower_index_loads, body);
+ lower_ir(ctx, lower_tgsm_loads, body); + lower_ir(ctx, lower_tgsm_stores, body); + + if (entry_func->return_var) + { + if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, + "Geometry shaders cannot return values."); + else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT + && !entry_func->return_var->semantic.name) + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, + "Entry point "%s" is missing a return value semantic.", entry_func->func->name); + + append_output_var_copy(ctx, body, semantic_vars, entry_func->return_var); + } + for (i = 0; i < entry_func->parameters.count; ++i) { var = entry_func->parameters.vars[i]; @@ -13454,7 +14061,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, }
validate_and_record_prim_type(ctx, var); - prepend_input_var_copy(ctx, entry_func, var); + prepend_input_var_copy(ctx, body, semantic_vars, var); } else if (var->data_type->reg_size[HLSL_REGSET_STREAM_OUTPUTS]) { @@ -13490,7 +14097,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, continue; }
- prepend_input_var_copy(ctx, entry_func, var); + prepend_input_var_copy(ctx, body, semantic_vars, var); } if (var->storage_modifiers & HLSL_STORAGE_OUT) { @@ -13501,29 +14108,39 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_error(ctx, &var->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_MODIFIER, "Output parameters are not allowed in geometry shaders."); else - append_output_var_copy(ctx, entry_func, var); + append_output_var_copy(ctx, body, semantic_vars, var); } } } + if (entry_func->return_var) { - if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) - hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INCOMPATIBLE_PROFILE, - "Geometry shaders cannot return values."); - else if (entry_func->return_var->data_type->class != HLSL_CLASS_STRUCT - && !entry_func->return_var->semantic.name) - hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_SEMANTIC, - "Entry point "%s" is missing a return value semantic.", entry_func->func->name); - - append_output_var_copy(ctx, entry_func, entry_func->return_var); - if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func) ctx->output_control_point_type = entry_func->return_var->data_type; } else { if (profile->type == VKD3D_SHADER_TYPE_HULL && !ctx->is_patch_constant_func) - hlsl_fixme(ctx, &entry_func->loc, "Passthrough hull shader control point function."); + { + if (!ctx->input_control_point_type) + { + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH, + "Pass-through control point function "%s" is missing an InputPatch parameter.", + entry_func->func->name); + } + else if (ctx->output_control_point_count + && ctx->output_control_point_count != ctx->input_control_point_count) + { + hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_INVALID_CONTROL_POINT_COUNT, + "Output control point count %u does not match the input control point count %u.", + ctx->output_control_point_count, ctx->input_control_point_count); + } + else + { + ctx->output_control_point_type = ctx->input_control_point_type; + ctx->output_control_point_count = ctx->input_control_point_count; + } + } }
if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY && ctx->input_primitive_type == VKD3D_PT_UNDEFINED) @@ -13540,8 +14157,8 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_transform_ir(ctx, lower_resource_load_bias, body, NULL); }
- compute_liveness(ctx, entry_func); - transform_derefs(ctx, divert_written_uniform_derefs_to_temp, &entry_func->body); + compute_liveness(ctx, body); + transform_derefs(ctx, divert_written_uniform_derefs_to_temp, body);
loop_unrolling_execute(ctx, body); hlsl_run_const_passes(ctx, body); @@ -13561,7 +14178,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, do { progress = vectorize_exprs(ctx, body); - compute_liveness(ctx, entry_func); + compute_liveness(ctx, body); progress |= hlsl_transform_ir(ctx, dce, body, NULL); progress |= hlsl_transform_ir(ctx, fold_swizzle_chains, body, NULL); progress |= hlsl_transform_ir(ctx, remove_trivial_swizzles, body, NULL); @@ -13574,7 +14191,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_transform_ir(ctx, lower_combined_samples, body, NULL);
do - compute_liveness(ctx, entry_func); + compute_liveness(ctx, body); while (hlsl_transform_ir(ctx, dce, body, NULL));
hlsl_transform_ir(ctx, track_components_usage, body, NULL); @@ -13587,9 +14204,6 @@ static void process_entry_function(struct hlsl_ctx *ctx, { allocate_stream_outputs(ctx); validate_and_record_stream_outputs(ctx); - - memset(&stream_append_ctx, 0, sizeof(stream_append_ctx)); - stream_append_ctx.func = entry_func; hlsl_transform_ir(ctx, lower_stream_appends, body, &stream_append_ctx); }
@@ -13630,7 +14244,7 @@ static void process_entry_function(struct hlsl_ctx *ctx, hlsl_run_folding_passes(ctx, body);
do - compute_liveness(ctx, entry_func); + compute_liveness(ctx, body); while (hlsl_transform_ir(ctx, dce, body, NULL));
/* TODO: move forward, remove when no longer needed */ @@ -13639,27 +14253,30 @@ static void process_entry_function(struct hlsl_ctx *ctx, transform_derefs(ctx, clean_constant_deref_offset_srcs, body);
do - compute_liveness(ctx, entry_func); + compute_liveness(ctx, body); while (hlsl_transform_ir(ctx, dce, body, NULL));
- compute_liveness(ctx, entry_func); + compute_liveness(ctx, body); mark_vars_usage(ctx);
calculate_resource_register_counts(ctx);
allocate_register_reservations(ctx, &ctx->extern_vars); - allocate_register_reservations(ctx, &entry_func->extern_vars); - allocate_semantic_registers(ctx, entry_func, &output_reg_count); + allocate_register_reservations(ctx, semantic_vars); + allocate_semantic_registers(ctx, semantic_vars, &output_reg_count);
if (profile->type == VKD3D_SHADER_TYPE_GEOMETRY) - validate_max_output_size(ctx, entry_func, output_reg_count); + validate_max_output_size(ctx, semantic_vars, output_reg_count, &entry_func->loc); }
-int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry_func, - enum vkd3d_shader_target_type target_type, struct vkd3d_shader_code *out) +int hlsl_emit_vsir(struct hlsl_ctx *ctx, const struct vkd3d_shader_compile_info *compile_info, + struct hlsl_ir_function_decl *entry_func, struct vsir_program *program, + struct vkd3d_shader_code *reflection_data) { + struct hlsl_block global_uniform_block, body, patch_body; + uint32_t config_flags = vkd3d_shader_init_config_flags(); const struct hlsl_profile_info *profile = ctx->profile; - struct hlsl_block global_uniform_block; + struct list semantic_vars, patch_semantic_vars; struct hlsl_ir_var *var;
parse_entry_function_attributes(ctx, entry_func); @@ -13678,21 +14295,31 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry hlsl_error(ctx, &entry_func->loc, VKD3D_SHADER_ERROR_HLSL_MISSING_ATTRIBUTE, "Entry point "%s" is missing a [maxvertexcount] attribute.", entry_func->func->name);
+ list_init(&ctx->extern_vars); + list_init(&semantic_vars); + list_init(&patch_semantic_vars); hlsl_block_init(&global_uniform_block);
LIST_FOR_EACH_ENTRY(var, &ctx->globals->vars, struct hlsl_ir_var, scope_entry) { if (var->storage_modifiers & HLSL_STORAGE_UNIFORM) + { prepend_uniform_copy(ctx, &global_uniform_block, var); + } + else if (var->storage_modifiers & HLSL_STORAGE_GROUPSHARED) + { + var->is_tgsm = 1; + list_add_tail(&ctx->extern_vars, &var->extern_entry); + } }
- process_entry_function(ctx, &global_uniform_block, entry_func); + process_entry_function(ctx, &semantic_vars, &body, &global_uniform_block, entry_func); if (ctx->result) return ctx->result;
if (profile->type == VKD3D_SHADER_TYPE_HULL) { - process_entry_function(ctx, &global_uniform_block, ctx->patch_constant_func); + process_entry_function(ctx, &patch_semantic_vars, &patch_body, &global_uniform_block, ctx->patch_constant_func); if (ctx->result) return ctx->result; } @@ -13701,79 +14328,49 @@ int hlsl_emit_bytecode(struct hlsl_ctx *ctx, struct hlsl_ir_function_decl *entry
if (profile->major_version < 4) { - mark_indexable_vars(ctx, entry_func); - allocate_const_registers(ctx, entry_func); + mark_indexable_vars(ctx, &body); + allocate_const_registers(ctx, &body); sort_uniforms_by_bind_count(ctx, HLSL_REGSET_SAMPLERS); - allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS); + allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); } else { allocate_buffers(ctx); - allocate_objects(ctx, entry_func, HLSL_REGSET_TEXTURES); - allocate_objects(ctx, entry_func, HLSL_REGSET_UAVS); - allocate_objects(ctx, entry_func, HLSL_REGSET_SAMPLERS); + allocate_objects(ctx, &semantic_vars, HLSL_REGSET_TEXTURES); + allocate_objects(ctx, &semantic_vars, HLSL_REGSET_UAVS); + allocate_objects(ctx, &semantic_vars, HLSL_REGSET_SAMPLERS); + allocate_tgsms(ctx); }
if (TRACE_ON()) + { rb_for_each_entry(&ctx->functions, dump_function, ctx); + hlsl_dump_function(ctx, entry_func, "processed entry point", &body); + if (profile->type == VKD3D_SHADER_TYPE_HULL) + hlsl_dump_function(ctx, ctx->patch_constant_func, "processed patch-constant function", &patch_body); + }
if (ctx->result) return ctx->result;
- switch (target_type) - { - case VKD3D_SHADER_TARGET_D3D_BYTECODE: - { - uint32_t config_flags = vkd3d_shader_init_config_flags(); - struct vkd3d_shader_code ctab = {0}; - struct vsir_program program; - int result; - - sm1_generate_ctab(ctx, &ctab); - if (ctx->result) - return ctx->result; - - sm1_generate_vsir(ctx, entry_func, config_flags, &program); - if (ctx->result) - { - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&ctab); - return ctx->result; - } + generate_vsir_signature(ctx, program, entry_func, &semantic_vars); + if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL) + generate_vsir_signature(ctx, program, ctx->patch_constant_func, &patch_semantic_vars);
- result = d3dbc_compile(&program, config_flags, NULL, &ctab, out, ctx->message_context); - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&ctab); - return result; - } - - case VKD3D_SHADER_TARGET_DXBC_TPF: - { - uint32_t config_flags = vkd3d_shader_init_config_flags(); - struct vkd3d_shader_code rdef = {0}; - struct vsir_program program; - int result; - - sm4_generate_rdef(ctx, &rdef); - if (ctx->result) - return ctx->result; - - sm4_generate_vsir(ctx, entry_func, config_flags, &program); - if (ctx->result) - { - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&rdef); - return ctx->result; - } + if (program->shader_version.major < 4) + sm1_generate_ctab(ctx, reflection_data); + else + sm4_generate_rdef(ctx, reflection_data); + if (ctx->result) + return ctx->result;
- result = tpf_compile(&program, config_flags, &rdef, out, ctx->message_context); - vsir_program_cleanup(&program); - vkd3d_shader_free_shader_code(&rdef); - return result; - } + if (program->shader_version.major < 4) + sm1_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, config_flags, program); + else + sm4_generate_vsir(ctx, compile_info, entry_func, &semantic_vars, &body, + &patch_semantic_vars, &patch_body, config_flags, program); + if (ctx->result) + vkd3d_shader_free_shader_code(reflection_data);
- default: - ERR("Unsupported shader target type %#x.\n", target_type); - return VKD3D_ERROR_INVALID_ARGUMENT; - } + return ctx->result; } diff --git a/libs/vkd3d/libs/vkd3d-shader/ir.c b/libs/vkd3d/libs/vkd3d-shader/ir.c index 7466f7a2da1..23e059a3490 100644 --- a/libs/vkd3d/libs/vkd3d-shader/ir.c +++ b/libs/vkd3d/libs/vkd3d-shader/ir.c @@ -29,6 +29,350 @@ struct vsir_transformation_context struct vkd3d_shader_message_context *message_context; };
+const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error) +{ + static const char * const names[] = + { + [VSIR_OP_ABS ] = "abs", + [VSIR_OP_ACOS ] = "acos", + [VSIR_OP_ADD ] = "add", + [VSIR_OP_AND ] = "and", + [VSIR_OP_ASIN ] = "asin", + [VSIR_OP_ATAN ] = "atan", + [VSIR_OP_ATOMIC_AND ] = "atomic_and", + [VSIR_OP_ATOMIC_CMP_STORE ] = "atomic_cmp_store", + [VSIR_OP_ATOMIC_IADD ] = "atomic_iadd", + [VSIR_OP_ATOMIC_IMAX ] = "atomic_imax", + [VSIR_OP_ATOMIC_IMIN ] = "atomic_imin", + [VSIR_OP_ATOMIC_OR ] = "atomic_or", + [VSIR_OP_ATOMIC_UMAX ] = "atomic_umax", + [VSIR_OP_ATOMIC_UMIN ] = "atomic_umin", + [VSIR_OP_ATOMIC_XOR ] = "atomic_xor", + [VSIR_OP_BEM ] = "bem", + [VSIR_OP_BFI ] = "bfi", + [VSIR_OP_BFREV ] = "bfrev", + [VSIR_OP_BRANCH ] = "branch", + [VSIR_OP_BREAK ] = "break", + [VSIR_OP_BREAKC ] = "break", + [VSIR_OP_BREAKP ] = "breakp", + [VSIR_OP_BUFINFO ] = "bufinfo", + [VSIR_OP_CALL ] = "call", + [VSIR_OP_CALLNZ ] = "callnz", + [VSIR_OP_CASE ] = "case", + [VSIR_OP_CHECK_ACCESS_FULLY_MAPPED ] = "check_access_fully_mapped", + [VSIR_OP_CMP ] = "cmp", + [VSIR_OP_CND ] = "cnd", + [VSIR_OP_COS ] = "cos", + [VSIR_OP_CONTINUE ] = "continue", + [VSIR_OP_CONTINUEP ] = "continuec", + [VSIR_OP_COUNTBITS ] = "countbits", + [VSIR_OP_CRS ] = "crs", + [VSIR_OP_CUT ] = "cut", + [VSIR_OP_CUT_STREAM ] = "cut_stream", + [VSIR_OP_DADD ] = "dadd", + [VSIR_OP_DCL ] = "dcl", + [VSIR_OP_DCL_CONSTANT_BUFFER ] = "dcl_constantBuffer", + [VSIR_OP_DCL_FUNCTION_BODY ] = "dcl_function_body", + [VSIR_OP_DCL_FUNCTION_TABLE ] = "dcl_function_table", + [VSIR_OP_DCL_GLOBAL_FLAGS ] = "dcl_globalFlags", + [VSIR_OP_DCL_GS_INSTANCES ] = "dcl_gs_instances", + [VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT] = "dcl_hs_fork_phase_instance_count", + [VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT] = "dcl_hs_join_phase_instance_count", + [VSIR_OP_DCL_HS_MAX_TESSFACTOR ] = "dcl_hs_max_tessfactor", + [VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER ] = "dcl_immediateConstantBuffer", + [VSIR_OP_DCL_INDEX_RANGE ] = "dcl_index_range", + [VSIR_OP_DCL_INDEXABLE_TEMP ] = "dcl_indexableTemp", + [VSIR_OP_DCL_INPUT ] = "dcl_input", + [VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT ] = "dcl_input_control_point_count", + [VSIR_OP_DCL_INPUT_PRIMITIVE ] = "dcl_inputprimitive", + [VSIR_OP_DCL_INPUT_PS ] = "dcl_input_ps", + [VSIR_OP_DCL_INPUT_PS_SGV ] = "dcl_input_ps_sgv", + [VSIR_OP_DCL_INPUT_PS_SIV ] = "dcl_input_ps_siv", + [VSIR_OP_DCL_INPUT_SGV ] = "dcl_input_sgv", + [VSIR_OP_DCL_INPUT_SIV ] = "dcl_input_siv", + [VSIR_OP_DCL_INTERFACE ] = "dcl_interface", + [VSIR_OP_DCL_OUTPUT ] = "dcl_output", + [VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT ] = "dcl_output_control_point_count", + [VSIR_OP_DCL_OUTPUT_SGV ] = "dcl_output_sgv", + [VSIR_OP_DCL_OUTPUT_SIV ] = "dcl_output_siv", + [VSIR_OP_DCL_OUTPUT_TOPOLOGY ] = "dcl_outputtopology", + [VSIR_OP_DCL_RESOURCE_RAW ] = "dcl_resource_raw", + [VSIR_OP_DCL_RESOURCE_STRUCTURED ] = "dcl_resource_structured", + [VSIR_OP_DCL_SAMPLER ] = "dcl_sampler", + [VSIR_OP_DCL_STREAM ] = "dcl_stream", + [VSIR_OP_DCL_TEMPS ] = "dcl_temps", + [VSIR_OP_DCL_TESSELLATOR_DOMAIN ] = "dcl_tessellator_domain", + [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = "dcl_tessellator_output_primitive", + [VSIR_OP_DCL_TESSELLATOR_PARTITIONING ] = "dcl_tessellator_partitioning", + [VSIR_OP_DCL_TGSM_RAW ] = "dcl_tgsm_raw", + [VSIR_OP_DCL_TGSM_STRUCTURED ] = "dcl_tgsm_structured", + [VSIR_OP_DCL_THREAD_GROUP ] = "dcl_thread_group", + [VSIR_OP_DCL_UAV_RAW ] = "dcl_uav_raw", + [VSIR_OP_DCL_UAV_STRUCTURED ] = "dcl_uav_structured", + [VSIR_OP_DCL_UAV_TYPED ] = "dcl_uav_typed", + [VSIR_OP_DCL_VERTICES_OUT ] = "dcl_maxout", + [VSIR_OP_DDIV ] = "ddiv", + [VSIR_OP_DEF ] = "def", + [VSIR_OP_DEFAULT ] = "default", + [VSIR_OP_DEFB ] = "defb", + [VSIR_OP_DEFI ] = "defi", + [VSIR_OP_DEQO ] = "deq", + [VSIR_OP_DFMA ] = "dfma", + [VSIR_OP_DGEO ] = "dge", + [VSIR_OP_DISCARD ] = "discard", + [VSIR_OP_DIV ] = "div", + [VSIR_OP_DLT ] = "dlt", + [VSIR_OP_DMAX ] = "dmax", + [VSIR_OP_DMIN ] = "dmin", + [VSIR_OP_DMOV ] = "dmov", + [VSIR_OP_DMOVC ] = "dmovc", + [VSIR_OP_DMUL ] = "dmul", + [VSIR_OP_DNE ] = "dne", + [VSIR_OP_DP2 ] = "dp2", + [VSIR_OP_DP2ADD ] = "dp2add", + [VSIR_OP_DP3 ] = "dp3", + [VSIR_OP_DP4 ] = "dp4", + [VSIR_OP_DRCP ] = "drcp", + [VSIR_OP_DST ] = "dst", + [VSIR_OP_DSX ] = "dsx", + [VSIR_OP_DSX_COARSE ] = "deriv_rtx_coarse", + [VSIR_OP_DSX_FINE ] = "deriv_rtx_fine", + [VSIR_OP_DSY ] = "dsy", + [VSIR_OP_DSY_COARSE ] = "deriv_rty_coarse", + [VSIR_OP_DSY_FINE ] = "deriv_rty_fine", + [VSIR_OP_DTOF ] = "dtof", + [VSIR_OP_DTOI ] = "dtoi", + [VSIR_OP_DTOU ] = "dtou", + [VSIR_OP_ELSE ] = "else", + [VSIR_OP_EMIT ] = "emit", + [VSIR_OP_EMIT_STREAM ] = "emit_stream", + [VSIR_OP_ENDIF ] = "endif", + [VSIR_OP_ENDLOOP ] = "endloop", + [VSIR_OP_ENDREP ] = "endrep", + [VSIR_OP_ENDSWITCH ] = "endswitch", + [VSIR_OP_EQO ] = "eq", + [VSIR_OP_EQU ] = "eq_unord", + [VSIR_OP_EVAL_CENTROID ] = "eval_centroid", + [VSIR_OP_EVAL_SAMPLE_INDEX ] = "eval_sample_index", + [VSIR_OP_EXP ] = "exp", + [VSIR_OP_EXPP ] = "expp", + [VSIR_OP_F16TOF32 ] = "f16tof32", + [VSIR_OP_F32TOF16 ] = "f32tof16", + [VSIR_OP_FCALL ] = "fcall", + [VSIR_OP_FIRSTBIT_HI ] = "firstbit_hi", + [VSIR_OP_FIRSTBIT_LO ] = "firstbit_lo", + [VSIR_OP_FIRSTBIT_SHI ] = "firstbit_shi", + [VSIR_OP_FRC ] = "frc", + [VSIR_OP_FREM ] = "frem", + [VSIR_OP_FTOD ] = "ftod", + [VSIR_OP_FTOI ] = "ftoi", + [VSIR_OP_FTOU ] = "ftou", + [VSIR_OP_GATHER4 ] = "gather4", + [VSIR_OP_GATHER4_C ] = "gather4_c", + [VSIR_OP_GATHER4_C_S ] = "gather4_c_s", + [VSIR_OP_GATHER4_PO ] = "gather4_po", + [VSIR_OP_GATHER4_PO_C ] = "gather4_po_c", + [VSIR_OP_GATHER4_PO_C_S ] = "gather4_po_c_s", + [VSIR_OP_GATHER4_PO_S ] = "gather4_po_s", + [VSIR_OP_GATHER4_S ] = "gather4_s", + [VSIR_OP_GEO ] = "ge", + [VSIR_OP_GEU ] = "ge_unord", + [VSIR_OP_HCOS ] = "hcos", + [VSIR_OP_HS_CONTROL_POINT_PHASE ] = "hs_control_point_phase", + [VSIR_OP_HS_DECLS ] = "hs_decls", + [VSIR_OP_HS_FORK_PHASE ] = "hs_fork_phase", + [VSIR_OP_HS_JOIN_PHASE ] = "hs_join_phase", + [VSIR_OP_HSIN ] = "hsin", + [VSIR_OP_HTAN ] = "htan", + [VSIR_OP_IADD ] = "iadd", + [VSIR_OP_IBFE ] = "ibfe", + [VSIR_OP_IDIV ] = "idiv", + [VSIR_OP_IEQ ] = "ieq", + [VSIR_OP_IF ] = "if", + [VSIR_OP_IFC ] = "if", + [VSIR_OP_IGE ] = "ige", + [VSIR_OP_ILT ] = "ilt", + [VSIR_OP_IMAD ] = "imad", + [VSIR_OP_IMAX ] = "imax", + [VSIR_OP_IMIN ] = "imin", + [VSIR_OP_IMM_ATOMIC_ALLOC ] = "imm_atomic_alloc", + [VSIR_OP_IMM_ATOMIC_AND ] = "imm_atomic_and", + [VSIR_OP_IMM_ATOMIC_CMP_EXCH ] = "imm_atomic_cmp_exch", + [VSIR_OP_IMM_ATOMIC_CONSUME ] = "imm_atomic_consume", + [VSIR_OP_IMM_ATOMIC_EXCH ] = "imm_atomic_exch", + [VSIR_OP_IMM_ATOMIC_IADD ] = "imm_atomic_iadd", + [VSIR_OP_IMM_ATOMIC_IMAX ] = "imm_atomic_imax", + [VSIR_OP_IMM_ATOMIC_IMIN ] = "imm_atomic_imin", + [VSIR_OP_IMM_ATOMIC_OR ] = "imm_atomic_or", + [VSIR_OP_IMM_ATOMIC_UMAX ] = "imm_atomic_umax", + [VSIR_OP_IMM_ATOMIC_UMIN ] = "imm_atomic_umin", + [VSIR_OP_IMM_ATOMIC_XOR ] = "imm_atomic_xor", + [VSIR_OP_IMUL ] = "imul", + [VSIR_OP_IMUL_LOW ] = "imul_low", + [VSIR_OP_INE ] = "ine", + [VSIR_OP_INEG ] = "ineg", + [VSIR_OP_IREM ] = "irem", + [VSIR_OP_ISFINITE ] = "isfinite", + [VSIR_OP_ISHL ] = "ishl", + [VSIR_OP_ISHR ] = "ishr", + [VSIR_OP_ISINF ] = "isinf", + [VSIR_OP_ISNAN ] = "isnan", + [VSIR_OP_ITOD ] = "itod", + [VSIR_OP_ITOF ] = "itof", + [VSIR_OP_ITOI ] = "itoi", + [VSIR_OP_LABEL ] = "label", + [VSIR_OP_LD ] = "ld", + [VSIR_OP_LD2DMS ] = "ld2dms", + [VSIR_OP_LD2DMS_S ] = "ld2dms_s", + [VSIR_OP_LD_RAW ] = "ld_raw", + [VSIR_OP_LD_RAW_S ] = "ld_raw_s", + [VSIR_OP_LD_S ] = "ld_s", + [VSIR_OP_LD_STRUCTURED ] = "ld_structured", + [VSIR_OP_LD_STRUCTURED_S ] = "ld_structured_s", + [VSIR_OP_LD_UAV_TYPED ] = "ld_uav_typed", + [VSIR_OP_LD_UAV_TYPED_S ] = "ld_uav_typed_s", + [VSIR_OP_LIT ] = "lit", + [VSIR_OP_LOD ] = "lod", + [VSIR_OP_LOG ] = "log", + [VSIR_OP_LOGP ] = "logp", + [VSIR_OP_LOOP ] = "loop", + [VSIR_OP_LRP ] = "lrp", + [VSIR_OP_LTO ] = "lt", + [VSIR_OP_LTU ] = "lt_unord", + [VSIR_OP_M3x2 ] = "m3x2", + [VSIR_OP_M3x3 ] = "m3x3", + [VSIR_OP_M3x4 ] = "m3x4", + [VSIR_OP_M4x3 ] = "m4x3", + [VSIR_OP_M4x4 ] = "m4x4", + [VSIR_OP_MAD ] = "mad", + [VSIR_OP_MAX ] = "max", + [VSIR_OP_MIN ] = "min", + [VSIR_OP_MOV ] = "mov", + [VSIR_OP_MOVA ] = "mova", + [VSIR_OP_MOVC ] = "movc", + [VSIR_OP_MSAD ] = "msad", + [VSIR_OP_MUL ] = "mul", + [VSIR_OP_NEO ] = "ne_ord", + [VSIR_OP_NEU ] = "ne", + [VSIR_OP_NOP ] = "nop", + [VSIR_OP_NOT ] = "not", + [VSIR_OP_NRM ] = "nrm", + [VSIR_OP_OR ] = "or", + [VSIR_OP_ORD ] = "ord", + [VSIR_OP_PHASE ] = "phase", + [VSIR_OP_PHI ] = "phi", + [VSIR_OP_POW ] = "pow", + [VSIR_OP_QUAD_READ_ACROSS_D ] = "quad_read_across_d", + [VSIR_OP_QUAD_READ_ACROSS_X ] = "quad_read_across_x", + [VSIR_OP_QUAD_READ_ACROSS_Y ] = "quad_read_across_y", + [VSIR_OP_QUAD_READ_LANE_AT ] = "quad_read_lane_at", + [VSIR_OP_RCP ] = "rcp", + [VSIR_OP_REP ] = "rep", + [VSIR_OP_RESINFO ] = "resinfo", + [VSIR_OP_RET ] = "ret", + [VSIR_OP_RETP ] = "retp", + [VSIR_OP_ROUND_NE ] = "round_ne", + [VSIR_OP_ROUND_NI ] = "round_ni", + [VSIR_OP_ROUND_PI ] = "round_pi", + [VSIR_OP_ROUND_Z ] = "round_z", + [VSIR_OP_RSQ ] = "rsq", + [VSIR_OP_SAMPLE ] = "sample", + [VSIR_OP_SAMPLE_B ] = "sample_b", + [VSIR_OP_SAMPLE_B_CL_S ] = "sample_b_cl_s", + [VSIR_OP_SAMPLE_C ] = "sample_c", + [VSIR_OP_SAMPLE_C_CL_S ] = "sample_c_cl_s", + [VSIR_OP_SAMPLE_C_LZ ] = "sample_c_lz", + [VSIR_OP_SAMPLE_C_LZ_S ] = "sample_c_lz_s", + [VSIR_OP_SAMPLE_CL_S ] = "sample_cl_s", + [VSIR_OP_SAMPLE_GRAD ] = "sample_d", + [VSIR_OP_SAMPLE_GRAD_CL_S ] = "sample_d_cl_s", + [VSIR_OP_SAMPLE_INFO ] = "sample_info", + [VSIR_OP_SAMPLE_LOD ] = "sample_l", + [VSIR_OP_SAMPLE_LOD_S ] = "sample_l_s", + [VSIR_OP_SAMPLE_POS ] = "sample_pos", + [VSIR_OP_SETP ] = "setp", + [VSIR_OP_SGE ] = "sge", + [VSIR_OP_SGN ] = "sgn", + [VSIR_OP_SIN ] = "sin", + [VSIR_OP_SINCOS ] = "sincos", + [VSIR_OP_SLT ] = "slt", + [VSIR_OP_SQRT ] = "sqrt", + [VSIR_OP_STORE_RAW ] = "store_raw", + [VSIR_OP_STORE_STRUCTURED ] = "store_structured", + [VSIR_OP_STORE_UAV_TYPED ] = "store_uav_typed", + [VSIR_OP_SUB ] = "sub", + [VSIR_OP_SWAPC ] = "swapc", + [VSIR_OP_SWITCH ] = "switch", + [VSIR_OP_SWITCH_MONOLITHIC ] = "switch", + [VSIR_OP_SYNC ] = "sync", + [VSIR_OP_TAN ] = "tan", + [VSIR_OP_TEX ] = "tex", + [VSIR_OP_TEXBEM ] = "texbem", + [VSIR_OP_TEXBEML ] = "texbeml", + [VSIR_OP_TEXCOORD ] = "texcoord", + [VSIR_OP_TEXCRD ] = "texcrd", + [VSIR_OP_TEXDEPTH ] = "texdepth", + [VSIR_OP_TEXDP3 ] = "texdp3", + [VSIR_OP_TEXDP3TEX ] = "texdp3tex", + [VSIR_OP_TEXKILL ] = "texkill", + [VSIR_OP_TEXLD ] = "texld", + [VSIR_OP_TEXLDD ] = "texldd", + [VSIR_OP_TEXLDL ] = "texldl", + [VSIR_OP_TEXM3x2DEPTH ] = "texm3x2depth", + [VSIR_OP_TEXM3x2PAD ] = "texm3x2pad", + [VSIR_OP_TEXM3x2TEX ] = "texm3x2tex", + [VSIR_OP_TEXM3x3 ] = "texm3x3", + [VSIR_OP_TEXM3x3DIFF ] = "texm3x3diff", + [VSIR_OP_TEXM3x3PAD ] = "texm3x3pad", + [VSIR_OP_TEXM3x3SPEC ] = "texm3x3spec", + [VSIR_OP_TEXM3x3TEX ] = "texm3x3tex", + [VSIR_OP_TEXM3x3VSPEC ] = "texm3x3vspec", + [VSIR_OP_TEXREG2AR ] = "texreg2ar", + [VSIR_OP_TEXREG2GB ] = "texreg2gb", + [VSIR_OP_TEXREG2RGB ] = "texreg2rgb", + [VSIR_OP_UBFE ] = "ubfe", + [VSIR_OP_UDIV ] = "udiv", + [VSIR_OP_UDIV_SIMPLE ] = "udiv_simple", + [VSIR_OP_UGE ] = "uge", + [VSIR_OP_ULT ] = "ult", + [VSIR_OP_UMAX ] = "umax", + [VSIR_OP_UMIN ] = "umin", + [VSIR_OP_UMUL ] = "umul", + [VSIR_OP_UNO ] = "uno", + [VSIR_OP_UREM ] = "urem", + [VSIR_OP_USHR ] = "ushr", + [VSIR_OP_UTOD ] = "utod", + [VSIR_OP_UTOF ] = "utof", + [VSIR_OP_UTOU ] = "utou", + [VSIR_OP_WAVE_ACTIVE_ALL_EQUAL ] = "wave_active_all_equal", + [VSIR_OP_WAVE_ACTIVE_BALLOT ] = "wave_active_ballot", + [VSIR_OP_WAVE_ACTIVE_BIT_AND ] = "wave_active_bit_and", + [VSIR_OP_WAVE_ACTIVE_BIT_OR ] = "wave_active_bit_or", + [VSIR_OP_WAVE_ACTIVE_BIT_XOR ] = "wave_active_bit_xor", + [VSIR_OP_WAVE_ALL_BIT_COUNT ] = "wave_all_bit_count", + [VSIR_OP_WAVE_ALL_TRUE ] = "wave_all_true", + [VSIR_OP_WAVE_ANY_TRUE ] = "wave_any_true", + [VSIR_OP_WAVE_IS_FIRST_LANE ] = "wave_is_first_lane", + [VSIR_OP_WAVE_OP_ADD ] = "wave_op_add", + [VSIR_OP_WAVE_OP_IMAX ] = "wave_op_imax", + [VSIR_OP_WAVE_OP_IMIN ] = "wave_op_imin", + [VSIR_OP_WAVE_OP_MAX ] = "wave_op_max", + [VSIR_OP_WAVE_OP_MIN ] = "wave_op_min", + [VSIR_OP_WAVE_OP_MUL ] = "wave_op_mul", + [VSIR_OP_WAVE_OP_UMAX ] = "wave_op_umax", + [VSIR_OP_WAVE_OP_UMIN ] = "wave_op_umin", + [VSIR_OP_WAVE_PREFIX_BIT_COUNT ] = "wave_prefix_bit_count", + [VSIR_OP_WAVE_READ_LANE_AT ] = "wave_read_lane_at", + [VSIR_OP_WAVE_READ_LANE_FIRST ] = "wave_read_lane_first", + [VSIR_OP_XOR ] = "xor", + }; + + if ((uint32_t)op < ARRAY_SIZE(names)) + return names[op] ? names[op] : error; + + return error; +} + static int convert_parameter_info(const struct vkd3d_shader_compile_info *compile_info, unsigned int *ret_count, const struct vkd3d_shader_parameter1 **ret_parameters) { @@ -100,7 +444,16 @@ bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_c program->shader_version = *version; program->cf_type = cf_type; program->normalisation_level = normalisation_level; - return shader_instruction_array_init(&program->instructions, reserve); + if (!shader_instruction_array_init(&program->instructions, reserve)) + { + if (program->free_parameters) + vkd3d_free((void *)program->parameters); + return false; + } + + vkd3d_shader_source_list_init(&program->source_files); + + return true; }
void vsir_program_cleanup(struct vsir_program *program) @@ -112,6 +465,7 @@ void vsir_program_cleanup(struct vsir_program *program) for (i = 0; i < program->block_name_count; ++i) vkd3d_free((void *)program->block_names[i]); vkd3d_free(program->block_names); + vkd3d_shader_source_list_cleanup(&program->source_files); shader_instruction_array_destroy(&program->instructions); shader_signature_cleanup(&program->input_signature); shader_signature_cleanup(&program->output_signature); @@ -163,8 +517,55 @@ bool vsir_signature_find_sysval(const struct shader_signature *signature, return false; }
+const char *debug_vsir_writemask(unsigned int writemask) +{ + static const char components[] = {'x', 'y', 'z', 'w'}; + char string[5]; + unsigned int i = 0, pos = 0; + + VKD3D_ASSERT(!(writemask & ~VKD3DSP_WRITEMASK_ALL)); + + while (writemask) + { + if (writemask & 1) + string[pos++] = components[i]; + writemask >>= 1; + i++; + } + string[pos] = '\0'; + return vkd3d_dbg_sprintf(".%s", string); +} + +static unsigned int vsir_combine_write_masks(unsigned int first, unsigned int second) +{ + unsigned int ret = 0, j = 0; + + for (unsigned int i = 0; i < VKD3D_VEC4_SIZE; ++i) + { + if (first & (1u << i)) + { + if (second & (1u << j++)) + ret |= (1u << i); + } + } + + return ret; +} + +static uint32_t vsir_combine_swizzles(uint32_t first, uint32_t second) +{ + uint32_t ret = 0; + + for (unsigned int i = 0; i < VKD3D_VEC4_SIZE; ++i) + { + unsigned int s = vsir_swizzle_get_component(second, i); + vsir_swizzle_set_component(&ret, i, vsir_swizzle_get_component(first, s)); + } + return ret; +} + void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count) + enum vsir_data_type data_type, unsigned int idx_count) { reg->type = reg_type; reg->precision = VKD3D_SHADER_REGISTER_PRECISION_DEFAULT; @@ -190,7 +591,7 @@ static inline bool shader_register_is_phase_instance_id(const struct vkd3d_shade }
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count) + enum vsir_data_type data_type, unsigned int idx_count) { vsir_register_init(¶m->reg, reg_type, data_type, idx_count); param->swizzle = 0; @@ -199,32 +600,32 @@ void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader
static void src_param_init_const_uint(struct vkd3d_shader_src_param *src, uint32_t value) { - vsir_src_param_init(src, VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); + vsir_src_param_init(src, VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); src->reg.u.immconst_u32[0] = value; }
static void vsir_src_param_init_io(struct vkd3d_shader_src_param *src, enum vkd3d_shader_register_type reg_type, const struct signature_element *e, unsigned int idx_count) { - vsir_src_param_init(src, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); + vsir_src_param_init(src, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count); src->reg.dimension = VSIR_DIMENSION_VEC4; src->swizzle = vsir_swizzle_from_writemask(e->mask); }
void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id) { - vsir_src_param_init(param, VKD3DSPR_LABEL, VKD3D_DATA_UNUSED, 1); + vsir_src_param_init(param, VKD3DSPR_LABEL, VSIR_DATA_UNUSED, 1); param->reg.dimension = VSIR_DIMENSION_NONE; param->reg.idx[0].offset = label_id; }
-static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type) +static void src_param_init_parameter(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type) { vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1); src->reg.idx[0].offset = idx; }
-static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vkd3d_data_type type) +static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, uint32_t idx, enum vsir_data_type type) { vsir_src_param_init(src, VKD3DSPR_PARAMETER, type, 1); src->reg.idx[0].offset = idx; @@ -234,7 +635,7 @@ static void src_param_init_parameter_vec4(struct vkd3d_shader_src_param *src, ui
static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_RESOURCE, VKD3D_DATA_UNUSED, 2); + vsir_src_param_init(src, VKD3DSPR_RESOURCE, VSIR_DATA_UNUSED, 2); src->reg.idx[0].offset = id; src->reg.idx[1].offset = idx; src->reg.dimension = VSIR_DIMENSION_VEC4; @@ -243,47 +644,61 @@ static void vsir_src_param_init_resource(struct vkd3d_shader_src_param *src, uns
static void vsir_src_param_init_sampler(struct vkd3d_shader_src_param *src, unsigned int id, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_SAMPLER, VKD3D_DATA_UNUSED, 2); + vsir_src_param_init(src, VKD3DSPR_SAMPLER, VSIR_DATA_UNUSED, 2); src->reg.idx[0].offset = id; src->reg.idx[1].offset = idx; src->reg.dimension = VSIR_DIMENSION_NONE; }
-static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx) +static void src_param_init_ssa(struct vkd3d_shader_src_param *src, unsigned int idx, + enum vsir_data_type data_type, enum vsir_dimension dimension) { - vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); + vsir_src_param_init(src, VKD3DSPR_SSA, data_type, 1); src->reg.idx[0].offset = idx; + + if (dimension == VSIR_DIMENSION_VEC4) + { + src->reg.dimension = VSIR_DIMENSION_VEC4; + src->swizzle = VKD3D_SHADER_NO_SWIZZLE; + } +} + +static void src_param_init_ssa_scalar(struct vkd3d_shader_src_param *src, + unsigned int idx, enum vsir_data_type data_type) +{ + src_param_init_ssa(src, idx, data_type, VSIR_DIMENSION_SCALAR); +} + +static void src_param_init_ssa_bool(struct vkd3d_shader_src_param *src, unsigned int idx) +{ + src_param_init_ssa_scalar(src, idx, VSIR_DATA_BOOL); }
static void src_param_init_ssa_float(struct vkd3d_shader_src_param *src, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1); - src->reg.idx[0].offset = idx; + src_param_init_ssa_scalar(src, idx, VSIR_DATA_F32); }
static void src_param_init_ssa_float4(struct vkd3d_shader_src_param *src, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1); - src->reg.idx[0].offset = idx; - src->reg.dimension = VSIR_DIMENSION_VEC4; - src->swizzle = VKD3D_SHADER_NO_SWIZZLE; + src_param_init_ssa(src, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4); }
static void src_param_init_temp_bool(struct vkd3d_shader_src_param *src, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1); + vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1); src->reg.idx[0].offset = idx; }
static void src_param_init_temp_float(struct vkd3d_shader_src_param *src, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); src->reg.idx[0].offset = idx; }
static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); src->reg.dimension = VSIR_DIMENSION_VEC4; src->swizzle = VKD3D_SHADER_NO_SWIZZLE; src->reg.idx[0].offset = idx; @@ -291,12 +706,12 @@ static void src_param_init_temp_float4(struct vkd3d_shader_src_param *src, unsig
static void src_param_init_temp_uint(struct vkd3d_shader_src_param *src, unsigned int idx) { - vsir_src_param_init(src, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_src_param_init(src, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); src->reg.idx[0].offset = idx; }
void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count) + enum vsir_data_type data_type, unsigned int idx_count) { vsir_register_init(¶m->reg, reg_type, data_type, idx_count); param->write_mask = VKD3DSP_WRITEMASK_0; @@ -307,59 +722,73 @@ void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader static void vsir_dst_param_init_io(struct vkd3d_shader_dst_param *dst, enum vkd3d_shader_register_type reg_type, const struct signature_element *e, unsigned int idx_count) { - vsir_dst_param_init(dst, reg_type, vkd3d_data_type_from_component_type(e->component_type), idx_count); + vsir_dst_param_init(dst, reg_type, vsir_data_type_from_component_type(e->component_type), idx_count); dst->reg.dimension = VSIR_DIMENSION_VEC4; dst->write_mask = e->mask; }
void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst) { - vsir_dst_param_init(dst, VKD3DSPR_NULL, VKD3D_DATA_UNUSED, 0); + vsir_dst_param_init(dst, VKD3DSPR_NULL, VSIR_DATA_UNUSED, 0); dst->reg.dimension = VSIR_DIMENSION_NONE; dst->write_mask = 0; }
-static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) +static void dst_param_init_ssa(struct vkd3d_shader_dst_param *dst, unsigned int idx, + enum vsir_data_type data_type, enum vsir_dimension dimension) { - vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_BOOL, 1); + vsir_dst_param_init(dst, VKD3DSPR_SSA, data_type, 1); dst->reg.idx[0].offset = idx; + + if (dimension == VSIR_DIMENSION_VEC4) + { + dst->reg.dimension = VSIR_DIMENSION_VEC4; + dst->write_mask = VKD3DSP_WRITEMASK_ALL; + } +} + +static void dst_param_init_ssa_scalar(struct vkd3d_shader_dst_param *dst, + unsigned int idx, enum vsir_data_type data_type) +{ + dst_param_init_ssa(dst, idx, data_type, VSIR_DIMENSION_SCALAR); +} + +static void dst_param_init_ssa_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) +{ + dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_BOOL); }
static void dst_param_init_ssa_float(struct vkd3d_shader_dst_param *dst, unsigned int idx) { - vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1); - dst->reg.idx[0].offset = idx; + dst_param_init_ssa_scalar(dst, idx, VSIR_DATA_F32); }
static void dst_param_init_ssa_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx) { - vsir_dst_param_init(dst, VKD3DSPR_SSA, VKD3D_DATA_FLOAT, 1); - dst->reg.idx[0].offset = idx; - dst->reg.dimension = VSIR_DIMENSION_VEC4; - dst->write_mask = VKD3DSP_WRITEMASK_ALL; + dst_param_init_ssa(dst, idx, VSIR_DATA_F32, VSIR_DIMENSION_VEC4); }
static void dst_param_init_temp_bool(struct vkd3d_shader_dst_param *dst, unsigned int idx) { - vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_BOOL, 1); + vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_BOOL, 1); dst->reg.idx[0].offset = idx; }
static void dst_param_init_temp_float4(struct vkd3d_shader_dst_param *dst, unsigned int idx) { - vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); dst->reg.idx[0].offset = idx; dst->reg.dimension = VSIR_DIMENSION_VEC4; }
static void dst_param_init_temp_uint(struct vkd3d_shader_dst_param *dst, unsigned int idx) { - vsir_dst_param_init(dst, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_dst_param_init(dst, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); dst->reg.idx[0].offset = idx; }
static void dst_param_init_output(struct vkd3d_shader_dst_param *dst, - enum vkd3d_data_type data_type, uint32_t idx, uint32_t write_mask) + enum vsir_data_type data_type, uint32_t idx, uint32_t write_mask) { vsir_dst_param_init(dst, VKD3DSPR_OUTPUT, data_type, 1); dst->reg.idx[0].offset = idx; @@ -373,6 +802,10 @@ void vsir_instruction_init(struct vkd3d_shader_instruction *ins, const struct vk memset(ins, 0, sizeof(*ins)); ins->location = *location; ins->opcode = opcode; + ins->resource_data_type[0] = VSIR_DATA_F32; + ins->resource_data_type[1] = VSIR_DATA_F32; + ins->resource_data_type[2] = VSIR_DATA_F32; + ins->resource_data_type[3] = VSIR_DATA_F32; }
bool vsir_instruction_init_with_params(struct vsir_program *program, @@ -410,7 +843,7 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins,
vsir_src_param_init_label(src_param, label_id);
- vsir_instruction_init(ins, location, VKD3DSIH_LABEL); + vsir_instruction_init(ins, location, VSIR_OP_LABEL); ins->src = src_param; ins->src_count = 1;
@@ -420,28 +853,28 @@ static bool vsir_instruction_init_label(struct vkd3d_shader_instruction *ins, static bool vsir_instruction_is_dcl(const struct vkd3d_shader_instruction *instruction) { enum vkd3d_shader_opcode opcode = instruction->opcode; - return (VKD3DSIH_DCL <= opcode && opcode <= VKD3DSIH_DCL_VERTICES_OUT) - || opcode == VKD3DSIH_HS_DECLS; + return (VSIR_OP_DCL <= opcode && opcode <= VSIR_OP_DCL_VERTICES_OUT) + || opcode == VSIR_OP_HS_DECLS; }
static void vkd3d_shader_instruction_make_nop(struct vkd3d_shader_instruction *ins) { struct vkd3d_shader_location location = ins->location;
- vsir_instruction_init(ins, &location, VKD3DSIH_NOP); + vsir_instruction_init(ins, &location, VSIR_OP_NOP); }
-static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_data_type data_type, - enum vkd3d_shader_opcode *opcode, bool *requires_swap) +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) { switch (rel_op) { case VKD3D_SHADER_REL_OP_LT: case VKD3D_SHADER_REL_OP_GT: *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_GT); - if (data_type == VKD3D_DATA_FLOAT) + if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_LTO; + *opcode = VSIR_OP_LTO; return true; } break; @@ -449,27 +882,27 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d case VKD3D_SHADER_REL_OP_GE: case VKD3D_SHADER_REL_OP_LE: *requires_swap = (rel_op == VKD3D_SHADER_REL_OP_LE); - if (data_type == VKD3D_DATA_FLOAT) + if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_GEO; + *opcode = VSIR_OP_GEO; return true; } break;
case VKD3D_SHADER_REL_OP_EQ: *requires_swap = false; - if (data_type == VKD3D_DATA_FLOAT) + if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_EQO; + *opcode = VSIR_OP_EQO; return true; } break;
case VKD3D_SHADER_REL_OP_NE: *requires_swap = false; - if (data_type == VKD3D_DATA_FLOAT) + if (data_type == VSIR_DATA_F32) { - *opcode = VKD3DSIH_NEO; + *opcode = VSIR_OP_NEO; return true; } break; @@ -480,48 +913,47 @@ static bool get_opcode_from_rel_op(enum vkd3d_shader_rel_op rel_op, enum vkd3d_d static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_instruction *ins, *ins2; unsigned int tmp_idx = ~0u; - unsigned int i, k, r; + unsigned int k, r;
- for (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 (ins->opcode == VKD3DSIH_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR) + if (ins->opcode == VSIR_OP_MOV && ins->dst[0].reg.type == VKD3DSPR_ADDR) { if (tmp_idx == ~0u) tmp_idx = program->temp_count++;
- ins->opcode = VKD3DSIH_FTOU; - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + ins->opcode = VSIR_OP_FTOU; + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->dst[0].reg.idx[0].offset = tmp_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; } - else if (ins->opcode == VKD3DSIH_MOVA) + else if (ins->opcode == VSIR_OP_MOVA) { if (tmp_idx == ~0u) tmp_idx = program->temp_count++;
- 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]; - ins2 = &program->instructions.elements[i + 1]; + ins = vsir_program_iterator_current(&it);
- ins->opcode = VKD3DSIH_ROUND_NE; - vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + ins->opcode = VSIR_OP_ROUND_NE; + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = tmp_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4;
- if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VKD3DSIH_FTOU, 1, 1)) + ins2 = vsir_program_iterator_next(&it); + if (!vsir_instruction_init_with_params(program, ins2, &ins->location, VSIR_OP_FTOU, 1, 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins2->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins2->dst[0].reg.idx[0].offset = tmp_idx; ins2->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins2->dst[0].write_mask = ins->dst[0].write_mask;
- vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + vsir_register_init(&ins2->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_F32, 1); ins2->src[0].reg.idx[0].offset = tmp_idx; ins2->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins2->src[0].swizzle = vsir_swizzle_from_writemask(ins2->dst[0].write_mask); @@ -540,7 +972,7 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra if (tmp_idx == ~0u) tmp_idx = program->temp_count++;
- vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&rel->reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); rel->reg.idx[0].offset = tmp_idx; rel->reg.dimension = VSIR_DIMENSION_VEC4; } @@ -552,18 +984,16 @@ static enum vkd3d_result vsir_program_normalize_addr(struct vsir_program *progra }
static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, - struct vkd3d_shader_instruction *ifc, unsigned int *tmp_idx, + struct vsir_program_iterator *it, unsigned int *tmp_idx, struct vkd3d_shader_message_context *message_context) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - size_t pos = ifc - instructions->elements; - struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_instruction *ifc, *ins; enum vkd3d_shader_opcode opcode; bool swap;
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) + if (!vsir_program_iterator_insert_after(it, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; - ifc = &instructions->elements[pos]; + ifc = vsir_program_iterator_current(it);
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++; @@ -577,11 +1007,11 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, return VKD3D_ERROR_NOT_IMPLEMENTED; }
- ins = &instructions->elements[pos + 1]; + ins = vsir_program_iterator_next(it); if (!vsir_instruction_init_with_params(program, ins, &ifc->location, opcode, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].reg.idx[0].offset = *tmp_idx; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; @@ -590,12 +1020,12 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, ins->src[1] = ifc->src[!swap];
/* Create new if instruction using the previous result. */ - ins = &instructions->elements[pos + 2]; - if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VKD3DSIH_IF, 0, 1)) + ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &ifc->location, VSIR_OP_IF, 0, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[0].reg.idx[0].offset = *tmp_idx; ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); @@ -607,35 +1037,33 @@ static enum vkd3d_result vsir_program_lower_ifc(struct vsir_program *program, }
static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program, - struct vkd3d_shader_instruction *texkill, unsigned int *tmp_idx) + struct vsir_program_iterator *it, unsigned int *tmp_idx) { const unsigned int components_read = 3 + (program->shader_version.major >= 2); - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - size_t pos = texkill - instructions->elements; - struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_instruction *ins, *texkill; unsigned int j;
- if (!shader_instruction_array_insert_at(instructions, pos + 1, components_read + 1)) + if (!vsir_program_iterator_insert_after(it, components_read + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - texkill = &instructions->elements[pos]; + texkill = vsir_program_iterator_current(it);
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++;
/* tmp = ins->src[0] < 0 */
- ins = &instructions->elements[pos + 1]; - if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_LTO, 1, 2)) + ins = vsir_program_iterator_next(it); + if (!vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_LTO, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].reg.idx[0].offset = *tmp_idx; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL;
ins->src[0].reg = texkill->src[0].reg; ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&ins->src[1].reg, VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].reg.u.immconst_f32[0] = 0.0f; ins->src[1].reg.u.immconst_f32[1] = 0.0f; @@ -648,20 +1076,20 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
for (j = 1; j < components_read; ++j) { - ins = &instructions->elements[pos + 1 + j]; - if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_OR, 1, 2))) + ins = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_OR, 1, 2))) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins->dst[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].reg.idx[0].offset = *tmp_idx; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0;
- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[0].reg.idx[0].offset = *tmp_idx; ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); - vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins->src[1].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[1].reg.idx[0].offset = *tmp_idx; ins->src[1].swizzle = vkd3d_shader_create_swizzle(j, j, j, j); @@ -669,12 +1097,12 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program
/* discard_nz tmp.x */
- ins = &instructions->elements[pos + 1 + components_read]; - if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VKD3DSIH_DISCARD, 0, 1))) + ins = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, ins, &texkill->location, VSIR_OP_DISCARD, 0, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; ins->flags = VKD3D_SHADER_CONDITIONAL_OP_NZ;
- vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VKD3D_DATA_UINT, 1); + vsir_register_init(&ins->src[0].reg, VKD3DSPR_TEMP, VSIR_DATA_U32, 1); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[0].reg.idx[0].offset = *tmp_idx; ins->src[0].swizzle = VKD3D_SHADER_SWIZZLE(X, X, X, X); @@ -692,30 +1120,29 @@ static enum vkd3d_result vsir_program_lower_texkill(struct vsir_program *program * not fused for "precise" operations." * Windows drivers seem to conform with the latter, for SM 4-5 and SM 6. */ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *program, - struct vkd3d_shader_instruction *mad, unsigned int *tmp_idx) + struct vsir_program_iterator *it, unsigned int *tmp_idx) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - struct vkd3d_shader_instruction *mul_ins, *add_ins; - size_t pos = mad - instructions->elements; + struct vkd3d_shader_instruction *mad, *mul_ins, *add_ins; struct vkd3d_shader_dst_param *mul_dst;
+ mad = vsir_program_iterator_current(it); + if (!(mad->flags & VKD3DSI_PRECISE_XYZW)) return VKD3D_OK;
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) + if (!vsir_program_iterator_insert_after(it, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - mad = &instructions->elements[pos];
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++;
- mul_ins = &instructions->elements[pos]; - add_ins = &instructions->elements[pos + 1]; + mul_ins = vsir_program_iterator_current(it); + add_ins = vsir_program_iterator_next(it);
- mul_ins->opcode = VKD3DSIH_MUL; + mul_ins->opcode = VSIR_OP_MUL; mul_ins->src_count = 2;
- if (!(vsir_instruction_init_with_params(program, add_ins, &mul_ins->location, VKD3DSIH_ADD, 1, 2))) + if (!(vsir_instruction_init_with_params(program, add_ins, &mul_ins->location, VSIR_OP_ADD, 1, 2))) return VKD3D_ERROR_OUT_OF_MEMORY;
add_ins->flags = mul_ins->flags & VKD3DSI_PRECISE_XYZW; @@ -736,84 +1163,308 @@ static enum vkd3d_result vsir_program_lower_precise_mad(struct vsir_program *pro return VKD3D_OK; }
-static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, - struct vkd3d_shader_instruction *sincos) +static enum vkd3d_result vsir_program_lower_imul(struct vsir_program *program, + struct vkd3d_shader_instruction *imul, struct vsir_transformation_context *ctx) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - size_t pos = sincos - instructions->elements; - struct vkd3d_shader_instruction *ins; - unsigned int s; + if (imul->dst[0].reg.type != VKD3DSPR_NULL) + { + vkd3d_shader_error(ctx->message_context, &imul->location, + VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Extended multiplication is not implemented."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + }
- if (sincos->dst_count != 1) - return VKD3D_OK; + imul->dst[0] = imul->dst[1]; + imul->dst_count = 1; + imul->opcode = VSIR_OP_IMUL_LOW; + + return VKD3D_OK; +} + +static enum vkd3d_result vsir_program_lower_udiv(struct vsir_program *program, + struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) +{ + struct vkd3d_shader_instruction *udiv, *ins, *mov; + unsigned int count = 2; + + udiv = vsir_program_iterator_current(it); + + if (udiv->dst_count != 2) + { + vkd3d_shader_error(ctx->message_context, &udiv->location, + VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, + "Internal compiler error: invalid destination count %zu for UDIV.", + udiv->dst_count); + return VKD3D_ERROR; + } + + if (udiv->dst[0].reg.type != VKD3DSPR_NULL) + ++count; + if (udiv->dst[1].reg.type != VKD3DSPR_NULL) + ++count; + + if (!vsir_program_iterator_insert_after(it, count)) + return VKD3D_ERROR_OUT_OF_MEMORY; + udiv = vsir_program_iterator_current(it); + + /* Save the sources in a SSA in case a destination collides with a source. */ + mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + mov->src[0] = udiv->src[0]; + dst_param_init_ssa(&mov->dst[0], program->ssa_count, udiv->src[0].reg.data_type, udiv->src[0].reg.dimension);
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 1)) + mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &udiv->location, VSIR_OP_MOV, 1, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; - sincos = &instructions->elements[pos];
- ins = &instructions->elements[pos + 1]; + mov->src[0] = udiv->src[1]; + dst_param_init_ssa(&mov->dst[0], program->ssa_count + 1, udiv->src[1].reg.data_type, udiv->src[1].reg.dimension);
- if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VKD3DSIH_SINCOS, 2, 1))) + if (udiv->dst[0].reg.type != VKD3DSPR_NULL) + { + ins = vsir_program_iterator_next(it); + + if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UDIV_SIMPLE, 1, 2))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins->flags = udiv->flags; + + src_param_init_ssa(&ins->src[0], program->ssa_count, + udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); + src_param_init_ssa(&ins->src[1], program->ssa_count + 1, + udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + ins->dst[0] = udiv->dst[0]; + } + + if (udiv->dst[1].reg.type != VKD3DSPR_NULL) + { + ins = vsir_program_iterator_next(it); + + if (!(vsir_instruction_init_with_params(program, ins, &udiv->location, VSIR_OP_UREM, 1, 2))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins->flags = udiv->flags; + + src_param_init_ssa(&ins->src[0], program->ssa_count, + udiv->src[0].reg.data_type, udiv->src[0].reg.dimension); + src_param_init_ssa(&ins->src[1], program->ssa_count + 1, + udiv->src[1].reg.data_type, udiv->src[1].reg.dimension); + ins->dst[0] = udiv->dst[1]; + } + + vkd3d_shader_instruction_make_nop(udiv); + program->ssa_count += 2; + + return VKD3D_OK; +} + +static enum vkd3d_result vsir_program_lower_sm1_sincos(struct vsir_program *program, + struct vsir_program_iterator *it) +{ + struct vkd3d_shader_instruction *ins, *mov, *sincos; + unsigned int s, count; + + sincos = vsir_program_iterator_current(it); + count = 1 + vkd3d_popcount(sincos->dst[0].write_mask & (VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1)); + + if (!vsir_program_iterator_insert_after(it, count)) + return VKD3D_ERROR_OUT_OF_MEMORY; + sincos = vsir_program_iterator_current(it); + + /* Save the source in a SSA in case a destination collides with the source. */ + mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1))) return VKD3D_ERROR_OUT_OF_MEMORY;
- ins->flags = sincos->flags; + mov->src[0] = sincos->src[0];
- *ins->src = *sincos->src; /* Set the source swizzle to replicate the first component. */ s = vsir_swizzle_get_component(sincos->src->swizzle, 0); - ins->src->swizzle = vkd3d_shader_create_swizzle(s, s, s, s); + mov->src[0].swizzle = vkd3d_shader_create_swizzle(s, s, s, s); + + dst_param_init_ssa_scalar(&mov->dst[0], program->ssa_count, sincos->src[0].reg.data_type);
if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_1) { + ins = vsir_program_iterator_next(it); + + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins->flags = sincos->flags; + + src_param_init_ssa_scalar(&ins->src[0], program->ssa_count, sincos->src[0].reg.data_type); + ins->dst[0] = *sincos->dst; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_1; } - else + + if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) { - vsir_dst_param_init_null(&ins->dst[0]); + ins = vsir_program_iterator_next(it); + + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins->flags = sincos->flags; + + src_param_init_ssa_scalar(&ins->src[0], program->ssa_count, sincos->src[0].reg.data_type); + + ins->dst[0] = *sincos->dst; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_0; }
- if (sincos->dst->write_mask & VKD3DSP_WRITEMASK_0) + vkd3d_shader_instruction_make_nop(sincos); + ++program->ssa_count; + + return VKD3D_OK; +} + +static enum vkd3d_result vsir_program_lower_sm4_sincos(struct vsir_program *program, + struct vsir_program_iterator *it, struct vsir_transformation_context *ctx) +{ + struct vkd3d_shader_instruction *ins, *mov, *sincos; + unsigned int count = 1; + + sincos = vsir_program_iterator_current(it); + + if (sincos->dst_count != 2) { - ins->dst[1] = *sincos->dst; - ins->dst[1].write_mask = VKD3DSP_WRITEMASK_0; + vkd3d_shader_error(ctx->message_context, &sincos->location, + VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, + "Internal compiler error: invalid destination count %zu for SINCOS.", + sincos->dst_count); + return VKD3D_ERROR; } - else + + if (sincos->dst[0].reg.type != VKD3DSPR_NULL) + ++count; + if (sincos->dst[1].reg.type != VKD3DSPR_NULL) + ++count; + + if (!vsir_program_iterator_insert_after(it, count)) + return VKD3D_ERROR_OUT_OF_MEMORY; + sincos = vsir_program_iterator_current(it); + + /* Save the source in a SSA in case a destination collides with the source. */ + mov = vsir_program_iterator_next(it); + if (!(vsir_instruction_init_with_params(program, mov, &sincos->location, VSIR_OP_MOV, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + mov->src[0] = sincos->src[0]; + dst_param_init_ssa(&mov->dst[0], program->ssa_count, sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); + + if (sincos->dst[0].reg.type != VKD3DSPR_NULL) { - vsir_dst_param_init_null(&ins->dst[1]); + ins = vsir_program_iterator_next(it); + + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_SIN, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins->flags = sincos->flags; + + src_param_init_ssa(&ins->src[0], program->ssa_count, + sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); + ins->dst[0] = sincos->dst[0]; + } + + if (sincos->dst[1].reg.type != VKD3DSPR_NULL) + { + ins = vsir_program_iterator_next(it); + + if (!(vsir_instruction_init_with_params(program, ins, &sincos->location, VSIR_OP_COS, 1, 1))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins->flags = sincos->flags; + + src_param_init_ssa(&ins->src[0], program->ssa_count, + sincos->src[0].reg.data_type, sincos->src[0].reg.dimension); + ins->dst[0] = sincos->dst[1]; }
- /* Make the original instruction no-op */ vkd3d_shader_instruction_make_nop(sincos); + ++program->ssa_count; + + return VKD3D_OK; +} + +static enum vkd3d_result vsir_program_lower_texcrd(struct vsir_program *program, + struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) +{ + /* texcrd DST, t# -> mov DST, t# */ + + if (ins->src[0].modifiers) + { + vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Aborting due to not yet implemented feature: texcrd source modifier."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + + ins->opcode = VSIR_OP_MOV; + + return VKD3D_OK; +} + +static enum vkd3d_result vsir_program_lower_texld_sm1(struct vsir_program *program, + struct vkd3d_shader_instruction *ins, struct vkd3d_shader_message_context *message_context) +{ + unsigned int idx = ins->src[0].reg.idx[0].offset; + struct vkd3d_shader_src_param *srcs; + + /* texld DST, t# -> sample DST, t#, resource#, sampler# */ + + if (ins->src[0].modifiers) + { + vkd3d_shader_error(message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, + "Aborting due to not yet implemented feature: texld source modifier."); + return VKD3D_ERROR_NOT_IMPLEMENTED; + } + + if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 3))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + /* Note we run before I/O normalization. */ + srcs[0] = ins->src[0]; + vsir_src_param_init_resource(&srcs[1], idx, idx); + vsir_src_param_init_sampler(&srcs[2], idx, idx); + + ins->opcode = VSIR_OP_SAMPLE; + ins->src = srcs; + ins->src_count = 3;
return VKD3D_OK; }
static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, - struct vkd3d_shader_instruction *tex, unsigned int *tmp_idx) + struct vsir_program_iterator *it, unsigned int *tmp_idx) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - struct vkd3d_shader_location *location = &tex->location; - struct vkd3d_shader_instruction *div_ins, *tex_ins; - size_t pos = tex - instructions->elements; + struct vkd3d_shader_instruction *div_ins, *tex, *tex_ins; + struct vsir_program_iterator it2; unsigned int w_comp;
+ tex = vsir_program_iterator_current(it); + w_comp = vsir_swizzle_get_component(tex->src[0].swizzle, 3);
- if (!shader_instruction_array_insert_at(instructions, pos + 1, 2)) + if (!vsir_program_iterator_insert_after(it, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; - tex = &instructions->elements[pos]; + tex = vsir_program_iterator_current(it);
if (*tmp_idx == ~0u) *tmp_idx = program->temp_count++;
- div_ins = &instructions->elements[pos + 1]; - tex_ins = &instructions->elements[pos + 2]; + /* Do not increment `it', because we need to scan the generated instructions + * again to lower TEXLD. */ + it2 = *it; + div_ins = vsir_program_iterator_next(&it2); + tex_ins = vsir_program_iterator_next(&it2);
- if (!vsir_instruction_init_with_params(program, div_ins, location, VKD3DSIH_DIV, 1, 2)) + if (!vsir_instruction_init_with_params(program, div_ins, &tex->location, VSIR_OP_DIV, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VKD3D_DATA_FLOAT, 1); + vsir_dst_param_init(&div_ins->dst[0], VKD3DSPR_TEMP, VSIR_DATA_F32, 1); div_ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; div_ins->dst[0].reg.idx[0].offset = *tmp_idx; div_ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; @@ -823,7 +1474,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, div_ins->src[1] = tex->src[0]; div_ins->src[1].swizzle = vkd3d_shader_create_swizzle(w_comp, w_comp, w_comp, w_comp);
- if (!vsir_instruction_init_with_params(program, tex_ins, location, VKD3DSIH_TEX, 1, 2)) + if (!vsir_instruction_init_with_params(program, tex_ins, &tex->location, VSIR_OP_TEXLD, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY;
tex_ins->dst[0] = tex->dst[0]; @@ -838,7 +1489,7 @@ static enum vkd3d_result vsir_program_lower_texldp(struct vsir_program *program, return VKD3D_OK; }
-static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, +static enum vkd3d_result vsir_program_lower_texld(struct vsir_program *program, struct vkd3d_shader_instruction *tex, struct vkd3d_shader_message_context *message_context) { unsigned int idx = tex->src[1].reg.idx[0].offset; @@ -856,7 +1507,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program,
if (!tex->flags) { - tex->opcode = VKD3DSIH_SAMPLE; + tex->opcode = VSIR_OP_SAMPLE; tex->src = srcs; tex->src_count = 3; } @@ -864,7 +1515,7 @@ static enum vkd3d_result vsir_program_lower_tex(struct vsir_program *program, { enum vkd3d_shader_swizzle_component w = vsir_swizzle_get_component(srcs[0].swizzle, 3);
- tex->opcode = VKD3DSIH_SAMPLE_B; + tex->opcode = VSIR_OP_SAMPLE_B; tex->src = srcs; tex->src_count = 4;
@@ -899,13 +1550,41 @@ static enum vkd3d_result vsir_program_lower_texldd(struct vsir_program *program, srcs[3] = texldd->src[2]; srcs[4] = texldd->src[3];
- texldd->opcode = VKD3DSIH_SAMPLE_GRAD; + texldd->opcode = VSIR_OP_SAMPLE_GRAD; texldd->src = srcs; texldd->src_count = 5;
return VKD3D_OK; }
+static enum vkd3d_result vsir_program_lower_texldl(struct vsir_program *program, + struct vkd3d_shader_instruction *texldl) +{ + unsigned int idx = texldl->src[1].reg.idx[0].offset; + enum vkd3d_shader_swizzle_component w; + struct vkd3d_shader_src_param *srcs; + + VKD3D_ASSERT(texldl->src[1].reg.idx_count == 1); + VKD3D_ASSERT(!texldl->src[1].reg.idx[0].rel_addr); + + if (!(srcs = shader_src_param_allocator_get(&program->instructions.src_params, 4))) + return VKD3D_ERROR_OUT_OF_MEMORY; + + srcs[0] = texldl->src[0]; + vsir_src_param_init_resource(&srcs[1], idx, idx); + vsir_src_param_init_sampler(&srcs[2], idx, idx); + + texldl->opcode = VSIR_OP_SAMPLE_LOD; + texldl->src = srcs; + texldl->src_count = 4; + + w = vsir_swizzle_get_component(srcs[0].swizzle, 3); + srcs[3] = texldl->src[0]; + srcs[3].swizzle = vkd3d_shader_create_swizzle(w, w, w, w); + + return VKD3D_OK; +} + static enum vkd3d_result vsir_program_lower_dcl_input(struct vsir_program *program, struct vkd3d_shader_instruction *ins, struct vsir_transformation_context *ctx) { @@ -976,108 +1655,157 @@ static enum vkd3d_result vsir_program_lower_dcl_output(struct vsir_program *prog return VKD3D_OK; }
+static enum vkd3d_result vsir_program_lower_d3dbc_instructions(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; + unsigned int tmp_idx = ~0u; + + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + enum vkd3d_result ret; + + switch (ins->opcode) + { + case VSIR_OP_TEXCRD: + ret = vsir_program_lower_texcrd(program, ins, message_context); + break; + + case VSIR_OP_TEXLD: + if (program->shader_version.major == 1) + ret = vsir_program_lower_texld_sm1(program, ins, message_context); + else if (ins->flags == VKD3DSI_TEXLD_PROJECT) + ret = vsir_program_lower_texldp(program, &it, &tmp_idx); + else + ret = vsir_program_lower_texld(program, ins, message_context); + break; + + default: + ret = VKD3D_OK; + break; + } + + if (ret < 0) + return ret; + } + + return VKD3D_OK; +} + static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *program, struct vsir_transformation_context *ctx) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_message_context *message_context = ctx->message_context; - unsigned int tmp_idx = ~0u, i; + struct vkd3d_shader_instruction *ins; + unsigned int tmp_idx = ~0u; enum vkd3d_result ret;
- for (i = 0; i < instructions->count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - struct vkd3d_shader_instruction *ins = &instructions->elements[i]; - switch (ins->opcode) { - case VKD3DSIH_IFC: - if ((ret = vsir_program_lower_ifc(program, ins, &tmp_idx, message_context)) < 0) + case VSIR_OP_IFC: + if ((ret = vsir_program_lower_ifc(program, &it, &tmp_idx, message_context)) < 0) return ret; break;
- case VKD3DSIH_TEXKILL: - if ((ret = vsir_program_lower_texkill(program, ins, &tmp_idx)) < 0) + case VSIR_OP_TEXKILL: + if ((ret = vsir_program_lower_texkill(program, &it, &tmp_idx)) < 0) return ret; break;
- case VKD3DSIH_MAD: - if ((ret = vsir_program_lower_precise_mad(program, ins, &tmp_idx)) < 0) + case VSIR_OP_MAD: + if ((ret = vsir_program_lower_precise_mad(program, &it, &tmp_idx)) < 0) return ret; break;
- case VKD3DSIH_DCL: - case VKD3DSIH_DCL_CONSTANT_BUFFER: - case VKD3DSIH_DCL_GLOBAL_FLAGS: - case VKD3DSIH_DCL_SAMPLER: - case VKD3DSIH_DCL_TEMPS: - case VKD3DSIH_DCL_TESSELLATOR_DOMAIN: - case VKD3DSIH_DCL_THREAD_GROUP: - case VKD3DSIH_DCL_UAV_TYPED: + case VSIR_OP_DCL: + case VSIR_OP_DCL_CONSTANT_BUFFER: + case VSIR_OP_DCL_GLOBAL_FLAGS: + case VSIR_OP_DCL_SAMPLER: + case VSIR_OP_DCL_TEMPS: + case VSIR_OP_DCL_TESSELLATOR_DOMAIN: + case VSIR_OP_DCL_THREAD_GROUP: + case VSIR_OP_DCL_UAV_TYPED: vkd3d_shader_instruction_make_nop(ins); break;
- case VKD3DSIH_DCL_INPUT: + case VSIR_OP_DCL_INPUT: vsir_program_lower_dcl_input(program, ins, ctx); vkd3d_shader_instruction_make_nop(ins); break;
- case VKD3DSIH_DCL_OUTPUT: + case VSIR_OP_DCL_OUTPUT: vsir_program_lower_dcl_output(program, ins, ctx); vkd3d_shader_instruction_make_nop(ins); break;
- case VKD3DSIH_DCL_INPUT_SGV: - case VKD3DSIH_DCL_INPUT_SIV: - case VKD3DSIH_DCL_INPUT_PS: - case VKD3DSIH_DCL_INPUT_PS_SGV: - case VKD3DSIH_DCL_INPUT_PS_SIV: - case VKD3DSIH_DCL_OUTPUT_SIV: + case VSIR_OP_DCL_INPUT_SGV: + case VSIR_OP_DCL_INPUT_SIV: + case VSIR_OP_DCL_INPUT_PS: + case VSIR_OP_DCL_INPUT_PS_SGV: + case VSIR_OP_DCL_INPUT_PS_SIV: + case VSIR_OP_DCL_OUTPUT_SGV: + case VSIR_OP_DCL_OUTPUT_SIV: vkd3d_shader_instruction_make_nop(ins); break;
- case VKD3DSIH_SINCOS: - if ((ret = vsir_program_lower_sm1_sincos(program, ins)) < 0) + case VSIR_OP_IMUL: + case VSIR_OP_UMUL: + if ((ret = vsir_program_lower_imul(program, ins, ctx)) < 0) return ret; break;
- case VKD3DSIH_TEX: - if (ins->flags == VKD3DSI_TEXLD_PROJECT) + case VSIR_OP_UDIV: + if ((ret = vsir_program_lower_udiv(program, &it, ctx)) < 0) + return ret; + break; + + case VSIR_OP_SINCOS: + if (ins->dst_count == 1) { - if ((ret = vsir_program_lower_texldp(program, ins, &tmp_idx)) < 0) + if ((ret = vsir_program_lower_sm1_sincos(program, &it)) < 0) return ret; } else { - if ((ret = vsir_program_lower_tex(program, ins, message_context)) < 0) + if ((ret = vsir_program_lower_sm4_sincos(program, &it, ctx)) < 0) return ret; } break;
- case VKD3DSIH_TEXLDD: + case VSIR_OP_TEXLDD: if ((ret = vsir_program_lower_texldd(program, ins)) < 0) return ret; break;
- case VKD3DSIH_TEXBEM: - case VKD3DSIH_TEXBEML: - case VKD3DSIH_TEXCOORD: - case VKD3DSIH_TEXDEPTH: - case VKD3DSIH_TEXDP3: - case VKD3DSIH_TEXDP3TEX: - case VKD3DSIH_TEXLDL: - case VKD3DSIH_TEXM3x2PAD: - case VKD3DSIH_TEXM3x2TEX: - case VKD3DSIH_TEXM3x3DIFF: - case VKD3DSIH_TEXM3x3PAD: - case VKD3DSIH_TEXM3x3SPEC: - case VKD3DSIH_TEXM3x3TEX: - case VKD3DSIH_TEXM3x3VSPEC: - case VKD3DSIH_TEXREG2AR: - case VKD3DSIH_TEXREG2GB: - case VKD3DSIH_TEXREG2RGB: + case VSIR_OP_TEXLDL: + if ((ret = vsir_program_lower_texldl(program, ins)) < 0) + return ret; + break; + + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXCOORD: + case VSIR_OP_TEXDEPTH: + case VSIR_OP_TEXDP3: + case VSIR_OP_TEXDP3TEX: + case VSIR_OP_TEXM3x2PAD: + case VSIR_OP_TEXM3x2TEX: + case VSIR_OP_TEXM3x3DIFF: + case VSIR_OP_TEXM3x3PAD: + case VSIR_OP_TEXM3x3SPEC: + case VSIR_OP_TEXM3x3TEX: + case VSIR_OP_TEXM3x3VSPEC: + case VSIR_OP_TEXREG2AR: + case VSIR_OP_TEXREG2GB: + case VSIR_OP_TEXREG2RGB: vkd3d_shader_error(ctx->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Aborting due to unimplemented feature: Combined sampler instruction %#x.", - ins->opcode); + "Aborting due to unimplemented feature: Combined sampler instruction "%s" (%#x).", + vsir_opcode_get_name(ins->opcode, "<unknown>"), ins->opcode); return VKD3D_ERROR_NOT_IMPLEMENTED;
default: @@ -1088,69 +1816,69 @@ static enum vkd3d_result vsir_program_lower_instructions(struct vsir_program *pr return VKD3D_OK; }
-static void shader_register_eliminate_phase_addressing(struct vkd3d_shader_register *reg, - unsigned int instance_id) +/* Ensure that the program closes with a ret. sm1 programs do not, by default. + * Many of our IR passes rely on this in order to insert instructions at the + * end of execution. */ +static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, + struct vsir_transformation_context *ctx) { - unsigned int i; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + static const struct vkd3d_shader_location no_loc; + struct vkd3d_shader_instruction *ins;
- for (i = 0; i < reg->idx_count; ++i) - { - if (reg->idx[i].rel_addr && shader_register_is_phase_instance_id(®->idx[i].rel_addr->reg)) - { - reg->idx[i].rel_addr = NULL; - reg->idx[i].offset += instance_id; - } - } -} - -static void shader_instruction_eliminate_phase_instance_id(struct vkd3d_shader_instruction *ins, - unsigned int instance_id) -{ - struct vkd3d_shader_register *reg; - unsigned int i; + ins = vsir_program_iterator_tail(&it); + if (ins && ins->opcode == VSIR_OP_RET) + return VKD3D_OK;
- for (i = 0; i < ins->src_count; ++i) - { - reg = (struct vkd3d_shader_register *)&ins->src[i].reg; - if (shader_register_is_phase_instance_id(reg)) - { - vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0); - reg->u.immconst_u32[0] = instance_id; - continue; - } - shader_register_eliminate_phase_addressing(reg, instance_id); - } + if (!(ins = vsir_program_append(program))) + return VKD3D_ERROR_OUT_OF_MEMORY; + vsir_instruction_init(ins, &no_loc, VSIR_OP_RET);
- for (i = 0; i < ins->dst_count; ++i) - shader_register_eliminate_phase_addressing(&ins->dst[i].reg, instance_id); + return VKD3D_OK; }
-/* Ensure that the program closes with a ret. sm1 programs do not, by default. - * Many of our IR passes rely on this in order to insert instructions at the - * end of execution. */ -static enum vkd3d_result vsir_program_ensure_ret(struct vsir_program *program, +/* ps_1_* outputs color in r0. Add an instruction to copy that to oC0. + * We don't need to modify the signature since it already contains COLOR. */ +static enum vkd3d_result vsir_program_normalise_ps1_output(struct vsir_program *program, struct vsir_transformation_context *ctx) { - static const struct vkd3d_shader_location no_loc; - if (program->instructions.count - && program->instructions.elements[program->instructions.count - 1].opcode == VKD3DSIH_RET) + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_instruction *ins; + struct vkd3d_shader_location loc; + + if (!(ins = vsir_program_iterator_tail(&it))) return VKD3D_OK; + loc = ins->location;
- if (!shader_instruction_array_insert_at(&program->instructions, program->instructions.count, 1)) + if (!(ins = vsir_program_append(program))) + return VKD3D_ERROR_OUT_OF_MEMORY; + if (!vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1)) + { + vsir_instruction_init(ins, &loc, VSIR_OP_NOP); return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_instruction_init(&program->instructions.elements[program->instructions.count - 1], &no_loc, VKD3DSIH_RET); + } + + src_param_init_temp_float4(&ins->src[0], 0); + ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + /* Note we run before I/O normalization. */ + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_COLOROUT, VSIR_DATA_F32, 1); + ins->dst[0].reg.idx[0].offset = 0; + ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; + ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL; + ins->dst[0].modifiers = VKD3DSPDM_SATURATE; + return VKD3D_OK; }
-static bool add_signature_element(struct shader_signature *signature, const char *semantic_name, - uint32_t semantic_index, uint32_t mask, uint32_t register_index, +static struct signature_element *add_signature_element(struct shader_signature *signature, + const char *semantic_name, uint32_t semantic_index, uint32_t mask, uint32_t register_index, enum vkd3d_shader_interpolation_mode interpolation_mode) { struct signature_element *new_elements, *e;
if (!(new_elements = vkd3d_realloc(signature->elements, (signature->element_count + 1) * sizeof(*signature->elements)))) - return false; + return NULL; signature->elements = new_elements; e = &signature->elements[signature->element_count++]; memset(e, 0, sizeof(*e)); @@ -1164,7 +1892,7 @@ static bool add_signature_element(struct shader_signature *signature, const char e->register_index = register_index; e->target_location = register_index; e->interpolation_mode = interpolation_mode; - return true; + return e; }
static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *program, @@ -1194,6 +1922,7 @@ static enum vkd3d_result vsir_program_add_diffuse_output(struct vsir_program *pr static enum vkd3d_result vsir_program_ensure_diffuse(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; unsigned int i; @@ -1205,24 +1934,23 @@ static enum vkd3d_result vsir_program_ensure_diffuse(struct vsir_program *progra /* Write the instruction after all LABEL, DCL, and NOP instructions. * We need to skip NOP instructions because they might result from removed * DCLs, and there could still be DCLs after NOPs. */ - for (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) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP) + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) break; }
- if (!shader_instruction_array_insert_at(&program->instructions, i, 1)) + vsir_program_iterator_prev(&it); + if (!vsir_program_iterator_insert_after(&it, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[i]; + ins = vsir_program_iterator_next(&it);
- vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_ATTROUT, VKD3D_DATA_FLOAT, 1); + vsir_instruction_init_with_params(program, ins, &no_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; ins->dst[0].write_mask = VKD3DSP_WRITEMASK_ALL & ~program->diffuse_written_mask; - vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); + vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; for (i = 0; i < 4; ++i) ins->src[0].reg.u.immconst_f32[i] = 1.0f; @@ -1316,6 +2044,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program struct vsir_transformation_context *ctx) { const struct vkd3d_shader_location location = {.source_name = ctx->compile_info->source_name}; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct vkd3d_shader_message_context *message_context = ctx->message_context; const struct vkd3d_shader_compile_info *compile_info = ctx->compile_info; bool allows_subset_masks = target_allows_subset_masks(compile_info); @@ -1325,6 +2054,7 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program struct signature_element *new_elements, *e; unsigned int uninit_varying_count = 0; unsigned int subset_varying_count = 0; + struct vkd3d_shader_instruction *ins; unsigned int new_register_count = 0; unsigned int i;
@@ -1424,31 +2154,29 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program }
/* Write each uninitialized varying before each ret. */ - 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]; struct vkd3d_shader_location loc;
- if (ins->opcode != VKD3DSIH_RET) + if (ins->opcode != VSIR_OP_RET) continue;
loc = ins->location; - if (!shader_instruction_array_insert_at(&program->instructions, i, uninit_varying_count)) + vsir_program_iterator_prev(&it); + if (!vsir_program_iterator_insert_after(&it, uninit_varying_count)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[i]; + ins = vsir_program_iterator_next(&it);
for (unsigned int j = signature->element_count - uninit_varying_count; j < signature->element_count; ++j) { e = &signature->elements[j];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); - dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, e->register_index, e->mask); - vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VKD3D_DATA_FLOAT, 0); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, e->register_index, e->mask); + vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ++ins; + ins = vsir_program_iterator_next(&it); } - - i += uninit_varying_count; }
/* Vulkan (without KHR_maintenance4) disallows any mismatching masks, @@ -1459,10 +2187,8 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program if (!subset_varying_count || allows_subset_masks) return VKD3D_OK;
- 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]; - for (unsigned int j = 0; j < ins->dst_count; ++j) remove_unread_output_components(signature, ins, &ins->dst[j]); } @@ -1472,17 +2198,19 @@ static enum vkd3d_result vsir_program_remap_output_signature(struct vsir_program
struct hull_flattener { - struct vkd3d_shader_instruction_array instructions; + 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; + unsigned int orig_ssa_count; };
static bool flattener_is_in_fork_or_join_phase(const struct hull_flattener *flattener) { - return flattener->phase == VKD3DSIH_HS_FORK_PHASE || flattener->phase == VKD3DSIH_HS_JOIN_PHASE; + return flattener->phase == VSIR_OP_HS_FORK_PHASE || flattener->phase == VSIR_OP_HS_JOIN_PHASE; }
struct shader_phase_location @@ -1499,14 +2227,13 @@ struct shader_phase_location_array unsigned int count; };
-static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normaliser, - unsigned int index, struct shader_phase_location_array *locations) +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 vkd3d_shader_instruction *ins = &normaliser->instructions.elements[index]; struct shader_phase_location *loc; bool b;
- if (ins->opcode == VKD3DSIH_HS_FORK_PHASE || ins->opcode == VKD3DSIH_HS_JOIN_PHASE) + 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. */ @@ -1518,21 +2245,21 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal vkd3d_shader_instruction_make_nop(ins); return; } - else if (ins->opcode == VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT - || ins->opcode == VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT) + 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 == VKD3DSIH_INVALID || vsir_instruction_is_dcl(ins)) + 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 == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) { normaliser->last_ret_location = ins->location; vkd3d_shader_instruction_make_nop(ins); @@ -1548,26 +2275,89 @@ static void flattener_eliminate_phase_related_dcls(struct hull_flattener *normal } }
+static void flattener_fixup_ssa_register(struct hull_flattener *normaliser, + struct vkd3d_shader_register *reg, unsigned int instance_id) +{ + unsigned int id; + + if (!register_is_ssa(reg)) + return; + + /* No need to alter the first copy, they are already not conflicting. */ + if (instance_id == 0) + return; + + id = reg->idx[0].offset; + VKD3D_ASSERT(id < normaliser->orig_ssa_count); + if (normaliser->ssa_map[id] == UINT_MAX) + normaliser->ssa_map[id] = normaliser->program->ssa_count++; + reg->idx[0].offset = normaliser->ssa_map[id]; +} + +static void flattener_fixup_register_indices(struct hull_flattener *normaliser, + struct vkd3d_shader_register *reg, unsigned int instance_id) +{ + unsigned int i; + + flattener_fixup_ssa_register(normaliser, reg, instance_id); + + for (i = 0; i < reg->idx_count; ++i) + { + if (reg->idx[i].rel_addr) + { + flattener_fixup_ssa_register(normaliser, ®->idx[i].rel_addr->reg, instance_id); + if (shader_register_is_phase_instance_id(®->idx[i].rel_addr->reg)) + { + reg->idx[i].rel_addr = NULL; + reg->idx[i].offset += instance_id; + } + } + } +} + +static void flattener_fixup_registers(struct hull_flattener *normaliser, + struct vkd3d_shader_instruction *ins, unsigned int instance_id) +{ + struct vkd3d_shader_register *reg; + unsigned int i; + + for (i = 0; i < ins->src_count; ++i) + { + reg = &ins->src[i].reg; + if (shader_register_is_phase_instance_id(reg)) + { + vsir_register_init(reg, VKD3DSPR_IMMCONST, reg->data_type, 0); + reg->u.immconst_u32[0] = instance_id; + continue; + } + flattener_fixup_register_indices(normaliser, reg, instance_id); + } + + for (i = 0; i < ins->dst_count; ++i) + 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) { + 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;
- if (!shader_instruction_array_reserve(&normaliser->instructions, normaliser->instructions.count + count)) + if (!shader_instruction_array_reserve(instructions, instructions->count + count)) return VKD3D_ERROR_OUT_OF_MEMORY; - end = normaliser->instructions.count; - normaliser->instructions.count += count; + end = instructions->count; + instructions->count += count;
for (i = locations->count; i > 0; --i) { loc = &locations->locations[i - 1]; j = loc->index + loc->instruction_count; - memmove(&normaliser->instructions.elements[j + count], &normaliser->instructions.elements[j], - (end - j) * sizeof(*normaliser->instructions.elements)); + 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; @@ -1581,7 +2371,7 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali { for (k = 0; k < loc->instruction_count; ++k) { - if (!shader_instruction_array_clone_instruction(&normaliser->instructions, + if (!shader_instruction_array_clone_instruction(instructions, loc->index + loc->instruction_count * j + k, loc->index + k)) return VKD3D_ERROR_OUT_OF_MEMORY; } @@ -1589,9 +2379,12 @@ static enum vkd3d_result flattener_flatten_phases(struct hull_flattener *normali /* Replace each reference to the instance id with a constant instance id. */ for (j = 0; j < loc->instance_count; ++j) { + if (j != 0) + memset(normaliser->ssa_map, 0xff, normaliser->orig_ssa_count * sizeof(*normaliser->ssa_map)); + for (k = 0; k < loc->instruction_count; ++k) - shader_instruction_eliminate_phase_instance_id( - &normaliser->instructions.elements[loc->index + loc->instruction_count * j + k], j); + flattener_fixup_registers(normaliser, + &instructions->elements[loc->index + loc->instruction_count * j + k], j); } }
@@ -1601,31 +2394,41 @@ 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 hull_flattener flattener = {program->instructions}; - struct vkd3d_shader_instruction_array *instructions; + 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;
- instructions = &flattener.instructions; - - flattener.phase = VKD3DSIH_INVALID; - for (i = 0, locations.count = 0; i < instructions->count; ++i) - flattener_eliminate_phase_related_dcls(&flattener, i, &locations); + 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);
- if ((result = flattener_flatten_phases(&flattener, &locations)) < 0) + flattener.orig_ssa_count = program->ssa_count; + 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); + + vkd3d_free(flattener.ssa_map); + flattener.ssa_map = NULL; + + if (result < 0) return result;
- if (flattener.phase != VKD3DSIH_INVALID) + if (flattener.phase != VSIR_OP_INVALID) { - if (!shader_instruction_array_reserve(&flattener.instructions, flattener.instructions.count + 1)) + if (!(ins = vsir_program_append(program))) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_instruction_init(&instructions->elements[instructions->count++], &flattener.last_ret_location, VKD3DSIH_RET); + vsir_instruction_init(ins, &flattener.last_ret_location, VSIR_OP_RET); }
- program->instructions = flattener.instructions; return result; }
@@ -1638,7 +2441,7 @@ struct control_point_normaliser
static bool control_point_normaliser_is_in_control_point_phase(const struct control_point_normaliser *normaliser) { - return normaliser->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE; + return normaliser->phase == VSIR_OP_HS_CONTROL_POINT_PHASE; }
struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_program *program) @@ -1652,7 +2455,7 @@ struct vkd3d_shader_src_param *vsir_program_create_outpointid_param(struct vsir_ if (!(rel_addr = shader_src_param_allocator_get(&instructions->src_params, 1))) return NULL;
- vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VKD3D_DATA_UINT, 0); + vsir_register_init(&rel_addr->reg, VKD3DSPR_OUTPOINTID, VSIR_DATA_U32, 0); rel_addr->swizzle = 0; rel_addr->modifiers = 0;
@@ -1696,7 +2499,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p normaliser->instructions.count += count;
ins = &normaliser->instructions.elements[dst]; - vsir_instruction_init(ins, location, VKD3DSIH_HS_CONTROL_POINT_PHASE); + vsir_instruction_init(ins, location, VSIR_OP_HS_CONTROL_POINT_PHASE);
++ins;
@@ -1706,7 +2509,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p if (!e->used_mask) continue;
- vsir_instruction_init(ins, location, VKD3DSIH_MOV); + vsir_instruction_init(ins, location, VSIR_OP_MOV); ins->dst = shader_dst_param_allocator_get(&normaliser->instructions.dst_params, 1); ins->dst_count = 1; ins->src = shader_src_param_allocator_get(&normaliser->instructions.src_params, 1); @@ -1733,7 +2536,7 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p ++ins; }
- vsir_instruction_init(ins, location, VKD3DSIH_RET); + vsir_instruction_init(ins, location, VSIR_OP_RET);
return VKD3D_OK; } @@ -1741,11 +2544,11 @@ static enum vkd3d_result control_point_normaliser_emit_hs_input(struct control_p static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_io( struct vsir_program *program, struct vsir_transformation_context *ctx) { - struct vkd3d_shader_instruction_array *instructions; struct control_point_normaliser normaliser; unsigned int input_control_point_count; struct vkd3d_shader_location location; struct vkd3d_shader_instruction *ins; + struct vsir_program_iterator it; enum vkd3d_result ret; unsigned int i, j;
@@ -1763,18 +2566,16 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i return VKD3D_ERROR_OUT_OF_MEMORY; } normaliser.instructions = program->instructions; - instructions = &normaliser.instructions; - normaliser.phase = VKD3DSIH_INVALID; + it = vsir_program_iterator(&normaliser.instructions); + normaliser.phase = VSIR_OP_INVALID;
- for (i = 0; i < normaliser.instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - ins = &instructions->elements[i]; - switch (ins->opcode) { - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: normaliser.phase = ins->opcode; break; default: @@ -1786,24 +2587,22 @@ static enum vkd3d_result instruction_array_normalise_hull_shader_control_point_i } }
- normaliser.phase = VKD3DSIH_INVALID; + normaliser.phase = VSIR_OP_INVALID; input_control_point_count = 1;
- for (i = 0; i < instructions->count; ++i) + for (ins = vsir_program_iterator_head(&it), i = 0; ins; ins = vsir_program_iterator_next(&it), ++i) { - ins = &instructions->elements[i]; - switch (ins->opcode) { - case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: + case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: input_control_point_count = ins->declaration.count; break; - case VKD3DSIH_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: program->instructions = normaliser.instructions; program->normalisation_level = VSIR_NORMALISED_HULL_CONTROL_POINT_IO; return VKD3D_OK; - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_FORK_PHASE: + 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, @@ -1835,7 +2634,7 @@ struct io_normaliser_register_data struct io_normaliser { struct vkd3d_shader_message_context *message_context; - struct vkd3d_shader_instruction_array instructions; + enum vkd3d_result result; enum vkd3d_shader_type shader_type; uint8_t major; struct shader_signature *input_signature; @@ -1861,7 +2660,7 @@ struct io_normaliser
static bool io_normaliser_is_in_fork_or_join_phase(const struct io_normaliser *normaliser) { - return normaliser->phase == VKD3DSIH_HS_FORK_PHASE || normaliser->phase == VKD3DSIH_HS_JOIN_PHASE; + return normaliser->phase == VSIR_OP_HS_FORK_PHASE || normaliser->phase == VSIR_OP_HS_JOIN_PHASE; }
static bool shader_signature_find_element_for_reg(const struct shader_signature *signature, @@ -2338,7 +3137,7 @@ static bool shader_dst_param_io_normalise(struct vkd3d_shader_dst_param *dst_par }
static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_param, - struct io_normaliser *normaliser) + struct io_normaliser *normaliser, struct vkd3d_shader_instruction *ins) { unsigned int i, id_idx, reg_idx, write_mask, element_idx, component_idx; struct vkd3d_shader_register *reg = &src_param->reg; @@ -2401,7 +3200,12 @@ static void shader_src_param_io_normalise(struct vkd3d_shader_src_param *src_par id_idx = reg->idx_count - 1; write_mask = VKD3DSP_WRITEMASK_0 << vsir_swizzle_get_component(src_param->swizzle, 0); if (!shader_signature_find_element_for_reg(signature, reg_idx, write_mask, &element_idx)) - vkd3d_unreachable(); + { + vkd3d_shader_error(normaliser->message_context, &ins->location, VKD3D_SHADER_ERROR_VSIR_INVALID_SIGNATURE, + "Unable to resolve I/O register to a signature element."); + normaliser->result = VKD3D_ERROR_INVALID_SHADER; + return; + }
e = &signature->elements[element_idx]; if ((e->register_count > 1 || vsir_sysval_semantic_is_tess_factor(e->sysval_semantic))) @@ -2424,9 +3228,9 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi
switch (ins->opcode) { - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: normaliser->phase = ins->opcode; memset(normaliser->input_dcl_params, 0, sizeof(normaliser->input_dcl_params)); memset(normaliser->output_dcl_params, 0, sizeof(normaliser->output_dcl_params)); @@ -2438,7 +3242,7 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi for (i = 0; i < ins->dst_count; ++i) shader_dst_param_io_normalise(&ins->dst[i], normaliser); for (i = 0; i < ins->src_count; ++i) - shader_src_param_io_normalise(&ins->src[i], normaliser); + shader_src_param_io_normalise(&ins->src[i], normaliser, ins); break; } } @@ -2446,37 +3250,35 @@ static void shader_instruction_normalise_io_params(struct vkd3d_shader_instructi static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program *program, struct vsir_transformation_context *ctx) { - struct io_normaliser normaliser = {ctx->message_context, program->instructions}; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct io_normaliser normaliser = {ctx->message_context, VKD3D_OK}; struct vkd3d_shader_instruction *ins; enum vkd3d_result ret; - unsigned int i;
VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_HULL_CONTROL_POINT_IO);
- normaliser.phase = VKD3DSIH_INVALID; + normaliser.phase = VSIR_OP_INVALID; normaliser.shader_type = program->shader_version.type; normaliser.major = program->shader_version.major; normaliser.input_signature = &program->input_signature; normaliser.output_signature = &program->output_signature; normaliser.patch_constant_signature = &program->patch_constant_signature;
- for (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]; - switch (ins->opcode) { - case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: + case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: normaliser.output_control_point_count = ins->declaration.count; break; - case VKD3DSIH_DCL_INDEX_RANGE: + case VSIR_OP_DCL_INDEX_RANGE: if ((ret = io_normaliser_add_index_range(&normaliser, ins)) < 0) return ret; vkd3d_shader_instruction_make_nop(ins); break; - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: normaliser.phase = ins->opcode; break; default: @@ -2489,19 +3291,17 @@ static enum vkd3d_result vsir_program_normalise_io_registers(struct vsir_program normaliser.output_range_map, false)) < 0 || (ret = shader_signature_merge(&normaliser, &program->patch_constant_signature, normaliser.pc_range_map, true)) < 0) - { - program->instructions = normaliser.instructions; return ret; - }
- normaliser.phase = VKD3DSIH_INVALID; - for (i = 0; i < normaliser.instructions.count; ++i) - shader_instruction_normalise_io_params(&normaliser.instructions.elements[i], &normaliser); + normaliser.phase = VSIR_OP_INVALID; + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + shader_instruction_normalise_io_params(ins, &normaliser); + }
- program->instructions = normaliser.instructions; program->use_vocp = normaliser.use_vocp; program->normalisation_level = VSIR_NORMALISED_SM6; - return VKD3D_OK; + return normaliser.result; }
struct flat_constant_def @@ -2587,14 +3387,14 @@ static void shader_register_normalise_flat_constants(struct vkd3d_shader_src_par static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct flat_constants_normaliser normaliser = {0}; - unsigned int i, j; + struct vkd3d_shader_instruction *ins; + unsigned int i;
- 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]; - - if (ins->opcode == VKD3DSIH_DEF || ins->opcode == VKD3DSIH_DEFI || ins->opcode == VKD3DSIH_DEFB) + if (ins->opcode == VSIR_OP_DEF || ins->opcode == VSIR_OP_DEFI || ins->opcode == VSIR_OP_DEFB) { struct flat_constant_def *def;
@@ -2608,15 +3408,19 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr def = &normaliser.defs[normaliser.def_count++];
get_flat_constant_register_type(&ins->dst[0].reg, &def->set, &def->index, NULL); - for (j = 0; j < 4; ++j) - def->value[j] = ins->src[0].reg.u.immconst_u32[j]; + for (i = 0; i < 4; ++i) + { + def->value[i] = ins->src[0].reg.u.immconst_u32[i]; + }
vkd3d_shader_instruction_make_nop(ins); } else { - for (j = 0; j < ins->src_count; ++j) - shader_register_normalise_flat_constants(&ins->src[j], &normaliser); + for (i = 0; i < ins->src_count; ++i) + { + shader_register_normalise_flat_constants(&ins->src[i], &normaliser); + } } }
@@ -2627,18 +3431,18 @@ static enum vkd3d_result vsir_program_normalise_flat_constants(struct vsir_progr static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *program, struct vsir_transformation_context *ctx) { - size_t i, depth = 0; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_instruction *ins; bool dead = false; + size_t depth = 0;
- 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]; - switch (ins->opcode) { - case VKD3DSIH_IF: - case VKD3DSIH_LOOP: - case VKD3DSIH_SWITCH: + case VSIR_OP_IF: + case VSIR_OP_LOOP: + case VSIR_OP_SWITCH: if (dead) { vkd3d_shader_instruction_make_nop(ins); @@ -2646,15 +3450,15 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog } break;
- case VKD3DSIH_ENDIF: - case VKD3DSIH_ENDLOOP: - case VKD3DSIH_ENDSWITCH: - case VKD3DSIH_ELSE: + case VSIR_OP_ENDIF: + case VSIR_OP_ENDLOOP: + case VSIR_OP_ENDSWITCH: + case VSIR_OP_ELSE: if (dead) { if (depth > 0) { - if (ins->opcode != VKD3DSIH_ELSE) + if (ins->opcode != VSIR_OP_ELSE) --depth; vkd3d_shader_instruction_make_nop(ins); } @@ -2669,9 +3473,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog * segment began. So it starts at zero and it signals the * termination of the dead code segment when it would * become negative. */ - case VKD3DSIH_BREAK: - case VKD3DSIH_RET: - case VKD3DSIH_CONTINUE: + case VSIR_OP_BREAK: + case VSIR_OP_RET: + case VSIR_OP_CONTINUE: if (dead) { vkd3d_shader_instruction_make_nop(ins); @@ -2686,8 +3490,8 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog /* If `case' or `default' appears at zero depth, it means * that they are a possible target for the corresponding * switch, so the code is live again. */ - case VKD3DSIH_CASE: - case VKD3DSIH_DEFAULT: + case VSIR_OP_CASE: + case VSIR_OP_DEFAULT: if (dead) { if (depth == 0) @@ -2701,9 +3505,9 @@ static enum vkd3d_result vsir_program_remove_dead_code(struct vsir_program *prog * outside of any block. When a phase returns, control is * moved to the following phase, so they make code live * again. */ - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: dead = false; break;
@@ -2817,7 +3621,7 @@ static bool cf_flattener_copy_instruction(struct cf_flattener *flattener, { struct vkd3d_shader_instruction *dst_ins;
- if (instruction->opcode == VKD3DSIH_NOP) + if (instruction->opcode == VSIR_OP_NOP) return true;
if (!(dst_ins = cf_flattener_require_space(flattener, 1))) @@ -2871,7 +3675,7 @@ static struct vkd3d_shader_src_param *cf_flattener_emit_branch(struct cf_flatten
if (!(ins = cf_flattener_require_space(flattener, 1))) return NULL; - vsir_instruction_init(ins, &flattener->location, VKD3DSIH_BRANCH); + vsir_instruction_init(ins, &flattener->location, VSIR_OP_BRANCH);
if (condition) { @@ -3006,10 +3810,11 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_instruction_array *instructions; + const struct vkd3d_shader_instruction *instruction; struct vsir_program *program = flattener->program; bool is_hull_shader, after_declarations_section; struct vkd3d_shader_instruction *dst_ins; - size_t i; + struct vsir_program_iterator it;
instructions = &program->instructions; is_hull_shader = program->shader_version.type == VKD3D_SHADER_TYPE_HULL; @@ -3018,10 +3823,10 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte if (!cf_flattener_require_space(flattener, instructions->count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
- for (i = 0; i < instructions->count; ++i) + it = vsir_program_iterator(instructions); + for (instruction = vsir_program_iterator_head(&it); instruction; instruction = vsir_program_iterator_next(&it)) { unsigned int loop_header_block_id, loop_body_block_id, continue_block_id, merge_block_id, true_block_id; - const struct vkd3d_shader_instruction *instruction = &instructions->elements[i]; const struct vkd3d_shader_src_param *src = instruction->src; struct cf_flattener_info *cf_info;
@@ -3031,9 +3836,9 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte * phase instruction, and in all other shader types begins with the first label instruction. * Declaring an indexable temp with function scope is not considered a declaration, * because it needs to live inside a function. */ - if (!after_declarations_section && instruction->opcode != VKD3DSIH_NOP) + if (!after_declarations_section && instruction->opcode != VSIR_OP_NOP) { - bool is_function_indexable = instruction->opcode == VKD3DSIH_DCL_INDEXABLE_TEMP + bool is_function_indexable = instruction->opcode == VSIR_OP_DCL_INDEXABLE_TEMP && instruction->declaration.indexable_temp.has_function_scope;
if (!vsir_instruction_is_dcl(instruction) || is_function_indexable) @@ -3048,22 +3853,22 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
switch (instruction->opcode) { - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: if (!cf_flattener_copy_instruction(flattener, instruction)) return VKD3D_ERROR_OUT_OF_MEMORY; - if (instruction->opcode != VKD3DSIH_HS_CONTROL_POINT_PHASE || !instruction->flags) + if (instruction->opcode != VSIR_OP_HS_CONTROL_POINT_PHASE || !instruction->flags) after_declarations_section = false; break;
- case VKD3DSIH_LABEL: + case VSIR_OP_LABEL: vkd3d_shader_error(message_context, &instruction->location, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Aborting due to not yet implemented feature: Label instruction."); return VKD3D_ERROR_NOT_IMPLEMENTED;
- case VKD3DSIH_IF: + case VSIR_OP_IF: if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3087,7 +3892,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte ++flattener->branch_id; break;
- case VKD3DSIH_ELSE: + case VSIR_OP_ELSE: if (cf_info->inside_block) cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id);
@@ -3101,7 +3906,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_info->inside_block = true; break;
- case VKD3DSIH_ENDIF: + case VSIR_OP_ENDIF: if (cf_info->inside_block) cf_flattener_emit_unconditional_branch(flattener, cf_info->u.if_.merge_block_id);
@@ -3110,7 +3915,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_flattener_pop_control_flow_level(flattener); break;
- case VKD3DSIH_LOOP: + case VSIR_OP_LOOP: if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3139,7 +3944,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte ++flattener->loop_id; break;
- case VKD3DSIH_ENDLOOP: + case VSIR_OP_ENDLOOP: if (cf_info->inside_block) cf_flattener_emit_unconditional_branch(flattener, cf_info->u.loop.continue_block_id);
@@ -3150,7 +3955,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_flattener_pop_control_flow_level(flattener); break;
- case VKD3DSIH_SWITCH: + case VSIR_OP_SWITCH: if (!(cf_info = cf_flattener_push_control_flow_level(flattener))) return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3161,7 +3966,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
if (!(dst_ins = cf_flattener_require_space(flattener, 1))) return VKD3D_ERROR_OUT_OF_MEMORY; - vsir_instruction_init(dst_ins, &instruction->location, VKD3DSIH_SWITCH_MONOLITHIC); + vsir_instruction_init(dst_ins, &instruction->location, VSIR_OP_SWITCH_MONOLITHIC); ++flattener->instruction_count;
cf_info->u.switch_.id = flattener->switch_id; @@ -3182,7 +3987,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte
break;
- case VKD3DSIH_ENDSWITCH: + case VSIR_OP_ENDSWITCH: { struct vkd3d_shader_src_param *src_params; unsigned int j; @@ -3207,7 +4012,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte for (j = 0; j < cf_info->u.switch_.cases_count; ++j) { unsigned int index = j * 2 + 3; - vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VKD3D_DATA_UINT, 0); + vsir_src_param_init(&src_params[index], VKD3DSPR_IMMCONST, VSIR_DATA_U32, 0); src_params[index].reg.u.immconst_u32[0] = cf_info->u.switch_.cases[j].value; vsir_src_param_init_label(&src_params[index + 1], cf_info->u.switch_.cases[j].block_id); } @@ -3217,7 +4022,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; }
- case VKD3DSIH_CASE: + case VSIR_OP_CASE: { unsigned int label_id, value;
@@ -3249,7 +4054,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; }
- case VKD3DSIH_DEFAULT: + case VSIR_OP_DEFAULT: cf_info->u.switch_.default_block_id = cf_flattener_alloc_block_id(flattener); if (cf_info->inside_block) /* fall-through */ cf_flattener_emit_unconditional_branch(flattener, cf_info->u.switch_.default_block_id); @@ -3261,7 +4066,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte cf_info->inside_block = true; break;
- case VKD3DSIH_BREAK: + case VSIR_OP_BREAK: { struct cf_flattener_info *breakable_cf_info;
@@ -3284,7 +4089,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; }
- case VKD3DSIH_BREAKP: + case VSIR_OP_BREAKP: { struct cf_flattener_info *loop_cf_info;
@@ -3299,7 +4104,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; }
- case VKD3DSIH_CONTINUE: + case VSIR_OP_CONTINUE: { struct cf_flattener_info *loop_cf_info;
@@ -3315,7 +4120,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; }
- case VKD3DSIH_CONTINUEP: + case VSIR_OP_CONTINUEP: { struct cf_flattener_info *loop_cf_info;
@@ -3330,7 +4135,7 @@ static enum vkd3d_result cf_flattener_iterate_instruction_array(struct cf_flatte break; }
- case VKD3DSIH_RET: + case VSIR_OP_RET: if (!cf_flattener_copy_instruction(flattener, instruction)) return VKD3D_ERROR_OUT_OF_MEMORY;
@@ -3447,14 +4252,14 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs
switch (ins->opcode) { - case VKD3DSIH_LABEL: + case VSIR_OP_LABEL: current_label = label_from_src_param(&ins->src[0]); if (!reserve_instructions(&instructions, &ins_capacity, ins_count + 1)) goto fail; instructions[ins_count++] = *ins; continue;
- case VKD3DSIH_SWITCH_MONOLITHIC: + case VSIR_OP_SWITCH_MONOLITHIC: break;
default: @@ -3475,7 +4280,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs goto fail;
if (!vsir_instruction_init_with_params(program, &instructions[ins_count], - &ins->location, VKD3DSIH_BRANCH, 0, 1)) + &ins->location, VSIR_OP_BRANCH, 0, 1)) goto fail; vsir_src_param_init_label(&instructions[ins_count].src[0], default_label); ++ins_count; @@ -3491,7 +4296,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs unsigned int fallthrough_label, case_label = label_from_src_param(&ins->src[3 + 2 * j + 1]);
if (!vsir_instruction_init_with_params(program, - &instructions[ins_count], &ins->location, VKD3DSIH_IEQ, 1, 2)) + &instructions[ins_count], &ins->location, VSIR_OP_IEQ, 1, 2)) goto fail; dst_param_init_ssa_bool(&instructions[ins_count].dst[0], ssa_count); instructions[ins_count].src[0] = ins->src[0]; @@ -3507,7 +4312,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs fallthrough_label = block_count + 1;
if (!vsir_instruction_init_with_params(program, &instructions[ins_count], - &ins->location, VKD3DSIH_BRANCH, 0, 3)) + &ins->location, VSIR_OP_BRANCH, 0, 3)) goto fail; src_param_init_ssa_bool(&instructions[ins_count].src[0], ssa_count); vsir_src_param_init_label(&instructions[ins_count].src[1], case_label); @@ -3529,7 +4334,7 @@ static enum vkd3d_result vsir_program_lower_switch_to_selection_ladder(struct vs else { if (!vsir_instruction_init_with_params(program, - &instructions[ins_count], &ins->location, VKD3DSIH_LABEL, 0, 1)) + &instructions[ins_count], &ins->location, VSIR_OP_LABEL, 0, 1)) goto fail; vsir_src_param_init_label(&instructions[ins_count].src[0], ++block_count); ++ins_count; @@ -3620,10 +4425,12 @@ static void ssas_to_temps_block_info_cleanup(struct ssas_to_temps_block_info *bl static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_program *program, struct vsir_transformation_context *ctx) { - size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count, i; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + size_t ins_capacity = 0, ins_count = 0, phi_count, incoming_count; struct ssas_to_temps_block_info *info, *block_info = NULL; struct vkd3d_shader_instruction *instructions = NULL; struct ssas_to_temps_alloc alloc = {0}; + struct vkd3d_shader_instruction *ins; unsigned int current_label = 0;
VKD3D_ASSERT(program->cf_type == VSIR_CF_BLOCKS); @@ -3637,14 +4444,15 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ if (!ssas_to_temps_alloc_init(&alloc, program->ssa_count, program->temp_count)) goto fail;
- for (i = 0, phi_count = 0, incoming_count = 0; i < program->instructions.count; ++i) + phi_count = 0; + incoming_count = 0; + 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 j, temp_idx;
/* Only phi src/dst SSA values need be converted here. Structurisation may * introduce new cases of undominated SSA use, which will be handled later. */ - if (ins->opcode != VKD3DSIH_PHI) + if (ins->opcode != VSIR_OP_PHI) continue; ++phi_count;
@@ -3682,9 +4490,9 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ if (!reserve_instructions(&instructions, &ins_capacity, program->instructions.count + incoming_count - phi_count)) goto fail;
- 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 *mov_ins, *ins = &program->instructions.elements[i]; + struct vkd3d_shader_instruction *mov_ins; size_t j;
for (j = 0; j < ins->dst_count; ++j) @@ -3695,12 +4503,12 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_
switch (ins->opcode) { - case VKD3DSIH_LABEL: + case VSIR_OP_LABEL: current_label = label_from_src_param(&ins->src[0]); break;
- case VKD3DSIH_BRANCH: - case VKD3DSIH_SWITCH_MONOLITHIC: + case VSIR_OP_BRANCH: + case VSIR_OP_SWITCH_MONOLITHIC: info = &block_info[current_label - 1];
for (j = 0; j < info->incoming_count; ++j) @@ -3708,7 +4516,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ struct phi_incoming_to_temp *incoming = &info->incomings[j];
mov_ins = &instructions[ins_count++]; - if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VKD3DSIH_MOV, 1, 0)) + if (!vsir_instruction_init_with_params(program, mov_ins, &ins->location, VSIR_OP_MOV, 1, 0)) goto fail; *mov_ins->dst = *incoming->dst; mov_ins->src = incoming->src; @@ -3716,7 +4524,7 @@ static enum vkd3d_result vsir_program_materialise_phi_ssas_to_temps(struct vsir_ } break;
- case VKD3DSIH_PHI: + case VSIR_OP_PHI: continue;
default: @@ -3753,7 +4561,7 @@ struct vsir_block_list
static void vsir_block_list_init(struct vsir_block_list *list) { - memset(list, 0, sizeof(*list)); + *list = (struct vsir_block_list){0}; }
static void vsir_block_list_cleanup(struct vsir_block_list *list) @@ -4125,11 +4933,11 @@ static void vsir_cfg_dump_dot(struct vsir_cfg *cfg)
switch (block->end->opcode) { - case VKD3DSIH_RET: + case VSIR_OP_RET: shape = "trapezium"; break;
- case VKD3DSIH_BRANCH: + case VSIR_OP_BRANCH: shape = vsir_register_is_label(&block->end->src[0].reg) ? "ellipse" : "box"; break;
@@ -4267,11 +5075,11 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
switch (instruction->opcode) { - case VKD3DSIH_PHI: - case VKD3DSIH_SWITCH_MONOLITHIC: + case VSIR_OP_PHI: + case VSIR_OP_SWITCH_MONOLITHIC: vkd3d_unreachable();
- case VKD3DSIH_LABEL: + case VSIR_OP_LABEL: { unsigned int label = label_from_src_param(&instruction->src[0]);
@@ -4288,16 +5096,16 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program break; }
- case VKD3DSIH_BRANCH: - case VKD3DSIH_RET: + case VSIR_OP_BRANCH: + case VSIR_OP_RET: VKD3D_ASSERT(current_block); current_block->end = instruction; current_block = NULL; break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: VKD3D_ASSERT(!current_block); finish = true; break; @@ -4322,10 +5130,10 @@ static enum vkd3d_result vsir_cfg_init(struct vsir_cfg *cfg, struct vsir_program
switch (block->end->opcode) { - case VKD3DSIH_RET: + case VSIR_OP_RET: break;
- case VKD3DSIH_BRANCH: + case VSIR_OP_BRANCH: if (vsir_register_is_label(&block->end->src[0].reg)) { if ((ret = vsir_cfg_add_edge(cfg, block, &block->end->src[0])) < 0) @@ -5004,7 +5812,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) /* Generate between zero and two jump instructions. */ switch (block->end->opcode) { - case VKD3DSIH_BRANCH: + case VSIR_OP_BRANCH: { struct vsir_cfg_edge_action action_true, action_false; bool invert_condition = false; @@ -5090,7 +5898,7 @@ static enum vkd3d_result vsir_cfg_build_structured_program(struct vsir_cfg *cfg) break; }
- case VKD3DSIH_RET: + case VSIR_OP_RET: if (!(structure = vsir_cfg_structure_list_append(stack[stack_depth - 1], STRUCTURE_TYPE_JUMP))) goto fail; structure->u.jump.type = JUMP_RET; @@ -5584,7 +6392,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_LOOP); + vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_LOOP);
if ((ret = vsir_cfg_structure_list_emit(cfg, &loop->body, loop->idx)) < 0) return ret; @@ -5592,7 +6400,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 5)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDLOOP); + vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDLOOP);
/* Add a trampoline to implement multilevel jumping depending on the stored * jump_target value. */ @@ -5607,7 +6415,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, const unsigned int inner_break_target = loop->idx << 1;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VKD3DSIH_IEQ, 1, 2)) + &no_loc, VSIR_OP_IEQ, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY;
dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count); @@ -5617,7 +6425,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, ++target->ins_count;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VKD3DSIH_CONTINUEP, 0, 1)) + &no_loc, VSIR_OP_CONTINUEP, 0, 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
src_param_init_temp_bool(&target->instructions[target->ins_count].src[0], target->temp_count); @@ -5626,7 +6434,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, ++target->temp_count;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VKD3DSIH_IEQ, 1, 2)) + &no_loc, VSIR_OP_IEQ, 1, 2)) return VKD3D_ERROR_OUT_OF_MEMORY;
dst_param_init_temp_bool(&target->instructions[target->ins_count].dst[0], target->temp_count); @@ -5636,7 +6444,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_loop(struct vsir_cfg *cfg, ++target->ins_count;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VKD3DSIH_BREAKP, 0, 1)) + &no_loc, VSIR_OP_BREAKP, 0, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; target->instructions[target->ins_count].flags |= VKD3D_SHADER_CONDITIONAL_OP_Z;
@@ -5660,7 +6468,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg return VKD3D_ERROR_OUT_OF_MEMORY;
if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VKD3DSIH_IF, 0, 1)) + &no_loc, VSIR_OP_IF, 0, 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
target->instructions[target->ins_count].src[0] = *selection->condition; @@ -5678,7 +6486,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ELSE); + vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ELSE);
if ((ret = vsir_cfg_structure_list_emit(cfg, &selection->else_body, loop_idx)) < 0) return ret; @@ -5687,7 +6495,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_selection(struct vsir_cfg if (!reserve_instructions(&target->instructions, &target->ins_capacity, target->ins_count + 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
- vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VKD3DSIH_ENDIF); + vsir_instruction_init(&target->instructions[target->ins_count++], &no_loc, VSIR_OP_ENDIF);
return VKD3D_OK; } @@ -5711,19 +6519,19 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, * in the lowest bit of jump_target. */ if (jump->target == loop_idx) { - opcode = jump->condition ? VKD3DSIH_CONTINUEP : VKD3DSIH_CONTINUE; + opcode = jump->condition ? VSIR_OP_CONTINUEP : VSIR_OP_CONTINUE; break; } jump_target |= 1; /* fall through */
case JUMP_BREAK: - opcode = jump->condition ? VKD3DSIH_BREAKP : VKD3DSIH_BREAK; + opcode = jump->condition ? VSIR_OP_BREAKP : VSIR_OP_BREAK; break;
case JUMP_RET: VKD3D_ASSERT(!jump->condition); - opcode = VKD3DSIH_RET; + opcode = VSIR_OP_RET; break;
default: @@ -5736,7 +6544,7 @@ static enum vkd3d_result vsir_cfg_structure_list_emit_jump(struct vsir_cfg *cfg, if (jump->needs_launcher) { if (!vsir_instruction_init_with_params(cfg->program, &target->instructions[target->ins_count], - &no_loc, VKD3DSIH_MOV, 1, 1)) + &no_loc, VSIR_OP_MOV, 1, 1)) return VKD3D_ERROR_OUT_OF_MEMORY;
dst_param_init_temp_uint(&target->instructions[target->ins_count].dst[0], target->jump_target_temp_idx); @@ -5864,7 +6672,7 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program,
switch (ins->opcode) { - case VKD3DSIH_LABEL: + 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, @@ -5873,9 +6681,9 @@ static enum vkd3d_result vsir_program_structurize(struct vsir_program *program, VKD3D_ASSERT(i == program->instructions.count); break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: 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; @@ -6041,7 +6849,7 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru
switch (ins->opcode) { - case VKD3DSIH_LABEL: + 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( @@ -6050,9 +6858,9 @@ static enum vkd3d_result vsir_program_materialize_undominated_ssas_to_temps(stru VKD3D_ASSERT(i == program->instructions.count); break;
- case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + 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; @@ -6125,14 +6933,12 @@ static enum vkd3d_result vsir_program_apply_flat_interpolation(struct vsir_progr }
static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *program, - const struct vkd3d_shader_instruction *ret, enum vkd3d_shader_comparison_func compare_func, + struct vsir_program_iterator *it, enum vkd3d_shader_comparison_func compare_func, const struct vkd3d_shader_parameter1 *ref, uint32_t colour_signature_idx, - uint32_t colour_temp, size_t *ret_pos, struct vkd3d_shader_message_context *message_context) + uint32_t colour_temp, struct vkd3d_shader_message_context *message_context) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - const struct vkd3d_shader_location loc = ret->location; + struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; static const struct vkd3d_shader_location no_loc; - size_t pos = ret - instructions->elements; struct vkd3d_shader_instruction *ins;
static const struct @@ -6143,33 +6949,33 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr } opcodes[] = { - [VKD3D_SHADER_COMPARISON_FUNC_EQUAL] = {VKD3DSIH_EQO, VKD3DSIH_IEQ}, - [VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL] = {VKD3DSIH_NEO, VKD3DSIH_INE}, - [VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE}, - [VKD3D_SHADER_COMPARISON_FUNC_LESS] = {VKD3DSIH_LTO, VKD3DSIH_ULT}, - [VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL] = {VKD3DSIH_GEO, VKD3DSIH_UGE, true}, - [VKD3D_SHADER_COMPARISON_FUNC_GREATER] = {VKD3DSIH_LTO, VKD3DSIH_ULT, true}, + [VKD3D_SHADER_COMPARISON_FUNC_EQUAL] = {VSIR_OP_EQO, VSIR_OP_IEQ}, + [VKD3D_SHADER_COMPARISON_FUNC_NOT_EQUAL] = {VSIR_OP_NEO, VSIR_OP_INE}, + [VKD3D_SHADER_COMPARISON_FUNC_GREATER_EQUAL] = {VSIR_OP_GEO, VSIR_OP_UGE}, + [VKD3D_SHADER_COMPARISON_FUNC_LESS] = {VSIR_OP_LTO, VSIR_OP_ULT}, + [VKD3D_SHADER_COMPARISON_FUNC_LESS_EQUAL] = {VSIR_OP_GEO, VSIR_OP_UGE, true}, + [VKD3D_SHADER_COMPARISON_FUNC_GREATER] = {VSIR_OP_LTO, VSIR_OP_ULT, true}, };
if (compare_func == VKD3D_SHADER_COMPARISON_FUNC_NEVER) { - if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) + vsir_program_iterator_prev(it); + if (!vsir_program_iterator_insert_after(it, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - ins = &program->instructions.elements[pos]; + ins = vsir_program_iterator_next(it);
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DISCARD, 0, 1); ins->flags = VKD3D_SHADER_CONDITIONAL_OP_Z; src_param_init_const_uint(&ins->src[0], 0); + vsir_program_iterator_next(it);
- *ret_pos = pos + 1; return VKD3D_OK; }
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 3)) + vsir_program_iterator_prev(it); + if (!vsir_program_iterator_insert_after(it, 3)) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - ins = &program->instructions.elements[pos]; + ins = vsir_program_iterator_next(it);
switch (ref->data_type) { @@ -6177,14 +6983,14 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].float_opcode, 1, 2); src_param_init_temp_float(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], - VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_FLOAT); + VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_F32); break;
case VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32: vsir_instruction_init_with_params(program, ins, &loc, opcodes[compare_func].uint_opcode, 1, 2); src_param_init_temp_uint(&ins->src[opcodes[compare_func].swap ? 1 : 0], colour_temp); src_param_init_parameter(&ins->src[opcodes[compare_func].swap ? 0 : 1], - VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VKD3D_DATA_UINT); + VKD3D_SHADER_PARAMETER_NAME_ALPHA_TEST_REF, VSIR_DATA_U32); break;
case VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4: @@ -6201,16 +7007,16 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr ins->src[opcodes[compare_func].swap ? 1 : 0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[opcodes[compare_func].swap ? 1 : 0].swizzle = VKD3D_SHADER_SWIZZLE(W, W, W, W);
- ++ins; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DISCARD, 0, 1); + 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; src_param_init_ssa_bool(&ins->src[0], program->ssa_count);
++program->ssa_count;
- ++ins; - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); + ins = 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_OUTPUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = colour_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].write_mask = program->output_signature.elements[colour_signature_idx].mask; @@ -6218,20 +7024,21 @@ static enum vkd3d_result insert_alpha_test_before_ret(struct vsir_program *progr ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE;
- *ret_pos = pos + 3; + vsir_program_iterator_next(it); + return VKD3D_OK; }
static enum vkd3d_result vsir_program_insert_alpha_test(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 *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; - size_t new_pos; int ret;
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) @@ -6268,19 +7075,16 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro if (compare_func != VKD3D_SHADER_COMPARISON_FUNC_NEVER) 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 == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) { - if ((ret = insert_alpha_test_before_ret(program, ins, compare_func, - ref, colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) + if ((ret = insert_alpha_test_before_ret(program, &it, compare_func, + ref, colour_signature_idx, colour_temp, message_context)) < 0) return ret; - i = new_pos; continue; }
@@ -6306,32 +7110,30 @@ static enum vkd3d_result vsir_program_insert_alpha_test(struct vsir_program *pro }
static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *program, - const struct vkd3d_shader_instruction *ret, uint32_t mask, uint32_t position_signature_idx, - uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx, size_t *ret_pos) + struct vsir_program_iterator *it, uint32_t mask, uint32_t position_signature_idx, + uint32_t position_temp, uint32_t low_signature_idx, uint32_t high_signature_idx) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - const struct vkd3d_shader_location loc = ret->location; - size_t pos = ret - instructions->elements; + const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; struct vkd3d_shader_instruction *ins; unsigned int output_idx = 0;
- if (!shader_instruction_array_insert_at(&program->instructions, pos, vkd3d_popcount(mask) + 1)) + vsir_program_iterator_prev(it); + if (!vsir_program_iterator_insert_after(it, vkd3d_popcount(mask) + 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - ins = &program->instructions.elements[pos]; + ins = vsir_program_iterator_next(it);
for (unsigned int i = 0; i < 8; ++i) { if (!(mask & (1u << i))) continue;
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_DP4, 1, 2); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_DP4, 1, 2); src_param_init_temp_float4(&ins->src[0], position_temp); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VKD3D_DATA_FLOAT); + src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_CLIP_PLANE_0 + i, VSIR_DATA_F32); ins->src[1].swizzle = VKD3D_SHADER_NO_SWIZZLE; ins->src[1].reg.dimension = VSIR_DIMENSION_VEC4;
- vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); if (output_idx < 4) ins->dst[0].reg.idx[0].offset = low_signature_idx; else @@ -6340,34 +7142,34 @@ static enum vkd3d_result insert_clip_planes_before_ret(struct vsir_program *prog ins->dst[0].write_mask = (1u << (output_idx % 4)); ++output_idx;
- ++ins; + ins = vsir_program_iterator_next(it); }
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VKD3D_DATA_FLOAT, 1); + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_OUTPUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = position_signature_idx; ins->dst[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->dst[0].write_mask = program->output_signature.elements[position_signature_idx].mask; src_param_init_temp_float(&ins->src[0], position_temp); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; + ins = vsir_program_iterator_next(it);
- *ret_pos = pos + vkd3d_popcount(mask) + 1; return VKD3D_OK; }
static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *program, struct vsir_transformation_context *ctx) { + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); struct shader_signature *signature = &program->output_signature; unsigned int low_signature_idx = ~0u, high_signature_idx = ~0u; const struct vkd3d_shader_parameter1 *mask_parameter = NULL; - struct signature_element *new_elements, *clip_element; 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; - size_t new_pos; int ret;
if (program->shader_version.type != VKD3D_SHADER_TYPE_VERTEX) @@ -6422,33 +7224,20 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
plane_count = vkd3d_popcount(mask);
- if (!(new_elements = vkd3d_realloc(signature->elements, - (signature->element_count + 2) * sizeof(*signature->elements)))) + /* Register mask is ignored since we operate after I/O normalisation. */ + if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 0, + vkd3d_write_mask_from_component_count(min(plane_count, 4)), 0, VKD3DSIM_NONE))) return VKD3D_ERROR_OUT_OF_MEMORY; - signature->elements = new_elements; - - low_signature_idx = signature->element_count; - clip_element = &signature->elements[signature->element_count++]; - memset(clip_element, 0, sizeof(*clip_element)); + low_signature_idx = clip_element - signature->elements; clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE; - clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; - clip_element->register_count = 1; - clip_element->mask = vkd3d_write_mask_from_component_count(min(plane_count, 4)); - clip_element->used_mask = clip_element->mask; - clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE;
if (plane_count > 4) { - high_signature_idx = signature->element_count; - clip_element = &signature->elements[signature->element_count++]; - memset(clip_element, 0, sizeof(*clip_element)); + if (!(clip_element = add_signature_element(signature, "SV_ClipDistance", 1, + vkd3d_write_mask_from_component_count(plane_count - 4), 0, VKD3DSIM_NONE))) + return VKD3D_ERROR_OUT_OF_MEMORY; + high_signature_idx = clip_element - signature->elements; clip_element->sysval_semantic = VKD3D_SHADER_SV_CLIP_DISTANCE; - clip_element->semantic_index = 1; - clip_element->component_type = VKD3D_SHADER_COMPONENT_FLOAT; - clip_element->register_count = 1; - clip_element->mask = vkd3d_write_mask_from_component_count(plane_count - 4); - clip_element->used_mask = clip_element->mask; - clip_element->min_precision = VKD3D_SHADER_MINIMUM_PRECISION_NONE; }
/* We're going to be reading from the output position, so we need to go @@ -6456,19 +7245,16 @@ static enum vkd3d_result vsir_program_insert_clip_planes(struct vsir_program *pr
position_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 == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) { - if ((ret = insert_clip_planes_before_ret(program, ins, mask, position_signature_idx, - position_temp, low_signature_idx, high_signature_idx, &new_pos)) < 0) + if ((ret = insert_clip_planes_before_ret(program, &it, mask, position_signature_idx, + position_temp, low_signature_idx, high_signature_idx)) < 0) return ret; - i = new_pos; continue; }
@@ -6497,32 +7283,32 @@ static bool is_pre_rasterization_shader(enum vkd3d_shader_type type) }
static enum vkd3d_result insert_point_size_before_ret(struct vsir_program *program, - const struct vkd3d_shader_instruction *ret, size_t *ret_pos) + struct vsir_program_iterator *it) { - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - const struct vkd3d_shader_location loc = ret->location; - size_t pos = ret - instructions->elements; + const struct vkd3d_shader_location loc = vsir_program_iterator_current(it)->location; struct vkd3d_shader_instruction *ins;
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 1)) + vsir_program_iterator_prev(it); + if (!vsir_program_iterator_insert_after(it, 1)) return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; - ins = &program->instructions.elements[pos]; + ins = vsir_program_iterator_next(it);
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); + 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); ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VKD3D_DATA_FLOAT); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE, VSIR_DATA_F32); + ins = vsir_program_iterator_next(it);
- *ret_pos = pos + 1; return VKD3D_OK; }
static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *program, struct vsir_transformation_context *ctx) { + 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) return VKD3D_OK; @@ -6551,18 +7337,14 @@ static enum vkd3d_result vsir_program_insert_point_size(struct vsir_program *pro program->has_point_size = true;
/* Append a point size write before each ret. */ - 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 (ins->opcode == VKD3DSIH_RET) + if (ins->opcode == VSIR_OP_RET) { - size_t new_pos; int ret;
- if ((ret = insert_point_size_before_ret(program, ins, &new_pos)) < 0) + if ((ret = insert_point_size_before_ret(program, &it)) < 0) return ret; - i = new_pos; } }
@@ -6573,7 +7355,9 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra struct vsir_transformation_context *ctx) { 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) return VKD3D_OK; @@ -6610,9 +7394,8 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra
/* Replace writes to the point size by inserting a clamp before each write. */
- 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]; const struct vkd3d_shader_location *loc; unsigned int ssa_value; bool clamp = false; @@ -6636,17 +7419,17 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra if (!clamp) continue;
- if (!shader_instruction_array_insert_at(&program->instructions, i + 1, !!min_parameter + !!max_parameter)) + if (!vsir_program_iterator_insert_after(&it, !!min_parameter + !!max_parameter)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[i + 1];
- loc = &program->instructions.elements[i].location; + loc = &vsir_program_iterator_current(&it)->location; + ins = vsir_program_iterator_next(&it);
if (min_parameter) { - vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MAX, 1, 2); + vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MAX, 1, 2); src_param_init_ssa_float(&ins->src[0], ssa_value); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VKD3D_DATA_FLOAT); + src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MIN, VSIR_DATA_F32); if (max_parameter) { dst_param_init_ssa_float(&ins->dst[0], program->ssa_count); @@ -6654,22 +7437,20 @@ static enum vkd3d_result vsir_program_insert_point_size_clamp(struct vsir_progra } else { - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; } - ++ins; - ++i; + ins = vsir_program_iterator_next(&it); }
if (max_parameter) { - vsir_instruction_init_with_params(program, ins, loc, VKD3DSIH_MIN, 1, 2); + vsir_instruction_init_with_params(program, ins, loc, VSIR_OP_MIN, 1, 2); src_param_init_ssa_float(&ins->src[0], ssa_value); - src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VKD3D_DATA_FLOAT); - vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); + src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_POINT_SIZE_MAX, VSIR_DATA_F32); + vsir_dst_param_init(&ins->dst[0], VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); ins->dst[0].reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; - - ++i; + ins = vsir_program_iterator_next(&it); } }
@@ -6747,12 +7528,13 @@ static bool replace_texcoord_with_point_coord(struct vsir_program *program, static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *program, struct vsir_transformation_context *ctx) { + 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_instruction *ins; bool used_texcoord = false; unsigned int coord_temp; - size_t i, insert_pos; + size_t i;
if (program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) return VKD3D_OK; @@ -6793,21 +7575,16 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr /* Construct the new temp after all LABEL, DCL, and NOP instructions. * We need to skip NOP instructions because they might result from removed * DCLs, and there could still be DCLs after NOPs. */ - for (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) && ins->opcode != VKD3DSIH_LABEL && ins->opcode != VKD3DSIH_NOP) + if (!vsir_instruction_is_dcl(ins) && ins->opcode != VSIR_OP_LABEL && ins->opcode != VSIR_OP_NOP) break; }
- insert_pos = i; - + it2 = it; /* Replace each texcoord read with a read from the point coord. */ - for (; i < program->instructions.count; ++i) + for (; ins; ins = vsir_program_iterator_next(&it2)) { - ins = &program->instructions.elements[i]; - if (vsir_instruction_is_dcl(ins)) continue;
@@ -6836,24 +7613,25 @@ static enum vkd3d_result vsir_program_insert_point_coord(struct vsir_program *pr
if (used_texcoord) { - if (!shader_instruction_array_insert_at(&program->instructions, insert_pos, 2)) + vsir_program_iterator_prev(&it); + if (!vsir_program_iterator_insert_after(&it, 2)) return VKD3D_ERROR_OUT_OF_MEMORY; - ins = &program->instructions.elements[insert_pos]; + ins = vsir_program_iterator_next(&it);
- vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &no_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, VKD3D_DATA_FLOAT, 0); + vsir_src_param_init(&ins->src[0], VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; ins->src[0].swizzle = VKD3D_SHADER_NO_SWIZZLE; - ++ins; + ins = vsir_program_iterator_next(&it);
- vsir_instruction_init_with_params(program, ins, &no_loc, VKD3DSIH_MOV, 1, 1); + vsir_instruction_init_with_params(program, ins, &no_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, VKD3D_DATA_FLOAT, 0); + vsir_src_param_init(&ins->src[0], VKD3DSPR_IMMCONST, VSIR_DATA_F32, 0); ins->src[0].reg.dimension = VSIR_DIMENSION_VEC4; - ++ins; + vsir_program_iterator_next(&it);
program->has_point_coord = true; } @@ -6919,20 +7697,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_ADD, 1, 2); + 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, VKD3D_DATA_FLOAT); - vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_END, VSIR_DATA_F32); + vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); 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->src[1].modifiers = VKD3DSPSM_NEG;
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_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, VKD3D_DATA_FLOAT); + src_param_init_parameter(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); break;
case VKD3D_SHADER_FOG_FRAGMENT_EXP: @@ -6951,15 +7729,15 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_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_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); - vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); + vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); 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);
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_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); @@ -6984,20 +7762,20 @@ static enum vkd3d_result insert_fragment_fog_before_ret(struct vsir_program *pro
ins = &program->instructions.elements[pos];
- vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_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_temp); - src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VKD3D_DATA_FLOAT); - vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VKD3D_DATA_FLOAT, 1); + src_param_init_parameter(&ins->src[0], VKD3D_SHADER_PARAMETER_NAME_FOG_SCALE, VSIR_DATA_F32); + vsir_src_param_init(&ins->src[1], VKD3DSPR_INPUT, VSIR_DATA_F32, 1); 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);
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_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);
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_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); @@ -7014,18 +7792,18 @@ 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, VKD3DSIH_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, VKD3D_DATA_FLOAT); + src_param_init_parameter_vec4(&ins->src[1], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32); ins->src[1].modifiers = VKD3DSPSM_NEG;
- vsir_instruction_init_with_params(program, ++ins, &loc, VKD3DSIH_MAD, 1, 3); - dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, colour_signature_idx, + 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, VKD3D_DATA_FLOAT); + src_param_init_parameter_vec4(&ins->src[2], VKD3D_SHADER_PARAMETER_NAME_FOG_COLOUR, VSIR_DATA_F32);
return VKD3D_OK; } @@ -7088,200 +7866,1096 @@ static enum vkd3d_result vsir_program_insert_fragment_fog(struct vsir_program *p if (vsir_instruction_is_dcl(ins)) continue;
- if (ins->opcode == VKD3DSIH_RET) + 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) + return ret; + i = new_pos; + continue; + } + + for (size_t j = 0; j < ins->dst_count; ++j) + { + struct vkd3d_shader_dst_param *dst = &ins->dst[j]; + + /* Note we run after I/O normalization. */ + if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx) + { + dst->reg.type = VKD3DSPR_TEMP; + dst->reg.idx[0].offset = colour_temp; + } + } + } + + return VKD3D_OK; +} + +static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *program, + struct vsir_transformation_context *ctx) +{ + struct shader_signature *signature = &program->output_signature; + const struct vkd3d_shader_parameter1 *source_parameter; + uint32_t register_idx = 0; + + if (!is_pre_rasterization_shader(program->shader_version.type)) + return VKD3D_OK; + + if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE))) + return VKD3D_OK; + + if (source_parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { + enum vkd3d_shader_fog_source source = source_parameter->u.immediate_constant.u.u32; + + if (source == VKD3D_SHADER_FOG_SOURCE_FOG) + return VKD3D_OK; + + if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W + && !vsir_signature_find_element_by_name(signature, "COLOR", 1)) + return VKD3D_OK; + } + + if (vsir_signature_find_element_by_name(signature, "FOG", 0)) + return VKD3D_OK; + + for (unsigned int i = 0; i < signature->element_count; ++i) + register_idx = max(register_idx, signature->elements[i].register_index + 1); + + if (!add_signature_element(signature, "FOG", 0, VKD3DSP_WRITEMASK_0, register_idx, VKD3DSIM_LINEAR)) + return VKD3D_ERROR_OUT_OF_MEMORY; + 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) +{ + const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; + struct vkd3d_shader_instruction_array *instructions = &program->instructions; + const struct vkd3d_shader_location loc = ret->location; + size_t pos = ret - instructions->elements; + struct vkd3d_shader_instruction *ins; + + if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) + return VKD3D_ERROR_OUT_OF_MEMORY; + ret = NULL; + + ins = &program->instructions.elements[pos]; + + /* Write the fog output. */ + vsir_instruction_init_with_params(program, ins, &loc, VSIR_OP_MOV, 1, 1); + dst_param_init_output(&ins->dst[0], VSIR_DATA_F32, fog_signature_idx, 0x1); + src_param_init_temp_float4(&ins->src[0], temp); + if (source == VKD3D_SHADER_FOG_SOURCE_Z) + 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; + + /* 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; + + *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 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; + enum vkd3d_shader_fog_source source; + const struct signature_element *e; + + if (!is_pre_rasterization_shader(program->shader_version.type)) + return VKD3D_OK; + + if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE))) + return VKD3D_OK; + + if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + { + vkd3d_shader_error(message_context, &no_loc, 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, + "Invalid fog source parameter data type %#x.", source_parameter->data_type); + return VKD3D_ERROR_INVALID_ARGUMENT; + } + source = source_parameter->u.immediate_constant.u.u32; + + TRACE("Fog source %#x.\n", source); + + if (source == VKD3D_SHADER_FOG_SOURCE_FOG) + return VKD3D_OK; + + if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W) + { + if (program->has_fog || !(e = vsir_signature_find_element_by_name(&program->output_signature, "COLOR", 1))) + return VKD3D_OK; + source_signature_idx = e - program->output_signature.elements; + } + else + { + 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_VSIR_MISSING_SEMANTIC, "Shader does not write position."); + return VKD3D_ERROR_INVALID_SHADER; + } + } + + if (!(e = vsir_signature_find_element_by_name(&program->output_signature, "FOG", 0))) + { + ERR("Fog output not found.\n"); + return VKD3D_ERROR_INVALID_SHADER; + } + fog_signature_idx = e - program->output_signature.elements; + + temp = program->temp_count++; + + /* 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) + { + 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) + return ret; + i = new_pos; + continue; + } + + for (size_t j = 0; j < ins->dst_count; ++j) + { + struct vkd3d_shader_dst_param *dst = &ins->dst[j]; + + /* Note we run after I/O normalization. */ + if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == source_signature_idx) + { + dst->reg.type = VKD3DSPR_TEMP; + dst->reg.idx[0].offset = temp; + } + } + } + + program->has_fog = true; + + return VKD3D_OK; +} + + +/* Distinguishes between instruction sources which are masked, where the used + * components of the source are determined by the write mask, and sources which + * are not masked, where the used components are pre-defined. + * + * E.g. "add r0.yz, r1.xyzw, r2.xyzw" uses the .yz components of r1 and r2, and + * therefore those sources are considered "masked", but + * "dp3 r0.y, r1.xyzw, r2.xyzw" uses the .xyz components. */ +static bool vsir_src_is_masked(enum vkd3d_shader_opcode opcode, unsigned int src_idx) +{ + switch (opcode) + { + case VSIR_OP_ABS: + case VSIR_OP_ACOS: + case VSIR_OP_ADD: + case VSIR_OP_AND: + case VSIR_OP_ASIN: + case VSIR_OP_ATAN: + case VSIR_OP_BFI: + case VSIR_OP_BFREV: + case VSIR_OP_CMP: + case VSIR_OP_CND: + case VSIR_OP_COS: + case VSIR_OP_COUNTBITS: + case VSIR_OP_DADD: /* NB: These are masked, but the mask is double-sized. */ + case VSIR_OP_DDIV: + case VSIR_OP_DFMA: + case VSIR_OP_DIV: + case VSIR_OP_DMAX: + case VSIR_OP_DMIN: + case VSIR_OP_DMOV: + case VSIR_OP_DMOVC: + case VSIR_OP_DMUL: + case VSIR_OP_DRCP: + case VSIR_OP_DSX: + case VSIR_OP_DSX_COARSE: + case VSIR_OP_DSX_FINE: + case VSIR_OP_DSY: + case VSIR_OP_DSY_COARSE: + case VSIR_OP_DSY_FINE: + case VSIR_OP_EQO: + case VSIR_OP_EQU: + case VSIR_OP_EXP: + case VSIR_OP_EXPP: + case VSIR_OP_F16TOF32: + case VSIR_OP_F32TOF16: + case VSIR_OP_FIRSTBIT_HI: + case VSIR_OP_FIRSTBIT_LO: + case VSIR_OP_FIRSTBIT_SHI: + case VSIR_OP_FRC: + case VSIR_OP_FREM: + case VSIR_OP_FTOD: + case VSIR_OP_FTOI: + case VSIR_OP_FTOU: + case VSIR_OP_GEO: + case VSIR_OP_GEU: + case VSIR_OP_HCOS: + case VSIR_OP_HSIN: + case VSIR_OP_HTAN: + case VSIR_OP_IADD: + case VSIR_OP_IBFE: + case VSIR_OP_IDIV: + case VSIR_OP_IEQ: + case VSIR_OP_IGE: + case VSIR_OP_ILT: + case VSIR_OP_IMAD: + case VSIR_OP_IMAX: + case VSIR_OP_IMIN: + case VSIR_OP_IMUL: + case VSIR_OP_IMUL_LOW: + case VSIR_OP_INE: + case VSIR_OP_INEG: + case VSIR_OP_IREM: + case VSIR_OP_ISFINITE: + case VSIR_OP_ISHL: + case VSIR_OP_ISHR: + case VSIR_OP_ISINF: + case VSIR_OP_ISNAN: + case VSIR_OP_ITOD: + case VSIR_OP_ITOF: + case VSIR_OP_ITOI: + case VSIR_OP_LOG: + case VSIR_OP_LOGP: + case VSIR_OP_LRP: + case VSIR_OP_LTO: + case VSIR_OP_LTU: + case VSIR_OP_MAD: + case VSIR_OP_MAX: + case VSIR_OP_MIN: + case VSIR_OP_MOV: + case VSIR_OP_MOVA: + case VSIR_OP_MOVC: + case VSIR_OP_MSAD: /* FIXME: Is this correct? */ + case VSIR_OP_MUL: + case VSIR_OP_NEO: + case VSIR_OP_NEU: + case VSIR_OP_NOT: + case VSIR_OP_OR: + case VSIR_OP_ORD: + case VSIR_OP_PHI: + case VSIR_OP_POW: + case VSIR_OP_QUAD_READ_ACROSS_D: + case VSIR_OP_QUAD_READ_ACROSS_X: + case VSIR_OP_QUAD_READ_ACROSS_Y: + case VSIR_OP_RCP: + case VSIR_OP_ROUND_NE: + case VSIR_OP_ROUND_NI: + case VSIR_OP_ROUND_PI: + case VSIR_OP_ROUND_Z: + case VSIR_OP_RSQ: + case VSIR_OP_SETP: + case VSIR_OP_SGE: + case VSIR_OP_SGN: + case VSIR_OP_SIN: + case VSIR_OP_SINCOS: /* FIXME: Only for sm4. */ + case VSIR_OP_SLT: + case VSIR_OP_SQRT: + case VSIR_OP_SUB: + case VSIR_OP_SWAPC: + case VSIR_OP_TAN: + case VSIR_OP_UBFE: + case VSIR_OP_UDIV: + case VSIR_OP_UDIV_SIMPLE: + case VSIR_OP_UGE: + case VSIR_OP_ULT: + case VSIR_OP_UMAX: + case VSIR_OP_UMIN: + case VSIR_OP_UMUL: + case VSIR_OP_UNO: + case VSIR_OP_UREM: + case VSIR_OP_USHR: + case VSIR_OP_UTOD: + case VSIR_OP_UTOF: + case VSIR_OP_UTOU: + case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL: + case VSIR_OP_WAVE_ACTIVE_BIT_AND: + case VSIR_OP_WAVE_ACTIVE_BIT_OR: + case VSIR_OP_WAVE_ACTIVE_BIT_XOR: + case VSIR_OP_WAVE_ALL_TRUE: + case VSIR_OP_WAVE_ANY_TRUE: + case VSIR_OP_WAVE_OP_ADD: + case VSIR_OP_WAVE_OP_IMAX: + case VSIR_OP_WAVE_OP_IMIN: + case VSIR_OP_WAVE_OP_MAX: + case VSIR_OP_WAVE_OP_MIN: + case VSIR_OP_WAVE_OP_MUL: + case VSIR_OP_WAVE_OP_UMAX: + case VSIR_OP_WAVE_OP_UMIN: + case VSIR_OP_WAVE_READ_LANE_FIRST: + case VSIR_OP_XOR: + return true; + + /* Atomics can't have a writemask. */ + case VSIR_OP_ATOMIC_AND: + case VSIR_OP_ATOMIC_CMP_STORE: + case VSIR_OP_ATOMIC_IADD: + case VSIR_OP_ATOMIC_IMAX: + case VSIR_OP_ATOMIC_IMIN: + case VSIR_OP_ATOMIC_OR: + case VSIR_OP_ATOMIC_UMAX: + case VSIR_OP_ATOMIC_UMIN: + case VSIR_OP_ATOMIC_XOR: + case VSIR_OP_BEM: + case VSIR_OP_BRANCH: + case VSIR_OP_BREAK: + case VSIR_OP_BREAKC: + case VSIR_OP_BREAKP: + case VSIR_OP_BUFINFO: + case VSIR_OP_CALL: + case VSIR_OP_CALLNZ: + case VSIR_OP_CASE: + case VSIR_OP_CHECK_ACCESS_FULLY_MAPPED: /* FIXME: Is this correct? */ + case VSIR_OP_CONTINUE: + case VSIR_OP_CONTINUEP: + case VSIR_OP_CRS: + case VSIR_OP_CUT: + case VSIR_OP_CUT_STREAM: + case VSIR_OP_DCL: + case VSIR_OP_DCL_CONSTANT_BUFFER: + case VSIR_OP_DCL_FUNCTION_BODY: + case VSIR_OP_DCL_FUNCTION_TABLE: + case VSIR_OP_DCL_GLOBAL_FLAGS: + case VSIR_OP_DCL_GS_INSTANCES: + case VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT: + case VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT: + case VSIR_OP_DCL_HS_MAX_TESSFACTOR: + case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: + case VSIR_OP_DCL_INDEXABLE_TEMP: + case VSIR_OP_DCL_INDEX_RANGE: + case VSIR_OP_DCL_INPUT: + case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: + case VSIR_OP_DCL_INPUT_PRIMITIVE: + case VSIR_OP_DCL_INPUT_PS: + case VSIR_OP_DCL_INPUT_PS_SGV: + case VSIR_OP_DCL_INPUT_PS_SIV: + case VSIR_OP_DCL_INPUT_SGV: + case VSIR_OP_DCL_INPUT_SIV: + case VSIR_OP_DCL_INTERFACE: + case VSIR_OP_DCL_OUTPUT: + case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: + case VSIR_OP_DCL_OUTPUT_SGV: + case VSIR_OP_DCL_OUTPUT_SIV: + case VSIR_OP_DCL_OUTPUT_TOPOLOGY: + case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_RESOURCE_STRUCTURED: + case VSIR_OP_DCL_SAMPLER: + case VSIR_OP_DCL_STREAM: + case VSIR_OP_DCL_TEMPS: + case VSIR_OP_DCL_TESSELLATOR_DOMAIN: + case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: + case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: + case VSIR_OP_DCL_TGSM_RAW: + case VSIR_OP_DCL_TGSM_STRUCTURED: + case VSIR_OP_DCL_THREAD_GROUP: + case VSIR_OP_DCL_UAV_RAW: + case VSIR_OP_DCL_UAV_STRUCTURED: + case VSIR_OP_DCL_UAV_TYPED: + case VSIR_OP_DCL_VERTICES_OUT: + case VSIR_OP_DEF: + case VSIR_OP_DEFAULT: + case VSIR_OP_DEFB: + case VSIR_OP_DEFI: + case VSIR_OP_DEQO: + case VSIR_OP_DGEO: + case VSIR_OP_DISCARD: + case VSIR_OP_DLT: + case VSIR_OP_DNE: + case VSIR_OP_DP2: + case VSIR_OP_DP2ADD: + case VSIR_OP_DP3: + case VSIR_OP_DP4: + case VSIR_OP_DST: + case VSIR_OP_DTOF: + case VSIR_OP_DTOI: + case VSIR_OP_DTOU: + case VSIR_OP_ELSE: + case VSIR_OP_EMIT: + case VSIR_OP_EMIT_STREAM: + case VSIR_OP_ENDIF: + case VSIR_OP_ENDLOOP: + case VSIR_OP_ENDREP: + case VSIR_OP_ENDSWITCH: + case VSIR_OP_FCALL: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_DECLS: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: + case VSIR_OP_IF: + case VSIR_OP_IFC: + /* It's unclear if any mapping is done for the source value. + * Does it require replicate swizzle? */ + case VSIR_OP_IMM_ATOMIC_ALLOC: + case VSIR_OP_IMM_ATOMIC_AND: + case VSIR_OP_IMM_ATOMIC_CMP_EXCH: + case VSIR_OP_IMM_ATOMIC_CONSUME: + case VSIR_OP_IMM_ATOMIC_EXCH: + case VSIR_OP_IMM_ATOMIC_IADD: + case VSIR_OP_IMM_ATOMIC_IMAX: + case VSIR_OP_IMM_ATOMIC_IMIN: + case VSIR_OP_IMM_ATOMIC_OR: + case VSIR_OP_IMM_ATOMIC_UMAX: + case VSIR_OP_IMM_ATOMIC_UMIN: + case VSIR_OP_IMM_ATOMIC_XOR: + case VSIR_OP_LABEL: + case VSIR_OP_LOOP: + case VSIR_OP_LIT: + case VSIR_OP_M3x2: + case VSIR_OP_M3x3: + case VSIR_OP_M3x4: + case VSIR_OP_M4x3: + case VSIR_OP_M4x4: + case VSIR_OP_NOP: + /* NRM writemask must be .xyz or .xyzw. */ + case VSIR_OP_NRM: + case VSIR_OP_PHASE: + case VSIR_OP_REP: + case VSIR_OP_RET: + case VSIR_OP_RETP: + /* Store instructions always require a trivial writemask. */ + case VSIR_OP_STORE_RAW: + case VSIR_OP_STORE_STRUCTURED: + case VSIR_OP_STORE_UAV_TYPED: + case VSIR_OP_SWITCH: + case VSIR_OP_SWITCH_MONOLITHIC: + case VSIR_OP_SYNC: + case VSIR_OP_TEX: + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXCOORD: + case VSIR_OP_TEXCRD: + case VSIR_OP_TEXDEPTH: + case VSIR_OP_TEXDP3: + case VSIR_OP_TEXDP3TEX: + case VSIR_OP_TEXKILL: + case VSIR_OP_TEXLD: + case VSIR_OP_TEXLDD: + case VSIR_OP_TEXLDL: + case VSIR_OP_TEXM3x2DEPTH: + case VSIR_OP_TEXM3x2PAD: + case VSIR_OP_TEXM3x2TEX: + case VSIR_OP_TEXM3x3: + case VSIR_OP_TEXM3x3DIFF: + case VSIR_OP_TEXM3x3PAD: + case VSIR_OP_TEXM3x3SPEC: + case VSIR_OP_TEXM3x3TEX: + case VSIR_OP_TEXM3x3VSPEC: + case VSIR_OP_TEXREG2AR: + case VSIR_OP_TEXREG2GB: + case VSIR_OP_TEXREG2RGB: + case VSIR_OP_WAVE_ACTIVE_BALLOT: + case VSIR_OP_WAVE_ALL_BIT_COUNT: + case VSIR_OP_WAVE_IS_FIRST_LANE: + case VSIR_OP_WAVE_PREFIX_BIT_COUNT: + return false; + + case VSIR_OP_QUAD_READ_LANE_AT: + case VSIR_OP_WAVE_READ_LANE_AT: + return (src_idx == 0); + + /* sm4 resource instructions are an odd case, since they're not actually + * per-component. However, the "swizzle" placed on the resource allows + * arbitrary destination writemasks to be used. + * + * This means that for the purposes of the "remapping" done by + * temp_allocator_set_dst(), we can basically treat those sources as + * "mapped", altering them when we reassign the destination writemask. */ + + /* FIXME: The documentation seems to say that these instructions behave + * this way, but is it correct? + * (It's silent about EVAL_*, but presumably they behave the same way.) */ + case VSIR_OP_EVAL_CENTROID: + case VSIR_OP_EVAL_SAMPLE_INDEX: + case VSIR_OP_SAMPLE_INFO: + case VSIR_OP_SAMPLE_POS: + return (src_idx == 0); + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_C: + case VSIR_OP_GATHER4_C_S: + case VSIR_OP_GATHER4_S: + case VSIR_OP_LD: + case VSIR_OP_LD2DMS: + case VSIR_OP_LD2DMS_S: + case VSIR_OP_LD_RAW: + case VSIR_OP_LD_RAW_S: + case VSIR_OP_LD_S: + case VSIR_OP_LD_UAV_TYPED: + case VSIR_OP_LD_UAV_TYPED_S: + case VSIR_OP_LOD: + case VSIR_OP_RESINFO: + case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_B_CL_S: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_CL_S: + case VSIR_OP_SAMPLE_C_CL_S: + case VSIR_OP_SAMPLE_C_LZ: + case VSIR_OP_SAMPLE_C_LZ_S: + case VSIR_OP_SAMPLE_GRAD: + case VSIR_OP_SAMPLE_GRAD_CL_S: + case VSIR_OP_SAMPLE_LOD: + case VSIR_OP_SAMPLE_LOD_S: + return (src_idx == 1); + case VSIR_OP_GATHER4_PO: + case VSIR_OP_GATHER4_PO_C: + case VSIR_OP_GATHER4_PO_C_S: + case VSIR_OP_GATHER4_PO_S: + case VSIR_OP_LD_STRUCTURED: + case VSIR_OP_LD_STRUCTURED_S: + return (src_idx == 2); + + case VSIR_OP_INVALID: + case VSIR_OP_COUNT: + break; + } + + vkd3d_unreachable(); +} + +struct liveness_tracker +{ + struct liveness_tracker_reg + { + bool written; + bool fixed_mask; + uint8_t mask; + unsigned int first_write, last_access; + } *ssa_regs; +}; + +static void liveness_track_src(struct liveness_tracker *tracker, + struct vkd3d_shader_src_param *src, unsigned int index) +{ + for (unsigned int k = 0; k < src->reg.idx_count; ++k) + { + if (src->reg.idx[k].rel_addr) + liveness_track_src(tracker, src->reg.idx[k].rel_addr, index); + } + + if (src->reg.type == VKD3DSPR_SSA) + tracker->ssa_regs[src->reg.idx[0].offset].last_access = index; +} + +static void liveness_track_dst(struct liveness_tracker *tracker, struct vkd3d_shader_dst_param *dst, + unsigned int index, const struct vkd3d_shader_version *version, enum vkd3d_shader_opcode opcode) +{ + struct liveness_tracker_reg *reg; + + for (unsigned int k = 0; k < dst->reg.idx_count; ++k) + { + if (dst->reg.idx[k].rel_addr) + liveness_track_src(tracker, dst->reg.idx[k].rel_addr, index); + } + + if (dst->reg.type == VKD3DSPR_SSA) + reg = &tracker->ssa_regs[dst->reg.idx[0].offset]; + else + return; + + if (!reg->written) + reg->first_write = index; + reg->last_access = index; + reg->written = true; + reg->mask |= dst->write_mask; + + switch (opcode) + { + case VSIR_OP_BEM: + case VSIR_OP_CRS: + case VSIR_OP_DST: + case VSIR_OP_LIT: + case VSIR_OP_M3x2: + case VSIR_OP_M3x3: + case VSIR_OP_M3x4: + case VSIR_OP_M4x3: + case VSIR_OP_M4x4: + case VSIR_OP_NRM: + case VSIR_OP_TEX: + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXCOORD: + case VSIR_OP_TEXCRD: + case VSIR_OP_TEXDEPTH: + case VSIR_OP_TEXDP3: + case VSIR_OP_TEXDP3TEX: + case VSIR_OP_TEXLD: + case VSIR_OP_TEXLDD: + case VSIR_OP_TEXLDL: + case VSIR_OP_TEXM3x2DEPTH: + case VSIR_OP_TEXM3x2PAD: + case VSIR_OP_TEXM3x2TEX: + case VSIR_OP_TEXM3x3: + case VSIR_OP_TEXM3x3DIFF: + case VSIR_OP_TEXM3x3PAD: + case VSIR_OP_TEXM3x3SPEC: + case VSIR_OP_TEXM3x3TEX: + case VSIR_OP_TEXM3x3VSPEC: + case VSIR_OP_TEXREG2AR: + case VSIR_OP_TEXREG2GB: + case VSIR_OP_TEXREG2RGB: + /* All of these instructions have fixed destinations—they can + * in some cases be masked, but the destination cannot be + * reallocated to a different set of components. */ + case VSIR_OP_IMUL: + case VSIR_OP_SWAPC: + case VSIR_OP_UDIV: + case VSIR_OP_UMUL: + /* These instructions don't have fixed destinations, but they have + * multiple destination and are per-component, meaning that the + * destination masks for each component have to match. + * This is a bit tricky to pull off, so for now we just force + * these to have a fixed mask as well. + * This assumes that the destination masks are equal to each other + * to begin with! */ + reg->fixed_mask = true; + break; + + case VSIR_OP_SINCOS: + /* sm1 has a fixed destination like LIT, NRM. + * sm4 is two-component and masked, like IMUL. */ + if (version->major < 3) + { + /* We have the additional constraint here that sincos scratches + * whichever components of .xyz it doesn't write. We can achieve + * this by simply adding those components to reg->mask. */ + reg->mask |= 0x7; + } + reg->fixed_mask = true; + break; + + default: + break; + } +} + +static void liveness_tracker_cleanup(struct liveness_tracker *tracker) +{ + vkd3d_free(tracker->ssa_regs); +} + +static enum vkd3d_result track_liveness(struct vsir_program *program, struct liveness_tracker *tracker) +{ + struct liveness_tracker_reg *regs; + unsigned int loop_depth = 0; + unsigned int loop_start = 0; + + memset(tracker, 0, sizeof(*tracker)); + + if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) + return VKD3D_ERROR_OUT_OF_MEMORY; + tracker->ssa_regs = regs; + + for (unsigned int i = 0; i < program->instructions.count; ++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++) + loop_start = i; + } + else if (ins->opcode == VSIR_OP_ENDLOOP || ins->opcode == VSIR_OP_ENDREP) + { + if (!--loop_depth) + { + /* Go through the allocator, find anything that was touched + * during the loop, and extend its liveness to the whole range + * of the loop. + * This isn't very sophisticated (e.g. we could try to avoid + * this for registers first written inside a loop body and only + * ever read inside one), but many of the cases that matter are + * affected by other optimizations such as copy propagation + * anyway. + * + * This is overkill for SSA registers. If an SSA register is + * written in loop L and last read in L, we don't need to touch + * its liveness. If it's last read in an inferior loop of L, we + * only need to extend its last-read to the end of L. (And it + * 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. */ + for (unsigned int j = 0; j < program->ssa_count; ++j) + { + struct liveness_tracker_reg *reg = &tracker->ssa_regs[j]; + + if (reg->first_write > loop_start) + reg->first_write = loop_start; + if (reg->last_access < i) + reg->last_access = i; + } + } + } + + for (unsigned int j = 0; j < ins->dst_count; ++j) + liveness_track_dst(tracker, &ins->dst[j], i, &program->shader_version, ins->opcode); + for (unsigned int j = 0; j < ins->src_count; ++j) + liveness_track_src(tracker, &ins->src[j], i); + } + + return VKD3D_OK; +} + +struct temp_allocator +{ + struct vkd3d_shader_message_context *message_context; + struct temp_allocator_reg + { + uint8_t allocated_mask; + uint32_t temp_id; + } *ssa_regs; + size_t allocated_ssa_count; + enum vkd3d_result result; +}; + +static uint8_t get_available_writemask(const struct temp_allocator *allocator, + struct liveness_tracker *tracker, unsigned int first_write, unsigned int last_access, uint32_t temp_id) +{ + uint8_t writemask = VKD3DSP_WRITEMASK_ALL; + + for (size_t i = 0; i < allocator->allocated_ssa_count; ++i) + { + const struct temp_allocator_reg *reg = &allocator->ssa_regs[i]; + const struct liveness_tracker_reg *liveness_reg = &tracker->ssa_regs[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 (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) +{ + if (!liveness_reg->written) + return false; + + for (uint32_t id = base_id;; ++id) + { + uint8_t available_mask = get_available_writemask(allocator, tracker, + liveness_reg->first_write, liveness_reg->last_access, id); + + if (liveness_reg->fixed_mask) { - if ((ret = insert_fragment_fog_before_ret(program, ins, mode, fog_signature_idx, - colour_signature_idx, colour_temp, &new_pos, message_context)) < 0) - return ret; - i = new_pos; - continue; + if ((available_mask & liveness_reg->mask) == liveness_reg->mask) + { + reg->temp_id = id; + reg->allocated_mask = liveness_reg->mask; + return true; + } } - - for (size_t j = 0; j < ins->dst_count; ++j) + else { - struct vkd3d_shader_dst_param *dst = &ins->dst[j]; + /* 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);
- /* Note we run after I/O normalization. */ - if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == colour_signature_idx) + if (vkd3d_popcount(available_mask) >= vkd3d_popcount(liveness_reg->mask)) { - dst->reg.type = VKD3DSPR_TEMP; - dst->reg.idx[0].offset = colour_temp; + reg->temp_id = id; + reg->allocated_mask = vsir_combine_write_masks(available_mask, liveness_reg->mask); + return true; } } } - - return VKD3D_OK; }
-static enum vkd3d_result vsir_program_add_fog_output(struct vsir_program *program, - struct vsir_transformation_context *ctx) +static void temp_allocator_set_src(struct temp_allocator *allocator, struct vkd3d_shader_src_param *src) { - struct shader_signature *signature = &program->output_signature; - const struct vkd3d_shader_parameter1 *source_parameter; - uint32_t register_idx = 0; + struct temp_allocator_reg *reg;
- if (!is_pre_rasterization_shader(program->shader_version.type)) - return VKD3D_OK; - - if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE))) - return VKD3D_OK; - - if (source_parameter->type == VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + for (unsigned int k = 0; k < src->reg.idx_count; ++k) { - enum vkd3d_shader_fog_source source = source_parameter->u.immediate_constant.u.u32; - - if (source == VKD3D_SHADER_FOG_SOURCE_FOG) - return VKD3D_OK; - - if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W - && !vsir_signature_find_element_by_name(signature, "COLOR", 1)) - return VKD3D_OK; + if (src->reg.idx[k].rel_addr) + temp_allocator_set_src(allocator, src->reg.idx[k].rel_addr); }
- if (vsir_signature_find_element_by_name(signature, "FOG", 0)) - return VKD3D_OK; - - for (unsigned int i = 0; i < signature->element_count; ++i) - register_idx = max(register_idx, signature->elements[i].register_index + 1); + if (src->reg.type == VKD3DSPR_SSA) + reg = &allocator->ssa_regs[src->reg.idx[0].offset]; + else + return;
- if (!add_signature_element(signature, "FOG", 0, VKD3DSP_WRITEMASK_0, register_idx, VKD3DSIM_LINEAR)) - return VKD3D_ERROR_OUT_OF_MEMORY; - return VKD3D_OK; + src->reg.type = VKD3DSPR_TEMP; + src->reg.dimension = VSIR_DIMENSION_VEC4; + src->reg.idx[0].offset = reg->temp_id; + src->swizzle = vsir_combine_swizzles(vsir_swizzle_from_writemask(reg->allocated_mask), src->swizzle); }
-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 uint32_t vsir_map_swizzle(uint32_t swizzle, unsigned int writemask) { - const struct signature_element *e = &program->output_signature.elements[source_signature_idx]; - struct vkd3d_shader_instruction_array *instructions = &program->instructions; - const struct vkd3d_shader_location loc = ret->location; - size_t pos = ret - instructions->elements; - struct vkd3d_shader_instruction *ins; + unsigned int src_component = 0; + uint32_t ret = 0;
- if (!shader_instruction_array_insert_at(&program->instructions, pos, 2)) - return VKD3D_ERROR_OUT_OF_MEMORY; - ret = NULL; + /* Leave replicate swizzles alone; some instructions need them. */ + if (swizzle == VKD3D_SHADER_SWIZZLE(X, X, X, X) + || swizzle == VKD3D_SHADER_SWIZZLE(Y, Y, Y, Y) + || swizzle == VKD3D_SHADER_SWIZZLE(Z, Z, Z, Z) + || swizzle == VKD3D_SHADER_SWIZZLE(W, W, W, W)) + return swizzle;
- ins = &program->instructions.elements[pos]; + for (unsigned int dst_component = 0; dst_component < VKD3D_VEC4_SIZE; ++dst_component) + { + if (writemask & (1u << dst_component)) + vsir_swizzle_set_component(&ret, dst_component, vsir_swizzle_get_component(swizzle, src_component++)); + } + return ret; +}
- /* Write the fog output. */ - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); - dst_param_init_output(&ins->dst[0], VKD3D_DATA_FLOAT, fog_signature_idx, 0x1); - src_param_init_temp_float4(&ins->src[0], temp); - if (source == VKD3D_SHADER_FOG_SOURCE_Z) - 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; +static void vsir_remap_immconst(struct vkd3d_shader_src_param *src, unsigned int writemask) +{ + union vsir_immediate_constant prev = src->reg.u; + unsigned int src_component = 0;
- /* Write the position or specular output. */ - vsir_instruction_init_with_params(program, ins, &loc, VKD3DSIH_MOV, 1, 1); - dst_param_init_output(&ins->dst[0], vkd3d_data_type_from_component_type(e->component_type), - source_signature_idx, e->mask); - src_param_init_temp_float4(&ins->src[0], temp); - ++ins; + for (unsigned int dst_component = 0; dst_component < VKD3D_VEC4_SIZE; ++dst_component) + { + if (writemask & (1u << dst_component)) + src->reg.u.immconst_u32[dst_component] = prev.immconst_u32[src_component++]; + } +}
- *ret_pos = pos + 2; - return VKD3D_OK; +static void vsir_remap_immconst64(struct vkd3d_shader_src_param *src, unsigned int writemask) +{ + if (writemask == (VKD3DSP_WRITEMASK_2 | VKD3DSP_WRITEMASK_3)) + src->reg.u.immconst_u64[1] = src->reg.u.immconst_u64[0]; }
-static enum vkd3d_result vsir_program_insert_vertex_fog(struct vsir_program *program, - struct vsir_transformation_context *ctx) +static bool vsir_opcode_is_double(enum vkd3d_shader_opcode opcode) { - 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; - enum vkd3d_shader_fog_source source; - const struct signature_element *e; + switch (opcode) + { + case VSIR_OP_DADD: + case VSIR_OP_DDIV: + case VSIR_OP_DFMA: + case VSIR_OP_DMAX: + case VSIR_OP_DMIN: + case VSIR_OP_DMOV: + case VSIR_OP_DMOVC: + case VSIR_OP_DMUL: + case VSIR_OP_DRCP: + case VSIR_OP_DEQO: + case VSIR_OP_DGEO: + case VSIR_OP_DLT: + case VSIR_OP_DNE: + case VSIR_OP_DTOF: + case VSIR_OP_DTOI: + case VSIR_OP_DTOU: + case VSIR_OP_FTOD: + return true;
- if (!is_pre_rasterization_shader(program->shader_version.type)) - return VKD3D_OK; + default: + return false; + } +}
- if (!(source_parameter = vsir_program_get_parameter(program, VKD3D_SHADER_PARAMETER_NAME_FOG_SOURCE))) - return VKD3D_OK; +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;
- if (source_parameter->type != VKD3D_SHADER_PARAMETER_TYPE_IMMEDIATE_CONSTANT) + for (unsigned int k = 0; k < dst->reg.idx_count; ++k) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, - "Unsupported fog source parameter type %#x.", source_parameter->type); - return VKD3D_ERROR_NOT_IMPLEMENTED; + if (dst->reg.idx[k].rel_addr) + temp_allocator_set_src(allocator, dst->reg.idx[k].rel_addr); } - if (source_parameter->data_type != VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32) + + if (dst->reg.type == VKD3DSPR_SSA) + reg = &allocator->ssa_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) { - vkd3d_shader_error(message_context, &no_loc, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, - "Invalid fog source parameter data type %#x.", source_parameter->data_type); - return VKD3D_ERROR_INVALID_ARGUMENT; + dst->write_mask = reg->allocated_mask; + + if (vsir_opcode_is_double(ins->opcode)) + { + vkd3d_shader_error(allocator->message_context, &ins->location, + VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED, "Doubles are not currently handled."); + allocator->result = VKD3D_ERROR_NOT_IMPLEMENTED; + } + + for (unsigned int i = 0; i < ins->src_count; ++i) + { + struct vkd3d_shader_src_param *src = &ins->src[i]; + + if (vsir_src_is_masked(ins->opcode, i)) + { + if (src->reg.type == VKD3DSPR_IMMCONST) + vsir_remap_immconst(src, dst->write_mask); + else if (src->reg.type == VKD3DSPR_IMMCONST64) + vsir_remap_immconst64(src, dst->write_mask); + else + src->swizzle = vsir_map_swizzle(src->swizzle, dst->write_mask); + } + } } - source = source_parameter->u.immediate_constant.u.u32; +}
- TRACE("Fog source %#x.\n", source); +enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) +{ + const unsigned int prev_temp_count = program->temp_count; + struct temp_allocator allocator = {0}; + struct temp_allocator_reg *regs; + struct liveness_tracker tracker; + enum vkd3d_result ret;
- if (source == VKD3D_SHADER_FOG_SOURCE_FOG) + if (!program->ssa_count) return VKD3D_OK;
- if (source == VKD3D_SHADER_FOG_SOURCE_FOG_OR_SPECULAR_W) + if ((ret = track_liveness(program, &tracker))) + return ret; + + if (!(regs = vkd3d_calloc(program->ssa_count, sizeof(*regs)))) { - if (program->has_fog || !(e = vsir_signature_find_element_by_name(&program->output_signature, "COLOR", 1))) - return VKD3D_OK; - source_signature_idx = e - program->output_signature.elements; + liveness_tracker_cleanup(&tracker); + return VKD3D_ERROR_OUT_OF_MEMORY; } - else + allocator.message_context = message_context; + allocator.ssa_regs = regs; + + for (unsigned int i = 0; i < program->ssa_count; ++i) { - if (!vsir_signature_find_sysval(&program->output_signature, - VKD3D_SHADER_SV_POSITION, 0, &source_signature_idx)) + 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)) { - vkd3d_shader_error(ctx->message_context, &no_loc, - VKD3D_SHADER_ERROR_VSIR_MISSING_SEMANTIC, "Shader does not write position."); - return VKD3D_ERROR_INVALID_SHADER; + TRACE("Allocated r%u%s to 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); } + ++allocator.allocated_ssa_count; }
- if (!(e = vsir_signature_find_element_by_name(&program->output_signature, "FOG", 0))) + for (unsigned int i = 0; i < program->instructions.count; ++i) { - ERR("Fog output not found.\n"); - return VKD3D_ERROR_INVALID_SHADER; + 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) + temp_allocator_set_src(&allocator, &ins->src[j]); + for (unsigned int j = 0; j < ins->dst_count; ++j) + temp_allocator_set_dst(&allocator, &ins->dst[j], ins); } - fog_signature_idx = e - program->output_signature.elements;
- temp = program->temp_count++; + program->ssa_count = 0;
- /* 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) + vkd3d_free(regs); + liveness_tracker_cleanup(&tracker); + return allocator.result; +} + +/* Rewrite dcl_temps to reflect the new temp count. + * Note that dcl_temps appears once per phase, and should reflect only the + * number of temps needed by that phase. + * Therefore we iterate backwards through the shader, finding the maximum + * register used by any instruction, update the dcl_temps at the beginning + * of each phase, and then reset the temp count back to 0 for the next + * phase (if any). */ +enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context) +{ + unsigned int temp_count = 0; + + for (int i = program->instructions.count - 1; i >= 0; --i) { struct vkd3d_shader_instruction *ins = &program->instructions.elements[i];
- if (vsir_instruction_is_dcl(ins)) + if (ins->opcode == VSIR_OP_DCL_TEMPS) + { + ins->declaration.count = temp_count; + temp_count = 0; continue; + }
- if (ins->opcode == VKD3DSIH_RET) + if (temp_count && program->shader_version.major >= 4 + && (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE + || ins->opcode == VSIR_OP_HS_FORK_PHASE + || ins->opcode == VSIR_OP_HS_JOIN_PHASE)) { - size_t new_pos; - int ret; + /* 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)) + return VKD3D_ERROR_OUT_OF_MEMORY;
- if ((ret = insert_vertex_fog_before_ret(program, ins, source, temp, - fog_signature_idx, source_signature_idx, &new_pos)) < 0) - return ret; - i = new_pos; + ins = &program->instructions.elements[i + 1]; + vsir_instruction_init(ins, &program->instructions.elements[i].location, VSIR_OP_DCL_TEMPS); + ins->declaration.count = temp_count; + temp_count = 0; continue; }
- for (size_t j = 0; j < ins->dst_count; ++j) + for (unsigned int j = 0; j < ins->src_count; ++j) { - struct vkd3d_shader_dst_param *dst = &ins->dst[j]; + if (ins->src[j].reg.type == VKD3DSPR_TEMP) + temp_count = max(temp_count, ins->src[j].reg.idx[0].offset + 1); + }
- /* Note we run after I/O normalization. */ - if (dst->reg.type == VKD3DSPR_OUTPUT && dst->reg.idx[0].offset == source_signature_idx) - { - dst->reg.type = VKD3DSPR_TEMP; - dst->reg.idx[0].offset = temp; - } + for (unsigned int j = 0; j < ins->dst_count; ++j) + { + if (ins->dst[j].reg.type == VKD3DSPR_TEMP) + temp_count = max(temp_count, ins->dst[j].reg.idx[0].offset + 1); } }
- program->has_fog = true; + if (temp_count && program->shader_version.major >= 4) + { + struct vkd3d_shader_instruction *ins; + + if (!shader_instruction_array_insert_at(&program->instructions, 0, 1)) + return VKD3D_ERROR_OUT_OF_MEMORY; + + ins = &program->instructions.elements[0]; + vsir_instruction_init(ins, &program->instructions.elements[1].location, VSIR_OP_DCL_TEMPS); + ins->declaration.count = temp_count; + }
return VKD3D_OK; } @@ -7307,7 +8981,7 @@ struct validation_context struct validation_context_ssa_data { enum vsir_dimension dimension; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; size_t first_seen; uint32_t write_mask; uint32_t read_mask; @@ -7538,10 +9212,10 @@ static const bool vsir_get_io_register_data(struct validation_context *ctx,
switch (ctx->phase) { - case VKD3DSIH_HS_CONTROL_POINT_PHASE: phase = PHASE_CONTROL_POINT; break; - case VKD3DSIH_HS_FORK_PHASE: phase = PHASE_FORK; break; - case VKD3DSIH_HS_JOIN_PHASE: phase = PHASE_JOIN; break; - case VKD3DSIH_INVALID: phase = PHASE_NONE; break; + case VSIR_OP_HS_CONTROL_POINT_PHASE: phase = PHASE_CONTROL_POINT; break; + case VSIR_OP_HS_FORK_PHASE: phase = PHASE_FORK; break; + case VSIR_OP_HS_JOIN_PHASE: phase = PHASE_JOIN; break; + case VSIR_OP_INVALID: phase = PHASE_NONE; break;
default: vkd3d_unreachable(); @@ -7783,7 +9457,7 @@ static void vsir_validate_label_register(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid precision %#x for a LABEL register.", reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED) + 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);
@@ -7841,10 +9515,6 @@ static void vsir_validate_descriptor_indices(struct validation_context *ctx, static void vsir_validate_constbuffer_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { - if (reg->precision != VKD3D_SHADER_REGISTER_PRECISION_DEFAULT) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, - "Invalid precision %#x for a CONSTBUFFER register.", reg->precision); - if (reg->dimension != VSIR_DIMENSION_VEC4) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DIMENSION, "Invalid dimension %#x for a CONSTBUFFER register.", reg->dimension); @@ -7866,7 +9536,7 @@ static void vsir_validate_sampler_register(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid precision %#x for a SAMPLER register.", reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED) + 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);
@@ -7892,7 +9562,7 @@ static void vsir_validate_resource_register(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid precision %#x for a RESOURCE register.", reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED) + 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);
@@ -7918,7 +9588,7 @@ static void vsir_validate_uav_register(struct validation_context *ctx, "Invalid precision %#x for a UAV register.", reg->precision);
- if (reg->data_type != VKD3D_DATA_UNUSED) + 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); @@ -8005,6 +9675,30 @@ static void vsir_validate_src_param(struct validation_context *ctx, static void vsir_validate_register(struct validation_context *ctx, const struct vkd3d_shader_register *reg) { + static const struct register_validation_data + { + bool valid; + unsigned int idx_count; + enum vsir_dimension dimension; + } + register_validation_data[] = + { + [VKD3DSPR_DEPTHOUT] = {true, 0, VSIR_DIMENSION_SCALAR}, + [VKD3DSPR_PRIMID] = {true, 0, VSIR_DIMENSION_SCALAR}, + [VKD3DSPR_OUTPOINTID] = {true, 0, VSIR_DIMENSION_SCALAR}, + [VKD3DSPR_THREADID] = {true, 0, VSIR_DIMENSION_VEC4}, + [VKD3DSPR_THREADGROUPID] = {true, 0, VSIR_DIMENSION_VEC4}, + [VKD3DSPR_LOCALTHREADID] = {true, 0, VSIR_DIMENSION_VEC4}, + [VKD3DSPR_LOCALTHREADINDEX] = {true, 0, VSIR_DIMENSION_VEC4}, + [VKD3DSPR_COVERAGE] = {true, 0, VSIR_DIMENSION_VEC4}, + [VKD3DSPR_SAMPLEMASK] = {true, 0, VSIR_DIMENSION_SCALAR}, + [VKD3DSPR_GSINSTID] = {true, 0, VSIR_DIMENSION_VEC4}, + [VKD3DSPR_DEPTHOUTGE] = {true, 0, VSIR_DIMENSION_SCALAR}, + [VKD3DSPR_DEPTHOUTLE] = {true, 0, VSIR_DIMENSION_SCALAR}, + [VKD3DSPR_OUTSTENCILREF] = {true, 0, VSIR_DIMENSION_SCALAR}, + }; + + const struct register_validation_data *validation_data; unsigned int i;
if (reg->type >= VKD3DSPR_COUNT) @@ -8015,7 +9709,7 @@ static void vsir_validate_register(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_PRECISION, "Invalid register precision %#x.", reg->precision);
- if (reg->data_type >= VKD3D_DATA_COUNT) + if (reg->data_type >= VSIR_DATA_TYPE_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Invalid register data type %#x.", reg->data_type);
@@ -8070,10 +9764,6 @@ static void vsir_validate_register(struct validation_context *ctx, vsir_validate_io_register(ctx, reg); break;
- case VKD3DSPR_DEPTHOUT: - vsir_validate_register_without_indices(ctx, reg); - break; - case VKD3DSPR_MISCTYPE: vsir_validate_misctype_register(ctx, reg); break; @@ -8094,10 +9784,6 @@ static void vsir_validate_register(struct validation_context *ctx, vsir_validate_constbuffer_register(ctx, reg); break;
- case VKD3DSPR_PRIMID: - vsir_validate_register_without_indices(ctx, reg); - break; - case VKD3DSPR_NULL: vsir_validate_register_without_indices(ctx, reg); break; @@ -8110,75 +9796,31 @@ static void vsir_validate_register(struct validation_context *ctx, vsir_validate_resource_register(ctx, reg); break;
- case VKD3DSPR_UAV: - vsir_validate_uav_register(ctx, reg); - break; - - case VKD3DSPR_OUTPOINTID: - vsir_validate_register_without_indices(ctx, reg); - break; - - case VKD3DSPR_FORKINSTID: - vsir_validate_register_without_indices(ctx, reg); - break; - - case VKD3DSPR_JOININSTID: - vsir_validate_register_without_indices(ctx, reg); - break; - - case VKD3DSPR_INCONTROLPOINT: - vsir_validate_io_register(ctx, reg); - break; - - case VKD3DSPR_OUTCONTROLPOINT: - vsir_validate_io_register(ctx, reg); - break; - - case VKD3DSPR_PATCHCONST: - vsir_validate_io_register(ctx, reg); - break; - - case VKD3DSPR_TESSCOORD: - vsir_validate_register_without_indices(ctx, reg); - break; - - case VKD3DSPR_THREADID: - vsir_validate_register_without_indices(ctx, reg); - break; - - case VKD3DSPR_THREADGROUPID: - vsir_validate_register_without_indices(ctx, reg); - break; - - case VKD3DSPR_LOCALTHREADID: - vsir_validate_register_without_indices(ctx, reg); - break; - - case VKD3DSPR_LOCALTHREADINDEX: - vsir_validate_register_without_indices(ctx, reg); + case VKD3DSPR_UAV: + vsir_validate_uav_register(ctx, reg); break;
- case VKD3DSPR_COVERAGE: + case VKD3DSPR_FORKINSTID: vsir_validate_register_without_indices(ctx, reg); break;
- case VKD3DSPR_SAMPLEMASK: + case VKD3DSPR_JOININSTID: vsir_validate_register_without_indices(ctx, reg); break;
- case VKD3DSPR_GSINSTID: - vsir_validate_register_without_indices(ctx, reg); + case VKD3DSPR_INCONTROLPOINT: + vsir_validate_io_register(ctx, reg); break;
- case VKD3DSPR_DEPTHOUTGE: - vsir_validate_register_without_indices(ctx, reg); + case VKD3DSPR_OUTCONTROLPOINT: + vsir_validate_io_register(ctx, reg); break;
- case VKD3DSPR_DEPTHOUTLE: - vsir_validate_register_without_indices(ctx, reg); + case VKD3DSPR_PATCHCONST: + vsir_validate_io_register(ctx, reg); break;
- case VKD3DSPR_OUTSTENCILREF: + case VKD3DSPR_TESSCOORD: vsir_validate_register_without_indices(ctx, reg); break;
@@ -8197,6 +9839,24 @@ static void vsir_validate_register(struct validation_context *ctx, default: break; } + + if (reg->type >= ARRAY_SIZE(register_validation_data)) + return; + + validation_data = ®ister_validation_data[reg->type]; + + if (!validation_data->valid) + return; + + if (reg->idx_count != validation_data->idx_count) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, + "Invalid index count %u for a register of type %#x, expected %u.", + reg->idx_count, reg->type, validation_data->idx_count); + + if (reg->dimension != validation_data->dimension) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_INDEX_COUNT, + "Invalid dimension %#x for a register of type %#x, expected %#x.", + reg->dimension, reg->type, validation_data->dimension); }
static void vsir_validate_io_dst_param(struct validation_context *ctx, @@ -8242,15 +9902,37 @@ static void vsir_validate_dst_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Destination has invalid modifiers %#x.", dst->modifiers);
+ if (dst->modifiers & VKD3DSPDM_SATURATE) + { + switch (dst->reg.data_type) + { + case VSIR_DATA_F16: + case VSIR_DATA_F32: + case VSIR_DATA_F64: + break; + + default: + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, + "Invalid data type %#x for destination with saturate modifier.", dst->reg.data_type); + break; + + } + } + switch (dst->shift) { case 0: + break; + case 1: case 2: case 3: case 13: case 14: 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); break;
default: @@ -8332,9 +10014,44 @@ static void vsir_validate_io_src_param(struct validation_context *ctx, "Invalid register type %#x used as source parameter.", src->reg.type); }
+#define F64_BIT (1u << VSIR_DATA_F64) +#define F32_BIT (1u << VSIR_DATA_F32) +#define F16_BIT (1u << VSIR_DATA_F16) + +#define I32_BIT (1u << VSIR_DATA_I32) + +#define U64_BIT (1u << VSIR_DATA_U64) +#define U32_BIT (1u << VSIR_DATA_U32) +#define U16_BIT (1u << VSIR_DATA_U16) + static void vsir_validate_src_param(struct validation_context *ctx, const struct vkd3d_shader_src_param *src) { + static const struct + { + uint32_t data_type_mask; + } + src_modifier_data[VKD3DSPSM_COUNT] = + { + [VKD3DSPSM_NEG] = {F64_BIT | F32_BIT | F16_BIT | I32_BIT | U64_BIT | U32_BIT | U16_BIT}, + [VKD3DSPSM_BIAS] = {F32_BIT}, + [VKD3DSPSM_BIASNEG] = {F32_BIT}, + [VKD3DSPSM_SIGN] = {F32_BIT}, + [VKD3DSPSM_SIGNNEG] = {F32_BIT}, + [VKD3DSPSM_COMP] = {F32_BIT}, + [VKD3DSPSM_X2] = {F32_BIT}, + [VKD3DSPSM_X2NEG] = {F32_BIT}, + [VKD3DSPSM_DZ] = {F32_BIT}, + [VKD3DSPSM_DW] = {F32_BIT}, + [VKD3DSPSM_ABS] = {F64_BIT | F32_BIT | F16_BIT}, + [VKD3DSPSM_ABSNEG] = {F64_BIT | F32_BIT | F16_BIT}, + /* This doesn't make a lot of sense. NOT is used only by D3DBC, and + * apparently only for IF instructions reading from a CONSTBOOL register. + * However, currently the D3DBC parser generates those registers of + * type float, so for the moment let's allow that. */ + [VKD3DSPSM_NOT] = {F32_BIT}, + }; + vsir_validate_register(ctx, &src->reg);
if (src->swizzle & ~0x03030303u) @@ -8349,6 +10066,13 @@ static void vsir_validate_src_param(struct validation_context *ctx, validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS, "Source has invalid modifiers %#x.", src->modifiers);
+ if (src->modifiers != VKD3DSPSM_NONE && src->modifiers < ARRAY_SIZE(src_modifier_data)) + { + 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); + } + switch (src->reg.type) { case VKD3DSPR_SSA: @@ -8400,8 +10124,9 @@ static void vsir_validate_dst_count(struct validation_context *ctx, { if (instruction->dst_count != count) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DEST_COUNT, - "Invalid destination count %u for an instruction of type %#x, expected %u.", - instruction->dst_count, instruction->opcode, count); + "Invalid destination parameter count %zu for instruction "%s" (%#x); expected %u.", + instruction->dst_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"), + instruction->opcode, count); }
static void vsir_validate_src_count(struct validation_context *ctx, @@ -8409,8 +10134,9 @@ static void vsir_validate_src_count(struct validation_context *ctx, { if (instruction->src_count != count) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for an instruction of type %#x, expected %u.", - instruction->src_count, instruction->opcode, count); + "Invalid source parameter count %zu for instruction "%s" (%#x); expected %u.", + instruction->src_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"), + instruction->opcode, count); }
static bool vsir_validate_src_min_count(struct validation_context *ctx, @@ -8419,8 +10145,9 @@ static bool vsir_validate_src_min_count(struct validation_context *ctx, if (instruction->src_count < count) { validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for an instruction of type %#x, expected at least %u.", - instruction->src_count, instruction->opcode, count); + "Invalid source parameter count %zu for instruction "%s" (%#x); expected at least %u.", + instruction->src_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"), + instruction->opcode, count); return false; }
@@ -8433,8 +10160,9 @@ static bool vsir_validate_src_max_count(struct validation_context *ctx, if (instruction->src_count > count) { validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for an instruction of type %#x, expected at most %u.", - instruction->src_count, instruction->opcode, count); + "Invalid source parameter count %zu for instruction "%s" (%#x); expected at most %u.", + instruction->src_count, vsir_opcode_get_name(instruction->opcode, "<unknown>"), + instruction->opcode, count); return false; }
@@ -8874,6 +10602,7 @@ static void vsir_validate_descriptors(struct validation_context *ctx) for (i = 0; i < descriptors->descriptor_count; ++i) { const struct vkd3d_shader_descriptor_info1 *descriptor = &descriptors->descriptors[i]; + uint32_t flags_mask = 0, uav_flags_mask = 0;
if (descriptor->type >= VKD3D_SHADER_DESCRIPTOR_TYPE_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE, @@ -8888,10 +10617,10 @@ static void vsir_validate_descriptors(struct validation_context *ctx) "Descriptor %u has invalid resource type %#x for descriptor type %#x.", i, descriptor->resource_type, descriptor->type);
- if (descriptor->resource_data_type >= VKD3D_DATA_COUNT) + if (descriptor->resource_data_type >= VSIR_DATA_TYPE_COUNT) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Descriptor %u has invalid resource data type %#x.", i, descriptor->resource_data_type); - else if ((descriptor->resource_data_type == VKD3D_DATA_UNUSED) + else if ((descriptor->resource_data_type == VSIR_DATA_UNUSED) != (descriptor->type == VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DATA_TYPE, "Descriptor %u has invalid resource data type %#x for descriptor type %#x.", @@ -8902,6 +10631,43 @@ static void vsir_validate_descriptors(struct validation_context *ctx) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT, "Descriptor %u has invalid descriptor count %u starting at index %u.", i, descriptor->count, descriptor->register_index); + + switch (descriptor->type) + { + case VKD3D_SHADER_DESCRIPTOR_TYPE_SRV: + flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; + break; + + case VKD3D_SHADER_DESCRIPTOR_TYPE_UAV: + flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_COUNTER + | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_READ + | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_UAV_ATOMICS + | VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_RAW_BUFFER; + uav_flags_mask = VKD3DSUF_GLOBALLY_COHERENT + | VKD3DSUF_RASTERISER_ORDERED_VIEW + | VKD3DSUF_ORDER_PRESERVING_COUNTER; + break; + + case VKD3D_SHADER_DESCRIPTOR_TYPE_CBV: + break; + + case VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER: + flags_mask = VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; + break; + + case VKD3D_SHADER_DESCRIPTOR_TYPE_FORCE_32BIT: + break; + } + + if (descriptor->flags & ~flags_mask) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS, + "Descriptor %u of type %#x has invalid flags %#x.", + i, descriptor->type, descriptor->flags); + + if (descriptor->uav_flags & ~uav_flags_mask) + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS, + "Descriptor %u of type %#x has invalid UAV flags %#x.", + i, descriptor->type, descriptor->uav_flags); } }
@@ -8922,7 +10688,9 @@ static void vsir_validate_cf_type(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction, enum vsir_control_flow_type expected_type) { if (ctx->program->cf_type != expected_type) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "Invalid instruction %#x in %s shader.", + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, + "Invalid instruction "%s" (%#x) in %s shader.", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode, name_from_cf_type(ctx->program->cf_type)); }
@@ -8940,17 +10708,230 @@ static void vsir_validate_hull_shader_phase(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { if (ctx->program->shader_version.type != VKD3D_SHADER_TYPE_HULL) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, - "Phase instruction %#x is only valid in a hull shader.", - instruction->opcode); + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, + "Phase instruction "%s" (%#x) is only valid in a hull shader.", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); if (ctx->depth != 0) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, - "Phase instruction %#x must appear to top level.", - instruction->opcode); + "Phase instruction "%s" (%#x) must appear at the top level.", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); ctx->phase = instruction->opcode; ctx->dcl_temps_found = false; }
+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; + unsigned int i; + + if (instruction->dst_count < 1) + return; + + dst_data_type = instruction->dst[0].reg.data_type; + + if (dst_data_type >= VSIR_DATA_TYPE_COUNT) + return; + + 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, "<unknown>"), instruction->opcode); + + for (i = 0; i < instruction->src_count; ++i) + { + if (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 " + "for elementwise operation "%s" (%#x).", + instruction->src[i].reg.data_type, i, dst_data_type, + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); + } +} + +static void vsir_validate_double_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + +static void vsir_validate_float_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F32] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + +static void vsir_validate_integer_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_I32] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + +static void vsir_validate_logic_elementwise_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_BOOL] = true, + [VSIR_DATA_I32] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + + vsir_validate_elementwise_operation(ctx, instruction, types); +} + +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; + unsigned int i; + + if (instruction->dst_count < 1) + return; + + dst_data_type = instruction->dst[0].reg.data_type; + + 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, "<unknown>"), instruction->opcode); + + if (instruction->src_count == 0) + return; + + src_data_type = instruction->src[0].reg.data_type; + + if (src_data_type >= VSIR_DATA_TYPE_COUNT) + return; + + 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, "<unknown>"), instruction->opcode); + + for (i = 1; i < instruction->src_count; ++i) + { + if (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, + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); + } +} + +static void vsir_validate_double_comparison_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F64] = true, + }; + + vsir_validate_comparison_operation(ctx, instruction, types); +} + +static void vsir_validate_float_comparison_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F32] = true, + [VSIR_DATA_F64] = true, + }; + + vsir_validate_comparison_operation(ctx, instruction, types); +} + +static void vsir_validate_integer_comparison_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_I32] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + + vsir_validate_comparison_operation(ctx, instruction, types); +} + +static void vsir_validate_cast_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction, + const bool src_types[VSIR_DATA_TYPE_COUNT], const bool dst_types[VSIR_DATA_TYPE_COUNT]) +{ + enum vsir_data_type dst_data_type, src_data_type; + + if (instruction->dst_count < 1 || instruction->src_count < 1) + return; + + dst_data_type = instruction->dst[0].reg.data_type; + src_data_type = instruction->src[0].reg.data_type; + + if (src_data_type >= VSIR_DATA_TYPE_COUNT || dst_data_type >= VSIR_DATA_TYPE_COUNT) + return; + + 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, "<unknown>"), 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, "<unknown>"), instruction->opcode); +} + +static void vsir_validate_shift_operation(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + enum vsir_data_type data_type; + + static const bool types[] = + { + [VSIR_DATA_I32] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + + data_type = instruction->dst[0].reg.data_type; + if ((size_t)data_type >= ARRAY_SIZE(types) || !types[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, "<unknown>"), instruction->opcode); + + if (instruction->src[0].reg.data_type != 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 " + "for shift operation "%s" (%#x).", + instruction->src[0].reg.data_type, data_type, + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); + + data_type = instruction->src[1].reg.data_type; + if ((size_t)data_type >= ARRAY_SIZE(types) || !types[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, "<unknown>"), instruction->opcode); +} + static void vsir_validate_branch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { size_t i; @@ -9026,7 +11007,7 @@ static void vsir_validate_dcl_index_range(struct validation_context *ctx,
if (ctx->program->normalisation_level >= VSIR_NORMALISED_SM6) { - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, "DCL_INDEX_RANGE is not allowed with fully normalised input/output."); return; } @@ -9416,18 +11397,18 @@ static void vsir_validate_dcl_vertices_out(struct validation_context *ctx, static void vsir_validate_else(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF) + if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_IF) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ELSE instruction doesn't terminate IF block."); else - ctx->blocks[ctx->depth - 1] = VKD3DSIH_ELSE; + ctx->blocks[ctx->depth - 1] = VSIR_OP_ELSE; }
static void vsir_validate_endif(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VKD3DSIH_IF - && ctx->blocks[ctx->depth - 1] != VKD3DSIH_ELSE)) + if (ctx->depth == 0 || (ctx->blocks[ctx->depth - 1] != VSIR_OP_IF + && ctx->blocks[ctx->depth - 1] != VSIR_OP_ELSE)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDIF instruction doesn't terminate IF/ELSE block."); else @@ -9437,7 +11418,7 @@ static void vsir_validate_endif(struct validation_context *ctx, const struct vkd static void vsir_validate_endloop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_LOOP) + if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_LOOP) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDLOOP instruction doesn't terminate LOOP block."); else @@ -9447,7 +11428,7 @@ static void vsir_validate_endloop(struct validation_context *ctx, const struct v static void vsir_validate_endrep(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_REP) + if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_REP) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDREP instruction doesn't terminate REP block."); else @@ -9457,23 +11438,88 @@ static void vsir_validate_endrep(struct validation_context *ctx, const struct vk static void vsir_validate_endswitch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VKD3DSIH_SWITCH) + if (ctx->depth == 0 || ctx->blocks[ctx->depth - 1] != VSIR_OP_SWITCH) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, "ENDSWITCH instruction doesn't terminate SWITCH block."); else --ctx->depth; }
+static void vsir_validate_ftoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) +{ + static const bool src_types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F16] = true, + [VSIR_DATA_F32] = true, + [VSIR_DATA_F64] = true, + }; + static const bool dst_types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_I32] = true, + [VSIR_DATA_U32] = true, + }; + + vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); +} + +static void vsir_validate_ftou(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) +{ + static const bool src_types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F16] = true, + [VSIR_DATA_F32] = true, + [VSIR_DATA_F64] = true, + }; + static const bool dst_types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_U32] = true, + }; + + vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); +} + static void vsir_validate_if(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - vsir_validator_push_block(ctx, VKD3DSIH_IF); + vsir_validator_push_block(ctx, VSIR_OP_IF); }
static void vsir_validate_ifc(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - vsir_validator_push_block(ctx, VKD3DSIH_IF); + vsir_validator_push_block(ctx, VSIR_OP_IF); +} + +static void vsir_validate_itof(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) +{ + static const bool src_types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_BOOL] = true, + [VSIR_DATA_I32] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + static const bool dst_types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_F16] = true, + [VSIR_DATA_F32] = true, + [VSIR_DATA_F64] = true, + }; + + vsir_validate_cast_operation(ctx, instruction, src_types, dst_types); +} + +static void vsir_validate_itoi(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) +{ + static const bool types[VSIR_DATA_TYPE_COUNT] = + { + [VSIR_DATA_BOOL] = true, + [VSIR_DATA_I32] = true, + [VSIR_DATA_U32] = true, + [VSIR_DATA_U64] = true, + }; + + vsir_validate_cast_operation(ctx, instruction, types, types); }
static void vsir_validate_label(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) @@ -9494,7 +11540,7 @@ static void vsir_validate_loop(struct validation_context *ctx, const struct vkd3 { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); vsir_validate_src_count(ctx, instruction, ctx->program->shader_version.major <= 3 ? 2 : 0); - vsir_validator_push_block(ctx, VKD3DSIH_LOOP); + vsir_validator_push_block(ctx, VSIR_OP_LOOP); }
static void vsir_validate_nop(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) @@ -9511,7 +11557,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d
if (instruction->src_count % 2 != 0) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for a PHI instruction, it must be an even number.", + "Invalid source count %zu for a PHI instruction, it must be an even number.", instruction->src_count); incoming_count = instruction->src_count / 2;
@@ -9564,7 +11610,7 @@ static void vsir_validate_phi(struct validation_context *ctx, const struct vkd3d static void vsir_validate_rep(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - vsir_validator_push_block(ctx, VKD3DSIH_REP); + vsir_validator_push_block(ctx, VSIR_OP_REP); }
static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) @@ -9572,10 +11618,58 @@ static void vsir_validate_ret(struct validation_context *ctx, const struct vkd3d ctx->inside_block = false; }
+static void vsir_validate_throw_invalid_dst_type_error_with_flags(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + 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, + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode, instruction->flags); +} + +static void vsir_validate_sample_info(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; + + switch (dst_data_type) + { + case VSIR_DATA_F32: + case VSIR_DATA_U32: + if (!!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT) != (dst_data_type == VSIR_DATA_U32)) + vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); + break; + + default: + vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); + break; + } +} + +static void vsir_validate_resinfo(struct validation_context *ctx, + const struct vkd3d_shader_instruction *instruction) +{ + enum vsir_data_type dst_data_type = instruction->dst[0].reg.data_type; + + switch (dst_data_type) + { + case VSIR_DATA_F32: + case VSIR_DATA_U32: + if (!!(instruction->flags & VKD3DSI_RESINFO_UINT) != (dst_data_type == VSIR_DATA_U32)) + vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); + break; + + default: + vsir_validate_throw_invalid_dst_type_error_with_flags(ctx, instruction); + break; + } +} + static void vsir_validate_switch(struct validation_context *ctx, const struct vkd3d_shader_instruction *instruction) { vsir_validate_cf_type(ctx, instruction, VSIR_CF_STRUCTURED); - vsir_validator_push_block(ctx, VKD3DSIH_SWITCH); + vsir_validator_push_block(ctx, VSIR_OP_SWITCH); }
static void vsir_validate_switch_monolithic(struct validation_context *ctx, @@ -9593,7 +11687,7 @@ static void vsir_validate_switch_monolithic(struct validation_context *ctx,
if (instruction->src_count % 2 != 1) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_SOURCE_COUNT, - "Invalid source count %u for a monolithic SWITCH instruction, it must be an odd number.", + "Invalid source count %zu for a monolithic SWITCH instruction, it must be an odd number.", instruction->src_count);
if (!vsir_register_is_label(&instruction->src[1].reg)) @@ -9636,45 +11730,116 @@ struct vsir_validator_instruction_desc
static const struct vsir_validator_instruction_desc vsir_validator_instructions[] = { - [VKD3DSIH_BRANCH] = {0, ~0u, vsir_validate_branch}, - [VKD3DSIH_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, - [VKD3DSIH_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase}, - [VKD3DSIH_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, - [VKD3DSIH_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, - [VKD3DSIH_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances}, - [VKD3DSIH_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor}, - [VKD3DSIH_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range}, - [VKD3DSIH_DCL_INPUT] = {0, 0, vsir_validate_dcl_input}, - [VKD3DSIH_DCL_INPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_input_primitive}, - [VKD3DSIH_DCL_INPUT_PS] = {0, 0, vsir_validate_dcl_input_ps}, - [VKD3DSIH_DCL_INPUT_PS_SGV] = {0, 0, vsir_validate_dcl_input_ps_sgv}, - [VKD3DSIH_DCL_INPUT_PS_SIV] = {0, 0, vsir_validate_dcl_input_ps_siv}, - [VKD3DSIH_DCL_INPUT_SGV] = {0, 0, vsir_validate_dcl_input_sgv}, - [VKD3DSIH_DCL_INPUT_SIV] = {0, 0, vsir_validate_dcl_input_siv}, - [VKD3DSIH_DCL_OUTPUT] = {0, 0, vsir_validate_dcl_output}, - [VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT] = {0, 0, vsir_validate_dcl_output_control_point_count}, - [VKD3DSIH_DCL_OUTPUT_SIV] = {0, 0, vsir_validate_dcl_output_siv}, - [VKD3DSIH_DCL_OUTPUT_TOPOLOGY] = {0, 0, vsir_validate_dcl_output_topology}, - [VKD3DSIH_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps}, - [VKD3DSIH_DCL_TESSELLATOR_DOMAIN] = {0, 0, vsir_validate_dcl_tessellator_domain}, - [VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive}, - [VKD3DSIH_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning}, - [VKD3DSIH_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out}, - [VKD3DSIH_ELSE] = {0, 0, vsir_validate_else}, - [VKD3DSIH_ENDIF] = {0, 0, vsir_validate_endif}, - [VKD3DSIH_ENDLOOP] = {0, 0, vsir_validate_endloop}, - [VKD3DSIH_ENDREP] = {0, 0, vsir_validate_endrep}, - [VKD3DSIH_ENDSWITCH] = {0, 0, vsir_validate_endswitch}, - [VKD3DSIH_IF] = {0, 1, vsir_validate_if}, - [VKD3DSIH_IFC] = {0, 2, vsir_validate_ifc}, - [VKD3DSIH_LABEL] = {0, 1, vsir_validate_label}, - [VKD3DSIH_LOOP] = {0, ~0u, vsir_validate_loop}, - [VKD3DSIH_NOP] = {0, 0, vsir_validate_nop}, - [VKD3DSIH_PHI] = {1, ~0u, vsir_validate_phi}, - [VKD3DSIH_REP] = {0, 1, vsir_validate_rep}, - [VKD3DSIH_RET] = {0, 0, vsir_validate_ret}, - [VKD3DSIH_SWITCH] = {0, 1, vsir_validate_switch}, - [VKD3DSIH_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, + [VSIR_OP_ABS] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ACOS] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ADD] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_AND] = {1, 2, vsir_validate_logic_elementwise_operation}, + [VSIR_OP_ASIN] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ATAN] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_BRANCH] = {0, ~0u, vsir_validate_branch}, + [VSIR_OP_DADD] = {1, 2, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DCL_GS_INSTANCES] = {0, 0, vsir_validate_dcl_gs_instances}, + [VSIR_OP_DCL_HS_MAX_TESSFACTOR] = {0, 0, vsir_validate_dcl_hs_max_tessfactor}, + [VSIR_OP_DCL_INDEX_RANGE] = {0, 0, vsir_validate_dcl_index_range}, + [VSIR_OP_DCL_INPUT] = {0, 0, vsir_validate_dcl_input}, + [VSIR_OP_DCL_INPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_input_primitive}, + [VSIR_OP_DCL_INPUT_PS] = {0, 0, vsir_validate_dcl_input_ps}, + [VSIR_OP_DCL_INPUT_PS_SGV] = {0, 0, vsir_validate_dcl_input_ps_sgv}, + [VSIR_OP_DCL_INPUT_PS_SIV] = {0, 0, vsir_validate_dcl_input_ps_siv}, + [VSIR_OP_DCL_INPUT_SGV] = {0, 0, vsir_validate_dcl_input_sgv}, + [VSIR_OP_DCL_INPUT_SIV] = {0, 0, vsir_validate_dcl_input_siv}, + [VSIR_OP_DCL_OUTPUT] = {0, 0, vsir_validate_dcl_output}, + [VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT] = {0, 0, vsir_validate_dcl_output_control_point_count}, + [VSIR_OP_DCL_OUTPUT_SIV] = {0, 0, vsir_validate_dcl_output_siv}, + [VSIR_OP_DCL_OUTPUT_TOPOLOGY] = {0, 0, vsir_validate_dcl_output_topology}, + [VSIR_OP_DCL_TEMPS] = {0, 0, vsir_validate_dcl_temps}, + [VSIR_OP_DCL_TESSELLATOR_DOMAIN] = {0, 0, vsir_validate_dcl_tessellator_domain}, + [VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE] = {0, 0, vsir_validate_dcl_tessellator_output_primitive}, + [VSIR_OP_DCL_TESSELLATOR_PARTITIONING] = {0, 0, vsir_validate_dcl_tessellator_partitioning}, + [VSIR_OP_DCL_VERTICES_OUT] = {0, 0, vsir_validate_dcl_vertices_out}, + [VSIR_OP_DDIV] = {1, 2, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DEQO] = {1, 2, vsir_validate_double_comparison_operation}, + [VSIR_OP_DFMA] = {1, 3, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DGEO] = {1, 2, vsir_validate_double_comparison_operation}, + [VSIR_OP_DIV] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_DLT] = {1, 2, vsir_validate_double_comparison_operation}, + [VSIR_OP_DMAX] = {1, 2, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DMIN] = {1, 2, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DMOV] = {1, 1, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DMUL] = {1, 2, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DNE] = {1, 2, vsir_validate_double_comparison_operation}, + [VSIR_OP_DRCP] = {1, 1, vsir_validate_double_elementwise_operation}, + [VSIR_OP_DSX] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_DSX_COARSE] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_DSX_FINE] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_DSY] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_DSY_COARSE] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_DSY_FINE] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ELSE] = {0, 0, vsir_validate_else}, + [VSIR_OP_ENDIF] = {0, 0, vsir_validate_endif}, + [VSIR_OP_ENDLOOP] = {0, 0, vsir_validate_endloop}, + [VSIR_OP_ENDREP] = {0, 0, vsir_validate_endrep}, + [VSIR_OP_ENDSWITCH] = {0, 0, vsir_validate_endswitch}, + [VSIR_OP_EQO] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_EQU] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_EXP] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_FRC] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_FREM] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_FTOI] = {1, 1, vsir_validate_ftoi}, + [VSIR_OP_FTOU] = {1, 1, vsir_validate_ftou}, + [VSIR_OP_GEO] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_GEU] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_HCOS] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_HSIN] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_HS_CONTROL_POINT_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, + [VSIR_OP_HS_DECLS] = {0, 0, vsir_validate_hull_shader_phase}, + [VSIR_OP_HS_FORK_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, + [VSIR_OP_HS_JOIN_PHASE] = {0, 0, vsir_validate_hull_shader_phase}, + [VSIR_OP_HTAN] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_IADD] = {1, 2, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_IEQ] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_IF] = {0, 1, vsir_validate_if}, + [VSIR_OP_IFC] = {0, 2, vsir_validate_ifc}, + [VSIR_OP_IGE] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_ILT] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_IMAD] = {1, 3, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_IMAX] = {1, 2, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_IMIN] = {1, 2, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_INE] = {1, 2, vsir_validate_integer_comparison_operation}, + [VSIR_OP_INEG] = {1, 1, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_IREM] = {1, 2, vsir_validate_integer_elementwise_operation}, + [VSIR_OP_ISFINITE] = {1, 1, vsir_validate_float_comparison_operation}, + [VSIR_OP_ISHL] = {1, 2, vsir_validate_shift_operation}, + [VSIR_OP_ISHR] = {1, 2, vsir_validate_shift_operation}, + [VSIR_OP_ISINF] = {1, 1, vsir_validate_float_comparison_operation}, + [VSIR_OP_ISNAN] = {1, 1, vsir_validate_float_comparison_operation}, + [VSIR_OP_ITOF] = {1, 1, vsir_validate_itof}, + [VSIR_OP_ITOI] = {1, 1, vsir_validate_itoi}, + [VSIR_OP_LABEL] = {0, 1, vsir_validate_label}, + [VSIR_OP_LOG] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_LOOP] = {0, ~0u, vsir_validate_loop}, + [VSIR_OP_LTO] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_LTU] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_MAD] = {1, 3, vsir_validate_float_elementwise_operation}, + [VSIR_OP_MAX] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_MIN] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_MUL] = {1, 2, vsir_validate_float_elementwise_operation}, + [VSIR_OP_NEO] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_NEU] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_NOP] = {0, 0, vsir_validate_nop}, + [VSIR_OP_NOT] = {1, 1, vsir_validate_logic_elementwise_operation}, + [VSIR_OP_OR] = {1, 2, vsir_validate_logic_elementwise_operation}, + [VSIR_OP_ORD] = {1, 2, vsir_validate_float_comparison_operation}, + [VSIR_OP_PHI] = {1, ~0u, vsir_validate_phi}, + [VSIR_OP_RCP] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_REP] = {0, 1, vsir_validate_rep}, + [VSIR_OP_RESINFO] = {1, 2, vsir_validate_resinfo}, + [VSIR_OP_RET] = {0, 0, vsir_validate_ret}, + [VSIR_OP_ROUND_NE] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_ROUND_NI] = {1, 1, vsir_validate_float_elementwise_operation}, + [VSIR_OP_SAMPLE_INFO] = {1, 1, vsir_validate_sample_info}, + [VSIR_OP_SWITCH] = {0, 1, vsir_validate_switch}, + [VSIR_OP_SWITCH_MONOLITHIC] = {0, ~0u, vsir_validate_switch_monolithic}, };
static void vsir_validate_instruction(struct validation_context *ctx) @@ -9691,28 +11856,28 @@ static void vsir_validate_instruction(struct validation_context *ctx) for (i = 0; i < instruction->src_count; ++i) vsir_validate_src_param(ctx, &instruction->src[i]);
- if (instruction->opcode >= VKD3DSIH_INVALID) + if (instruction->opcode >= VSIR_OP_INVALID) { - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, "Invalid instruction handler %#x.", - instruction->opcode); + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, + "Invalid opcode %#x.", instruction->opcode); }
- if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VKD3DSIH_INVALID) + if (version->type == VKD3D_SHADER_TYPE_HULL && ctx->phase == VSIR_OP_INVALID) { switch (instruction->opcode) { - case VKD3DSIH_NOP: - case VKD3DSIH_HS_DECLS: - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_NOP: + case VSIR_OP_HS_DECLS: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: break;
default: if (!vsir_instruction_is_dcl(instruction)) - validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER, - "Instruction %#x appear before any phase instruction in a hull shader.", - instruction->opcode); + validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE, + "Instruction "%s" (%#x) appears before any phase instruction in a hull shader.", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); break; } } @@ -9721,19 +11886,19 @@ static void vsir_validate_instruction(struct validation_context *ctx) { switch (instruction->opcode) { - case VKD3DSIH_NOP: - case VKD3DSIH_LABEL: - case VKD3DSIH_HS_DECLS: - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_NOP: + case VSIR_OP_LABEL: + case VSIR_OP_HS_DECLS: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: break;
default: if (!vsir_instruction_is_dcl(instruction)) validator_error(ctx, VKD3D_SHADER_ERROR_VSIR_INVALID_CONTROL_FLOW, - "Invalid instruction %#x outside any block.", - instruction->opcode); + "Invalid instruction "%s" (%#x) outside any block.", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); break; } } @@ -9764,7 +11929,7 @@ enum vkd3d_result vsir_program_validate(struct vsir_program *program, uint64_t c .program = program, .null_location = {.source_name = source_name}, .status = VKD3D_OK, - .phase = VKD3DSIH_INVALID, + .phase = VSIR_OP_INVALID, .invalid_instruction_idx = true, .outer_tess_idxs[0] = ~0u, .outer_tess_idxs[1] = ~0u, @@ -9970,6 +12135,28 @@ enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uin return ctx.result; }
+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, + }; + + 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); + + if (TRACE_ON()) + vsir_program_trace(program); + + return ctx.result; +} + 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) { @@ -9989,8 +12176,11 @@ enum vkd3d_result vsir_program_transform(struct vsir_program *program, uint64_t vsir_transform(&ctx, vsir_program_materialise_phi_ssas_to_temps); vsir_transform(&ctx, vsir_program_lower_switch_to_selection_ladder); vsir_transform(&ctx, vsir_program_structurize); - vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); - vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); + if (compile_info->target_type != VKD3D_SHADER_TARGET_MSL) + { + vsir_transform(&ctx, vsir_program_flatten_control_flow_constructs); + vsir_transform(&ctx, vsir_program_materialize_undominated_ssas_to_temps); + } } else { diff --git a/libs/vkd3d/libs/vkd3d-shader/msl.c b/libs/vkd3d/libs/vkd3d-shader/msl.c index 4f37468af86..c6e048adb20 100644 --- a/libs/vkd3d/libs/vkd3d-shader/msl.c +++ b/libs/vkd3d/libs/vkd3d-shader/msl.c @@ -18,6 +18,8 @@
#include "vkd3d_shader_private.h"
+#define MAX_IO_REG_COUNT 32 + enum msl_data_type { MSL_DATA_FLOAT, @@ -48,19 +50,29 @@ struct msl_generator const char *prefix; bool failed;
- bool write_depth; + bool read_vertex_id;
const struct vkd3d_shader_interface_info *interface_info; };
struct msl_resource_type_info { - size_t read_coord_size; + /* The number of coordinates needed to address/sample the resource type. */ + size_t coord_size; + /* Whether the resource type is an array type. */ bool array; - bool lod; + /* Whether the resource type has a shadow/comparison variant. */ + bool comparison; + /* Whether the resource type supports texel sample offsets. */ + bool offset; + /* The type suffix for the resource type. I.e., the "2d_ms" part of + * "texture2d_ms_array" or "depth2d_ms_array". */ const char *type_suffix; };
+static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, + const struct vkd3d_shader_src_param *rel_addr, unsigned int offset); + static void VKD3D_PRINTF_FUNC(3, 4) msl_compiler_error(struct msl_generator *gen, enum vkd3d_shader_error error, const char *fmt, ...) { @@ -76,17 +88,17 @@ static const struct msl_resource_type_info *msl_get_resource_type_info(enum vkd3 { static const struct msl_resource_type_info info[] = { - [VKD3D_SHADER_RESOURCE_NONE] = {0, false, false, "none"}, - [VKD3D_SHADER_RESOURCE_BUFFER] = {1, false, false, "_buffer"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, false, false, "1d"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, false, true, "2d"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, false, false, "2d_ms"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, false, true, "3d"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {2, false, true, "cube"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, true, false, "1d_array"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, true, true, "2d_array"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, true, false, "2d_ms_array"}, - [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {2, true, true, "cube_array"}, + [VKD3D_SHADER_RESOURCE_NONE] = {0, 0, 0, 0, "none"}, + [VKD3D_SHADER_RESOURCE_BUFFER] = {1, 0, 0, 0, "_buffer"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_1D] = {1, 0, 0, 0, "1d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2D] = {2, 0, 1, 1, "2d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DMS] = {2, 0, 1, 0, "2d_ms"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_3D] = {3, 0, 0, 1, "3d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBE] = {3, 0, 1, 0, "cube"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY] = {1, 1, 0, 0, "1d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DARRAY] = {2, 1, 1, 1, "2d"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY] = {2, 1, 1, 0, "2d_ms"}, + [VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY] = {3, 1, 1, 0, "cube"}, };
if (!t || t >= ARRAY_SIZE(info)) @@ -123,19 +135,19 @@ static void msl_print_indent(struct vkd3d_string_buffer *buffer, unsigned int in }
static void msl_print_resource_datatype(struct msl_generator *gen, - struct vkd3d_string_buffer *buffer, enum vkd3d_data_type data_type) + struct vkd3d_string_buffer *buffer, enum vsir_data_type data_type) { switch (data_type) { - case VKD3D_DATA_FLOAT: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: + case VSIR_DATA_F32: + case VSIR_DATA_SNORM: + case VSIR_DATA_UNORM: vkd3d_string_buffer_printf(buffer, "float"); break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: vkd3d_string_buffer_printf(buffer, "int"); break; - case VKD3D_DATA_UINT: + case VSIR_DATA_U32: vkd3d_string_buffer_printf(buffer, "uint"); break; default: @@ -147,18 +159,18 @@ static void msl_print_resource_datatype(struct msl_generator *gen, }
static void msl_print_register_datatype(struct vkd3d_string_buffer *buffer, - struct msl_generator *gen, enum vkd3d_data_type data_type) + struct msl_generator *gen, enum vsir_data_type data_type) { vkd3d_string_buffer_printf(buffer, "."); switch (data_type) { - case VKD3D_DATA_FLOAT: + case VSIR_DATA_F32: vkd3d_string_buffer_printf(buffer, "f"); break; - case VKD3D_DATA_INT: + case VSIR_DATA_I32: vkd3d_string_buffer_printf(buffer, "i"); break; - case VKD3D_DATA_UINT: + case VSIR_DATA_U32: vkd3d_string_buffer_printf(buffer, "u"); break; default: @@ -226,6 +238,35 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_cbv_binding(const s return NULL; }
+static const struct vkd3d_shader_descriptor_binding *msl_get_sampler_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx) +{ + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + const struct vkd3d_shader_resource_binding *binding; + unsigned int i; + + if (!interface_info) + return NULL; + + for (i = 0; i < interface_info->binding_count; ++i) + { + binding = &interface_info->bindings[i]; + + if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER) + continue; + if (binding->register_space != register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + + return &binding->binding; + } + + return NULL; +} + static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const struct msl_generator *gen, unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) { @@ -260,20 +301,71 @@ static const struct vkd3d_shader_descriptor_binding *msl_get_srv_binding(const s return NULL; }
+static const struct vkd3d_shader_descriptor_binding *msl_get_uav_binding(const struct msl_generator *gen, + unsigned int register_space, unsigned int register_idx, enum vkd3d_shader_resource_type resource_type) +{ + const struct vkd3d_shader_interface_info *interface_info = gen->interface_info; + const struct vkd3d_shader_resource_binding *binding; + enum vkd3d_shader_binding_flag resource_type_flag; + unsigned int i; + + if (!interface_info) + return NULL; + + resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER + ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; + + for (i = 0; i < interface_info->binding_count; ++i) + { + binding = &interface_info->bindings[i]; + + if (binding->type != VKD3D_SHADER_DESCRIPTOR_TYPE_UAV) + continue; + if (binding->register_space != register_space) + continue; + if (binding->register_index != register_idx) + continue; + if (!msl_check_shader_visibility(gen, binding->shader_visibility)) + continue; + if (!(binding->flags & resource_type_flag)) + continue; + + return &binding->binding; + } + + return NULL; +} + static void msl_print_cbv_name(struct vkd3d_string_buffer *buffer, unsigned int binding) { vkd3d_string_buffer_printf(buffer, "descriptors[%u].buf<vkd3d_vec4>()", binding); }
+static void msl_print_sampler_name(struct vkd3d_string_buffer *buffer, unsigned int binding) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<sampler>()", binding); +} + static void msl_print_srv_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, - const struct msl_resource_type_info *resource_type_info, enum vkd3d_data_type resource_data_type) + const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type, bool compare) { - vkd3d_string_buffer_printf(buffer, "descriptors[%u].tex<texture%s<", - binding, resource_type_info->type_suffix); + vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<%s%s%s<", + binding, compare ? "depth" : "texture", resource_type_info->type_suffix, + resource_type_info->array ? "_array" : ""); msl_print_resource_datatype(gen, buffer, resource_data_type); vkd3d_string_buffer_printf(buffer, ">>()"); }
+static void msl_print_uav_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, unsigned int binding, + const struct msl_resource_type_info *resource_type_info, enum vsir_data_type resource_data_type) +{ + vkd3d_string_buffer_printf(buffer, "descriptors[%u].as<texture%s%s<", + binding, resource_type_info->type_suffix, + resource_type_info->array ? "_array" : ""); + msl_print_resource_datatype(gen, buffer, resource_data_type); + vkd3d_string_buffer_printf(buffer, ", access::read_write>>()"); +} + static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, const struct vkd3d_shader_register *reg) { @@ -359,25 +451,40 @@ static enum msl_data_type msl_print_register_name(struct vkd3d_string_buffer *bu vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); return MSL_DATA_UNION; } - if (reg->idx[0].rel_addr || reg->idx[1].rel_addr || reg->idx[2].rel_addr) + if (reg->idx[0].rel_addr || reg->idx[1].rel_addr) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled constant buffer register indirect addressing."); vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); return MSL_DATA_UNION; } + /* FIXME: This should use vkd3d_shader_find_descriptor() to + * find the resource index/space from the resource ID. */ if (!(binding = msl_get_cbv_binding(gen, 0, reg->idx[1].offset))) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Cannot finding binding for CBV register %u.", reg->idx[0].offset); + "No descriptor binding specified for CBV %u.", reg->idx[0].offset); vkd3d_string_buffer_printf(buffer, "<unhandled register %#x>", reg->type); return MSL_DATA_UNION; } msl_print_cbv_name(buffer, binding->binding); - vkd3d_string_buffer_printf(buffer, "[%u]", reg->idx[2].offset); + msl_print_subscript(buffer, gen, reg->idx[2].rel_addr, reg->idx[2].offset); return MSL_DATA_UNION; }
+ case VKD3DSPR_IDXTEMP: + vkd3d_string_buffer_printf(buffer, "x%u", reg->idx[0].offset); + msl_print_subscript(buffer, gen, reg->idx[1].rel_addr, reg->idx[1].offset); + return MSL_DATA_UNION; + + case VKD3DSPR_SAMPLEMASK: + if (gen->program->shader_version.type != VKD3D_SHADER_TYPE_PIXEL) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled sample coverage mask in shader type #%x.", + gen->program->shader_version.type); + vkd3d_string_buffer_printf(buffer, "o_mask"); + return MSL_DATA_UNION; + default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled register type %#x.", reg->type); @@ -418,21 +525,21 @@ static void msl_src_cleanup(struct msl_src *src, struct vkd3d_string_buffer_cach }
static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_generator *gen, const char *src, - enum vkd3d_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) + enum vsir_data_type dst_data_type, enum msl_data_type src_data_type, enum vsir_dimension dimension) { bool write_cast = false;
- if (dst_data_type == VKD3D_DATA_UNORM || dst_data_type == VKD3D_DATA_SNORM) - dst_data_type = VKD3D_DATA_FLOAT; + if (dst_data_type == VSIR_DATA_UNORM || dst_data_type == VSIR_DATA_SNORM) + dst_data_type = VSIR_DATA_F32;
switch (src_data_type) { case MSL_DATA_FLOAT: - write_cast = dst_data_type != VKD3D_DATA_FLOAT; + write_cast = dst_data_type != VSIR_DATA_F32; break;
case MSL_DATA_UINT: - write_cast = dst_data_type != VKD3D_DATA_UINT; + write_cast = dst_data_type != VSIR_DATA_U32; break;
case MSL_DATA_UNION: @@ -456,7 +563,7 @@ static void msl_print_bitcast(struct vkd3d_string_buffer *dst, struct msl_genera }
static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, - const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vkd3d_data_type data_type) + const struct vkd3d_shader_src_param *vsir_src, uint32_t mask, enum vsir_data_type data_type) { const struct vkd3d_shader_register *reg = &vsir_src->reg; struct vkd3d_string_buffer *register_name, *str; @@ -488,6 +595,9 @@ static void msl_print_src_with_type(struct vkd3d_string_buffer *buffer, struct m case VKD3DSPSM_ABS: vkd3d_string_buffer_printf(buffer, "abs(%s)", str->buffer); break; + case VKD3DSPSM_ABSNEG: + vkd3d_string_buffer_printf(buffer, "-abs(%s)", str->buffer); + break; default: vkd3d_string_buffer_printf(buffer, "<unhandled modifier %#x>(%s)", vsir_src->modifiers, str->buffer); @@ -539,12 +649,34 @@ static uint32_t msl_dst_init(struct msl_dst *msl_dst, struct msl_generator *gen, return write_mask; }
+static void msl_print_subscript(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, + const struct vkd3d_shader_src_param *rel_addr, unsigned int offset) +{ + struct msl_src r; + + if (!rel_addr) + { + vkd3d_string_buffer_printf(buffer, "[%u]", offset); + return; + } + + msl_src_init(&r, gen, rel_addr, VKD3DSP_WRITEMASK_0); + vkd3d_string_buffer_printf(buffer, "[%s", r.str->buffer); + if (offset) + vkd3d_string_buffer_printf(buffer, " + %u", offset); + vkd3d_string_buffer_printf(buffer, "]"); + msl_src_cleanup(&r, &gen->string_buffers); +} + static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment( struct msl_generator *gen, struct msl_dst *dst, const char *format, ...) { uint32_t modifiers = dst->vsir->modifiers; va_list args;
+ /* It is always legitimate to ignore _pp. */ + modifiers &= ~VKD3DSPDM_PARTIALPRECISION; + if (dst->vsir->shift) msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled destination shift %#x.", dst->vsir->shift); @@ -570,10 +702,12 @@ static void VKD3D_PRINTF_FUNC(3, 4) msl_print_assignment(
static void msl_unhandled(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { + const char *name = vsir_opcode_get_name(ins->opcode, "<unknown>"); + msl_print_indent(gen->buffer, gen->indent); - vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction %#x> */\n", ins->opcode); + vkd3d_string_buffer_printf(gen->buffer, "/* <unhandled instruction "%s" (%#x)> */\n", name, ins->opcode); msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled instruction %#x.", ins->opcode); + "Internal compiler error: Unhandled instruction "%s" (%#x).", name, ins->opcode); }
static void msl_binop(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) @@ -695,19 +829,36 @@ static void msl_begin_block(struct msl_generator *gen) ++gen->indent; }
-static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +static void msl_print_condition(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, + enum vkd3d_shader_conditional_op op, const struct vkd3d_shader_src_param *arg) { const char *condition; struct msl_src src;
- msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); + msl_src_init(&src, gen, arg, VKD3DSP_WRITEMASK_0);
- msl_print_indent(gen->buffer, gen->indent); - condition = ins->flags == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; - vkd3d_string_buffer_printf(gen->buffer, "if (%s(%s))\n", condition, src.str->buffer); + condition = op == VKD3D_SHADER_CONDITIONAL_OP_NZ ? "bool" : "!bool"; + vkd3d_string_buffer_printf(buffer, "if (%s(%s))\n", condition, src.str->buffer);
msl_src_cleanup(&src, &gen->string_buffers); +}
+static void msl_discard(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + /* Note that discard_fragment() in Metal 2.2 and earlier behaves like + * SPIR-V OpKill, while in Metal 2.3 and later it behaves like + * OpDemoteToHelperInvocationEXT. We assume we have at least Metal 3 + * here. */ + msl_print_indent(gen->buffer, gen->indent); + msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); + msl_print_indent(gen->buffer, gen->indent + 1); + vkd3d_string_buffer_printf(gen->buffer, "discard_fragment();\n"); +} + +static void msl_if(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + msl_print_indent(gen->buffer, gen->indent); + msl_print_condition(gen->buffer, gen, ins->flags, &ins->src[0]); msl_begin_block(gen); }
@@ -719,6 +870,77 @@ static void msl_else(struct msl_generator *gen) msl_begin_block(gen); }
+static void msl_loop(struct msl_generator *gen) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "for (;;)\n"); + msl_begin_block(gen); +} + +static void msl_break(struct msl_generator *gen) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "break;\n"); +} + +static void msl_continue(struct msl_generator *gen) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "continue;\n"); +} + +static void msl_switch(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + struct msl_src src; + + msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); + + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "switch (%s)\n", src.str->buffer); + msl_begin_block(gen); + + msl_src_cleanup(&src, &gen->string_buffers); +} + +static void msl_case(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + struct msl_src src; + + msl_src_init(&src, gen, &ins->src[0], VKD3DSP_WRITEMASK_0); + + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "case %s:\n", src.str->buffer); + + msl_src_cleanup(&src, &gen->string_buffers); +} + +static void msl_default(struct msl_generator *gen) +{ + msl_print_indent(gen->buffer, gen->indent); + vkd3d_string_buffer_printf(gen->buffer, "default:\n"); +} + +static void msl_print_texel_offset(struct vkd3d_string_buffer *buffer, struct msl_generator *gen, + unsigned int offset_size, const struct vkd3d_shader_texel_offset *offset) +{ + switch (offset_size) + { + case 1: + vkd3d_string_buffer_printf(buffer, "%d", offset->u); + break; + case 2: + vkd3d_string_buffer_printf(buffer, "int2(%d, %d)", offset->u, offset->v); + break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Invalid texel offset size %u.", offset_size); + /* fall through */ + case 3: + vkd3d_string_buffer_printf(buffer, "int3(%d, %d, %d)", offset->u, offset->v, offset->w); + break; + } +} + static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { const struct msl_resource_type_info *resource_type_info; @@ -726,9 +948,10 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct const struct vkd3d_shader_descriptor_info1 *descriptor; const struct vkd3d_shader_descriptor_binding *binding; enum vkd3d_shader_resource_type resource_type; + uint32_t coord_mask, write_mask_size; struct vkd3d_string_buffer *read; - enum vkd3d_data_type data_type; - uint32_t coord_mask; + enum vsir_data_type data_type; + unsigned int srv_binding; struct msl_dst dst;
if (vkd3d_shader_instruction_has_texel_offset(ins)) @@ -754,47 +977,65 @@ 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; - data_type = VKD3D_DATA_FLOAT; + data_type = VSIR_DATA_F32; }
- if ((resource_type_info = msl_get_resource_type_info(resource_type))) - { - coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->read_coord_size); - } - else + if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBE + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_CUBEARRAY + || (ins->opcode != VSIR_OP_LD2DMS + && (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY))) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Texel fetches from resource type %#x are not supported.", resource_type); + + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled resource type %#x.", resource_type); - coord_mask = vkd3d_write_mask_from_component_count(2); + resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); } + coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size);
- if (!(binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) + if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) + { + srv_binding = binding->binding; + } + else { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, - "Cannot finding binding for SRV register %u index %u space %u.", + "No descriptor binding specified for SRV %u (index %u, space %u).", resource_id, resource_idx, resource_space); - return; + srv_binding = 0; }
msl_dst_init(&dst, gen, ins, &ins->dst[0]); read = vkd3d_string_buffer_get(&gen->string_buffers);
- vkd3d_string_buffer_printf(read, "as_type<uint4>("); - msl_print_srv_name(read, gen, binding->binding, resource_type_info, data_type); + vkd3d_string_buffer_printf(read, "as_type<"); + msl_print_resource_datatype(gen, read, ins->dst[0].reg.data_type); + write_mask_size = vkd3d_popcount(ins->dst[0].write_mask); + if (write_mask_size != 1) + vkd3d_string_buffer_printf(read, "%u", write_mask_size); + vkd3d_string_buffer_printf(read, ">("); + msl_print_srv_name(read, gen, srv_binding, resource_type_info, data_type, false); vkd3d_string_buffer_printf(read, ".read("); - msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VKD3D_DATA_UINT); + msl_print_src_with_type(read, gen, &ins->src[0], coord_mask, VSIR_DATA_U32); if (resource_type_info->array) { vkd3d_string_buffer_printf(read, ", "); - msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VKD3D_DATA_UINT); + msl_print_src_with_type(read, gen, &ins->src[0], coord_mask + 1, VSIR_DATA_U32); } - if (resource_type_info->lod) + if (resource_type != VKD3D_SHADER_RESOURCE_BUFFER) { vkd3d_string_buffer_printf(read, ", "); - msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VKD3D_DATA_UINT); + if (ins->opcode != VSIR_OP_LD2DMS) + msl_print_src_with_type(read, gen, &ins->src[0], VKD3DSP_WRITEMASK_3, VSIR_DATA_U32); + else + msl_print_src_with_type(read, gen, &ins->src[2], VKD3DSP_WRITEMASK_0, VSIR_DATA_U32); } - vkd3d_string_buffer_printf(read, "))"); + vkd3d_string_buffer_printf(read, ")"); msl_print_swizzle(read, ins->src[1].swizzle, ins->dst[0].write_mask); + vkd3d_string_buffer_printf(read, ")");
msl_print_assignment(gen, &dst, "%s", read->buffer);
@@ -802,6 +1043,313 @@ static void msl_ld(struct msl_generator *gen, const struct vkd3d_shader_instruct msl_dst_cleanup(&dst, &gen->string_buffers); }
+static void msl_sample(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + bool bias, compare, comparison_sampler, dynamic_offset, gather, grad, lod, lod_zero, offset; + const struct msl_resource_type_info *resource_type_info; + const struct vkd3d_shader_src_param *resource, *sampler; + unsigned int resource_id, resource_idx, resource_space; + const struct vkd3d_shader_descriptor_binding *binding; + unsigned int sampler_id, sampler_idx, sampler_space; + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; + unsigned int srv_binding, sampler_binding; + uint32_t coord_mask, write_mask_size; + struct vkd3d_string_buffer *sample; + enum vsir_data_type data_type; + unsigned int component_idx; + struct msl_dst dst; + + bias = ins->opcode == VSIR_OP_SAMPLE_B; + compare = ins->opcode == VSIR_OP_GATHER4_C || ins->opcode == VSIR_OP_SAMPLE_C + || ins->opcode == VSIR_OP_SAMPLE_C_LZ; + dynamic_offset = ins->opcode == VSIR_OP_GATHER4_PO; + gather = ins->opcode == VSIR_OP_GATHER4 || ins->opcode == VSIR_OP_GATHER4_C + || ins->opcode == VSIR_OP_GATHER4_PO; + grad = ins->opcode == VSIR_OP_SAMPLE_GRAD; + lod = ins->opcode == VSIR_OP_SAMPLE_LOD; + lod_zero = ins->opcode == VSIR_OP_SAMPLE_C_LZ; + offset = dynamic_offset || vkd3d_shader_instruction_has_texel_offset(ins); + + resource = &ins->src[1 + dynamic_offset]; + sampler = &ins->src[2 + dynamic_offset]; + + if (resource->reg.idx[0].rel_addr || resource->reg.idx[1].rel_addr + || sampler->reg.idx[0].rel_addr || sampler->reg.idx[1].rel_addr) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Descriptor indexing is not supported."); + + resource_id = resource->reg.idx[0].offset; + resource_idx = resource->reg.idx[1].offset; + if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_id))) + { + resource_space = d->register_space; + resource_type = d->resource_type; + data_type = d->resource_data_type; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared resource descriptor %u.", resource_id); + resource_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + data_type = VSIR_DATA_F32; + } + + if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMSARRAY) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Sampling resource type %#x is not supported.", resource_type); + + if ((resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1D || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY) + && (bias || grad || lod || lod_zero)) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Resource type %#x does not support mipmapping.", resource_type); + + if ((resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1D || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_1DARRAY + || resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_3D) && gather) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Resource type %#x does not support gather operations.", resource_type); + + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); + resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); + } + coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); + + if ((binding = msl_get_srv_binding(gen, resource_space, resource_idx, resource_type))) + { + srv_binding = binding->binding; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "No descriptor binding specified for SRV %u (index %u, space %u).", + resource_id, resource_idx, resource_space); + srv_binding = 0; + } + + sampler_id = sampler->reg.idx[0].offset; + sampler_idx = sampler->reg.idx[1].offset; + if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_id))) + { + sampler_space = d->register_space; + comparison_sampler = d->flags & VKD3D_SHADER_DESCRIPTOR_INFO_FLAG_SAMPLER_COMPARISON_MODE; + + if (compare) + { + if (!comparison_sampler) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Sampler %u is not a comparison sampler.", sampler_id); + } + else + { + if (comparison_sampler) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Sampler %u is a comparison sampler.", sampler_id); + } + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared sampler descriptor %u.", sampler_id); + sampler_space = 0; + } + + if ((binding = msl_get_sampler_binding(gen, sampler_space, sampler_idx))) + { + sampler_binding = binding->binding; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "No descriptor binding specified for sampler %u (index %u, space %u).", + sampler_id, sampler_idx, sampler_space); + sampler_binding = 0; + } + + msl_dst_init(&dst, gen, ins, &ins->dst[0]); + sample = vkd3d_string_buffer_get(&gen->string_buffers); + + vkd3d_string_buffer_printf(sample, "as_type<"); + msl_print_resource_datatype(gen, sample, ins->dst[0].reg.data_type); + write_mask_size = vkd3d_popcount(ins->dst[0].write_mask); + if (write_mask_size != 1) + vkd3d_string_buffer_printf(sample, "%u", write_mask_size); + vkd3d_string_buffer_printf(sample, ">("); + msl_print_srv_name(sample, gen, srv_binding, resource_type_info, data_type, compare); + if (gather && compare) + vkd3d_string_buffer_printf(sample, ".gather_compare("); + else if (gather) + vkd3d_string_buffer_printf(sample, ".gather("); + else if (compare) + vkd3d_string_buffer_printf(sample, ".sample_compare("); + else + vkd3d_string_buffer_printf(sample, ".sample("); + msl_print_sampler_name(sample, sampler_binding); + vkd3d_string_buffer_printf(sample, ", "); + msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask, ins->src[0].reg.data_type); + if (resource_type_info->array) + { + vkd3d_string_buffer_printf(sample, ", uint("); + msl_print_src_with_type(sample, gen, &ins->src[0], coord_mask + 1, ins->src[0].reg.data_type); + vkd3d_string_buffer_printf(sample, ")"); + } + if (compare) + { + if (!resource_type_info->comparison) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Comparison samplers are not supported with resource type %#x.", resource_type); + vkd3d_string_buffer_printf(sample, ", "); + msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); + } + if (grad) + { + vkd3d_string_buffer_printf(sample, ", gradient%s(", resource_type_info->type_suffix); + msl_print_src_with_type(sample, gen, &ins->src[3], coord_mask, ins->src[3].reg.data_type); + vkd3d_string_buffer_printf(sample, ", "); + msl_print_src_with_type(sample, gen, &ins->src[4], coord_mask, ins->src[4].reg.data_type); + vkd3d_string_buffer_printf(sample, ")"); + } + if (lod_zero) + { + vkd3d_string_buffer_printf(sample, ", level(0.0f)"); + } + else if (lod) + { + vkd3d_string_buffer_printf(sample, ", level("); + msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); + vkd3d_string_buffer_printf(sample, ")"); + } + if (bias) + { + vkd3d_string_buffer_printf(sample, ", bias("); + msl_print_src_with_type(sample, gen, &ins->src[3], VKD3DSP_WRITEMASK_0, ins->src[3].reg.data_type); + vkd3d_string_buffer_printf(sample, ")"); + } + if (offset) + { + if (!resource_type_info->offset) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Texel sample offsets are not supported with resource type %#x.", resource_type); + vkd3d_string_buffer_printf(sample, ", "); + if (dynamic_offset) + msl_print_src_with_type(sample, gen, &ins->src[1], coord_mask, ins->src[1].reg.data_type); + else + msl_print_texel_offset(sample, gen, resource_type_info->coord_size, &ins->texel_offset); + } + if (gather && !compare && (component_idx = vsir_swizzle_get_component(sampler->swizzle, 0))) + { + if (!offset && resource_type_info->offset) + vkd3d_string_buffer_printf(sample, ", int2(0)"); + vkd3d_string_buffer_printf(sample, ", component::%c", "xyzw"[component_idx]); + } + vkd3d_string_buffer_printf(sample, ")"); + if (!compare || gather) + msl_print_swizzle(sample, resource->swizzle, ins->dst[0].write_mask); + vkd3d_string_buffer_printf(sample, ")"); + + msl_print_assignment(gen, &dst, "%s", sample->buffer); + + vkd3d_string_buffer_release(&gen->string_buffers, sample); + msl_dst_cleanup(&dst, &gen->string_buffers); +} + +static void msl_store_uav_typed(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) +{ + const struct msl_resource_type_info *resource_type_info; + const struct vkd3d_shader_descriptor_binding *binding; + const struct vkd3d_shader_descriptor_info1 *d; + enum vkd3d_shader_resource_type resource_type; + unsigned int uav_id, uav_idx, uav_space; + struct vkd3d_string_buffer *image_data; + enum vsir_data_type data_type; + unsigned int uav_binding; + uint32_t coord_mask; + + if (ins->dst[0].reg.idx[0].rel_addr || ins->dst[0].reg.idx[1].rel_addr) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_UNSUPPORTED, + "Descriptor indexing is not supported."); + + uav_id = ins->dst[0].reg.idx[0].offset; + uav_idx = ins->dst[0].reg.idx[1].offset; + if ((d = vkd3d_shader_find_descriptor(&gen->program->descriptors, + VKD3D_SHADER_DESCRIPTOR_TYPE_UAV, uav_id))) + { + uav_space = d->register_space; + resource_type = d->resource_type; + data_type = d->resource_data_type; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Undeclared UAV descriptor %u.", uav_id); + uav_space = 0; + resource_type = VKD3D_SHADER_RESOURCE_TEXTURE_2D; + data_type = VSIR_DATA_F32; + } + + if (!(resource_type_info = msl_get_resource_type_info(resource_type))) + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled resource type %#x.", resource_type); + resource_type_info = msl_get_resource_type_info(VKD3D_SHADER_RESOURCE_TEXTURE_2D); + } + coord_mask = vkd3d_write_mask_from_component_count(resource_type_info->coord_size); + + if ((binding = msl_get_uav_binding(gen, uav_space, uav_idx, resource_type))) + { + uav_binding = binding->binding; + } + else + { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_BINDING_NOT_FOUND, + "No descriptor binding specified for UAV %u (index %u, space %u).", + uav_id, uav_idx, uav_space); + uav_binding = 0; + } + + image_data = vkd3d_string_buffer_get(&gen->string_buffers); + + if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) + { + switch (data_type) + { + case VSIR_DATA_U32: + vkd3d_string_buffer_printf(image_data, "uint4("); + break; + case VSIR_DATA_I32: + vkd3d_string_buffer_printf(image_data, "int4("); + break; + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled data type %#x.", data_type); + /* fall through */ + case VSIR_DATA_F32: + case VSIR_DATA_SNORM: + case VSIR_DATA_UNORM: + vkd3d_string_buffer_printf(image_data, "float4("); + break; + } + } + msl_print_src_with_type(image_data, gen, &ins->src[1], VKD3DSP_WRITEMASK_ALL, data_type); + if (ins->src[1].reg.dimension == VSIR_DIMENSION_SCALAR) + vkd3d_string_buffer_printf(image_data, ", 0, 0, 0)"); + + msl_print_indent(gen->buffer, gen->indent); + msl_print_uav_name(gen->buffer, gen, uav_binding, resource_type_info, data_type); + vkd3d_string_buffer_printf(gen->buffer, ".write(%s, ", image_data->buffer); + msl_print_src_with_type(gen->buffer, gen, &ins->src[0], coord_mask, VSIR_DATA_U32); + vkd3d_string_buffer_printf(gen->buffer, ");\n"); + + vkd3d_string_buffer_release(&gen->string_buffers, image_data); +} + static void msl_unary_op(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins, const char *op) { struct msl_src src; @@ -863,128 +1411,209 @@ static void msl_ret(struct msl_generator *gen, const struct vkd3d_shader_instruc vkd3d_string_buffer_printf(gen->buffer, "return;\n"); }
+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"; + 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, + ins->declaration.indexable_temp.register_size); +} + static void msl_handle_instruction(struct msl_generator *gen, const struct vkd3d_shader_instruction *ins) { gen->location = ins->location;
switch (ins->opcode) { - case VKD3DSIH_ADD: + case VSIR_OP_ADD: + case VSIR_OP_IADD: msl_binop(gen, ins, "+"); break; - case VKD3DSIH_AND: + case VSIR_OP_AND: msl_binop(gen, ins, "&"); break; - case VKD3DSIH_NOP: + case VSIR_OP_BREAK: + msl_break(gen); + break; + case VSIR_OP_CASE: + msl_case(gen, ins); + break; + case VSIR_OP_CONTINUE: + msl_continue(gen); + break; + case VSIR_OP_DCL_INDEXABLE_TEMP: + msl_dcl_indexable_temp(gen, ins); + break; + case VSIR_OP_NOP: break; - case VKD3DSIH_DIV: + case VSIR_OP_DEFAULT: + msl_default(gen); + break; + case VSIR_OP_DISCARD: + msl_discard(gen, ins); + break; + case VSIR_OP_DIV: msl_binop(gen, ins, "/"); break; - case VKD3DSIH_DP2: + case VSIR_OP_DP2: msl_dot(gen, ins, vkd3d_write_mask_from_component_count(2)); break; - case VKD3DSIH_DP3: + case VSIR_OP_DP3: msl_dot(gen, ins, vkd3d_write_mask_from_component_count(3)); break; - case VKD3DSIH_DP4: + case VSIR_OP_DP4: msl_dot(gen, ins, VKD3DSP_WRITEMASK_ALL); break; - case VKD3DSIH_ELSE: + case VSIR_OP_DSX: + case VSIR_OP_DSX_COARSE: + case VSIR_OP_DSX_FINE: + /* dfdx() and dfdy() are specified to return "a high precision + * partial derivative", which would seem to correspond to + * DSX_FINE/DSY_FINE. As of MSL 3.2, coarse/fast variants don't + * appear to be available. */ + msl_intrinsic(gen, ins, "dfdx"); + break; + case VSIR_OP_DSY: + case VSIR_OP_DSY_COARSE: + case VSIR_OP_DSY_FINE: + msl_intrinsic(gen, ins, "dfdy"); + break; + case VSIR_OP_ELSE: msl_else(gen); break; - case VKD3DSIH_ENDIF: + case VSIR_OP_ENDIF: + case VSIR_OP_ENDLOOP: + case VSIR_OP_ENDSWITCH: msl_end_block(gen); break; - case VKD3DSIH_IEQ: + case VSIR_OP_EQO: + case VSIR_OP_IEQ: msl_relop(gen, ins, "=="); break; - case VKD3DSIH_EXP: + case VSIR_OP_EXP: msl_intrinsic(gen, ins, "exp2"); break; - case VKD3DSIH_FRC: + case VSIR_OP_FRC: msl_intrinsic(gen, ins, "fract"); break; - case VKD3DSIH_FTOI: + case VSIR_OP_FTOI: msl_cast(gen, ins, "int"); break; - case VKD3DSIH_FTOU: + case VSIR_OP_FTOU: msl_cast(gen, ins, "uint"); break; - case VKD3DSIH_GEO: + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_C: + case VSIR_OP_GATHER4_PO: + case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: + case VSIR_OP_SAMPLE_GRAD: + case VSIR_OP_SAMPLE_LOD: + msl_sample(gen, ins); + break; + case VSIR_OP_GEO: + case VSIR_OP_IGE: msl_relop(gen, ins, ">="); break; - case VKD3DSIH_IF: + case VSIR_OP_IF: msl_if(gen, ins); break; - case VKD3DSIH_ISHL: + case VSIR_OP_ISHL: msl_binop(gen, ins, "<<"); break; - case VKD3DSIH_ISHR: - case VKD3DSIH_USHR: + case VSIR_OP_ISHR: + case VSIR_OP_USHR: msl_binop(gen, ins, ">>"); break; - case VKD3DSIH_LTO: + case VSIR_OP_ILT: + case VSIR_OP_LTO: + case VSIR_OP_ULT: msl_relop(gen, ins, "<"); break; - case VKD3DSIH_MAD: + case VSIR_OP_MAD: msl_intrinsic(gen, ins, "fma"); break; - case VKD3DSIH_MAX: + case VSIR_OP_IMAX: + case VSIR_OP_MAX: + case VSIR_OP_UMAX: msl_intrinsic(gen, ins, "max"); break; - case VKD3DSIH_MIN: + case VSIR_OP_MIN: + case VSIR_OP_UMIN: msl_intrinsic(gen, ins, "min"); break; - case VKD3DSIH_INE: - case VKD3DSIH_NEU: + case VSIR_OP_IMUL_LOW: + msl_binop(gen, ins, "*"); + break; + case VSIR_OP_INE: + case VSIR_OP_NEU: msl_relop(gen, ins, "!="); break; - case VKD3DSIH_ITOF: - case VKD3DSIH_UTOF: + case VSIR_OP_INEG: + msl_unary_op(gen, ins, "-"); + break; + case VSIR_OP_ITOF: + case VSIR_OP_UTOF: msl_cast(gen, ins, "float"); break; - case VKD3DSIH_LD: + case VSIR_OP_LD: + case VSIR_OP_LD2DMS: msl_ld(gen, ins); break; - case VKD3DSIH_LOG: + case VSIR_OP_LOG: msl_intrinsic(gen, ins, "log2"); break; - case VKD3DSIH_MOV: + case VSIR_OP_LOOP: + msl_loop(gen); + break; + case VSIR_OP_MOV: msl_mov(gen, ins); break; - case VKD3DSIH_MOVC: + case VSIR_OP_MOVC: msl_movc(gen, ins); break; - case VKD3DSIH_MUL: + case VSIR_OP_MUL: msl_binop(gen, ins, "*"); break; - case VKD3DSIH_NOT: + case VSIR_OP_NOT: msl_unary_op(gen, ins, "~"); break; - case VKD3DSIH_OR: + case VSIR_OP_OR: msl_binop(gen, ins, "|"); break; - case VKD3DSIH_RET: + case VSIR_OP_RET: msl_ret(gen, ins); break; - case VKD3DSIH_ROUND_NE: + case VSIR_OP_ROUND_NE: msl_intrinsic(gen, ins, "rint"); break; - case VKD3DSIH_ROUND_NI: + case VSIR_OP_ROUND_NI: msl_intrinsic(gen, ins, "floor"); break; - case VKD3DSIH_ROUND_PI: + case VSIR_OP_ROUND_PI: msl_intrinsic(gen, ins, "ceil"); break; - case VKD3DSIH_ROUND_Z: + case VSIR_OP_ROUND_Z: msl_intrinsic(gen, ins, "trunc"); break; - case VKD3DSIH_RSQ: + case VSIR_OP_RSQ: msl_intrinsic(gen, ins, "rsqrt"); break; - case VKD3DSIH_SQRT: + case VSIR_OP_SQRT: msl_intrinsic(gen, ins, "sqrt"); break; + case VSIR_OP_STORE_UAV_TYPED: + msl_store_uav_typed(gen, ins); + break; + case VSIR_OP_SWITCH: + msl_switch(gen, ins); + break; + case VSIR_OP_XOR: + msl_binop(gen, ins, "^"); + break; default: msl_unhandled(gen, ins); break; @@ -996,6 +1625,7 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) const struct shader_signature *signature = &gen->program->input_signature; enum vkd3d_shader_type type = gen->program->shader_version.type; struct vkd3d_string_buffer *buffer = gen->buffer; + bool locations[MAX_IO_REG_COUNT] = {0}; const struct signature_element *e; unsigned int i;
@@ -1008,21 +1638,60 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) continue;
- if (e->sysval_semantic) + if (e->target_location >= ARRAY_SIZE(locations)) { - if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) - { + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled input target location %u.", e->target_location); + continue; + } + + if (locations[e->target_location]) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); + locations[e->target_location] = true; + + switch (e->sysval_semantic) + { + case VKD3D_SHADER_SV_NONE: + break; + + case VKD3D_SHADER_SV_POSITION: if (type != VKD3D_SHADER_TYPE_PIXEL) msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type); + "Internal compiler error: Unhandled SV_POSITION in shader type #%x.", type); + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "float4 position [[position]];\n"); + continue;
+ case VKD3D_SHADER_SV_VERTEX_ID: + if (type != VKD3D_SHADER_TYPE_VERTEX) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled SV_VERTEX_ID in shader type #%x.", type); + gen->read_vertex_id = true; + continue; + + case VKD3D_SHADER_SV_IS_FRONT_FACE: + if (type != VKD3D_SHADER_TYPE_PIXEL) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled SV_IS_FRONT_FACE in shader type #%x.", type); msl_print_indent(gen->buffer, 1); vkd3d_string_buffer_printf(buffer, "bool is_front_face [[front_facing]];\n"); continue; - } - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); - continue; + + case VKD3D_SHADER_SV_SAMPLE_INDEX: + if (type != VKD3D_SHADER_TYPE_PIXEL) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled SV_SAMPLE_INDEX in shader type #%x.", type); + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "uint sample_index [[sample_id]];\n"); + continue; + + default: + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled system value %#x.", e->sysval_semantic); + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "<unhandled sysval %#x>;\n", e->sysval_semantic); + continue; }
if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) @@ -1059,15 +1728,15 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) break; }
- vkd3d_string_buffer_printf(buffer, "shader_in_%u ", i); + vkd3d_string_buffer_printf(buffer, "shader_in_%u [[", i);
switch (type) { case VKD3D_SHADER_TYPE_VERTEX: - vkd3d_string_buffer_printf(gen->buffer, "[[attribute(%u)]]", e->target_location); + vkd3d_string_buffer_printf(gen->buffer, "attribute(%u)", e->target_location); break; case VKD3D_SHADER_TYPE_PIXEL: - vkd3d_string_buffer_printf(gen->buffer, "[[user(locn%u)]]", e->target_location); + vkd3d_string_buffer_printf(gen->buffer, "user(locn%u)", e->target_location); break; default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -1081,13 +1750,16 @@ static void msl_generate_input_struct_declarations(struct msl_generator *gen) case VKD3DSIM_LINEAR: case VKD3DSIM_NONE: break; + case VKD3DSIM_CONSTANT: + vkd3d_string_buffer_printf(gen->buffer, ", flat"); + break; default: msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); break; }
- vkd3d_string_buffer_printf(buffer, ";\n"); + vkd3d_string_buffer_printf(buffer, "]];\n"); }
vkd3d_string_buffer_printf(buffer, "};\n\n"); @@ -1129,6 +1801,7 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) const struct shader_signature *signature = &gen->program->output_signature; enum vkd3d_shader_type type = gen->program->shader_version.type; struct vkd3d_string_buffer *buffer = gen->buffer; + bool locations[MAX_IO_REG_COUNT] = {0}; const struct signature_element *e; unsigned int i;
@@ -1138,28 +1811,26 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) { e = &signature->elements[i];
- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) - { - gen->write_depth = true; - msl_print_indent(gen->buffer, 1); - vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); + if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED + || e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) continue; - }
- if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) - continue; - - if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) + if (e->target_location >= ARRAY_SIZE(locations)) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); + "Internal compiler error: Unhandled input target location %u.", e->target_location); continue; }
- if (e->interpolation_mode != VKD3DSIM_NONE) + if (locations[e->target_location]) + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled duplicate input target location %u.", e->target_location); + locations[e->target_location] = true; + + if (e->min_precision != VKD3D_SHADER_MINIMUM_PRECISION_NONE) { msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled interpolation mode %#x.", e->interpolation_mode); + "Internal compiler error: Unhandled minimum precision %#x.", e->min_precision); continue; }
@@ -1209,6 +1880,18 @@ static void msl_generate_output_struct_declarations(struct msl_generator *gen) vkd3d_string_buffer_printf(buffer, ";\n"); }
+ if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) + { + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "float shader_out_depth [[depth(any)]];\n"); + } + + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + { + msl_print_indent(gen->buffer, 1); + vkd3d_string_buffer_printf(buffer, "uint shader_out_mask [[sample_mask]];\n"); + } + vkd3d_string_buffer_printf(buffer, "};\n\n"); }
@@ -1227,23 +1910,45 @@ static void msl_generate_entrypoint_prologue(struct msl_generator *gen) continue;
vkd3d_string_buffer_printf(buffer, " %s_in[%u]", gen->prefix, e->register_index); - if (e->sysval_semantic == VKD3D_SHADER_SV_NONE) - { - msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); - msl_print_write_mask(buffer, e->mask); - vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i); - msl_print_write_mask(buffer, e->mask); - } - else if (e->sysval_semantic == VKD3D_SHADER_SV_IS_FRONT_FACE) - { - vkd3d_string_buffer_printf(buffer, ".u = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); - } - else + switch (e->sysval_semantic) { - vkd3d_string_buffer_printf(buffer, " = <unhandled sysval %#x>", e->sysval_semantic); - msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, - "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic); + case VKD3D_SHADER_SV_NONE: + msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type)); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = input.shader_in_%u", i); + break; + + case VKD3D_SHADER_SV_POSITION: + msl_print_register_datatype(buffer, gen, VSIR_DATA_F32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = float4(input.position.xyz, 1.0f / input.position.w)"); + break; + + case VKD3D_SHADER_SV_VERTEX_ID: + msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = uint4(vertex_id, 0u, 0u, 0u)"); + break; + + case VKD3D_SHADER_SV_IS_FRONT_FACE: + msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = uint4(input.is_front_face ? 0xffffffffu : 0u, 0, 0, 0)"); + break; + + case VKD3D_SHADER_SV_SAMPLE_INDEX: + msl_print_register_datatype(buffer, gen, VSIR_DATA_U32); + msl_print_write_mask(buffer, e->mask); + vkd3d_string_buffer_printf(buffer, " = uint4(input.sample_index, 0u, 0u, 0u)"); + break; + + default: + vkd3d_string_buffer_printf(buffer, " = <unhandled sysval %#x>", e->sysval_semantic); + msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, + "Internal compiler error: Unhandled system value %#x input.", e->sysval_semantic); + break; } + msl_print_write_mask(buffer, e->mask); vkd3d_string_buffer_printf(buffer, ";\n"); } } @@ -1259,12 +1964,6 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) { e = &signature->elements[i];
- if (e->sysval_semantic == VKD3D_SHADER_SV_DEPTH) - { - vkd3d_string_buffer_printf(buffer, " output.shader_out_depth = shader_out_depth;\n"); - continue; - } - if (e->target_location == SIGNATURE_TARGET_LOCATION_UNUSED) continue;
@@ -1276,9 +1975,11 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) vkd3d_string_buffer_printf(buffer, " output.shader_out_%u", i); msl_print_write_mask(buffer, e->mask); vkd3d_string_buffer_printf(buffer, " = %s_out[%u]", gen->prefix, e->register_index); - msl_print_register_datatype(buffer, gen, vkd3d_data_type_from_component_type(e->component_type)); + msl_print_register_datatype(buffer, gen, vsir_data_type_from_component_type(e->component_type)); msl_print_write_mask(buffer, e->mask); break; + case VKD3D_SHADER_SV_DEPTH: + continue; default: vkd3d_string_buffer_printf(buffer, " <unhandled sysval %#x>", e->sysval_semantic); msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, @@ -1286,6 +1987,9 @@ static void msl_generate_entrypoint_epilogue(struct msl_generator *gen) } vkd3d_string_buffer_printf(buffer, ";\n"); } + + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, " output.shader_out_mask = o_mask.u;\n"); }
static void msl_generate_entrypoint(struct msl_generator *gen) @@ -1298,6 +2002,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen) vkd3d_string_buffer_printf(gen->buffer, "vertex "); break; case VKD3D_SHADER_TYPE_PIXEL: + if (gen->program->global_flags & VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL) + vkd3d_string_buffer_printf(gen->buffer, "[[early_fragment_tests]]\n"); vkd3d_string_buffer_printf(gen->buffer, "fragment "); break; default: @@ -1316,25 +2022,35 @@ static void msl_generate_entrypoint(struct msl_generator *gen) "constant descriptor *descriptors [[buffer(0)]],\n"); }
+ if (gen->read_vertex_id) + { + msl_print_indent(gen->buffer, 2); + vkd3d_string_buffer_printf(gen->buffer, "uint vertex_id [[vertex_id]],\n"); + } + msl_print_indent(gen->buffer, 2); vkd3d_string_buffer_printf(gen->buffer, "vkd3d_%s_in input [[stage_in]])\n{\n", gen->prefix);
/* TODO: declare #maximum_register + 1 */ - vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, 32); - vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, 32); + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_in[%u];\n", gen->prefix, MAX_IO_REG_COUNT); + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_vec4 %s_out[%u];\n", gen->prefix, MAX_IO_REG_COUNT); vkd3d_string_buffer_printf(gen->buffer, " vkd3d_%s_out output;\n", gen->prefix); - - if (gen->write_depth) - vkd3d_string_buffer_printf(gen->buffer, " float shader_out_depth;\n"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, " vkd3d_scalar o_mask;\n"); + vkd3d_string_buffer_printf(gen->buffer, "\n");
msl_generate_entrypoint_prologue(gen);
vkd3d_string_buffer_printf(gen->buffer, " %s_main(%s_in, %s_out", gen->prefix, gen->prefix, gen->prefix); - if (gen->write_depth) - vkd3d_string_buffer_printf(gen->buffer, ", shader_out_depth"); + if (gen->read_vertex_id) + vkd3d_string_buffer_printf(gen->buffer, ", vertex_id"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) + vkd3d_string_buffer_printf(gen->buffer, ", output.shader_out_depth"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, ", o_mask"); if (gen->program->descriptors.descriptor_count) vkd3d_string_buffer_printf(gen->buffer, ", descriptors"); - vkd3d_string_buffer_printf(gen->buffer, ");\n"); + vkd3d_string_buffer_printf(gen->buffer, ");\n\n");
msl_generate_entrypoint_epilogue(gen);
@@ -1343,8 +2059,8 @@ static void msl_generate_entrypoint(struct msl_generator *gen)
static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader_code *out) { - const struct vkd3d_shader_instruction_array *instructions = &gen->program->instructions; - unsigned int i; + struct vkd3d_shader_instruction *ins; + struct vsir_program_iterator it;
MESSAGE("Generating a MSL shader. This is unsupported; you get to keep all the pieces if it breaks.\n");
@@ -1353,10 +2069,15 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader vkd3d_string_buffer_printf(gen->buffer, "#include <metal_texture>\n\n"); vkd3d_string_buffer_printf(gen->buffer, "using namespace metal;\n\n");
- if (gen->program->global_flags) + if (gen->program->global_flags & ~(VKD3DSGF_REFACTORING_ALLOWED | VKD3DSGF_FORCE_EARLY_DEPTH_STENCIL)) msl_compiler_error(gen, VKD3D_SHADER_ERROR_MSL_INTERNAL, "Internal compiler error: Unhandled global flags %#"PRIx64".", (uint64_t)gen->program->global_flags);
+ vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_scalar\n{\n"); + vkd3d_string_buffer_printf(gen->buffer, " uint u;\n"); + vkd3d_string_buffer_printf(gen->buffer, " int i;\n"); + vkd3d_string_buffer_printf(gen->buffer, " float f;\n};\n\n"); + vkd3d_string_buffer_printf(gen->buffer, "union vkd3d_vec4\n{\n"); vkd3d_string_buffer_printf(gen->buffer, " uint4 u;\n"); vkd3d_string_buffer_printf(gen->buffer, " int4 i;\n"); @@ -1370,7 +2091,7 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader " const device void *ptr;\n" "\n" " template<typename T>\n" - " constant T &tex() constant\n" + " constant T &as() constant\n" " {\n" " return reinterpret_cast<constant T &>(this->ptr);\n" " }\n" @@ -1388,11 +2109,16 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader msl_generate_output_struct_declarations(gen);
vkd3d_string_buffer_printf(gen->buffer, - "void %s_main(thread vkd3d_vec4 *v, " + "static void %s_main(thread vkd3d_vec4 *v, " "thread vkd3d_vec4 *o", gen->prefix); - if (gen->write_depth) - vkd3d_string_buffer_printf(gen->buffer, ", thread float& o_depth"); + + if (gen->read_vertex_id) + vkd3d_string_buffer_printf(gen->buffer, ", uint vertex_id"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_DEPTHOUT)) + vkd3d_string_buffer_printf(gen->buffer, ", thread float &o_depth"); + if (bitmap_is_set(gen->program->io_dcls, VKD3DSPR_SAMPLEMASK)) + vkd3d_string_buffer_printf(gen->buffer, ", thread vkd3d_scalar &o_mask"); if (gen->program->descriptors.descriptor_count) vkd3d_string_buffer_printf(gen->buffer, ", constant descriptor *descriptors"); vkd3d_string_buffer_printf(gen->buffer, ")\n{\n"); @@ -1405,9 +2131,10 @@ static int msl_generator_generate(struct msl_generator *gen, struct vkd3d_shader vkd3d_string_buffer_printf(gen->buffer, "vkd3d_vec4 r[%u];\n\n", gen->program->temp_count); }
- for (i = 0; i < instructions->count; ++i) + it = vsir_program_iterator(&gen->program->instructions); + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - msl_handle_instruction(gen, &instructions->elements[i]); + msl_handle_instruction(gen, ins); }
--gen->indent; @@ -1469,6 +2196,9 @@ int msl_compile(struct vsir_program *program, uint64_t config_flags, if ((ret = vsir_program_transform(program, config_flags, compile_info, message_context)) < 0) return ret;
+ if ((ret = vsir_allocate_temp_registers(program, message_context)) < 0) + return ret; + VKD3D_ASSERT(program->normalisation_level == VSIR_NORMALISED_SM6); VKD3D_ASSERT(program->has_descriptor_info);
diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.h b/libs/vkd3d/libs/vkd3d-shader/preproc.h index a98c8ae3df5..9217237d8d3 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.h +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.h @@ -38,6 +38,7 @@ struct preproc_buffer { void *lexer_buffer; struct vkd3d_shader_location location; + bool eof; };
struct preproc_file @@ -125,7 +126,6 @@ struct preproc_ctx int lookahead_token;
bool last_was_newline; - bool last_was_eof; bool last_was_defined;
bool error; diff --git a/libs/vkd3d/libs/vkd3d-shader/preproc.l b/libs/vkd3d/libs/vkd3d-shader/preproc.l index 4a8d0fddae1..a8c0db358bc 100644 --- a/libs/vkd3d/libs/vkd3d-shader/preproc.l +++ b/libs/vkd3d/libs/vkd3d-shader/preproc.l @@ -71,8 +71,8 @@ INT_SUFFIX [uUlL]{0,2}
%%
-<INITIAL>"//" {yy_push_state(CXX_COMMENT, yyscanner);} -<INITIAL>"/*" {yy_push_state(C_COMMENT, yyscanner);} +<INITIAL,INCLUDE,LINE>"//" {yy_push_state(CXX_COMMENT, yyscanner);} +<INITIAL,INCLUDE,LINE>"/*" {yy_push_state(C_COMMENT, yyscanner);} <CXX_COMMENT>\{NEWLINE} {} <CXX_COMMENT>\n { yy_pop_state(yyscanner); @@ -80,7 +80,11 @@ INT_SUFFIX [uUlL]{0,2} return T_NEWLINE; } <C_COMMENT>"*/" {yy_pop_state(yyscanner);} -<C_COMMENT,CXX_COMMENT><<EOF>> {yy_pop_state(yyscanner);} +<C_COMMENT,CXX_COMMENT><<EOF>> { + yy_pop_state(yyscanner); + BEGIN(INITIAL); + yyterminate(); + } <C_COMMENT,CXX_COMMENT>. {} <C_COMMENT>\n {}
@@ -196,6 +200,10 @@ INT_SUFFIX [uUlL]{0,2} BEGIN(INITIAL); return T_NEWLINE; } +<INITIAL,INCLUDE,ERROR,LINE><<EOF>> { + BEGIN(INITIAL); + yyterminate(); + }
<INITIAL,INCLUDE,LINE>{WS}+ {} <INITIAL>[-()[]{},+!*/<>&|^?:] {return yytext[0];} @@ -250,8 +258,19 @@ static bool should_concat(struct preproc_ctx *ctx) return !macro || macro->arg_count; }
+static struct preproc_buffer *preproc_get_top_buffer(struct preproc_ctx *ctx) +{ + if (ctx->expansion_count) + return &ctx->expansion_stack[ctx->expansion_count - 1].buffer; + if (ctx->file_count) + return &ctx->file_stack[ctx->file_count - 1].buffer; + return NULL; +} + static void preproc_pop_buffer(struct preproc_ctx *ctx) { + struct preproc_buffer *buffer; + if (ctx->expansion_count) { struct preproc_expansion *exp = &ctx->expansion_stack[ctx->expansion_count - 1]; @@ -290,10 +309,8 @@ static void preproc_pop_buffer(struct preproc_ctx *ctx) TRACE("File stack size is now %zu.\n", ctx->file_count); }
- if (ctx->expansion_count) - yy_switch_to_buffer(ctx->expansion_stack[ctx->expansion_count - 1].buffer.lexer_buffer, ctx->scanner); - else if (ctx->file_count) - yy_switch_to_buffer(ctx->file_stack[ctx->file_count - 1].buffer.lexer_buffer, ctx->scanner); + if ((buffer = preproc_get_top_buffer(ctx))) + yy_switch_to_buffer(buffer->lexer_buffer, ctx->scanner); }
static int return_token(int token, YYSTYPE *lval, const char *text) @@ -347,6 +364,7 @@ static bool preproc_push_expansion(struct preproc_ctx *ctx, exp->text = text; exp->buffer.lexer_buffer = yy_scan_bytes(text->text.buffer, text->text.content_size, ctx->scanner); exp->buffer.location = text->location; + exp->buffer.eof = false; exp->macro = macro; exp->arg_values = arg_values; TRACE("Expansion stack size is now %zu.\n", ctx->expansion_count); @@ -407,18 +425,17 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner) } else { - if (ctx->last_was_eof) + if (preproc_get_top_buffer(ctx)->eof) { preproc_pop_buffer(ctx); if (!ctx->file_count) return 0; } - ctx->last_was_eof = false;
VKD3D_ASSERT(ctx->file_count); if (!(token = preproc_lexer_lex(lval, lloc, scanner))) { - ctx->last_was_eof = true; + preproc_get_top_buffer(ctx)->eof = true;
/* If we have reached the end of an included file, inject a newline. */ if (ctx->expansion_count) @@ -781,6 +798,7 @@ bool preproc_push_include(struct preproc_ctx *ctx, char *filename, const struct file->buffer.location.source_name = file->filename; file->buffer.location.line = 1; file->buffer.location.column = 1; + file->buffer.eof = false; TRACE("File stack size is now %zu.\n", ctx->file_count); ctx->last_was_newline = true; return true; diff --git a/libs/vkd3d/libs/vkd3d-shader/spirv.c b/libs/vkd3d/libs/vkd3d-shader/spirv.c index 1f967c22406..97c0d0e73a8 100644 --- a/libs/vkd3d/libs/vkd3d-shader/spirv.c +++ b/libs/vkd3d/libs/vkd3d-shader/spirv.c @@ -38,7 +38,7 @@ #define VKD3D_SPIRV_VERSION_1_0 0x00010000 #define VKD3D_SPIRV_VERSION_1_3 0x00010300 #define VKD3D_SPIRV_GENERATOR_ID 18 -#define VKD3D_SPIRV_GENERATOR_VERSION 16 +#define VKD3D_SPIRV_GENERATOR_VERSION 17 #define VKD3D_SPIRV_GENERATOR_MAGIC vkd3d_make_u32(VKD3D_SPIRV_GENERATOR_VERSION, VKD3D_SPIRV_GENERATOR_ID) #ifndef VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER # define VKD3D_SHADER_UNSUPPORTED_SPIRV_PARSER 0 @@ -847,57 +847,6 @@ static void vkd3d_spirv_dump(const struct vkd3d_shader_code *spirv, enum vkd3d_s vkd3d_shader_message_context_cleanup(&message_context); }
-enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, - unsigned int index) -{ - switch (sysval) - { - case VKD3D_SHADER_SV_COVERAGE: - case VKD3D_SHADER_SV_DEPTH: - case VKD3D_SHADER_SV_DEPTH_GREATER_EQUAL: - case VKD3D_SHADER_SV_DEPTH_LESS_EQUAL: - case VKD3D_SHADER_SV_NONE: - case VKD3D_SHADER_SV_STENCIL_REF: - case VKD3D_SHADER_SV_TARGET: - return VKD3D_SIV_NONE; - case VKD3D_SHADER_SV_POSITION: - return VKD3D_SIV_POSITION; - case VKD3D_SHADER_SV_CLIP_DISTANCE: - return VKD3D_SIV_CLIP_DISTANCE; - case VKD3D_SHADER_SV_CULL_DISTANCE: - return VKD3D_SIV_CULL_DISTANCE; - case VKD3D_SHADER_SV_INSTANCE_ID: - return VKD3D_SIV_INSTANCE_ID; - case VKD3D_SHADER_SV_IS_FRONT_FACE: - return VKD3D_SIV_IS_FRONT_FACE; - case VKD3D_SHADER_SV_PRIMITIVE_ID: - return VKD3D_SIV_PRIMITIVE_ID; - case VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX: - return VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX; - case VKD3D_SHADER_SV_SAMPLE_INDEX: - return VKD3D_SIV_SAMPLE_INDEX; - case VKD3D_SHADER_SV_TESS_FACTOR_QUADEDGE: - return VKD3D_SIV_QUAD_U0_TESS_FACTOR + index; - case VKD3D_SHADER_SV_TESS_FACTOR_QUADINT: - return VKD3D_SIV_QUAD_U_INNER_TESS_FACTOR + index; - case VKD3D_SHADER_SV_TESS_FACTOR_TRIEDGE: - return VKD3D_SIV_TRIANGLE_U_TESS_FACTOR + index; - case VKD3D_SHADER_SV_TESS_FACTOR_TRIINT: - return VKD3D_SIV_TRIANGLE_INNER_TESS_FACTOR; - case VKD3D_SHADER_SV_TESS_FACTOR_LINEDET: - return VKD3D_SIV_LINE_DETAIL_TESS_FACTOR; - case VKD3D_SHADER_SV_TESS_FACTOR_LINEDEN: - return VKD3D_SIV_LINE_DENSITY_TESS_FACTOR; - case VKD3D_SHADER_SV_VERTEX_ID: - return VKD3D_SIV_VERTEX_ID; - case VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX: - return VKD3D_SIV_VIEWPORT_ARRAY_INDEX; - default: - FIXME("Unhandled sysval %#x, index %u.\n", sysval, index); - return VKD3D_SIV_NONE; - } -} - struct vkd3d_spirv_stream { uint32_t *words; @@ -1033,6 +982,7 @@ struct vkd3d_spirv_builder SpvExecutionModel execution_model;
uint32_t current_id; + uint32_t source_name_id; uint32_t main_function_id; struct rb_tree declarations; uint32_t type_sampler_id; @@ -1602,6 +1552,34 @@ static void vkd3d_spirv_build_op_name(struct vkd3d_spirv_builder *builder, vkd3d_spirv_build_string(stream, name, name_size); }
+static uint32_t vkd3d_spirv_build_op_string(struct vkd3d_spirv_builder *builder, const char *s) +{ + struct vkd3d_spirv_stream *stream = &builder->debug_stream; + uint32_t result_id = vkd3d_spirv_alloc_id(builder); + unsigned int size; + + size = vkd3d_spirv_string_word_count(s); + vkd3d_spirv_build_word(stream, vkd3d_spirv_opcode_word(SpvOpString, 2 + size)); + vkd3d_spirv_build_word(stream, result_id); + vkd3d_spirv_build_string(stream, s, size); + + return result_id; +} + +static void vkd3d_spirv_build_op_source(struct vkd3d_spirv_builder *builder, const char *source_name) +{ + struct vkd3d_spirv_stream *stream = &builder->debug_stream; + + builder->source_name_id = vkd3d_spirv_build_op_string(builder, source_name ? source_name : "<anonymous>"); + vkd3d_spirv_build_op3(stream, SpvOpSource, 0, 0, builder->source_name_id); +} + +static void vkd3d_spirv_build_op_line(struct vkd3d_spirv_builder *builder, const struct vkd3d_shader_location *location) +{ + vkd3d_spirv_build_op3(&builder->function_stream, SpvOpLine, + builder->source_name_id, location->line, location->column); +} + static void vkd3d_spirv_build_op_member_name(struct vkd3d_spirv_builder *builder, uint32_t type_id, uint32_t member, const char *fmt, ...) { @@ -2513,18 +2491,6 @@ static uint32_t vkd3d_spirv_build_op_glsl_std450_fabs(struct vkd3d_spirv_builder return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450FAbs, result_type, operand); }
-static uint32_t vkd3d_spirv_build_op_glsl_std450_sin(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand) -{ - return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Sin, result_type, operand); -} - -static uint32_t vkd3d_spirv_build_op_glsl_std450_cos(struct vkd3d_spirv_builder *builder, - uint32_t result_type, uint32_t operand) -{ - return vkd3d_spirv_build_op_glsl_std450_tr1(builder, GLSLstd450Cos, result_type, operand); -} - static uint32_t vkd3d_spirv_build_op_glsl_std450_max(struct vkd3d_spirv_builder *builder, uint32_t result_type, uint32_t x, uint32_t y) { @@ -2608,7 +2574,7 @@ static uint32_t vkd3d_spirv_get_type_id(struct vkd3d_spirv_builder *builder, }
static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder *builder, - enum vkd3d_data_type data_type, unsigned int component_count) + enum vsir_data_type data_type, unsigned int component_count) { enum vkd3d_shader_component_type component_type;
@@ -2616,7 +2582,8 @@ static uint32_t vkd3d_spirv_get_type_id_for_data_type(struct vkd3d_spirv_builder return vkd3d_spirv_get_type_id(builder, component_type, component_count); }
-static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const char *entry_point) +static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, + const char *entry_point, const char *source_name) { vkd3d_spirv_stream_init(&builder->debug_stream); vkd3d_spirv_stream_init(&builder->annotation_stream); @@ -2631,6 +2598,7 @@ static void vkd3d_spirv_builder_init(struct vkd3d_spirv_builder *builder, const
rb_init(&builder->declarations, vkd3d_spirv_declaration_compare);
+ vkd3d_spirv_build_op_source(builder, source_name); builder->main_function_id = vkd3d_spirv_alloc_id(builder); vkd3d_spirv_build_op_name(builder, builder->main_function_id, "%s", entry_point); } @@ -3050,7 +3018,7 @@ struct vkd3d_hull_shader_variables
struct ssa_register_info { - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; uint8_t write_mask; uint32_t id; }; @@ -3058,7 +3026,7 @@ struct ssa_register_info struct spirv_compiler { struct vkd3d_spirv_builder spirv_builder; - const struct vsir_program *program; + struct vsir_program *program;
struct vkd3d_shader_message_context *message_context; struct vkd3d_shader_location location; @@ -3140,17 +3108,17 @@ struct spirv_compiler
static bool is_in_default_phase(const struct spirv_compiler *compiler) { - return compiler->phase == VKD3DSIH_INVALID; + return compiler->phase == VSIR_OP_INVALID; }
static bool is_in_control_point_phase(const struct spirv_compiler *compiler) { - return compiler->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE; + return compiler->phase == VSIR_OP_HS_CONTROL_POINT_PHASE; }
static bool is_in_fork_or_join_phase(const struct spirv_compiler *compiler) { - return compiler->phase == VKD3DSIH_HS_FORK_PHASE || compiler->phase == VKD3DSIH_HS_JOIN_PHASE; + return compiler->phase == VSIR_OP_HS_FORK_PHASE || compiler->phase == VSIR_OP_HS_JOIN_PHASE; }
static void spirv_compiler_emit_initial_declarations(struct spirv_compiler *compiler); @@ -3188,7 +3156,7 @@ static void spirv_compiler_destroy(struct spirv_compiler *compiler) vkd3d_free(compiler); }
-static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *program, +static struct spirv_compiler *spirv_compiler_create(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, uint64_t config_flags) { @@ -3224,7 +3192,8 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p compiler->spirv_target_info = target_info; }
- vkd3d_spirv_builder_init(&compiler->spirv_builder, spirv_compiler_get_entry_point_name(compiler)); + vkd3d_spirv_builder_init(&compiler->spirv_builder, + spirv_compiler_get_entry_point_name(compiler), compile_info->source_name);
compiler->formatting = VKD3D_SHADER_COMPILE_OPTION_FORMATTING_INDENT | VKD3D_SHADER_COMPILE_OPTION_FORMATTING_HEADER; @@ -3332,7 +3301,7 @@ static struct spirv_compiler *spirv_compiler_create(const struct vsir_program *p else if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY) compiler->emit_point_size = compiler->xfb_info && compiler->xfb_info->element_count;
- compiler->phase = VKD3DSIH_INVALID; + compiler->phase = VSIR_OP_INVALID;
vkd3d_string_buffer_cache_init(&compiler->string_buffers);
@@ -3559,8 +3528,12 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind goto done; }
- resource_type_flag = resource_type == VKD3D_SHADER_RESOURCE_BUFFER - ? VKD3D_SHADER_BINDING_FLAG_BUFFER : VKD3D_SHADER_BINDING_FLAG_IMAGE; + if (resource_type == VKD3D_SHADER_RESOURCE_NONE) + resource_type_flag = 0; + else if (resource_type == VKD3D_SHADER_RESOURCE_BUFFER) + resource_type_flag = VKD3D_SHADER_BINDING_FLAG_BUFFER; + else + resource_type_flag = VKD3D_SHADER_BINDING_FLAG_IMAGE;
if (is_uav_counter) { @@ -3604,7 +3577,7 @@ static struct vkd3d_shader_descriptor_binding spirv_compiler_get_descriptor_bind { const struct vkd3d_shader_resource_binding *current = &shader_interface->bindings[i];
- if (!(current->flags & resource_type_flag)) + if ((current->flags & resource_type_flag) != resource_type_flag) continue;
if (!spirv_compiler_check_shader_visibility(compiler, current->shader_visibility)) @@ -4018,7 +3991,7 @@ static uint32_t spirv_compiler_alloc_spec_constant_id(struct spirv_compiler *com
static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name, uint32_t spec_id, - enum vkd3d_data_type type, unsigned int component_count) + enum vsir_data_type type, unsigned int component_count) { uint32_t scalar_type_id, vector_type_id, id, default_value, components[4]; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4057,7 +4030,7 @@ static uint32_t spirv_compiler_emit_spec_constant(struct spirv_compiler *compile
static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler, enum vkd3d_shader_parameter_name name, uint32_t spec_id, - enum vkd3d_data_type type, unsigned int component_count) + enum vsir_data_type type, unsigned int component_count) { unsigned int i;
@@ -4071,7 +4044,7 @@ static uint32_t spirv_compiler_get_spec_constant(struct spirv_compiler *compiler }
static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compiler, - const struct vkd3d_shader_parameter1 *parameter, enum vkd3d_data_type type, unsigned int component_count) + const struct vkd3d_shader_parameter1 *parameter, enum vsir_data_type type, unsigned int component_count) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int index = parameter - compiler->program->parameters; @@ -4087,18 +4060,18 @@ static uint32_t spirv_compiler_get_buffer_parameter(struct spirv_compiler *compi
static const struct { - enum vkd3d_data_type type; + enum vsir_data_type type; unsigned int component_count; } parameter_data_type_map[] = { - [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VKD3D_DATA_FLOAT, 1}, - [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VKD3D_DATA_UINT, 1}, - [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VKD3D_DATA_FLOAT, 4}, + [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32] = {VSIR_DATA_F32, 1}, + [VKD3D_SHADER_PARAMETER_DATA_TYPE_UINT32] = {VSIR_DATA_U32, 1}, + [VKD3D_SHADER_PARAMETER_DATA_TYPE_FLOAT32_VEC4] = {VSIR_DATA_F32, 4}, };
static uint32_t spirv_compiler_emit_shader_parameter(struct spirv_compiler *compiler, - enum vkd3d_shader_parameter_name name, enum vkd3d_data_type type, unsigned int component_count) + enum vkd3d_shader_parameter_name name, enum vsir_data_type type, unsigned int component_count) { const struct vkd3d_shader_parameter1 *parameter;
@@ -4239,7 +4212,7 @@ static bool spirv_compiler_get_register_info(struct spirv_compiler *compiler, if (!(entry = rb_get(&compiler->symbol_table, ®_symbol))) { spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_REGISTER_TYPE, - "Unrecognized register (%s).\n", debug_vkd3d_symbol(®_symbol)); + "Unrecognized register (%s).", debug_vkd3d_symbol(®_symbol)); memset(register_info, 0, sizeof(*register_info)); return false; } @@ -4512,7 +4485,7 @@ static uint32_t spirv_compiler_emit_vector_shuffle(struct spirv_compiler *compil }
static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, - enum vkd3d_shader_conditional_op condition, enum vkd3d_data_type data_type, + enum vkd3d_shader_conditional_op condition, enum vsir_data_type data_type, unsigned int component_count, uint32_t val_id) { struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; @@ -4524,7 +4497,7 @@ static uint32_t spirv_compiler_emit_int_to_bool(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_BOOL, component_count); op = condition & VKD3D_SHADER_CONDITIONAL_OP_Z ? SpvOpIEqual : SpvOpINotEqual; return vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, val_id, - data_type == VKD3D_DATA_UINT64 + data_type == VSIR_DATA_U64 ? spirv_compiler_get_constant_uint64_vector(compiler, 0, component_count) : spirv_compiler_get_constant_uint_vector(compiler, 0, component_count)); } @@ -4578,70 +4551,6 @@ static uint32_t spirv_compiler_emit_bool_to_double(struct spirv_compiler *compil return vkd3d_spirv_build_op_select(builder, type_id, val_id, true_id, false_id); }
-/* Based on the implementation in the OpenGL Mathematics library. */ -static uint32_t half_to_float(uint16_t value) -{ - uint32_t s = (value & 0x8000u) << 16; - uint32_t e = (value >> 10) & 0x1fu; - uint32_t m = value & 0x3ffu; - - if (!e) - { - if (!m) - { - /* Plus or minus zero */ - return s; - } - else - { - /* Denormalized number -- renormalize it */ - - while (!(m & 0x400u)) - { - m <<= 1; - --e; - } - - ++e; - m &= ~0x400u; - } - } - else if (e == 31u) - { - /* Positive or negative infinity for zero 'm'. - * Nan for non-zero 'm' -- preserve sign and significand bits */ - return s | 0x7f800000u | (m << 13); - } - - /* Normalized number */ - e += 127u - 15u; - m <<= 13; - - /* Assemble s, e and m. */ - return s | (e << 23) | m; -} - -static uint32_t convert_raw_constant32(enum vkd3d_data_type data_type, unsigned int uint_value) -{ - int16_t i; - - /* TODO: native 16-bit support. */ - if (data_type != VKD3D_DATA_UINT16 && data_type != VKD3D_DATA_HALF) - return uint_value; - - if (data_type == VKD3D_DATA_HALF) - return half_to_float(uint_value); - - /* Values in DXIL have no signedness, so it is ambiguous whether 16-bit constants should or - * should not be sign-extended when 16-bit execution is not supported. The AMD RX 580 Windows - * driver has no 16-bit support, and sign-extends all 16-bit constant ints to 32 bits. These - * results differ from SM 5. The RX 6750 XT supports 16-bit execution, so constants are not - * extended, and results match SM 5. It seems best to replicate the sign-extension, and if - * execution is 16-bit, the values will be truncated. */ - i = uint_value; - return (int32_t)i; -} - static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compiler, const struct vkd3d_shader_register *reg, uint32_t swizzle, uint32_t write_mask) { @@ -4654,15 +4563,14 @@ static uint32_t spirv_compiler_emit_load_constant(struct spirv_compiler *compile if (reg->dimension == VSIR_DIMENSION_SCALAR) { for (i = 0; i < component_count; ++i) - values[i] = convert_raw_constant32(reg->data_type, reg->u.immconst_u32[0]); + values[i] = reg->u.immconst_u32[0]; } else { for (i = 0, j = 0; i < VKD3D_VEC4_SIZE; ++i) { if (write_mask & (VKD3DSP_WRITEMASK_0 << i)) - values[j++] = convert_raw_constant32(reg->data_type, - reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]); + values[j++] = reg->u.immconst_u32[vsir_swizzle_get_component(swizzle, i)]; } }
@@ -4758,8 +4666,8 @@ static uint32_t spirv_compiler_emit_load_scalar(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(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, VKD3D_SHADER_CONDITIONAL_OP_NZ, - VKD3D_DATA_UINT, 1, val_id); + val_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, 1, val_id); } else { @@ -4806,22 +4714,15 @@ static uint32_t spirv_compiler_emit_constant_array(struct spirv_compiler *compil
switch (icb->data_type) { - case VKD3D_DATA_HALF: - case VKD3D_DATA_UINT16: - /* Scalar only. */ - for (i = 0; i < element_count; ++i) - elements[i] = vkd3d_spirv_get_op_constant(builder, elem_type_id, - convert_raw_constant32(icb->data_type, icb->data[i])); - break; - case VKD3D_DATA_FLOAT: - case VKD3D_DATA_INT: - case VKD3D_DATA_UINT: + case VSIR_DATA_F32: + case VSIR_DATA_I32: + case VSIR_DATA_U32: for (i = 0; i < element_count; ++i) elements[i] = spirv_compiler_get_constant(compiler, component_type, component_count, &icb->data[component_count * i]); break; - case VKD3D_DATA_DOUBLE: - case VKD3D_DATA_UINT64: + case VSIR_DATA_F64: + case VSIR_DATA_U64: { uint64_t *data = (uint64_t *)icb->data; for (i = 0; i < element_count; ++i) @@ -4913,8 +4814,8 @@ static uint32_t spirv_compiler_emit_load_reg(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(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, VKD3D_SHADER_CONDITIONAL_OP_NZ, - VKD3D_DATA_UINT, component_count, val_id); + val_id = spirv_compiler_emit_int_to_bool(compiler, + VKD3D_SHADER_CONDITIONAL_OP_NZ, VSIR_DATA_U32, component_count, val_id); } else { @@ -5008,7 +4909,7 @@ static uint32_t spirv_compiler_emit_load_src_with_type(struct spirv_compiler *co { struct vkd3d_shader_src_param src_param = *src;
- src_param.reg.data_type = vkd3d_data_type_from_component_type(component_type); + src_param.reg.data_type = vsir_data_type_from_component_type(component_type); return spirv_compiler_emit_load_src(compiler, &src_param, write_mask); }
@@ -5134,7 +5035,7 @@ static uint32_t spirv_compiler_emit_sat(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; uint32_t type_id, zero_id, one_id;
- if (reg->data_type == VKD3D_DATA_DOUBLE) + if (reg->data_type == VSIR_DATA_F64) { zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); one_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); @@ -5188,7 +5089,7 @@ static void spirv_compiler_emit_store_dst_swizzled(struct spirv_compiler *compil /* XXX: The register data type could be fixed by the shader parser. For SM5 * shaders the data types are stored in instructions modifiers. */ - typed_dst.reg.data_type = vkd3d_data_type_from_component_type(component_type); + typed_dst.reg.data_type = vsir_data_type_from_component_type(component_type); spirv_compiler_emit_store_dst(compiler, &typed_dst, val_id); }
@@ -5616,7 +5517,7 @@ static uint32_t spirv_compiler_get_invocation_id(struct spirv_compiler *compiler
VKD3D_ASSERT(compiler->shader_type == VKD3D_SHADER_TYPE_HULL);
- vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VKD3D_DATA_FLOAT, 0); + vsir_register_init(&r, VKD3DSPR_OUTPOINTID, VSIR_DATA_F32, 0); return spirv_compiler_get_register_id(compiler, &r); }
@@ -5641,13 +5542,13 @@ static void spirv_compiler_emit_shader_phase_name(struct spirv_compiler *compile
switch (compiler->phase) { - case VKD3DSIH_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: name = "control"; break; - case VKD3DSIH_HS_FORK_PHASE: + case VSIR_OP_HS_FORK_PHASE: name = "fork"; break; - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_JOIN_PHASE: name = "join"; break; default: @@ -5775,6 +5676,48 @@ static unsigned int shader_signature_next_location(const struct shader_signature return max_row; }
+static const struct vkd3d_symbol *spirv_compiler_emit_io_register(struct spirv_compiler *compiler, + const struct vkd3d_shader_dst_param *dst) +{ + struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; + const struct vkd3d_shader_register *reg = &dst->reg; + const struct vkd3d_spirv_builtin *builtin; + struct vkd3d_symbol reg_symbol; + SpvStorageClass storage_class; + uint32_t write_mask, id; + struct rb_entry *entry; + + VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); + VKD3D_ASSERT(reg->idx_count < 2); + + if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) + { + builtin = &vkd3d_output_point_size_builtin; + storage_class = SpvStorageClassOutput; + } + else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) + { + FIXME("Unhandled register %#x.\n", reg->type); + return NULL; + } + + /* vPrim may be declared in multiple hull shader phases. */ + vkd3d_symbol_make_register(®_symbol, reg); + if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) + return RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry); + + id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); + spirv_compiler_emit_register_execution_mode(compiler, reg->type); + spirv_compiler_emit_register_debug_name(builder, id, reg); + + write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); + vkd3d_symbol_set_register_info(®_symbol, id, + storage_class, builtin->component_type, write_mask); + reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; + + return spirv_compiler_put_symbol(compiler, ®_symbol); +} + static void spirv_compiler_emit_input(struct spirv_compiler *compiler, enum vkd3d_shader_register_type reg_type, unsigned int element_idx) { @@ -5783,6 +5726,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, const struct signature_element *signature_element; const struct shader_signature *shader_signature; enum vkd3d_shader_component_type component_type; + enum vkd3d_shader_register_type sysval_reg_type; const struct vkd3d_spirv_builtin *builtin; enum vkd3d_shader_sysval_semantic sysval; uint32_t write_mask, reg_write_mask; @@ -5807,6 +5751,22 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, if (!signature_element->used_mask) return;
+ sysval_reg_type = vsir_register_type_from_sysval_input(signature_element->sysval_semantic); + if (sysval_reg_type != VKD3DSPR_INPUT) + { + struct vkd3d_shader_dst_param dst; + const struct vkd3d_symbol *symbol; + + vsir_dst_param_init(&dst, sysval_reg_type, VSIR_DATA_F32, 0); + symbol = spirv_compiler_emit_io_register(compiler, &dst); + + vkd3d_symbol_make_io(®_symbol, reg_type, element_idx); + reg_symbol.id = symbol->id; + reg_symbol.info.reg = symbol->info.reg; + spirv_compiler_put_symbol(compiler, ®_symbol); + return; + } + builtin = get_spirv_builtin_for_sysval(compiler, sysval);
array_sizes[0] = signature_element->register_count; @@ -5823,15 +5783,15 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, { component_type = builtin->component_type; input_component_count = builtin->component_count; - component_idx = 0; } else { component_type = signature_element->component_type; input_component_count = vsir_write_mask_component_count(signature_element->mask); - component_idx = vsir_write_mask_get_component_idx(signature_element->mask); }
+ component_idx = vsir_write_mask_get_component_idx(write_mask); + if (needs_private_io_variable(builtin)) { use_private_var = true; @@ -5839,7 +5799,6 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, } else { - component_idx = vsir_write_mask_get_component_idx(write_mask); reg_write_mask = write_mask >> component_idx; }
@@ -5905,7 +5864,7 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, { struct vkd3d_shader_register dst_reg;
- vsir_register_init(&dst_reg, reg_type, VKD3D_DATA_FLOAT, 1); + 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); @@ -5925,49 +5884,8 @@ static void spirv_compiler_emit_input(struct spirv_compiler *compiler, vkd3d_write_mask_from_component_count(input_component_count), VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_SHADER_NO_SWIZZLE, signature_element->mask >> component_idx);
- spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask, val_id); - } -} - -static void spirv_compiler_emit_io_register(struct spirv_compiler *compiler, - const struct vkd3d_shader_dst_param *dst) -{ - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_register *reg = &dst->reg; - const struct vkd3d_spirv_builtin *builtin; - struct vkd3d_symbol reg_symbol; - SpvStorageClass storage_class; - uint32_t write_mask, id; - struct rb_entry *entry; - - VKD3D_ASSERT(!reg->idx_count || !reg->idx[0].rel_addr); - VKD3D_ASSERT(reg->idx_count < 2); - - if (reg->type == VKD3DSPR_RASTOUT && reg->idx[0].offset == VSIR_RASTOUT_POINT_SIZE) - { - builtin = &vkd3d_output_point_size_builtin; - storage_class = SpvStorageClassOutput; - } - else if (!(builtin = get_spirv_builtin_for_register(reg->type, &storage_class))) - { - FIXME("Unhandled register %#x.\n", reg->type); - return; + spirv_compiler_emit_store_reg(compiler, &dst_reg, signature_element->mask >> component_idx, val_id); } - - /* vPrim may be declared in multiple hull shader phases. */ - vkd3d_symbol_make_register(®_symbol, reg); - if ((entry = rb_get(&compiler->symbol_table, ®_symbol))) - return; - - id = spirv_compiler_emit_builtin_variable(compiler, builtin, storage_class, 0); - - write_mask = vkd3d_write_mask_from_component_count(builtin->component_count); - vkd3d_symbol_set_register_info(®_symbol, id, - storage_class, builtin->component_type, write_mask); - reg_symbol.info.reg.is_aggregate = builtin->spirv_array_size; - spirv_compiler_put_symbol(compiler, ®_symbol); - spirv_compiler_emit_register_execution_mode(compiler, reg->type); - spirv_compiler_emit_register_debug_name(builder, id, reg); }
static unsigned int get_shader_output_swizzle(const struct spirv_compiler *compiler, @@ -6607,7 +6525,7 @@ static void spirv_compiler_emit_dcl_indexable_temp(struct spirv_compiler *compil * scope is specified, e.g. DXIL alloca. */ storage_class = temp->has_function_scope ? SpvStorageClassFunction : SpvStorageClassPrivate;
- vsir_register_init(®, VKD3DSPR_IDXTEMP, VKD3D_DATA_FLOAT, 1); + vsir_register_init(®, VKD3DSPR_IDXTEMP, VSIR_DATA_F32, 1); reg.idx[0].offset = temp->register_idx;
/* Alignment is supported only in the Kernel execution model and is an optimisation only. */ @@ -6847,7 +6765,7 @@ static void spirv_compiler_emit_cbv_declaration(struct spirv_compiler *compiler, struct vkd3d_symbol reg_symbol; unsigned int size;
- vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VKD3D_DATA_FLOAT, 3); + vsir_register_init(®, VKD3DSPR_CONSTBUFFER, VSIR_DATA_F32, 3); reg.idx[0].offset = descriptor->register_id; reg.idx[1].offset = range->first; reg.idx[2].offset = range->last; @@ -6907,7 +6825,7 @@ static void spirv_compiler_emit_dcl_immediate_constant_buffer(struct spirv_compi vkd3d_spirv_build_op_name(builder, icb_id, "icb");
/* Set an index count of 2 so vkd3d_symbol_make_register() uses idx[0] as a buffer id. */ - vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VKD3D_DATA_FLOAT, 2); + vsir_register_init(®, VKD3DSPR_IMMCONSTBUFFER, VSIR_DATA_F32, 2); reg.idx[0].offset = icb->register_idx; vkd3d_symbol_make_register(®_symbol, ®); vkd3d_symbol_set_register_info(®_symbol, icb_id, SpvStorageClassPrivate, @@ -6926,7 +6844,7 @@ static void spirv_compiler_emit_sampler_declaration(struct spirv_compiler *compi struct vkd3d_symbol reg_symbol; uint32_t type_id, var_id;
- vsir_register_init(®, VKD3DSPR_SAMPLER, VKD3D_DATA_FLOAT, 1); + vsir_register_init(®, VKD3DSPR_SAMPLER, VSIR_DATA_F32, 1); reg.idx[0].offset = descriptor->register_id;
vkd3d_symbol_make_sampler(®_symbol, ®); @@ -7107,7 +7025,7 @@ static void spirv_compiler_emit_resource_declaration(struct spirv_compiler *comp struct vkd3d_symbol resource_symbol; struct vkd3d_shader_register reg;
- vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VKD3D_DATA_FLOAT, 1); + vsir_register_init(®, is_uav ? VKD3DSPR_UAV : VKD3DSPR_RESOURCE, VSIR_DATA_F32, 1); reg.idx[0].offset = descriptor->register_id;
if (resource_type == VKD3D_SHADER_RESOURCE_TEXTURE_2DMS && sample_count == 1) @@ -7510,7 +7428,7 @@ static void spirv_compiler_enter_shader_phase(struct spirv_compiler *compiler, compiler->phase = instruction->opcode; spirv_compiler_emit_shader_phase_name(compiler, function_id, NULL);
- phase = (instruction->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE) + phase = (instruction->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE) ? &compiler->control_point_phase : &compiler->patch_constant_phase; phase->function_id = function_id; /* The insertion location must be set after the label is emitted. */ @@ -7524,7 +7442,7 @@ static void spirv_compiler_initialise_block(struct spirv_compiler *compiler) /* Insertion locations must point immediately after the function's initial label. */ if (compiler->shader_type == VKD3D_SHADER_TYPE_HULL) { - struct vkd3d_shader_phase *phase = (compiler->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE) + struct vkd3d_shader_phase *phase = (compiler->phase == VSIR_OP_HS_CONTROL_POINT_PHASE) ? &compiler->control_point_phase : &compiler->patch_constant_phase; if (!phase->function_location) phase->function_location = vkd3d_spirv_stream_current_location(&builder->function_stream); @@ -7626,35 +7544,40 @@ static SpvOp spirv_compiler_map_alu_instruction(const struct vkd3d_shader_instru } alu_ops[] = { - {VKD3DSIH_ADD, SpvOpFAdd}, - {VKD3DSIH_AND, SpvOpBitwiseAnd}, - {VKD3DSIH_BFREV, SpvOpBitReverse}, - {VKD3DSIH_COUNTBITS, SpvOpBitCount}, - {VKD3DSIH_DADD, SpvOpFAdd}, - {VKD3DSIH_DDIV, SpvOpFDiv}, - {VKD3DSIH_DIV, SpvOpFDiv}, - {VKD3DSIH_DMUL, SpvOpFMul}, - {VKD3DSIH_DTOI, SpvOpConvertFToS}, - {VKD3DSIH_DTOU, SpvOpConvertFToU}, - {VKD3DSIH_FREM, SpvOpFRem}, - {VKD3DSIH_FTOD, SpvOpFConvert}, - {VKD3DSIH_IADD, SpvOpIAdd}, - {VKD3DSIH_INEG, SpvOpSNegate}, - {VKD3DSIH_ISHL, SpvOpShiftLeftLogical}, - {VKD3DSIH_ISHR, SpvOpShiftRightArithmetic}, - {VKD3DSIH_ISINF, SpvOpIsInf}, - {VKD3DSIH_ISNAN, SpvOpIsNan}, - {VKD3DSIH_ITOD, SpvOpConvertSToF}, - {VKD3DSIH_ITOF, SpvOpConvertSToF}, - {VKD3DSIH_ITOI, SpvOpSConvert}, - {VKD3DSIH_MUL, SpvOpFMul}, - {VKD3DSIH_NOT, SpvOpNot}, - {VKD3DSIH_OR, SpvOpBitwiseOr}, - {VKD3DSIH_USHR, SpvOpShiftRightLogical}, - {VKD3DSIH_UTOD, SpvOpConvertUToF}, - {VKD3DSIH_UTOF, SpvOpConvertUToF}, - {VKD3DSIH_UTOU, SpvOpUConvert}, - {VKD3DSIH_XOR, SpvOpBitwiseXor}, + {VSIR_OP_ADD, SpvOpFAdd}, + {VSIR_OP_AND, SpvOpBitwiseAnd}, + {VSIR_OP_BFREV, SpvOpBitReverse}, + {VSIR_OP_COUNTBITS, SpvOpBitCount}, + {VSIR_OP_DADD, SpvOpFAdd}, + {VSIR_OP_DDIV, SpvOpFDiv}, + {VSIR_OP_DIV, SpvOpFDiv}, + {VSIR_OP_DMUL, SpvOpFMul}, + {VSIR_OP_DTOI, SpvOpConvertFToS}, + {VSIR_OP_DTOU, SpvOpConvertFToU}, + {VSIR_OP_FREM, SpvOpFRem}, + {VSIR_OP_FTOD, SpvOpFConvert}, + {VSIR_OP_IADD, SpvOpIAdd}, + {VSIR_OP_IDIV, SpvOpSDiv}, + {VSIR_OP_IMUL_LOW, SpvOpIMul}, + {VSIR_OP_INEG, SpvOpSNegate}, + {VSIR_OP_IREM, SpvOpSRem}, + {VSIR_OP_ISHL, SpvOpShiftLeftLogical}, + {VSIR_OP_ISHR, SpvOpShiftRightArithmetic}, + {VSIR_OP_ISINF, SpvOpIsInf}, + {VSIR_OP_ISNAN, SpvOpIsNan}, + {VSIR_OP_ITOD, SpvOpConvertSToF}, + {VSIR_OP_ITOF, SpvOpConvertSToF}, + {VSIR_OP_ITOI, SpvOpSConvert}, + {VSIR_OP_MUL, SpvOpFMul}, + {VSIR_OP_NOT, SpvOpNot}, + {VSIR_OP_OR, SpvOpBitwiseOr}, + {VSIR_OP_UDIV_SIMPLE, SpvOpUDiv}, + {VSIR_OP_UREM, SpvOpUMod}, + {VSIR_OP_USHR, SpvOpShiftRightLogical}, + {VSIR_OP_UTOD, SpvOpConvertUToF}, + {VSIR_OP_UTOF, SpvOpConvertUToF}, + {VSIR_OP_UTOU, SpvOpUConvert}, + {VSIR_OP_XOR, SpvOpBitwiseXor}, }; unsigned int i;
@@ -7671,11 +7594,11 @@ static SpvOp spirv_compiler_map_logical_instruction(const struct vkd3d_shader_in { switch (instruction->opcode) { - case VKD3DSIH_AND: + case VSIR_OP_AND: return SpvOpLogicalAnd; - case VKD3DSIH_OR: + case VSIR_OP_OR: return SpvOpLogicalOr; - case VKD3DSIH_XOR: + case VSIR_OP_XOR: return SpvOpLogicalNotEqual; default: return SpvOpMax; @@ -7689,25 +7612,25 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, const struct vkd3d_shader_src_param *src = instruction->src; uint32_t val_id;
- VKD3D_ASSERT(src->reg.data_type == VKD3D_DATA_BOOL && dst->reg.data_type != VKD3D_DATA_BOOL); + VKD3D_ASSERT(src->reg.data_type == VSIR_DATA_BOOL && dst->reg.data_type != VSIR_DATA_BOOL);
val_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - if (dst->reg.data_type == VKD3D_DATA_HALF || dst->reg.data_type == VKD3D_DATA_FLOAT) + if (dst->reg.data_type == VSIR_DATA_F16 || dst->reg.data_type == VSIR_DATA_F32) { - val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOF); + val_id = spirv_compiler_emit_bool_to_float(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); } - else if (dst->reg.data_type == VKD3D_DATA_DOUBLE) + else if (dst->reg.data_type == VSIR_DATA_F64) { /* 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 == VKD3DSIH_ITOF); + val_id = spirv_compiler_emit_bool_to_double(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOF); } - else if (dst->reg.data_type == VKD3D_DATA_UINT16 || dst->reg.data_type == VKD3D_DATA_UINT) + else if (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 == VKD3DSIH_ITOI); + val_id = spirv_compiler_emit_bool_to_int(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); } - else if (dst->reg.data_type == VKD3D_DATA_UINT64) + else if (dst->reg.data_type == VSIR_DATA_U64) { - val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VKD3DSIH_ITOI); + val_id = spirv_compiler_emit_bool_to_int64(compiler, 1, val_id, instruction->opcode == VSIR_OP_ITOI); } else { @@ -7722,15 +7645,16 @@ static void spirv_compiler_emit_bool_cast(struct spirv_compiler *compiler, static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { + uint32_t src_ids[SPIRV_MAX_SRC_COUNT], condition_id = 0, uint_max_id = 0; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t src_ids[SPIRV_MAX_SRC_COUNT]; + unsigned int i, component_count; uint32_t type_id, val_id; SpvOp op = SpvOpMax; - unsigned int i; + bool check_zero;
- if (src->reg.data_type == VKD3D_DATA_UINT64 && instruction->opcode == VKD3DSIH_COUNTBITS) + if (src->reg.data_type == VSIR_DATA_U64 && instruction->opcode == VSIR_OP_COUNTBITS) { /* At least some drivers support this anyway, but if validation is enabled it will fail. */ FIXME("Unsupported 64-bit source for bit count.\n"); @@ -7739,15 +7663,15 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil return VKD3D_ERROR_INVALID_SHADER; }
- if (src->reg.data_type == VKD3D_DATA_BOOL) + if (src->reg.data_type == VSIR_DATA_BOOL) { - if (dst->reg.data_type == VKD3D_DATA_BOOL) + if (dst->reg.data_type == VSIR_DATA_BOOL) { /* VSIR supports logic ops AND/OR/XOR on bool values. */ op = spirv_compiler_map_logical_instruction(instruction); } - else if (instruction->opcode == VKD3DSIH_ITOF || instruction->opcode == VKD3DSIH_UTOF - || instruction->opcode == VKD3DSIH_ITOI || instruction->opcode == VKD3DSIH_UTOU) + else if (instruction->opcode == VSIR_OP_ITOF || instruction->opcode == VSIR_OP_UTOF + || instruction->opcode == VSIR_OP_ITOI || instruction->opcode == VSIR_OP_UTOU) { /* VSIR supports cast from bool to signed/unsigned integer types and floating point types, * where bool is treated as a 1-bit integer and a signed 'true' value converts to -1. */ @@ -7762,20 +7686,50 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil
if (op == SpvOpMax) { - ERR("Unexpected instruction %#x.\n", instruction->opcode); spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER, - "Encountered invalid/unhandled instruction handler %#x.", instruction->opcode); + "Encountered invalid/unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return VKD3D_ERROR_INVALID_SHADER; }
+ /* SPIR-V doesn't mandate a behaviour when a denominator is zero, + * so we have an explicit check. */ + switch (instruction->opcode) + { + case VSIR_OP_IDIV: + case VSIR_OP_IREM: + case VSIR_OP_UDIV_SIMPLE: + case VSIR_OP_UREM: + check_zero = true; + break; + + default: + check_zero = false; + break; + } + VKD3D_ASSERT(instruction->dst_count == 1); VKD3D_ASSERT(instruction->src_count <= SPIRV_MAX_SRC_COUNT); + if (check_zero) + VKD3D_ASSERT(instruction->src_count == 2);
+ component_count = vsir_write_mask_component_count(dst[0].write_mask); type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
for (i = 0; i < instruction->src_count; ++i) src_ids[i] = spirv_compiler_emit_load_src(compiler, &src[i], dst->write_mask);
+ if (check_zero) + { + 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) + 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); + } + /* The SPIR-V specification states, "The resulting value is undefined if * Shift is greater than or equal to the bit width of the components of * Base." Direct3D applies only the lowest 5 bits of the shift. @@ -7783,8 +7737,8 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil * Microsoft fxc will compile immediate constants larger than 5 bits. * Fixing up the constants would be more elegant, but the simplest way is * to let this handle constants too. */ - if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->opcode == VKD3DSIH_ISHL - || instruction->opcode == VKD3DSIH_ISHR || instruction->opcode == VKD3DSIH_USHR)) + if (!(instruction->flags & VKD3DSI_SHIFT_UNMASKED) && (instruction->opcode == VSIR_OP_ISHL + || instruction->opcode == VSIR_OP_ISHR || instruction->opcode == VSIR_OP_USHR)) { uint32_t mask_id = spirv_compiler_get_constant_vector(compiler, VKD3D_SHADER_COMPONENT_UINT, vsir_write_mask_component_count(dst->write_mask), 0x1f); @@ -7796,6 +7750,9 @@ static enum vkd3d_result spirv_compiler_emit_alu_instruction(struct spirv_compil if (instruction->flags & VKD3DSI_PRECISE_XYZW) vkd3d_spirv_build_op_decorate(builder, val_id, SpvDecorationNoContraction, NULL, 0);
+ if (check_zero) + val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); + spirv_compiler_emit_store_dst(compiler, dst, val_id); return VKD3D_OK; } @@ -7827,36 +7784,38 @@ static enum GLSLstd450 spirv_compiler_map_ext_glsl_instruction( } glsl_insts[] = { - {VKD3DSIH_ABS, GLSLstd450FAbs}, - {VKD3DSIH_ACOS, GLSLstd450Acos}, - {VKD3DSIH_ASIN, GLSLstd450Asin}, - {VKD3DSIH_ATAN, GLSLstd450Atan}, - {VKD3DSIH_DFMA, GLSLstd450Fma}, - {VKD3DSIH_DMAX, GLSLstd450NMax}, - {VKD3DSIH_DMIN, GLSLstd450NMin}, - {VKD3DSIH_EXP, GLSLstd450Exp2}, - {VKD3DSIH_FIRSTBIT_HI, GLSLstd450FindUMsb}, - {VKD3DSIH_FIRSTBIT_LO, GLSLstd450FindILsb}, - {VKD3DSIH_FIRSTBIT_SHI, GLSLstd450FindSMsb}, - {VKD3DSIH_FRC, GLSLstd450Fract}, - {VKD3DSIH_HCOS, GLSLstd450Cosh}, - {VKD3DSIH_HSIN, GLSLstd450Sinh}, - {VKD3DSIH_HTAN, GLSLstd450Tanh}, - {VKD3DSIH_IMAX, GLSLstd450SMax}, - {VKD3DSIH_IMIN, GLSLstd450SMin}, - {VKD3DSIH_LOG, GLSLstd450Log2}, - {VKD3DSIH_MAD, GLSLstd450Fma}, - {VKD3DSIH_MAX, GLSLstd450NMax}, - {VKD3DSIH_MIN, GLSLstd450NMin}, - {VKD3DSIH_ROUND_NE, GLSLstd450RoundEven}, - {VKD3DSIH_ROUND_NI, GLSLstd450Floor}, - {VKD3DSIH_ROUND_PI, GLSLstd450Ceil}, - {VKD3DSIH_ROUND_Z, GLSLstd450Trunc}, - {VKD3DSIH_RSQ, GLSLstd450InverseSqrt}, - {VKD3DSIH_SQRT, GLSLstd450Sqrt}, - {VKD3DSIH_TAN, GLSLstd450Tan}, - {VKD3DSIH_UMAX, GLSLstd450UMax}, - {VKD3DSIH_UMIN, GLSLstd450UMin}, + {VSIR_OP_ABS, GLSLstd450FAbs}, + {VSIR_OP_ACOS, GLSLstd450Acos}, + {VSIR_OP_ASIN, GLSLstd450Asin}, + {VSIR_OP_ATAN, GLSLstd450Atan}, + {VSIR_OP_COS, GLSLstd450Cos}, + {VSIR_OP_DFMA, GLSLstd450Fma}, + {VSIR_OP_DMAX, GLSLstd450NMax}, + {VSIR_OP_DMIN, GLSLstd450NMin}, + {VSIR_OP_EXP, GLSLstd450Exp2}, + {VSIR_OP_FIRSTBIT_HI, GLSLstd450FindUMsb}, + {VSIR_OP_FIRSTBIT_LO, GLSLstd450FindILsb}, + {VSIR_OP_FIRSTBIT_SHI, GLSLstd450FindSMsb}, + {VSIR_OP_FRC, GLSLstd450Fract}, + {VSIR_OP_HCOS, GLSLstd450Cosh}, + {VSIR_OP_HSIN, GLSLstd450Sinh}, + {VSIR_OP_HTAN, GLSLstd450Tanh}, + {VSIR_OP_IMAX, GLSLstd450SMax}, + {VSIR_OP_IMIN, GLSLstd450SMin}, + {VSIR_OP_LOG, GLSLstd450Log2}, + {VSIR_OP_MAD, GLSLstd450Fma}, + {VSIR_OP_MAX, GLSLstd450NMax}, + {VSIR_OP_MIN, GLSLstd450NMin}, + {VSIR_OP_ROUND_NE, GLSLstd450RoundEven}, + {VSIR_OP_ROUND_NI, GLSLstd450Floor}, + {VSIR_OP_ROUND_PI, GLSLstd450Ceil}, + {VSIR_OP_ROUND_Z, GLSLstd450Trunc}, + {VSIR_OP_RSQ, GLSLstd450InverseSqrt}, + {VSIR_OP_SIN, GLSLstd450Sin}, + {VSIR_OP_SQRT, GLSLstd450Sqrt}, + {VSIR_OP_TAN, GLSLstd450Tan}, + {VSIR_OP_UMAX, GLSLstd450UMax}, + {VSIR_OP_UMIN, GLSLstd450UMin}, }; unsigned int i;
@@ -7880,20 +7839,22 @@ 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 == VKD3D_DATA_UINT64 && (instruction->opcode == VKD3DSIH_FIRSTBIT_HI - || instruction->opcode == VKD3DSIH_FIRSTBIT_LO || instruction->opcode == VKD3DSIH_FIRSTBIT_SHI)) + if (src[0].reg.data_type == VSIR_DATA_U64 && (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. */ - FIXME("Unsupported 64-bit source for handler %#x.\n", instruction->opcode); spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, - "64-bit source for handler %#x is not supported.", instruction->opcode); + "64-bit source for instruction "%s" (%#x) is not supported.", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return; }
glsl_inst = spirv_compiler_map_ext_glsl_instruction(instruction); if (glsl_inst == GLSLstd450Bad) { - ERR("Unexpected instruction %#x.\n", instruction->opcode); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return; }
@@ -7910,8 +7871,8 @@ static void spirv_compiler_emit_ext_glsl_instruction(struct spirv_compiler *comp val_id = vkd3d_spirv_build_op_ext_inst(builder, type_id, instr_set_id, glsl_inst, src_id, instruction->src_count);
- if (instruction->opcode == VKD3DSIH_FIRSTBIT_HI - || instruction->opcode == VKD3DSIH_FIRSTBIT_SHI) + if (instruction->opcode == VSIR_OP_FIRSTBIT_HI + || instruction->opcode == VSIR_OP_FIRSTBIT_SHI) { /* In D3D bits are numbered from the most significant bit. */ component_count = vsir_write_mask_component_count(dst->write_mask); @@ -7948,7 +7909,8 @@ static void spirv_compiler_emit_mov(struct spirv_compiler *compiler, || dst_reg_info.write_mask != src_reg_info.write_mask) goto general_implementation;
- if (vkd3d_swizzle_is_equal(dst_reg_info.write_mask, src->swizzle, src_reg_info.write_mask)) + if (dst_reg_info.write_mask == dst->write_mask + && vkd3d_swizzle_is_equal(dst_reg_info.write_mask, src->swizzle, src_reg_info.write_mask)) { dst_id = spirv_compiler_get_register_id(compiler, &dst->reg); src_id = spirv_compiler_get_register_id(compiler, &src->reg); @@ -8017,9 +7979,9 @@ static void spirv_compiler_emit_movc(struct spirv_compiler *compiler, component_count = vsir_write_mask_component_count(dst->write_mask); type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
- if (src[0].reg.data_type != VKD3D_DATA_BOOL) + if (src[0].reg.data_type != VSIR_DATA_BOOL) { - if (instruction->opcode == VKD3DSIH_CMP) + 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)); @@ -8073,9 +8035,9 @@ static void spirv_compiler_emit_dot(struct spirv_compiler *compiler, component_count = vsir_write_mask_component_count(dst->write_mask); component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
- if (instruction->opcode == VKD3DSIH_DP4) + if (instruction->opcode == VSIR_OP_DP4) write_mask = VKD3DSP_WRITEMASK_ALL; - else if (instruction->opcode == VKD3DSIH_DP3) + else if (instruction->opcode == VSIR_OP_DP3) write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1 | VKD3DSP_WRITEMASK_2; else write_mask = VKD3DSP_WRITEMASK_0 | VKD3DSP_WRITEMASK_1; @@ -8112,7 +8074,7 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, type_id = spirv_compiler_get_type_id_for_dst(compiler, dst);
src_id = spirv_compiler_emit_load_src(compiler, src, dst->write_mask); - if (src->reg.data_type == VKD3D_DATA_DOUBLE) + if (src->reg.data_type == VSIR_DATA_F64) div_id = spirv_compiler_get_constant_double_vector(compiler, 1.0, component_count); else div_id = spirv_compiler_get_constant_float_vector(compiler, 1.0f, component_count); @@ -8120,65 +8082,6 @@ static void spirv_compiler_emit_rcp(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); }
-static void spirv_compiler_emit_sincos(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) -{ - const struct vkd3d_shader_dst_param *dst_sin = &instruction->dst[0]; - const struct vkd3d_shader_dst_param *dst_cos = &instruction->dst[1]; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, src_id, sin_id = 0, cos_id = 0; - - if (dst_sin->reg.type != VKD3DSPR_NULL) - { - type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_sin); - src_id = spirv_compiler_emit_load_src(compiler, src, dst_sin->write_mask); - - sin_id = vkd3d_spirv_build_op_glsl_std450_sin(builder, type_id, src_id); - } - - if (dst_cos->reg.type != VKD3DSPR_NULL) - { - if (dst_sin->reg.type == VKD3DSPR_NULL || dst_cos->write_mask != dst_sin->write_mask) - { - type_id = spirv_compiler_get_type_id_for_dst(compiler, dst_cos); - src_id = spirv_compiler_emit_load_src(compiler, src, dst_cos->write_mask); - } - - cos_id = vkd3d_spirv_build_op_glsl_std450_cos(builder, type_id, src_id); - } - - if (sin_id) - spirv_compiler_emit_store_dst(compiler, dst_sin, sin_id); - - if (cos_id) - spirv_compiler_emit_store_dst(compiler, dst_cos, cos_id); -} - -static void spirv_compiler_emit_imul(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) -{ - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_dst_param *dst = instruction->dst; - const struct vkd3d_shader_src_param *src = instruction->src; - uint32_t type_id, val_id, src0_id, src1_id; - - if (dst[0].reg.type != VKD3DSPR_NULL) - FIXME("Extended multiplies not implemented.\n"); /* SpvOpSMulExtended/SpvOpUMulExtended */ - - if (dst[1].reg.type == VKD3DSPR_NULL) - return; - - type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]); - - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); - - val_id = vkd3d_spirv_build_op_imul(builder, type_id, src0_id, src1_id); - - spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); -} - static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -8200,67 +8103,6 @@ static void spirv_compiler_emit_imad(struct spirv_compiler *compiler, spirv_compiler_emit_store_dst(compiler, dst, val_id); }
-static void spirv_compiler_emit_int_div(struct spirv_compiler *compiler, - const struct vkd3d_shader_instruction *instruction) -{ - uint32_t type_id, val_id, src0_id, src1_id, condition_id, uint_max_id; - struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vkd3d_shader_dst_param *dst = instruction->dst; - const struct vkd3d_shader_src_param *src = instruction->src; - unsigned int component_count = 0; - SpvOp div_op, mod_op; - - div_op = instruction->opcode == VKD3DSIH_IDIV ? SpvOpSDiv : SpvOpUDiv; - mod_op = instruction->opcode == VKD3DSIH_IDIV ? SpvOpSRem : SpvOpUMod; - - if (dst[0].reg.type != VKD3DSPR_NULL) - { - component_count = vsir_write_mask_component_count(dst[0].write_mask); - type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[0]); - - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[0].write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[0].write_mask); - - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id); - if (dst[0].reg.data_type == VKD3D_DATA_UINT64) - 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, 0xffffffff, component_count); - - val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, div_op, type_id, src0_id, src1_id); - /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ - val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); - - spirv_compiler_emit_store_dst(compiler, &dst[0], val_id); - } - - if (dst[1].reg.type != VKD3DSPR_NULL) - { - if (!component_count || dst[0].write_mask != dst[1].write_mask) - { - component_count = vsir_write_mask_component_count(dst[1].write_mask); - type_id = spirv_compiler_get_type_id_for_dst(compiler, &dst[1]); - - src0_id = spirv_compiler_emit_load_src(compiler, &src[0], dst[1].write_mask); - src1_id = spirv_compiler_emit_load_src(compiler, &src[1], dst[1].write_mask); - - condition_id = spirv_compiler_emit_int_to_bool(compiler, - VKD3D_SHADER_CONDITIONAL_OP_NZ, src[1].reg.data_type, component_count, src1_id); - if (dst[1].reg.data_type == VKD3D_DATA_UINT64) - 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, 0xffffffff, component_count); - } - - val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, mod_op, type_id, src0_id, src1_id); - /* The SPIR-V spec says: "The resulting value is undefined if Operand 2 is 0." */ - val_id = vkd3d_spirv_build_op_select(builder, type_id, condition_id, val_id, uint_max_id); - - spirv_compiler_emit_store_dst(compiler, &dst[1], val_id); - } -} - static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { @@ -8282,7 +8124,7 @@ static void spirv_compiler_emit_ftoi(struct spirv_compiler *compiler,
component_count = vsir_write_mask_component_count(dst->write_mask);
- if (src->reg.data_type == VKD3D_DATA_DOUBLE) + if (src->reg.data_type == VSIR_DATA_F64) { write_mask = vkd3d_write_mask_from_component_count(component_count); int_min_id = spirv_compiler_get_constant_double_vector(compiler, -2147483648.0, component_count); @@ -8338,7 +8180,7 @@ static void spirv_compiler_emit_ftou(struct spirv_compiler *compiler,
component_count = vsir_write_mask_component_count(dst->write_mask);
- if (src->reg.data_type == VKD3D_DATA_DOUBLE) + if (src->reg.data_type == VSIR_DATA_F64) { write_mask = vkd3d_write_mask_from_component_count(component_count); zero_id = spirv_compiler_get_constant_double_vector(compiler, 0.0, component_count); @@ -8407,17 +8249,19 @@ static void spirv_compiler_emit_bitfield_instruction(struct spirv_compiler *comp
component_type = vkd3d_component_type_from_data_type(dst->reg.data_type); type_id = vkd3d_spirv_get_type_id(builder, component_type, 1); - size = (src[src_count - 1].reg.data_type == VKD3D_DATA_UINT64) ? 0x40 : 0x20; + size = (src[src_count - 1].reg.data_type == VSIR_DATA_U64) ? 0x40 : 0x20; mask_id = spirv_compiler_get_constant_uint(compiler, size - 1); size_id = spirv_compiler_get_constant_uint(compiler, size);
switch (instruction->opcode) { - case VKD3DSIH_BFI: op = SpvOpBitFieldInsert; break; - case VKD3DSIH_IBFE: op = SpvOpBitFieldSExtract; break; - case VKD3DSIH_UBFE: op = SpvOpBitFieldUExtract; break; + case VSIR_OP_BFI: op = SpvOpBitFieldInsert; break; + case VSIR_OP_IBFE: op = SpvOpBitFieldSExtract; break; + case VSIR_OP_UBFE: op = SpvOpBitFieldUExtract; break; default: - ERR("Unexpected instruction %#x.\n", instruction->opcode); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return; }
@@ -8531,26 +8375,28 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co
switch (instruction->opcode) { - case VKD3DSIH_DEQO: - case VKD3DSIH_EQO: op = SpvOpFOrdEqual; break; - case VKD3DSIH_EQU: op = SpvOpFUnordEqual; break; - case VKD3DSIH_DGEO: - case VKD3DSIH_GEO: op = SpvOpFOrdGreaterThanEqual; break; - case VKD3DSIH_GEU: op = SpvOpFUnordGreaterThanEqual; break; - case VKD3DSIH_IEQ: op = SpvOpIEqual; break; - case VKD3DSIH_IGE: op = SpvOpSGreaterThanEqual; break; - case VKD3DSIH_ILT: op = SpvOpSLessThan; break; - case VKD3DSIH_INE: op = SpvOpINotEqual; break; - case VKD3DSIH_DLT: - case VKD3DSIH_LTO: op = SpvOpFOrdLessThan; break; - case VKD3DSIH_LTU: op = SpvOpFUnordLessThan; break; - case VKD3DSIH_NEO: op = SpvOpFOrdNotEqual; break; - case VKD3DSIH_DNE: - case VKD3DSIH_NEU: op = SpvOpFUnordNotEqual; break; - case VKD3DSIH_UGE: op = SpvOpUGreaterThanEqual; break; - case VKD3DSIH_ULT: op = SpvOpULessThan; break; + case VSIR_OP_DEQO: + case VSIR_OP_EQO: op = SpvOpFOrdEqual; break; + case VSIR_OP_EQU: op = SpvOpFUnordEqual; break; + case VSIR_OP_DGEO: + case VSIR_OP_GEO: op = SpvOpFOrdGreaterThanEqual; break; + case VSIR_OP_GEU: op = SpvOpFUnordGreaterThanEqual; break; + case VSIR_OP_IEQ: op = SpvOpIEqual; break; + case VSIR_OP_IGE: op = SpvOpSGreaterThanEqual; break; + case VSIR_OP_ILT: op = SpvOpSLessThan; break; + case VSIR_OP_INE: op = SpvOpINotEqual; break; + case VSIR_OP_DLT: + case VSIR_OP_LTO: op = SpvOpFOrdLessThan; break; + case VSIR_OP_LTU: op = SpvOpFUnordLessThan; break; + case VSIR_OP_NEO: op = SpvOpFOrdNotEqual; break; + case VSIR_OP_DNE: + case VSIR_OP_NEU: op = SpvOpFUnordNotEqual; break; + case VSIR_OP_UGE: op = SpvOpUGreaterThanEqual; break; + case VSIR_OP_ULT: op = SpvOpULessThan; break; default: - ERR("Unexpected instruction %#x.\n", instruction->opcode); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return; }
@@ -8558,10 +8404,10 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co
switch (instruction->opcode) { - case VKD3DSIH_DEQO: - case VKD3DSIH_DGEO: - case VKD3DSIH_DLT: - case VKD3DSIH_DNE: + case VSIR_OP_DEQO: + case VSIR_OP_DGEO: + case VSIR_OP_DLT: + case VSIR_OP_DNE: write_mask = vkd3d_write_mask_from_component_count(component_count); break;
@@ -8576,7 +8422,7 @@ static void spirv_compiler_emit_comparison_instruction(struct spirv_compiler *co result_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream, op, type_id, src0_id, src1_id);
- if (dst->reg.data_type != VKD3D_DATA_BOOL) + if (dst->reg.data_type != VSIR_DATA_BOOL) result_id = spirv_compiler_emit_bool_to_int(compiler, component_count, result_id, true); spirv_compiler_emit_store_reg(compiler, &dst->reg, dst->write_mask, result_id); } @@ -8596,7 +8442,7 @@ static void spirv_compiler_emit_orderedness_instruction(struct spirv_compiler *c src0_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src0_id); src1_id = vkd3d_spirv_build_op_is_nan(builder, type_id, src1_id); val_id = vkd3d_spirv_build_op_logical_or(builder, type_id, src0_id, src1_id); - if (instruction->opcode == VKD3DSIH_ORD) + if (instruction->opcode == VSIR_OP_ORD) val_id = vkd3d_spirv_build_op_logical_not(builder, type_id, val_id); spirv_compiler_emit_store_dst(compiler, dst, val_id); } @@ -8613,8 +8459,8 @@ static void spirv_compiler_emit_float_comparison_instruction(struct spirv_compil
switch (instruction->opcode) { - case VKD3DSIH_SLT: op = SpvOpFOrdLessThan; break; - case VKD3DSIH_SGE: op = SpvOpFOrdGreaterThanEqual; break; + case VSIR_OP_SLT: op = SpvOpFOrdLessThan; break; + case VSIR_OP_SGE: op = SpvOpFOrdGreaterThanEqual; break; default: vkd3d_unreachable(); } @@ -8757,7 +8603,7 @@ static void spirv_compiler_emit_discard(struct spirv_compiler *compiler, * a mismatch between the VSIR structure and the SPIR-V one, which would cause problems if * structurisation is necessary. Therefore we emit it as a function call. */ condition_id = spirv_compiler_emit_load_src(compiler, src, VKD3DSP_WRITEMASK_0); - if (src->reg.data_type != VKD3D_DATA_BOOL) + if (src->reg.data_type != VSIR_DATA_BOOL) condition_id = spirv_compiler_emit_int_to_bool(compiler, instruction->flags, src->reg.data_type, 1, condition_id); else if (instruction->flags & VKD3D_SHADER_CONDITIONAL_OP_Z) @@ -8830,7 +8676,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, if (instruction->src_count == 3) spirv_compiler_emit_merge(compiler, src[1].reg.idx[0].offset, src[2].reg.idx[0].offset); else - ERR("Invalid branch with %u sources.\n", instruction->src_count); + ERR("Invalid branch with %zu sources.\n", instruction->src_count); } vkd3d_spirv_build_op_branch(builder, spirv_compiler_get_label_id(compiler, src[0].reg.idx[0].offset)); return; @@ -8844,7 +8690,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, }
condition_id = spirv_compiler_emit_load_src(compiler, &src[0], VKD3DSP_WRITEMASK_0); - if (src[0].reg.data_type != VKD3D_DATA_BOOL) + if (src[0].reg.data_type != VSIR_DATA_BOOL) condition_id = spirv_compiler_emit_int_to_bool(compiler, VKD3D_SHADER_CONDITIONAL_OP_NZ, src[0].reg.data_type, 1, condition_id); /* Emit the merge immediately before the branch instruction. */ @@ -8852,7 +8698,7 @@ static void spirv_compiler_emit_branch(struct spirv_compiler *compiler, spirv_compiler_emit_merge(compiler, src[3].reg.idx[0].offset, (instruction->src_count > 4) ? src[4].reg.idx[0].offset : 0); else - ERR("Invalid branch with %u sources.\n", instruction->src_count); + ERR("Invalid branch with %zu sources.\n", instruction->src_count); vkd3d_spirv_build_op_branch_conditional(builder, condition_id, spirv_compiler_get_label_id(compiler, src[1].reg.idx[0].offset), spirv_compiler_get_label_id(compiler, src[2].reg.idx[0].offset)); @@ -8917,12 +8763,12 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile } deriv_instructions[] = { - {VKD3DSIH_DSX, SpvOpDPdx}, - {VKD3DSIH_DSX_COARSE, SpvOpDPdxCoarse, true}, - {VKD3DSIH_DSX_FINE, SpvOpDPdxFine, true}, - {VKD3DSIH_DSY, SpvOpDPdy}, - {VKD3DSIH_DSY_COARSE, SpvOpDPdyCoarse, true}, - {VKD3DSIH_DSY_FINE, SpvOpDPdyFine, true}, + {VSIR_OP_DSX, SpvOpDPdx}, + {VSIR_OP_DSX_COARSE, SpvOpDPdxCoarse, true}, + {VSIR_OP_DSX_FINE, SpvOpDPdxFine, true}, + {VSIR_OP_DSY, SpvOpDPdy}, + {VSIR_OP_DSY_COARSE, SpvOpDPdyCoarse, true}, + {VSIR_OP_DSY_FINE, SpvOpDPdyFine, true}, };
info = NULL; @@ -8936,7 +8782,9 @@ static void spirv_compiler_emit_deriv_instruction(struct spirv_compiler *compile } if (!info) { - ERR("Unexpected instruction %#x.\n", instruction->opcode); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return; }
@@ -9147,7 +8995,7 @@ static void spirv_compiler_emit_ld(struct spirv_compiler *compiler, uint32_t coordinate_mask; bool multisample;
- multisample = instruction->opcode == VKD3DSIH_LD2DMS; + multisample = instruction->opcode == VSIR_OP_LD2DMS;
spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE);
@@ -9228,16 +9076,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler,
switch (instruction->opcode) { - case VKD3DSIH_SAMPLE: + case VSIR_OP_SAMPLE: op = SpvOpImageSampleImplicitLod; break; - case VKD3DSIH_SAMPLE_B: + case VSIR_OP_SAMPLE_B: op = SpvOpImageSampleImplicitLod; operands_mask |= SpvImageOperandsBiasMask; image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); break; - case VKD3DSIH_SAMPLE_GRAD: + case VSIR_OP_SAMPLE_GRAD: op = SpvOpImageSampleExplicitLod; operands_mask |= SpvImageOperandsGradMask; component_count = image.resource_type_info->coordinate_component_count - image.resource_type_info->arrayed; @@ -9247,14 +9095,16 @@ static void spirv_compiler_emit_sample(struct spirv_compiler *compiler, image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[4], coordinate_mask); break; - case VKD3DSIH_SAMPLE_LOD: + case VSIR_OP_SAMPLE_LOD: op = SpvOpImageSampleExplicitLod; operands_mask |= SpvImageOperandsLodMask; image_operands[image_operand_count++] = spirv_compiler_emit_load_src(compiler, &src[3], VKD3DSP_WRITEMASK_0); break; default: - ERR("Unexpected instruction %#x.\n", instruction->opcode); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return; }
@@ -9288,7 +9138,7 @@ static void spirv_compiler_emit_sample_c(struct spirv_compiler *compiler, uint32_t image_operands[2]; SpvOp op;
- if (instruction->opcode == VKD3DSIH_SAMPLE_C_LZ) + if (instruction->opcode == VSIR_OP_SAMPLE_C_LZ) { op = SpvOpImageSampleDrefExplicitLod; operands_mask |= SpvImageOperandsLodMask; @@ -9338,12 +9188,12 @@ static void spirv_compiler_emit_gather4(struct spirv_compiler *compiler, uint32_t coordinate_mask; bool extended_offset;
- if (instruction->opcode == VKD3DSIH_GATHER4_C - || instruction->opcode == VKD3DSIH_GATHER4_PO_C) + if (instruction->opcode == VSIR_OP_GATHER4_C + || instruction->opcode == VSIR_OP_GATHER4_PO_C) image_flags |= VKD3D_IMAGE_FLAG_DEPTH;
- extended_offset = instruction->opcode == VKD3DSIH_GATHER4_PO - || instruction->opcode == VKD3DSIH_GATHER4_PO_C; + extended_offset = instruction->opcode == VSIR_OP_GATHER4_PO + || instruction->opcode == VSIR_OP_GATHER4_PO_C;
addr = &src[0]; offset = extended_offset ? &src[1] : NULL; @@ -9597,7 +9447,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
data = &src[instruction->src_count - 1]; - VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT); + VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32); val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
component_count = vsir_write_mask_component_count(dst->write_mask); @@ -9625,7 +9475,7 @@ static void spirv_compiler_emit_store_uav_raw_structured(struct spirv_compiler * type_id, image.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
data = &src[instruction->src_count - 1]; - VKD3D_ASSERT(data->reg.data_type == VKD3D_DATA_UINT); + VKD3D_ASSERT(data->reg.data_type == VSIR_DATA_U32); val_id = spirv_compiler_emit_load_src(compiler, data, dst->write_mask);
component_count = vsir_write_mask_component_count(dst->write_mask); @@ -9668,7 +9518,7 @@ static void spirv_compiler_emit_store_tgsm(struct spirv_compiler *compiler, type_id, reg_info.structure_stride, &src[0], VKD3DSP_WRITEMASK_0, &src[1], VKD3DSP_WRITEMASK_0);
data = src[instruction->src_count - 1]; - data.reg.data_type = VKD3D_DATA_UINT; + data.reg.data_type = VSIR_DATA_U32; val_id = spirv_compiler_emit_load_src(compiler, &data, dst->write_mask);
component_count = vsir_write_mask_component_count(dst->write_mask); @@ -9801,7 +9651,7 @@ static void spirv_compiler_emit_uav_counter_instruction(struct spirv_compiler *c uint32_t operands[3]; SpvOp op;
- op = instruction->opcode == VKD3DSIH_IMM_ATOMIC_ALLOC + op = instruction->opcode == VSIR_OP_IMM_ATOMIC_ALLOC ? SpvOpAtomicIIncrement : SpvOpAtomicIDecrement;
resource_symbol = spirv_compiler_find_resource(compiler, &src->reg); @@ -9872,25 +9722,25 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins } atomic_ops[] = { - {VKD3DSIH_ATOMIC_AND, SpvOpAtomicAnd}, - {VKD3DSIH_ATOMIC_CMP_STORE, SpvOpAtomicCompareExchange}, - {VKD3DSIH_ATOMIC_IADD, SpvOpAtomicIAdd}, - {VKD3DSIH_ATOMIC_IMAX, SpvOpAtomicSMax}, - {VKD3DSIH_ATOMIC_IMIN, SpvOpAtomicSMin}, - {VKD3DSIH_ATOMIC_OR, SpvOpAtomicOr}, - {VKD3DSIH_ATOMIC_UMAX, SpvOpAtomicUMax}, - {VKD3DSIH_ATOMIC_UMIN, SpvOpAtomicUMin}, - {VKD3DSIH_ATOMIC_XOR, SpvOpAtomicXor}, - {VKD3DSIH_IMM_ATOMIC_AND, SpvOpAtomicAnd}, - {VKD3DSIH_IMM_ATOMIC_CMP_EXCH, SpvOpAtomicCompareExchange}, - {VKD3DSIH_IMM_ATOMIC_EXCH, SpvOpAtomicExchange}, - {VKD3DSIH_IMM_ATOMIC_IADD, SpvOpAtomicIAdd}, - {VKD3DSIH_IMM_ATOMIC_IMAX, SpvOpAtomicSMax}, - {VKD3DSIH_IMM_ATOMIC_IMIN, SpvOpAtomicSMin}, - {VKD3DSIH_IMM_ATOMIC_OR, SpvOpAtomicOr}, - {VKD3DSIH_IMM_ATOMIC_UMAX, SpvOpAtomicUMax}, - {VKD3DSIH_IMM_ATOMIC_UMIN, SpvOpAtomicUMin}, - {VKD3DSIH_IMM_ATOMIC_XOR, SpvOpAtomicXor}, + {VSIR_OP_ATOMIC_AND, SpvOpAtomicAnd}, + {VSIR_OP_ATOMIC_CMP_STORE, SpvOpAtomicCompareExchange}, + {VSIR_OP_ATOMIC_IADD, SpvOpAtomicIAdd}, + {VSIR_OP_ATOMIC_IMAX, SpvOpAtomicSMax}, + {VSIR_OP_ATOMIC_IMIN, SpvOpAtomicSMin}, + {VSIR_OP_ATOMIC_OR, SpvOpAtomicOr}, + {VSIR_OP_ATOMIC_UMAX, SpvOpAtomicUMax}, + {VSIR_OP_ATOMIC_UMIN, SpvOpAtomicUMin}, + {VSIR_OP_ATOMIC_XOR, SpvOpAtomicXor}, + {VSIR_OP_IMM_ATOMIC_AND, SpvOpAtomicAnd}, + {VSIR_OP_IMM_ATOMIC_CMP_EXCH, SpvOpAtomicCompareExchange}, + {VSIR_OP_IMM_ATOMIC_EXCH, SpvOpAtomicExchange}, + {VSIR_OP_IMM_ATOMIC_IADD, SpvOpAtomicIAdd}, + {VSIR_OP_IMM_ATOMIC_IMAX, SpvOpAtomicSMax}, + {VSIR_OP_IMM_ATOMIC_IMIN, SpvOpAtomicSMin}, + {VSIR_OP_IMM_ATOMIC_OR, SpvOpAtomicOr}, + {VSIR_OP_IMM_ATOMIC_UMAX, SpvOpAtomicUMax}, + {VSIR_OP_IMM_ATOMIC_UMIN, SpvOpAtomicUMin}, + {VSIR_OP_IMM_ATOMIC_XOR, SpvOpAtomicXor}, }; unsigned int i;
@@ -9905,7 +9755,7 @@ static SpvOp spirv_compiler_map_atomic_instruction(const struct vkd3d_shader_ins
static bool is_imm_atomic_instruction(enum vkd3d_shader_opcode opcode) { - return VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR; + return VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR; }
static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compiler, @@ -9935,7 +9785,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil op = spirv_compiler_map_atomic_instruction(instruction); if (op == SpvOpMax) { - ERR("Unexpected instruction %#x.\n", instruction->opcode); + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, + "Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); return; }
@@ -10014,9 +9866,9 @@ static void spirv_compiler_emit_atomic_instruction(struct spirv_compiler *compil
if (instruction->flags & VKD3DARF_VOLATILE) { - WARN("Ignoring 'volatile' attribute.\n"); spirv_compiler_warning(compiler, VKD3D_SHADER_WARNING_SPV_IGNORING_FLAG, - "Ignoring the 'volatile' attribute flag for atomic instruction %#x.", instruction->opcode); + "Ignoring the 'volatile' attribute flag for atomic instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); }
memory_semantic = (instruction->flags & VKD3DARF_SEQ_CST) @@ -10094,16 +9946,20 @@ static void spirv_compiler_emit_bufinfo(struct spirv_compiler *compiler, static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { + enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; uint32_t type_id, lod_id, val_id, miplevel_count_id; - enum vkd3d_shader_component_type component_type; uint32_t constituents[VKD3D_VEC4_SIZE]; unsigned int i, size_component_count; struct vkd3d_shader_image image; bool supports_mipmaps;
+ if (instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW)) + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled resinfo flags %#x.\n", + instruction->flags & ~(VKD3DSI_RESINFO_UINT | VKD3DSI_PRECISE_XYZW)); + vkd3d_spirv_enable_capability(builder, SpvCapabilityImageQuery);
spirv_compiler_prepare_image(compiler, &image, &src[1].reg, NULL, VKD3D_IMAGE_FLAG_NONE); @@ -10135,22 +9991,13 @@ static void spirv_compiler_emit_resinfo(struct spirv_compiler *compiler, val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, i + 2);
- component_type = VKD3D_SHADER_COMPONENT_FLOAT; - - type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - if (instruction->flags == VKD3DSI_RESINFO_UINT) - { - /* SSA registers must match the specified result type. */ - if (!register_is_ssa(&dst->reg)) - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - else - component_type = VKD3D_SHADER_COMPONENT_UINT; - } - else + if (!(instruction->flags & VKD3DSI_RESINFO_UINT)) { - if (instruction->flags) - FIXME("Unhandled flags %#x.\n", instruction->flags); + component_type = VKD3D_SHADER_COMPONENT_FLOAT; + type_id = vkd3d_spirv_get_type_id(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); } val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, component_type, src[1].swizzle, dst->write_mask); @@ -10168,7 +10015,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co if (src->reg.type == VKD3DSPR_RASTERIZER) { val_id = spirv_compiler_emit_shader_parameter(compiler, - VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VKD3D_DATA_UINT, 1); + VKD3D_SHADER_PARAMETER_NAME_RASTERIZER_SAMPLE_COUNT, VSIR_DATA_U32, 1); } else { @@ -10185,6 +10032,7 @@ static uint32_t spirv_compiler_emit_query_sample_count(struct spirv_compiler *co static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, const struct vkd3d_shader_instruction *instruction) { + enum vkd3d_shader_component_type component_type = VKD3D_SHADER_COMPONENT_UINT; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; const struct vkd3d_shader_dst_param *dst = instruction->dst; const struct vkd3d_shader_src_param *src = instruction->src; @@ -10192,6 +10040,10 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, uint32_t type_id, val_id; unsigned int i;
+ if (instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW)) + spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_NOT_IMPLEMENTED, "Unhandled sample info flags %#x.\n", + instruction->flags & ~(VKD3DSI_SAMPLE_INFO_UINT | VKD3DSI_PRECISE_XYZW)); + val_id = spirv_compiler_emit_query_sample_count(compiler, src);
constituents[0] = val_id; @@ -10200,20 +10052,16 @@ static void spirv_compiler_emit_sample_info(struct spirv_compiler *compiler, type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_UINT, VKD3D_VEC4_SIZE); val_id = vkd3d_spirv_build_op_composite_construct(builder, type_id, constituents, VKD3D_VEC4_SIZE);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_SHADER_COMPONENT_FLOAT, VKD3D_VEC4_SIZE); - if (instruction->flags == VKD3DSI_SAMPLE_INFO_UINT) - { - val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id); - } - else + if (!(instruction->flags & VKD3DSI_SAMPLE_INFO_UINT)) { - if (instruction->flags) - FIXME("Unhandled flags %#x.\n", instruction->flags); + component_type = VKD3D_SHADER_COMPONENT_FLOAT; + type_id = vkd3d_spirv_get_type_id(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); } - val_id = spirv_compiler_emit_swizzle(compiler, val_id, VKD3DSP_WRITEMASK_ALL, - VKD3D_SHADER_COMPONENT_FLOAT, src->swizzle, dst->write_mask); + component_type, src->swizzle, dst->write_mask);
spirv_compiler_emit_store_dst(compiler, dst, val_id); } @@ -10340,13 +10188,13 @@ static void spirv_compiler_emit_eval_attrib(struct spirv_compiler *compiler,
src_ids[src_count++] = register_info.id;
- if (instruction->opcode == VKD3DSIH_EVAL_CENTROID) + if (instruction->opcode == VSIR_OP_EVAL_CENTROID) { op = GLSLstd450InterpolateAtCentroid; } else { - VKD3D_ASSERT(instruction->opcode == VKD3DSIH_EVAL_SAMPLE_INDEX); + VKD3D_ASSERT(instruction->opcode == VSIR_OP_EVAL_SAMPLE_INDEX); op = GLSLstd450InterpolateAtSample; src_ids[src_count++] = spirv_compiler_emit_load_src(compiler, &src[1], VKD3DSP_WRITEMASK_0); } @@ -10428,7 +10276,7 @@ static void spirv_compiler_emit_emit_stream(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int stream_idx;
- if (instruction->opcode == VKD3DSIH_EMIT_STREAM) + if (instruction->opcode == VSIR_OP_EMIT_STREAM) stream_idx = instruction->src[0].reg.idx[0].offset; else stream_idx = 0; @@ -10449,7 +10297,7 @@ static void spirv_compiler_emit_cut_stream(struct spirv_compiler *compiler, struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; unsigned int stream_idx;
- if (instruction->opcode == VKD3DSIH_CUT_STREAM) + if (instruction->opcode == VSIR_OP_CUT_STREAM) stream_idx = instruction->src[0].reg.idx[0].offset; else stream_idx = 0; @@ -10467,11 +10315,11 @@ static uint32_t map_quad_read_across_direction(enum vkd3d_shader_opcode opcode) { switch (opcode) { - case VKD3DSIH_QUAD_READ_ACROSS_X: + case VSIR_OP_QUAD_READ_ACROSS_X: return 0; - case VKD3DSIH_QUAD_READ_ACROSS_Y: + case VSIR_OP_QUAD_READ_ACROSS_Y: return 1; - case VKD3DSIH_QUAD_READ_ACROSS_D: + case VSIR_OP_QUAD_READ_ACROSS_D: return 2; default: vkd3d_unreachable(); @@ -10488,7 +10336,7 @@ static void spirv_compiler_emit_quad_read_across(struct spirv_compiler *compiler
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, VKD3D_DATA_UINT, 1); + direction_type_id = vkd3d_spirv_get_type_id_for_data_type(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); @@ -10526,11 +10374,11 @@ static SpvOp map_wave_bool_op(enum vkd3d_shader_opcode opcode) { switch (opcode) { - case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL: + case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL: return SpvOpGroupNonUniformAllEqual; - case VKD3DSIH_WAVE_ALL_TRUE: + case VSIR_OP_WAVE_ALL_TRUE: return SpvOpGroupNonUniformAll; - case VKD3DSIH_WAVE_ANY_TRUE: + case VSIR_OP_WAVE_ANY_TRUE: return SpvOpGroupNonUniformAny; default: vkd3d_unreachable(); @@ -10584,27 +10432,27 @@ static SpvOp map_wave_alu_op(enum vkd3d_shader_opcode opcode, bool is_float) { switch (opcode) { - case VKD3DSIH_WAVE_ACTIVE_BIT_AND: + case VSIR_OP_WAVE_ACTIVE_BIT_AND: return SpvOpGroupNonUniformBitwiseAnd; - case VKD3DSIH_WAVE_ACTIVE_BIT_OR: + case VSIR_OP_WAVE_ACTIVE_BIT_OR: return SpvOpGroupNonUniformBitwiseOr; - case VKD3DSIH_WAVE_ACTIVE_BIT_XOR: + case VSIR_OP_WAVE_ACTIVE_BIT_XOR: return SpvOpGroupNonUniformBitwiseXor; - case VKD3DSIH_WAVE_OP_ADD: + case VSIR_OP_WAVE_OP_ADD: return is_float ? SpvOpGroupNonUniformFAdd : SpvOpGroupNonUniformIAdd; - case VKD3DSIH_WAVE_OP_IMAX: + case VSIR_OP_WAVE_OP_IMAX: return SpvOpGroupNonUniformSMax; - case VKD3DSIH_WAVE_OP_IMIN: + case VSIR_OP_WAVE_OP_IMIN: return SpvOpGroupNonUniformSMin; - case VKD3DSIH_WAVE_OP_MAX: + case VSIR_OP_WAVE_OP_MAX: return SpvOpGroupNonUniformFMax; - case VKD3DSIH_WAVE_OP_MIN: + case VSIR_OP_WAVE_OP_MIN: return SpvOpGroupNonUniformFMin; - case VKD3DSIH_WAVE_OP_MUL: + case VSIR_OP_WAVE_OP_MUL: return is_float ? SpvOpGroupNonUniformFMul : SpvOpGroupNonUniformIMul; - case VKD3DSIH_WAVE_OP_UMAX: + case VSIR_OP_WAVE_OP_UMAX: return SpvOpGroupNonUniformUMax; - case VKD3DSIH_WAVE_OP_UMIN: + case VSIR_OP_WAVE_OP_UMIN: return SpvOpGroupNonUniformUMin; default: vkd3d_unreachable(); @@ -10643,7 +10491,7 @@ static void spirv_compiler_emit_wave_bit_count(struct spirv_compiler *compiler, SpvGroupOperation group_op; uint32_t type_id, val_id;
- group_op = (instruction->opcode == VKD3DSIH_WAVE_PREFIX_BIT_COUNT) ? SpvGroupOperationExclusiveScan + group_op = (instruction->opcode == VSIR_OP_WAVE_PREFIX_BIT_COUNT) ? SpvGroupOperationExclusiveScan : SpvGroupOperationReduce;
val_id = spirv_compiler_emit_group_nonuniform_ballot(compiler, instruction->src); @@ -10728,372 +10576,379 @@ static int spirv_compiler_handle_instruction(struct spirv_compiler *compiler, int ret = VKD3D_OK;
compiler->location = instruction->location; + /* radeonsi from Mesa 20.3.5 seems to get confused by OpLine instructions + * before OpFunction, seemingly causing it to fail to find the entry + * point. As far as I can tell that's not prohibited, and the validation + * layers don't seem to mind either, but perhaps it's best avoided. + * Notably, radv from the same Mesa version doesn't mind either. + * + * This is an issue for hull shaders in particular, because we don't go + * through vkd3d_spirv_builder_begin_main_function() before getting here + * in that case. */ + if (!compiler->strip_debug && compiler->spirv_builder.function_stream.word_count) + vkd3d_spirv_build_op_line(&compiler->spirv_builder, &instruction->location);
switch (instruction->opcode) { - case VKD3DSIH_DCL_INDEXABLE_TEMP: + case VSIR_OP_DCL_INDEXABLE_TEMP: spirv_compiler_emit_dcl_indexable_temp(compiler, instruction); break; - case VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER: + case VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER: spirv_compiler_emit_dcl_immediate_constant_buffer(compiler, instruction); break; - case VKD3DSIH_DCL_TGSM_RAW: + case VSIR_OP_DCL_TGSM_RAW: spirv_compiler_emit_dcl_tgsm_raw(compiler, instruction); break; - case VKD3DSIH_DCL_TGSM_STRUCTURED: + case VSIR_OP_DCL_TGSM_STRUCTURED: spirv_compiler_emit_dcl_tgsm_structured(compiler, instruction); break; - case VKD3DSIH_DCL_STREAM: + case VSIR_OP_DCL_STREAM: spirv_compiler_emit_dcl_stream(compiler, instruction); break; - case VKD3DSIH_DCL_VERTICES_OUT: + case VSIR_OP_DCL_VERTICES_OUT: spirv_compiler_emit_output_vertex_count(compiler, instruction); break; - case VKD3DSIH_DCL_INPUT_PRIMITIVE: + case VSIR_OP_DCL_INPUT_PRIMITIVE: spirv_compiler_emit_dcl_input_primitive(compiler, instruction); break; - case VKD3DSIH_DCL_OUTPUT_TOPOLOGY: + case VSIR_OP_DCL_OUTPUT_TOPOLOGY: spirv_compiler_emit_dcl_output_topology(compiler, instruction); break; - case VKD3DSIH_DCL_GS_INSTANCES: + case VSIR_OP_DCL_GS_INSTANCES: spirv_compiler_emit_dcl_gs_instances(compiler, instruction); break; - case VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT: + case VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT: spirv_compiler_emit_output_vertex_count(compiler, instruction); break; - case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: + case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: spirv_compiler_emit_tessellator_output_primitive(compiler, instruction->declaration.tessellator_output_primitive); break; - case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING: + case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: spirv_compiler_emit_tessellator_partitioning(compiler, instruction->declaration.tessellator_partitioning); break; - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_HS_JOIN_PHASE: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_HS_JOIN_PHASE: spirv_compiler_enter_shader_phase(compiler, instruction); break; - case VKD3DSIH_DMOV: - case VKD3DSIH_MOV: + case VSIR_OP_DMOV: + case VSIR_OP_MOV: spirv_compiler_emit_mov(compiler, instruction); break; - case VKD3DSIH_DMOVC: - case VKD3DSIH_MOVC: - case VKD3DSIH_CMP: + case VSIR_OP_DMOVC: + case VSIR_OP_MOVC: + case VSIR_OP_CMP: spirv_compiler_emit_movc(compiler, instruction); break; - case VKD3DSIH_SWAPC: + case VSIR_OP_SWAPC: spirv_compiler_emit_swapc(compiler, instruction); break; - case VKD3DSIH_ADD: - case VKD3DSIH_AND: - case VKD3DSIH_BFREV: - case VKD3DSIH_COUNTBITS: - case VKD3DSIH_DADD: - case VKD3DSIH_DDIV: - case VKD3DSIH_DIV: - case VKD3DSIH_DMUL: - case VKD3DSIH_FREM: - case VKD3DSIH_FTOD: - case VKD3DSIH_IADD: - case VKD3DSIH_INEG: - case VKD3DSIH_ISHL: - case VKD3DSIH_ISHR: - case VKD3DSIH_ISINF: - case VKD3DSIH_ISNAN: - case VKD3DSIH_ITOD: - case VKD3DSIH_ITOF: - case VKD3DSIH_ITOI: - case VKD3DSIH_MUL: - case VKD3DSIH_NOT: - case VKD3DSIH_OR: - case VKD3DSIH_USHR: - case VKD3DSIH_UTOD: - case VKD3DSIH_UTOF: - case VKD3DSIH_UTOU: - case VKD3DSIH_XOR: + case VSIR_OP_ADD: + case VSIR_OP_AND: + case VSIR_OP_BFREV: + case VSIR_OP_COUNTBITS: + case VSIR_OP_DADD: + case VSIR_OP_DDIV: + case VSIR_OP_DIV: + case VSIR_OP_DMUL: + case VSIR_OP_FREM: + case VSIR_OP_FTOD: + case VSIR_OP_IADD: + case VSIR_OP_IDIV: + case VSIR_OP_IMUL_LOW: + case VSIR_OP_INEG: + case VSIR_OP_IREM: + case VSIR_OP_ISHL: + case VSIR_OP_ISHR: + case VSIR_OP_ISINF: + case VSIR_OP_ISNAN: + case VSIR_OP_ITOD: + case VSIR_OP_ITOF: + case VSIR_OP_ITOI: + case VSIR_OP_MUL: + case VSIR_OP_NOT: + case VSIR_OP_OR: + case VSIR_OP_UDIV_SIMPLE: + case VSIR_OP_UREM: + case VSIR_OP_USHR: + case VSIR_OP_UTOD: + case VSIR_OP_UTOF: + case VSIR_OP_UTOU: + case VSIR_OP_XOR: ret = spirv_compiler_emit_alu_instruction(compiler, instruction); break; - case VKD3DSIH_ISFINITE: + case VSIR_OP_ISFINITE: spirv_compiler_emit_isfinite(compiler, instruction); break; - case VKD3DSIH_ABS: - case VKD3DSIH_ACOS: - case VKD3DSIH_ASIN: - case VKD3DSIH_ATAN: - case VKD3DSIH_HCOS: - case VKD3DSIH_HSIN: - case VKD3DSIH_HTAN: - case VKD3DSIH_DFMA: - case VKD3DSIH_DMAX: - case VKD3DSIH_DMIN: - case VKD3DSIH_EXP: - case VKD3DSIH_FIRSTBIT_HI: - case VKD3DSIH_FIRSTBIT_LO: - case VKD3DSIH_FIRSTBIT_SHI: - case VKD3DSIH_FRC: - case VKD3DSIH_IMAX: - case VKD3DSIH_IMIN: - case VKD3DSIH_LOG: - case VKD3DSIH_MAD: - case VKD3DSIH_MAX: - case VKD3DSIH_MIN: - case VKD3DSIH_ROUND_NE: - case VKD3DSIH_ROUND_NI: - case VKD3DSIH_ROUND_PI: - case VKD3DSIH_ROUND_Z: - case VKD3DSIH_RSQ: - case VKD3DSIH_SQRT: - case VKD3DSIH_TAN: - case VKD3DSIH_UMAX: - case VKD3DSIH_UMIN: + case VSIR_OP_ABS: + case VSIR_OP_ACOS: + case VSIR_OP_ASIN: + case VSIR_OP_ATAN: + case VSIR_OP_COS: + case VSIR_OP_HCOS: + case VSIR_OP_HSIN: + case VSIR_OP_HTAN: + case VSIR_OP_DFMA: + case VSIR_OP_DMAX: + case VSIR_OP_DMIN: + case VSIR_OP_EXP: + case VSIR_OP_FIRSTBIT_HI: + case VSIR_OP_FIRSTBIT_LO: + case VSIR_OP_FIRSTBIT_SHI: + case VSIR_OP_FRC: + case VSIR_OP_IMAX: + case VSIR_OP_IMIN: + case VSIR_OP_LOG: + case VSIR_OP_MAD: + case VSIR_OP_MAX: + case VSIR_OP_MIN: + case VSIR_OP_ROUND_NE: + case VSIR_OP_ROUND_NI: + case VSIR_OP_ROUND_PI: + case VSIR_OP_ROUND_Z: + case VSIR_OP_RSQ: + case VSIR_OP_SIN: + case VSIR_OP_SQRT: + case VSIR_OP_TAN: + case VSIR_OP_UMAX: + case VSIR_OP_UMIN: spirv_compiler_emit_ext_glsl_instruction(compiler, instruction); break; - case VKD3DSIH_DP4: - case VKD3DSIH_DP3: - case VKD3DSIH_DP2: + case VSIR_OP_DP4: + case VSIR_OP_DP3: + case VSIR_OP_DP2: spirv_compiler_emit_dot(compiler, instruction); break; - case VKD3DSIH_DRCP: - case VKD3DSIH_RCP: + case VSIR_OP_DRCP: + case VSIR_OP_RCP: spirv_compiler_emit_rcp(compiler, instruction); break; - case VKD3DSIH_SINCOS: - spirv_compiler_emit_sincos(compiler, instruction); - break; - case VKD3DSIH_IMUL: - case VKD3DSIH_UMUL: - spirv_compiler_emit_imul(compiler, instruction); - break; - case VKD3DSIH_IMAD: + case VSIR_OP_IMAD: spirv_compiler_emit_imad(compiler, instruction); break; - case VKD3DSIH_IDIV: - case VKD3DSIH_UDIV: - spirv_compiler_emit_int_div(compiler, instruction); - break; - case VKD3DSIH_DTOI: - case VKD3DSIH_FTOI: + case VSIR_OP_DTOI: + case VSIR_OP_FTOI: spirv_compiler_emit_ftoi(compiler, instruction); break; - case VKD3DSIH_DTOU: - case VKD3DSIH_FTOU: + case VSIR_OP_DTOU: + case VSIR_OP_FTOU: spirv_compiler_emit_ftou(compiler, instruction); break; - case VKD3DSIH_DTOF: + case VSIR_OP_DTOF: spirv_compiler_emit_dtof(compiler, instruction); break; - case VKD3DSIH_DEQO: - case VKD3DSIH_DGEO: - case VKD3DSIH_DLT: - case VKD3DSIH_DNE: - case VKD3DSIH_EQO: - case VKD3DSIH_EQU: - case VKD3DSIH_GEO: - case VKD3DSIH_GEU: - case VKD3DSIH_IEQ: - case VKD3DSIH_IGE: - case VKD3DSIH_ILT: - case VKD3DSIH_INE: - case VKD3DSIH_LTO: - case VKD3DSIH_LTU: - case VKD3DSIH_NEO: - case VKD3DSIH_NEU: - case VKD3DSIH_UGE: - case VKD3DSIH_ULT: + case VSIR_OP_DEQO: + case VSIR_OP_DGEO: + case VSIR_OP_DLT: + case VSIR_OP_DNE: + case VSIR_OP_EQO: + case VSIR_OP_EQU: + case VSIR_OP_GEO: + case VSIR_OP_GEU: + case VSIR_OP_IEQ: + case VSIR_OP_IGE: + case VSIR_OP_ILT: + case VSIR_OP_INE: + case VSIR_OP_LTO: + case VSIR_OP_LTU: + case VSIR_OP_NEO: + case VSIR_OP_NEU: + case VSIR_OP_UGE: + case VSIR_OP_ULT: spirv_compiler_emit_comparison_instruction(compiler, instruction); break; - case VKD3DSIH_ORD: - case VKD3DSIH_UNO: + case VSIR_OP_ORD: + case VSIR_OP_UNO: spirv_compiler_emit_orderedness_instruction(compiler, instruction); break; - case VKD3DSIH_SLT: - case VKD3DSIH_SGE: + case VSIR_OP_SLT: + case VSIR_OP_SGE: spirv_compiler_emit_float_comparison_instruction(compiler, instruction); break; - case VKD3DSIH_BFI: - case VKD3DSIH_IBFE: - case VKD3DSIH_UBFE: + case VSIR_OP_BFI: + case VSIR_OP_IBFE: + case VSIR_OP_UBFE: spirv_compiler_emit_bitfield_instruction(compiler, instruction); break; - case VKD3DSIH_F16TOF32: + case VSIR_OP_F16TOF32: spirv_compiler_emit_f16tof32(compiler, instruction); break; - case VKD3DSIH_F32TOF16: + case VSIR_OP_F32TOF16: spirv_compiler_emit_f32tof16(compiler, instruction); break; - case VKD3DSIH_RET: + case VSIR_OP_RET: spirv_compiler_emit_return(compiler, instruction); break; - case VKD3DSIH_RETP: + case VSIR_OP_RETP: spirv_compiler_emit_retc(compiler, instruction); break; - case VKD3DSIH_DISCARD: + case VSIR_OP_DISCARD: spirv_compiler_emit_discard(compiler, instruction); break; - case VKD3DSIH_LABEL: + case VSIR_OP_LABEL: spirv_compiler_emit_label(compiler, instruction); break; - case VKD3DSIH_BRANCH: + case VSIR_OP_BRANCH: spirv_compiler_emit_branch(compiler, instruction); break; - case VKD3DSIH_SWITCH_MONOLITHIC: + case VSIR_OP_SWITCH_MONOLITHIC: spirv_compiler_emit_switch(compiler, instruction); break; - case VKD3DSIH_DSX: - case VKD3DSIH_DSX_COARSE: - case VKD3DSIH_DSX_FINE: - case VKD3DSIH_DSY: - case VKD3DSIH_DSY_COARSE: - case VKD3DSIH_DSY_FINE: + case VSIR_OP_DSX: + case VSIR_OP_DSX_COARSE: + case VSIR_OP_DSX_FINE: + case VSIR_OP_DSY: + case VSIR_OP_DSY_COARSE: + case VSIR_OP_DSY_FINE: spirv_compiler_emit_deriv_instruction(compiler, instruction); break; - case VKD3DSIH_LD2DMS: - case VKD3DSIH_LD: + case VSIR_OP_LD2DMS: + case VSIR_OP_LD: spirv_compiler_emit_ld(compiler, instruction); break; - case VKD3DSIH_LOD: + case VSIR_OP_LOD: spirv_compiler_emit_lod(compiler, instruction); break; - case VKD3DSIH_SAMPLE: - case VKD3DSIH_SAMPLE_B: - case VKD3DSIH_SAMPLE_GRAD: - case VKD3DSIH_SAMPLE_LOD: + case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_GRAD: + case VSIR_OP_SAMPLE_LOD: spirv_compiler_emit_sample(compiler, instruction); break; - case VKD3DSIH_SAMPLE_C: - case VKD3DSIH_SAMPLE_C_LZ: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: spirv_compiler_emit_sample_c(compiler, instruction); break; - case VKD3DSIH_GATHER4: - case VKD3DSIH_GATHER4_C: - case VKD3DSIH_GATHER4_PO: - case VKD3DSIH_GATHER4_PO_C: + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_C: + case VSIR_OP_GATHER4_PO: + case VSIR_OP_GATHER4_PO_C: spirv_compiler_emit_gather4(compiler, instruction); break; - case VKD3DSIH_LD_RAW: - case VKD3DSIH_LD_STRUCTURED: + case VSIR_OP_LD_RAW: + case VSIR_OP_LD_STRUCTURED: spirv_compiler_emit_ld_raw_structured(compiler, instruction); break; - case VKD3DSIH_STORE_RAW: - case VKD3DSIH_STORE_STRUCTURED: + case VSIR_OP_STORE_RAW: + case VSIR_OP_STORE_STRUCTURED: spirv_compiler_emit_store_raw_structured(compiler, instruction); break; - case VKD3DSIH_LD_UAV_TYPED: + case VSIR_OP_LD_UAV_TYPED: spirv_compiler_emit_ld_uav_typed(compiler, instruction); break; - case VKD3DSIH_STORE_UAV_TYPED: + case VSIR_OP_STORE_UAV_TYPED: spirv_compiler_emit_store_uav_typed(compiler, instruction); break; - case VKD3DSIH_IMM_ATOMIC_ALLOC: - case VKD3DSIH_IMM_ATOMIC_CONSUME: + case VSIR_OP_IMM_ATOMIC_ALLOC: + case VSIR_OP_IMM_ATOMIC_CONSUME: spirv_compiler_emit_uav_counter_instruction(compiler, instruction); break; - case VKD3DSIH_ATOMIC_AND: - case VKD3DSIH_ATOMIC_CMP_STORE: - case VKD3DSIH_ATOMIC_IADD: - case VKD3DSIH_ATOMIC_IMAX: - case VKD3DSIH_ATOMIC_IMIN: - case VKD3DSIH_ATOMIC_OR: - case VKD3DSIH_ATOMIC_UMAX: - case VKD3DSIH_ATOMIC_UMIN: - case VKD3DSIH_ATOMIC_XOR: - case VKD3DSIH_IMM_ATOMIC_AND: - case VKD3DSIH_IMM_ATOMIC_CMP_EXCH: - case VKD3DSIH_IMM_ATOMIC_EXCH: - case VKD3DSIH_IMM_ATOMIC_IADD: - case VKD3DSIH_IMM_ATOMIC_IMAX: - case VKD3DSIH_IMM_ATOMIC_IMIN: - case VKD3DSIH_IMM_ATOMIC_OR: - case VKD3DSIH_IMM_ATOMIC_UMAX: - case VKD3DSIH_IMM_ATOMIC_UMIN: - case VKD3DSIH_IMM_ATOMIC_XOR: + case VSIR_OP_ATOMIC_AND: + case VSIR_OP_ATOMIC_CMP_STORE: + case VSIR_OP_ATOMIC_IADD: + case VSIR_OP_ATOMIC_IMAX: + case VSIR_OP_ATOMIC_IMIN: + case VSIR_OP_ATOMIC_OR: + case VSIR_OP_ATOMIC_UMAX: + case VSIR_OP_ATOMIC_UMIN: + case VSIR_OP_ATOMIC_XOR: + case VSIR_OP_IMM_ATOMIC_AND: + case VSIR_OP_IMM_ATOMIC_CMP_EXCH: + case VSIR_OP_IMM_ATOMIC_EXCH: + case VSIR_OP_IMM_ATOMIC_IADD: + case VSIR_OP_IMM_ATOMIC_IMAX: + case VSIR_OP_IMM_ATOMIC_IMIN: + case VSIR_OP_IMM_ATOMIC_OR: + case VSIR_OP_IMM_ATOMIC_UMAX: + case VSIR_OP_IMM_ATOMIC_UMIN: + case VSIR_OP_IMM_ATOMIC_XOR: spirv_compiler_emit_atomic_instruction(compiler, instruction); break; - case VKD3DSIH_BUFINFO: + case VSIR_OP_BUFINFO: spirv_compiler_emit_bufinfo(compiler, instruction); break; - case VKD3DSIH_RESINFO: + case VSIR_OP_RESINFO: spirv_compiler_emit_resinfo(compiler, instruction); break; - case VKD3DSIH_SAMPLE_INFO: + case VSIR_OP_SAMPLE_INFO: spirv_compiler_emit_sample_info(compiler, instruction); break; - case VKD3DSIH_SAMPLE_POS: + case VSIR_OP_SAMPLE_POS: spirv_compiler_emit_sample_position(compiler, instruction); break; - case VKD3DSIH_EVAL_CENTROID: - case VKD3DSIH_EVAL_SAMPLE_INDEX: + case VSIR_OP_EVAL_CENTROID: + case VSIR_OP_EVAL_SAMPLE_INDEX: spirv_compiler_emit_eval_attrib(compiler, instruction); break; - case VKD3DSIH_SYNC: + case VSIR_OP_SYNC: spirv_compiler_emit_sync(compiler, instruction); break; - case VKD3DSIH_EMIT: - case VKD3DSIH_EMIT_STREAM: + case VSIR_OP_EMIT: + case VSIR_OP_EMIT_STREAM: spirv_compiler_emit_emit_stream(compiler, instruction); break; - case VKD3DSIH_CUT: - case VKD3DSIH_CUT_STREAM: + case VSIR_OP_CUT: + case VSIR_OP_CUT_STREAM: spirv_compiler_emit_cut_stream(compiler, instruction); break; - case VKD3DSIH_QUAD_READ_ACROSS_D: - case VKD3DSIH_QUAD_READ_ACROSS_X: - case VKD3DSIH_QUAD_READ_ACROSS_Y: + case VSIR_OP_QUAD_READ_ACROSS_D: + case VSIR_OP_QUAD_READ_ACROSS_X: + case VSIR_OP_QUAD_READ_ACROSS_Y: spirv_compiler_emit_quad_read_across(compiler, instruction); break; - case VKD3DSIH_QUAD_READ_LANE_AT: + case VSIR_OP_QUAD_READ_LANE_AT: spirv_compiler_emit_quad_read_lane_at(compiler, instruction); break; - case VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL: - case VKD3DSIH_WAVE_ALL_TRUE: - case VKD3DSIH_WAVE_ANY_TRUE: + case VSIR_OP_WAVE_ACTIVE_ALL_EQUAL: + case VSIR_OP_WAVE_ALL_TRUE: + case VSIR_OP_WAVE_ANY_TRUE: spirv_compiler_emit_wave_bool_op(compiler, instruction); break; - case VKD3DSIH_WAVE_ACTIVE_BALLOT: + case VSIR_OP_WAVE_ACTIVE_BALLOT: spirv_compiler_emit_wave_active_ballot(compiler, instruction); break; - case VKD3DSIH_WAVE_ACTIVE_BIT_AND: - case VKD3DSIH_WAVE_ACTIVE_BIT_OR: - case VKD3DSIH_WAVE_ACTIVE_BIT_XOR: - case VKD3DSIH_WAVE_OP_ADD: - case VKD3DSIH_WAVE_OP_IMAX: - case VKD3DSIH_WAVE_OP_IMIN: - case VKD3DSIH_WAVE_OP_MAX: - case VKD3DSIH_WAVE_OP_MIN: - case VKD3DSIH_WAVE_OP_MUL: - case VKD3DSIH_WAVE_OP_UMAX: - case VKD3DSIH_WAVE_OP_UMIN: + case VSIR_OP_WAVE_ACTIVE_BIT_AND: + case VSIR_OP_WAVE_ACTIVE_BIT_OR: + case VSIR_OP_WAVE_ACTIVE_BIT_XOR: + case VSIR_OP_WAVE_OP_ADD: + case VSIR_OP_WAVE_OP_IMAX: + case VSIR_OP_WAVE_OP_IMIN: + case VSIR_OP_WAVE_OP_MAX: + case VSIR_OP_WAVE_OP_MIN: + case VSIR_OP_WAVE_OP_MUL: + case VSIR_OP_WAVE_OP_UMAX: + case VSIR_OP_WAVE_OP_UMIN: spirv_compiler_emit_wave_alu_op(compiler, instruction); break; - case VKD3DSIH_WAVE_ALL_BIT_COUNT: - case VKD3DSIH_WAVE_PREFIX_BIT_COUNT: + case VSIR_OP_WAVE_ALL_BIT_COUNT: + case VSIR_OP_WAVE_PREFIX_BIT_COUNT: spirv_compiler_emit_wave_bit_count(compiler, instruction); break; - case VKD3DSIH_WAVE_IS_FIRST_LANE: + case VSIR_OP_WAVE_IS_FIRST_LANE: spirv_compiler_emit_wave_is_first_lane(compiler, instruction); break; - case VKD3DSIH_WAVE_READ_LANE_AT: + case VSIR_OP_WAVE_READ_LANE_AT: spirv_compiler_emit_wave_read_lane_at(compiler, instruction); break; - case VKD3DSIH_WAVE_READ_LANE_FIRST: + case VSIR_OP_WAVE_READ_LANE_FIRST: spirv_compiler_emit_wave_read_lane_first(compiler, instruction); break; - case VKD3DSIH_DCL_HS_MAX_TESSFACTOR: - case VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT: - case VKD3DSIH_DCL_RESOURCE_RAW: - case VKD3DSIH_DCL_RESOURCE_STRUCTURED: - case VKD3DSIH_DCL_UAV_RAW: - case VKD3DSIH_DCL_UAV_STRUCTURED: - case VKD3DSIH_HS_DECLS: - case VKD3DSIH_NOP: + case VSIR_OP_DCL_HS_MAX_TESSFACTOR: + case VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT: + 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_HS_DECLS: + case VSIR_OP_NOP: /* nothing to do */ break; default: - FIXME("Unhandled instruction %#x.\n", instruction->opcode); spirv_compiler_error(compiler, VKD3D_SHADER_ERROR_SPV_INVALID_HANDLER, - "Encountered invalid/unhandled instruction handler %#x.", instruction->opcode); + "Unhandled instruction "%s" (%#x).", + vsir_opcode_get_name(instruction->opcode, "<unknown>"), instruction->opcode); break; }
@@ -11127,14 +10982,14 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler)
if (compiler->program->has_point_size) { - vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VKD3D_DATA_FLOAT, 1); + vsir_dst_param_init(&dst, VKD3DSPR_RASTOUT, VSIR_DATA_F32, 1); dst.reg.idx[0].offset = VSIR_RASTOUT_POINT_SIZE; spirv_compiler_emit_io_register(compiler, &dst); }
if (compiler->program->has_point_coord) { - vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VKD3D_DATA_FLOAT, 0); + vsir_dst_param_init(&dst, VKD3DSPR_POINT_COORD, VSIR_DATA_F32, 0); spirv_compiler_emit_io_register(compiler, &dst); }
@@ -11145,7 +11000,7 @@ static void spirv_compiler_emit_io_declarations(struct spirv_compiler *compiler) if (bitmap_is_set(compiler->program->io_dcls, i) || (compiler->program->shader_version.type == VKD3D_SHADER_TYPE_HULL && i == VKD3DSPR_OUTPOINTID)) { - vsir_dst_param_init(&dst, i, VKD3D_DATA_FLOAT, 0); + vsir_dst_param_init(&dst, i, VSIR_DATA_F32, 0); spirv_compiler_emit_io_register(compiler, &dst); } } @@ -11195,11 +11050,12 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, const struct vkd3d_shader_spirv_target_info *info = compiler->spirv_target_info; const struct vkd3d_shader_spirv_domain_shader_target_info *ds_info; struct vkd3d_spirv_builder *builder = &compiler->spirv_builder; - const struct vsir_program *program = compiler->program; - struct vkd3d_shader_instruction_array instructions; + struct vsir_program *program = compiler->program; enum vkd3d_shader_spirv_environment environment; + struct vkd3d_shader_instruction *ins; enum vkd3d_result result = VKD3D_OK; unsigned int i, max_element_count; + struct vsir_program_iterator it;
max_element_count = max(program->output_signature.element_count, program->patch_constant_signature.element_count); if (!(compiler->output_info = vkd3d_calloc(max_element_count, sizeof(*compiler->output_info)))) @@ -11247,8 +11103,6 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (program->block_count && !spirv_compiler_init_blocks(compiler, program->block_count)) return VKD3D_ERROR_OUT_OF_MEMORY;
- instructions = program->instructions; - compiler->use_vocp = program->use_vocp; compiler->block_names = program->block_names; compiler->block_name_count = program->block_name_count; @@ -11263,9 +11117,10 @@ static int spirv_compiler_generate_spirv(struct spirv_compiler *compiler, if (compiler->shader_type != VKD3D_SHADER_TYPE_HULL) spirv_compiler_emit_shader_signature_outputs(compiler);
- for (i = 0; i < instructions.count && result >= 0; ++i) + it = vsir_program_iterator(&program->instructions); + for (ins = vsir_program_iterator_head(&it); ins && result >= 0; ins = vsir_program_iterator_next(&it)) { - result = spirv_compiler_handle_instruction(compiler, &instructions.elements[i]); + result = spirv_compiler_handle_instruction(compiler, ins); }
if (result < 0) diff --git a/libs/vkd3d/libs/vkd3d-shader/tpf.c b/libs/vkd3d/libs/vkd3d-shader/tpf.c index 29b03871e05..ea15c1a9ad5 100644 --- a/libs/vkd3d/libs/vkd3d-shader/tpf.c +++ b/libs/vkd3d/libs/vkd3d-shader/tpf.c @@ -261,6 +261,7 @@ enum vkd3d_sm4_opcode VKD3D_SM4_OP_DCL_INPUT_PS_SGV = 0x63, VKD3D_SM4_OP_DCL_INPUT_PS_SIV = 0x64, VKD3D_SM4_OP_DCL_OUTPUT = 0x65, + VKD3D_SM4_OP_DCL_OUTPUT_SGV = 0x66, VKD3D_SM4_OP_DCL_OUTPUT_SIV = 0x67, VKD3D_SM4_OP_DCL_TEMPS = 0x68, VKD3D_SM4_OP_DCL_INDEXABLE_TEMP = 0x69, @@ -654,7 +655,7 @@ struct sm4_index_range_array struct vkd3d_sm4_lookup_tables { const struct vkd3d_sm4_opcode_info *opcode_info_from_sm4[VKD3D_SM4_OP_COUNT]; - const struct vkd3d_sm4_opcode_info *opcode_info_from_vsir[VKD3DSIH_COUNT]; + const struct vkd3d_sm4_opcode_info *opcode_info_from_vsir[VSIR_OP_COUNT]; const struct vkd3d_sm4_register_type_info *register_type_info_from_sm4[VKD3D_SM4_REGISTER_TYPE_COUNT]; const struct vkd3d_sm4_register_type_info *register_type_info_from_vkd3d[VKD3DSPR_COUNT]; const struct vkd3d_sm4_stat_field_info *stat_field_from_sm4[VKD3D_SM4_OP_COUNT]; @@ -747,18 +748,18 @@ static const enum vkd3d_shader_resource_type resource_type_table[] = /* VKD3D_SM4_RESOURCE_STRUCTURED_BUFFER */ VKD3D_SHADER_RESOURCE_BUFFER, };
-static const enum vkd3d_data_type data_type_table[] = -{ - /* 0 */ VKD3D_DATA_FLOAT, - /* VKD3D_SM4_DATA_UNORM */ VKD3D_DATA_UNORM, - /* VKD3D_SM4_DATA_SNORM */ VKD3D_DATA_SNORM, - /* VKD3D_SM4_DATA_INT */ VKD3D_DATA_INT, - /* VKD3D_SM4_DATA_UINT */ VKD3D_DATA_UINT, - /* VKD3D_SM4_DATA_FLOAT */ VKD3D_DATA_FLOAT, - /* VKD3D_SM4_DATA_MIXED */ VKD3D_DATA_MIXED, - /* VKD3D_SM4_DATA_DOUBLE */ VKD3D_DATA_DOUBLE, - /* VKD3D_SM4_DATA_CONTINUED */ VKD3D_DATA_CONTINUED, - /* VKD3D_SM4_DATA_UNUSED */ VKD3D_DATA_UNUSED, +static const enum vsir_data_type data_type_table[] = +{ + /* 0 */ VSIR_DATA_F32, + /* VKD3D_SM4_DATA_UNORM */ VSIR_DATA_UNORM, + /* VKD3D_SM4_DATA_SNORM */ VSIR_DATA_SNORM, + /* VKD3D_SM4_DATA_INT */ VSIR_DATA_I32, + /* VKD3D_SM4_DATA_UINT */ VSIR_DATA_U32, + /* VKD3D_SM4_DATA_FLOAT */ VSIR_DATA_F32, + /* VKD3D_SM4_DATA_MIXED */ VSIR_DATA_MIXED, + /* VKD3D_SM4_DATA_DOUBLE */ VSIR_DATA_F64, + /* VKD3D_SM4_DATA_CONTINUED */ VSIR_DATA_CONTINUED, + /* VKD3D_SM4_DATA_UNUSED */ VSIR_DATA_UNUSED, };
static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) @@ -769,9 +770,9 @@ static bool shader_is_sm_5_1(const struct vkd3d_shader_sm4_parser *sm4) }
static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, - const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param); + const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param); static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, - const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param); + const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param);
static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, const uint32_t *end, unsigned int *register_space) @@ -794,7 +795,7 @@ static bool shader_sm4_read_register_space(struct vkd3d_shader_sm4_parser *priv, static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]); + shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]); ins->flags = (opcode_token & VKD3D_SM4_CONDITIONAL_NZ) ? VKD3D_SHADER_CONDITIONAL_OP_NZ : VKD3D_SHADER_CONDITIONAL_OP_Z; } @@ -802,7 +803,7 @@ static void shader_sm4_read_conditional_op(struct vkd3d_shader_instruction *ins, static void shader_sm4_read_case_condition(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_UINT, &ins->src[0]); + shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_U32, &ins->src[0]); if (ins->src[0].reg.type != VKD3DSPR_IMMCONST) { FIXME("Switch case value is not a 32-bit constant.\n"); @@ -822,7 +823,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui if (type != VKD3D_SM4_SHADER_DATA_IMMEDIATE_CONSTANT_BUFFER) { FIXME("Ignoring shader data type %#x.\n", type); - ins->opcode = VKD3DSIH_NOP; + ins->opcode = VSIR_OP_NOP; return; }
@@ -831,7 +832,7 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui if (icb_size % 4) { FIXME("Unexpected immediate constant buffer size %u.\n", icb_size); - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; return; }
@@ -839,11 +840,11 @@ static void shader_sm4_read_shader_data(struct vkd3d_shader_instruction *ins, ui { ERR("Failed to allocate immediate constant buffer, size %u.\n", icb_size); vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; return; } icb->register_idx = 0; - icb->data_type = VKD3D_DATA_FLOAT; + icb->data_type = VSIR_DATA_F32; icb->component_count = VKD3D_VEC4_SIZE; icb->element_count = icb_size / VKD3D_VEC4_SIZE; icb->is_null = false; @@ -872,7 +873,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u enum vkd3d_sm4_resource_type resource_type; const uint32_t *end = &tokens[token_count]; enum vkd3d_sm4_data_type data_type; - enum vkd3d_data_type reg_data_type; + enum vsir_data_type reg_data_type; uint32_t components; unsigned int i;
@@ -894,7 +895,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u >> VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; }
- reg_data_type = VKD3D_DATA_UNUSED; + reg_data_type = VSIR_DATA_UNUSED; shader_sm4_read_dst_param(priv, &tokens, end, reg_data_type, &semantic->resource.reg); shader_sm4_set_descriptor_register_range(priv, &semantic->resource.reg.reg, &semantic->resource.range);
@@ -906,7 +907,7 @@ static void shader_sm4_read_dcl_resource(struct vkd3d_shader_instruction *ins, u if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) { FIXME("Unhandled data type %#x.\n", data_type); - semantic->resource_data_type[i] = VKD3D_DATA_FLOAT; + semantic->resource_data_type[i] = VSIR_DATA_F32; } else { @@ -925,7 +926,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct vkd3d_shader_instruction { const uint32_t *end = &tokens[token_count];
- shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_FLOAT, &ins->declaration.cb.src); + shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_F32, &ins->declaration.cb.src); shader_sm4_set_descriptor_register_range(priv, &ins->declaration.cb.src.reg, &ins->declaration.cb.range); if (opcode_token & VKD3D_SM4_INDEX_TYPE_MASK) ins->flags |= VKD3DSI_INDEXED_DYNAMIC; @@ -956,14 +957,14 @@ static void shader_sm4_read_dcl_sampler(struct vkd3d_shader_instruction *ins, ui ins->flags = (opcode_token & VKD3D_SM4_SAMPLER_MODE_MASK) >> VKD3D_SM4_SAMPLER_MODE_SHIFT; if (ins->flags & ~VKD3D_SM4_SAMPLER_COMPARISON) FIXME("Unhandled sampler mode %#x.\n", ins->flags); - shader_sm4_read_src_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &ins->declaration.sampler.src); + shader_sm4_read_src_param(priv, &tokens, end, VSIR_DATA_UNUSED, &ins->declaration.sampler.src); shader_sm4_set_descriptor_register_range(priv, &ins->declaration.sampler.src.reg, &ins->declaration.sampler.range); shader_sm4_read_register_space(priv, &tokens, end, &ins->declaration.sampler.range.space); }
static bool sm4_parser_is_in_fork_or_join_phase(const struct vkd3d_shader_sm4_parser *sm4) { - return sm4->phase == VKD3DSIH_HS_FORK_PHASE || sm4->phase == VKD3DSIH_HS_JOIN_PHASE; + return sm4->phase == VSIR_OP_HS_FORK_PHASE || sm4->phase == VSIR_OP_HS_JOIN_PHASE; }
static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -978,8 +979,7 @@ static void shader_sm4_read_dcl_index_range(struct vkd3d_shader_instruction *ins unsigned int *io_masks; uint32_t write_mask;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, - &index_range->dst); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &index_range->dst); index_range->register_count = *tokens;
register_idx = index_range->dst.reg.idx[index_range->dst.reg.idx_count - 1].offset; @@ -1141,14 +1141,14 @@ static void shader_sm4_read_declaration_count(struct vkd3d_shader_instruction *i static void shader_sm4_read_declaration_dst(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.dst); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.dst); }
static void shader_sm4_read_declaration_register_semantic(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, - &ins->declaration.register_semantic.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], + VSIR_DATA_F32, &ins->declaration.register_semantic.reg); ins->declaration.register_semantic.sysval_semantic = *tokens; }
@@ -1158,7 +1158,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u struct vkd3d_shader_dst_param *dst = &ins->declaration.dst;
ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT; - if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) + 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); @@ -1168,7 +1168,7 @@ static void shader_sm4_read_dcl_input_ps(struct vkd3d_shader_instruction *ins, u WARN("No matching signature element for input register %u with mask %#x.\n", dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL, - "No matching signature element for input register %u with mask %#x.\n", + "No matching signature element for input register %u with mask %#x.", dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); } else @@ -1184,7 +1184,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in struct vkd3d_shader_dst_param *dst = &ins->declaration.register_semantic.reg;
ins->flags = (opcode_token & VKD3D_SM4_INTERPOLATION_MODE_MASK) >> VKD3D_SM4_INTERPOLATION_MODE_SHIFT; - if (shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, dst)) + 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); @@ -1194,7 +1194,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct vkd3d_shader_instruction *in WARN("No matching signature element for input register %u with mask %#x.\n", dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); vkd3d_shader_parser_error(&priv->p, VKD3D_SHADER_ERROR_TPF_INVALID_REGISTER_DCL, - "No matching signature element for input register %u with mask %#x.\n", + "No matching signature element for input register %u with mask %#x.", dst->reg.idx[dst->reg.idx_count - 1].offset, dst->write_mask); } else @@ -1211,7 +1211,7 @@ static void shader_sm4_read_dcl_indexable_temp(struct vkd3d_shader_instruction * ins->declaration.indexable_temp.register_idx = *tokens++; ins->declaration.indexable_temp.register_size = *tokens++; ins->declaration.indexable_temp.alignment = 0; - ins->declaration.indexable_temp.data_type = VKD3D_DATA_FLOAT; + ins->declaration.indexable_temp.data_type = VSIR_DATA_F32; ins->declaration.indexable_temp.component_count = *tokens; ins->declaration.indexable_temp.has_function_scope = false; } @@ -1227,7 +1227,7 @@ static void shader_sm5_read_fcall(struct vkd3d_shader_instruction *ins, uint32_t const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { ins->src[0].reg.u.fp_body_idx = *tokens++; - shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_OPAQUE, &ins->src[0]); + shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], VSIR_DATA_OPAQUE, &ins->src[0]); }
static void shader_sm5_read_dcl_function_body(struct vkd3d_shader_instruction *ins, uint32_t opcode, @@ -1314,7 +1314,7 @@ static void shader_sm5_read_dcl_uav_raw(struct vkd3d_shader_instruction *ins, ui struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource; const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); + shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space); @@ -1326,7 +1326,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction * struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource; const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); + shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); ins->flags = (opcode_token & VKD3D_SM5_UAV_FLAGS_MASK) >> VKD3D_SM5_UAV_FLAGS_SHIFT; resource->byte_stride = *tokens++; @@ -1338,7 +1338,7 @@ static void shader_sm5_read_dcl_uav_structured(struct vkd3d_shader_instruction * static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VSIR_DATA_F32, &ins->declaration.tgsm_raw.reg); ins->declaration.tgsm_raw.byte_count = *tokens; if (ins->declaration.tgsm_raw.byte_count % 4) FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count); @@ -1348,8 +1348,8 @@ static void shader_sm5_read_dcl_tgsm_raw(struct vkd3d_shader_instruction *ins, u static void shader_sm5_read_dcl_tgsm_structured(struct vkd3d_shader_instruction *ins, uint32_t opcode, uint32_t opcode_token, const uint32_t *tokens, unsigned int token_count, struct vkd3d_shader_sm4_parser *priv) { - shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], VKD3D_DATA_FLOAT, - &ins->declaration.tgsm_structured.reg); + shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], + VSIR_DATA_F32, &ins->declaration.tgsm_structured.reg); ins->declaration.tgsm_structured.byte_stride = *tokens++; ins->declaration.tgsm_structured.structure_count = *tokens; if (ins->declaration.tgsm_structured.byte_stride % 4) @@ -1363,7 +1363,7 @@ static void shader_sm5_read_dcl_resource_structured(struct vkd3d_shader_instruct struct vkd3d_shader_structured_resource *resource = &ins->declaration.structured_resource; const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); + shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); resource->byte_stride = *tokens++; if (resource->byte_stride % 4) @@ -1377,7 +1377,7 @@ static void shader_sm5_read_dcl_resource_raw(struct vkd3d_shader_instruction *in struct vkd3d_shader_raw_resource *resource = &ins->declaration.raw_resource; const uint32_t *end = &tokens[token_count];
- shader_sm4_read_dst_param(priv, &tokens, end, VKD3D_DATA_UNUSED, &resource->resource.reg); + shader_sm4_read_dst_param(priv, &tokens, end, VSIR_DATA_UNUSED, &resource->resource.reg); shader_sm4_set_descriptor_register_range(priv, &resource->resource.reg.reg, &resource->resource.range); shader_sm4_read_register_space(priv, &tokens, end, &resource->resource.range.space); } @@ -1429,284 +1429,284 @@ static void init_sm4_lookup_tables(struct vkd3d_sm4_lookup_tables *lookup) unsigned int i;
/* - * d -> VKD3D_DATA_DOUBLE - * f -> VKD3D_DATA_FLOAT - * i -> VKD3D_DATA_INT - * u -> VKD3D_DATA_UINT - * O -> VKD3D_DATA_OPAQUE - * R -> VKD3D_DATA_RESOURCE - * S -> VKD3D_DATA_SAMPLER - * U -> VKD3D_DATA_UAV + * d -> VSIR_DATA_F64 + * f -> VSIR_DATA_F32 + * i -> VSIR_DATA_I32 + * u -> VSIR_DATA_U32 + * O -> VSIR_DATA_OPAQUE + * * -> VSIR_DATA_UNUSED */ static const struct vkd3d_sm4_opcode_info opcode_table[] = { - {VKD3D_SM4_OP_ADD, VKD3DSIH_ADD, "f", "ff"}, - {VKD3D_SM4_OP_AND, VKD3DSIH_AND, "u", "uu"}, - {VKD3D_SM4_OP_BREAK, VKD3DSIH_BREAK, "", ""}, - {VKD3D_SM4_OP_BREAKC, VKD3DSIH_BREAKP, "", "u", + {VKD3D_SM4_OP_ADD, VSIR_OP_ADD, "f", "ff"}, + {VKD3D_SM4_OP_AND, VSIR_OP_AND, "u", "uu"}, + {VKD3D_SM4_OP_BREAK, VSIR_OP_BREAK, "", ""}, + {VKD3D_SM4_OP_BREAKC, VSIR_OP_BREAKP, "", "u", shader_sm4_read_conditional_op, true}, - {VKD3D_SM4_OP_CASE, VKD3DSIH_CASE, "", "u", + {VKD3D_SM4_OP_CASE, VSIR_OP_CASE, "", "u", shader_sm4_read_case_condition}, - {VKD3D_SM4_OP_CONTINUE, VKD3DSIH_CONTINUE, "", ""}, - {VKD3D_SM4_OP_CONTINUEC, VKD3DSIH_CONTINUEP, "", "u", + {VKD3D_SM4_OP_CONTINUE, VSIR_OP_CONTINUE, "", ""}, + {VKD3D_SM4_OP_CONTINUEC, VSIR_OP_CONTINUEP, "", "u", shader_sm4_read_conditional_op, true}, - {VKD3D_SM4_OP_CUT, VKD3DSIH_CUT, "", ""}, - {VKD3D_SM4_OP_DEFAULT, VKD3DSIH_DEFAULT, "", ""}, - {VKD3D_SM4_OP_DERIV_RTX, VKD3DSIH_DSX, "f", "f"}, - {VKD3D_SM4_OP_DERIV_RTY, VKD3DSIH_DSY, "f", "f"}, - {VKD3D_SM4_OP_DISCARD, VKD3DSIH_DISCARD, "", "u", + {VKD3D_SM4_OP_CUT, VSIR_OP_CUT, "", ""}, + {VKD3D_SM4_OP_DEFAULT, VSIR_OP_DEFAULT, "", ""}, + {VKD3D_SM4_OP_DERIV_RTX, VSIR_OP_DSX, "f", "f"}, + {VKD3D_SM4_OP_DERIV_RTY, VSIR_OP_DSY, "f", "f"}, + {VKD3D_SM4_OP_DISCARD, VSIR_OP_DISCARD, "", "u", shader_sm4_read_conditional_op, true}, - {VKD3D_SM4_OP_DIV, VKD3DSIH_DIV, "f", "ff"}, - {VKD3D_SM4_OP_DP2, VKD3DSIH_DP2, "f", "ff"}, - {VKD3D_SM4_OP_DP3, VKD3DSIH_DP3, "f", "ff"}, - {VKD3D_SM4_OP_DP4, VKD3DSIH_DP4, "f", "ff"}, - {VKD3D_SM4_OP_ELSE, VKD3DSIH_ELSE, "", ""}, - {VKD3D_SM4_OP_EMIT, VKD3DSIH_EMIT, "", ""}, - {VKD3D_SM4_OP_ENDIF, VKD3DSIH_ENDIF, "", ""}, - {VKD3D_SM4_OP_ENDLOOP, VKD3DSIH_ENDLOOP, "", ""}, - {VKD3D_SM4_OP_ENDSWITCH, VKD3DSIH_ENDSWITCH, "", ""}, - {VKD3D_SM4_OP_EQ, VKD3DSIH_EQO, "u", "ff"}, - {VKD3D_SM4_OP_EXP, VKD3DSIH_EXP, "f", "f"}, - {VKD3D_SM4_OP_FRC, VKD3DSIH_FRC, "f", "f"}, - {VKD3D_SM4_OP_FTOI, VKD3DSIH_FTOI, "i", "f"}, - {VKD3D_SM4_OP_FTOU, VKD3DSIH_FTOU, "u", "f"}, - {VKD3D_SM4_OP_GE, VKD3DSIH_GEO, "u", "ff"}, - {VKD3D_SM4_OP_IADD, VKD3DSIH_IADD, "i", "ii"}, - {VKD3D_SM4_OP_IF, VKD3DSIH_IF, "", "u", + {VKD3D_SM4_OP_DIV, VSIR_OP_DIV, "f", "ff"}, + {VKD3D_SM4_OP_DP2, VSIR_OP_DP2, "f", "ff"}, + {VKD3D_SM4_OP_DP3, VSIR_OP_DP3, "f", "ff"}, + {VKD3D_SM4_OP_DP4, VSIR_OP_DP4, "f", "ff"}, + {VKD3D_SM4_OP_ELSE, VSIR_OP_ELSE, "", ""}, + {VKD3D_SM4_OP_EMIT, VSIR_OP_EMIT, "", ""}, + {VKD3D_SM4_OP_ENDIF, VSIR_OP_ENDIF, "", ""}, + {VKD3D_SM4_OP_ENDLOOP, VSIR_OP_ENDLOOP, "", ""}, + {VKD3D_SM4_OP_ENDSWITCH, VSIR_OP_ENDSWITCH, "", ""}, + {VKD3D_SM4_OP_EQ, VSIR_OP_EQO, "u", "ff"}, + {VKD3D_SM4_OP_EXP, VSIR_OP_EXP, "f", "f"}, + {VKD3D_SM4_OP_FRC, VSIR_OP_FRC, "f", "f"}, + {VKD3D_SM4_OP_FTOI, VSIR_OP_FTOI, "i", "f"}, + {VKD3D_SM4_OP_FTOU, VSIR_OP_FTOU, "u", "f"}, + {VKD3D_SM4_OP_GE, VSIR_OP_GEO, "u", "ff"}, + {VKD3D_SM4_OP_IADD, VSIR_OP_IADD, "i", "ii"}, + {VKD3D_SM4_OP_IF, VSIR_OP_IF, "", "u", shader_sm4_read_conditional_op, true}, - {VKD3D_SM4_OP_IEQ, VKD3DSIH_IEQ, "u", "ii"}, - {VKD3D_SM4_OP_IGE, VKD3DSIH_IGE, "u", "ii"}, - {VKD3D_SM4_OP_ILT, VKD3DSIH_ILT, "u", "ii"}, - {VKD3D_SM4_OP_IMAD, VKD3DSIH_IMAD, "i", "iii"}, - {VKD3D_SM4_OP_IMAX, VKD3DSIH_IMAX, "i", "ii"}, - {VKD3D_SM4_OP_IMIN, VKD3DSIH_IMIN, "i", "ii"}, - {VKD3D_SM4_OP_IMUL, VKD3DSIH_IMUL, "ii", "ii"}, - {VKD3D_SM4_OP_INE, VKD3DSIH_INE, "u", "ii"}, - {VKD3D_SM4_OP_INEG, VKD3DSIH_INEG, "i", "i"}, - {VKD3D_SM4_OP_ISHL, VKD3DSIH_ISHL, "i", "ii"}, - {VKD3D_SM4_OP_ISHR, VKD3DSIH_ISHR, "i", "ii"}, - {VKD3D_SM4_OP_ITOF, VKD3DSIH_ITOF, "f", "i"}, - {VKD3D_SM4_OP_LABEL, VKD3DSIH_LABEL, "", "O"}, - {VKD3D_SM4_OP_LD, VKD3DSIH_LD, "u", "i*"}, - {VKD3D_SM4_OP_LD2DMS, VKD3DSIH_LD2DMS, "u", "i*i"}, - {VKD3D_SM4_OP_LOG, VKD3DSIH_LOG, "f", "f"}, - {VKD3D_SM4_OP_LOOP, VKD3DSIH_LOOP, "", ""}, - {VKD3D_SM4_OP_LT, VKD3DSIH_LTO, "u", "ff"}, - {VKD3D_SM4_OP_MAD, VKD3DSIH_MAD, "f", "fff"}, - {VKD3D_SM4_OP_MIN, VKD3DSIH_MIN, "f", "ff"}, - {VKD3D_SM4_OP_MAX, VKD3DSIH_MAX, "f", "ff"}, - {VKD3D_SM4_OP_SHADER_DATA, VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", + {VKD3D_SM4_OP_IEQ, VSIR_OP_IEQ, "u", "ii"}, + {VKD3D_SM4_OP_IGE, VSIR_OP_IGE, "u", "ii"}, + {VKD3D_SM4_OP_ILT, VSIR_OP_ILT, "u", "ii"}, + {VKD3D_SM4_OP_IMAD, VSIR_OP_IMAD, "i", "iii"}, + {VKD3D_SM4_OP_IMAX, VSIR_OP_IMAX, "i", "ii"}, + {VKD3D_SM4_OP_IMIN, VSIR_OP_IMIN, "i", "ii"}, + {VKD3D_SM4_OP_IMUL, VSIR_OP_IMUL, "ii", "ii"}, + {VKD3D_SM4_OP_INE, VSIR_OP_INE, "u", "ii"}, + {VKD3D_SM4_OP_INEG, VSIR_OP_INEG, "i", "i"}, + {VKD3D_SM4_OP_ISHL, VSIR_OP_ISHL, "i", "ii"}, + {VKD3D_SM4_OP_ISHR, VSIR_OP_ISHR, "i", "ii"}, + {VKD3D_SM4_OP_ITOF, VSIR_OP_ITOF, "f", "i"}, + {VKD3D_SM4_OP_LABEL, VSIR_OP_LABEL, "", "O"}, + {VKD3D_SM4_OP_LD, VSIR_OP_LD, "u", "i*"}, + {VKD3D_SM4_OP_LD2DMS, VSIR_OP_LD2DMS, "u", "i*i"}, + {VKD3D_SM4_OP_LOG, VSIR_OP_LOG, "f", "f"}, + {VKD3D_SM4_OP_LOOP, VSIR_OP_LOOP, "", ""}, + {VKD3D_SM4_OP_LT, VSIR_OP_LTO, "u", "ff"}, + {VKD3D_SM4_OP_MAD, VSIR_OP_MAD, "f", "fff"}, + {VKD3D_SM4_OP_MIN, VSIR_OP_MIN, "f", "ff"}, + {VKD3D_SM4_OP_MAX, VSIR_OP_MAX, "f", "ff"}, + {VKD3D_SM4_OP_SHADER_DATA, VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER, "", "", shader_sm4_read_shader_data}, - {VKD3D_SM4_OP_MOV, VKD3DSIH_MOV, "f", "f"}, - {VKD3D_SM4_OP_MOVC, VKD3DSIH_MOVC, "f", "uff"}, - {VKD3D_SM4_OP_MUL, VKD3DSIH_MUL, "f", "ff"}, - {VKD3D_SM4_OP_NE, VKD3DSIH_NEU, "u", "ff"}, - {VKD3D_SM4_OP_NOP, VKD3DSIH_NOP, "", ""}, - {VKD3D_SM4_OP_NOT, VKD3DSIH_NOT, "u", "u"}, - {VKD3D_SM4_OP_OR, VKD3DSIH_OR, "u", "uu"}, - {VKD3D_SM4_OP_RESINFO, VKD3DSIH_RESINFO, "f", "i*"}, - {VKD3D_SM4_OP_RET, VKD3DSIH_RET, "", ""}, - {VKD3D_SM4_OP_RETC, VKD3DSIH_RETP, "", "u", + {VKD3D_SM4_OP_MOV, VSIR_OP_MOV, "f", "f"}, + {VKD3D_SM4_OP_MOVC, VSIR_OP_MOVC, "f", "uff"}, + {VKD3D_SM4_OP_MUL, VSIR_OP_MUL, "f", "ff"}, + {VKD3D_SM4_OP_NE, VSIR_OP_NEU, "u", "ff"}, + {VKD3D_SM4_OP_NOP, VSIR_OP_NOP, "", ""}, + {VKD3D_SM4_OP_NOT, VSIR_OP_NOT, "u", "u"}, + {VKD3D_SM4_OP_OR, VSIR_OP_OR, "u", "uu"}, + {VKD3D_SM4_OP_RESINFO, VSIR_OP_RESINFO, "f", "i*"}, + {VKD3D_SM4_OP_RET, VSIR_OP_RET, "", ""}, + {VKD3D_SM4_OP_RETC, VSIR_OP_RETP, "", "u", shader_sm4_read_conditional_op, true}, - {VKD3D_SM4_OP_ROUND_NE, VKD3DSIH_ROUND_NE, "f", "f"}, - {VKD3D_SM4_OP_ROUND_NI, VKD3DSIH_ROUND_NI, "f", "f"}, - {VKD3D_SM4_OP_ROUND_PI, VKD3DSIH_ROUND_PI, "f", "f"}, - {VKD3D_SM4_OP_ROUND_Z, VKD3DSIH_ROUND_Z, "f", "f"}, - {VKD3D_SM4_OP_RSQ, VKD3DSIH_RSQ, "f", "f"}, - {VKD3D_SM4_OP_SAMPLE, VKD3DSIH_SAMPLE, "u", "f**"}, - {VKD3D_SM4_OP_SAMPLE_C, VKD3DSIH_SAMPLE_C, "f", "f**f"}, - {VKD3D_SM4_OP_SAMPLE_C_LZ, VKD3DSIH_SAMPLE_C_LZ, "f", "f**f"}, - {VKD3D_SM4_OP_SAMPLE_LOD, VKD3DSIH_SAMPLE_LOD, "u", "f**f"}, - {VKD3D_SM4_OP_SAMPLE_GRAD, VKD3DSIH_SAMPLE_GRAD, "u", "f**ff"}, - {VKD3D_SM4_OP_SAMPLE_B, VKD3DSIH_SAMPLE_B, "u", "f**f"}, - {VKD3D_SM4_OP_SQRT, VKD3DSIH_SQRT, "f", "f"}, - {VKD3D_SM4_OP_SWITCH, VKD3DSIH_SWITCH, "", "i"}, - {VKD3D_SM4_OP_SINCOS, VKD3DSIH_SINCOS, "ff", "f"}, - {VKD3D_SM4_OP_UDIV, VKD3DSIH_UDIV, "uu", "uu"}, - {VKD3D_SM4_OP_ULT, VKD3DSIH_ULT, "u", "uu"}, - {VKD3D_SM4_OP_UGE, VKD3DSIH_UGE, "u", "uu"}, - {VKD3D_SM4_OP_UMUL, VKD3DSIH_UMUL, "uu", "uu"}, - {VKD3D_SM4_OP_UMAX, VKD3DSIH_UMAX, "u", "uu"}, - {VKD3D_SM4_OP_UMIN, VKD3DSIH_UMIN, "u", "uu"}, - {VKD3D_SM4_OP_USHR, VKD3DSIH_USHR, "u", "uu"}, - {VKD3D_SM4_OP_UTOF, VKD3DSIH_UTOF, "f", "u"}, - {VKD3D_SM4_OP_XOR, VKD3DSIH_XOR, "u", "uu"}, - {VKD3D_SM4_OP_DCL_RESOURCE, VKD3DSIH_DCL, "", "", + {VKD3D_SM4_OP_ROUND_NE, VSIR_OP_ROUND_NE, "f", "f"}, + {VKD3D_SM4_OP_ROUND_NI, VSIR_OP_ROUND_NI, "f", "f"}, + {VKD3D_SM4_OP_ROUND_PI, VSIR_OP_ROUND_PI, "f", "f"}, + {VKD3D_SM4_OP_ROUND_Z, VSIR_OP_ROUND_Z, "f", "f"}, + {VKD3D_SM4_OP_RSQ, VSIR_OP_RSQ, "f", "f"}, + {VKD3D_SM4_OP_SAMPLE, VSIR_OP_SAMPLE, "u", "f**"}, + {VKD3D_SM4_OP_SAMPLE_C, VSIR_OP_SAMPLE_C, "f", "f**f"}, + {VKD3D_SM4_OP_SAMPLE_C_LZ, VSIR_OP_SAMPLE_C_LZ, "f", "f**f"}, + {VKD3D_SM4_OP_SAMPLE_LOD, VSIR_OP_SAMPLE_LOD, "u", "f**f"}, + {VKD3D_SM4_OP_SAMPLE_GRAD, VSIR_OP_SAMPLE_GRAD, "u", "f**ff"}, + {VKD3D_SM4_OP_SAMPLE_B, VSIR_OP_SAMPLE_B, "u", "f**f"}, + {VKD3D_SM4_OP_SQRT, VSIR_OP_SQRT, "f", "f"}, + {VKD3D_SM4_OP_SWITCH, VSIR_OP_SWITCH, "", "i"}, + {VKD3D_SM4_OP_SINCOS, VSIR_OP_SINCOS, "ff", "f"}, + {VKD3D_SM4_OP_UDIV, VSIR_OP_UDIV, "uu", "uu"}, + {VKD3D_SM4_OP_ULT, VSIR_OP_ULT, "u", "uu"}, + {VKD3D_SM4_OP_UGE, VSIR_OP_UGE, "u", "uu"}, + {VKD3D_SM4_OP_UMUL, VSIR_OP_UMUL, "uu", "uu"}, + {VKD3D_SM4_OP_UMAX, VSIR_OP_UMAX, "u", "uu"}, + {VKD3D_SM4_OP_UMIN, VSIR_OP_UMIN, "u", "uu"}, + {VKD3D_SM4_OP_USHR, VSIR_OP_USHR, "u", "uu"}, + {VKD3D_SM4_OP_UTOF, VSIR_OP_UTOF, "f", "u"}, + {VKD3D_SM4_OP_XOR, VSIR_OP_XOR, "u", "uu"}, + {VKD3D_SM4_OP_DCL_RESOURCE, VSIR_OP_DCL, "", "", shader_sm4_read_dcl_resource}, - {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VKD3DSIH_DCL_CONSTANT_BUFFER, "", "", + {VKD3D_SM4_OP_DCL_CONSTANT_BUFFER, VSIR_OP_DCL_CONSTANT_BUFFER, "", "", shader_sm4_read_dcl_constant_buffer}, - {VKD3D_SM4_OP_DCL_SAMPLER, VKD3DSIH_DCL_SAMPLER, "", "", + {VKD3D_SM4_OP_DCL_SAMPLER, VSIR_OP_DCL_SAMPLER, "", "", shader_sm4_read_dcl_sampler}, - {VKD3D_SM4_OP_DCL_INDEX_RANGE, VKD3DSIH_DCL_INDEX_RANGE, "", "", + {VKD3D_SM4_OP_DCL_INDEX_RANGE, VSIR_OP_DCL_INDEX_RANGE, "", "", shader_sm4_read_dcl_index_range}, - {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VKD3DSIH_DCL_OUTPUT_TOPOLOGY, "", "", + {VKD3D_SM4_OP_DCL_OUTPUT_TOPOLOGY, VSIR_OP_DCL_OUTPUT_TOPOLOGY, "", "", shader_sm4_read_dcl_output_topology}, - {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VKD3DSIH_DCL_INPUT_PRIMITIVE, "", "", + {VKD3D_SM4_OP_DCL_INPUT_PRIMITIVE, VSIR_OP_DCL_INPUT_PRIMITIVE, "", "", shader_sm4_read_dcl_input_primitive}, - {VKD3D_SM4_OP_DCL_VERTICES_OUT, VKD3DSIH_DCL_VERTICES_OUT, "", "", + {VKD3D_SM4_OP_DCL_VERTICES_OUT, VSIR_OP_DCL_VERTICES_OUT, "", "", shader_sm4_read_declaration_count}, - {VKD3D_SM4_OP_DCL_INPUT, VKD3DSIH_DCL_INPUT, "", "", + {VKD3D_SM4_OP_DCL_INPUT, VSIR_OP_DCL_INPUT, "", "", shader_sm4_read_declaration_dst}, - {VKD3D_SM4_OP_DCL_INPUT_SGV, VKD3DSIH_DCL_INPUT_SGV, "", "", + {VKD3D_SM4_OP_DCL_INPUT_SGV, VSIR_OP_DCL_INPUT_SGV, "", "", shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_INPUT_SIV, VKD3DSIH_DCL_INPUT_SIV, "", "", + {VKD3D_SM4_OP_DCL_INPUT_SIV, VSIR_OP_DCL_INPUT_SIV, "", "", shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_INPUT_PS, VKD3DSIH_DCL_INPUT_PS, "", "", + {VKD3D_SM4_OP_DCL_INPUT_PS, VSIR_OP_DCL_INPUT_PS, "", "", shader_sm4_read_dcl_input_ps}, - {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VKD3DSIH_DCL_INPUT_PS_SGV, "", "", + {VKD3D_SM4_OP_DCL_INPUT_PS_SGV, VSIR_OP_DCL_INPUT_PS_SGV, "", "", shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VKD3DSIH_DCL_INPUT_PS_SIV, "", "", + {VKD3D_SM4_OP_DCL_INPUT_PS_SIV, VSIR_OP_DCL_INPUT_PS_SIV, "", "", shader_sm4_read_dcl_input_ps_siv}, - {VKD3D_SM4_OP_DCL_OUTPUT, VKD3DSIH_DCL_OUTPUT, "", "", + {VKD3D_SM4_OP_DCL_OUTPUT, VSIR_OP_DCL_OUTPUT, "", "", shader_sm4_read_declaration_dst}, - {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VKD3DSIH_DCL_OUTPUT_SIV, "", "", + {VKD3D_SM4_OP_DCL_OUTPUT_SGV, VSIR_OP_DCL_OUTPUT_SGV, "", "", shader_sm4_read_declaration_register_semantic}, - {VKD3D_SM4_OP_DCL_TEMPS, VKD3DSIH_DCL_TEMPS, "", "", + {VKD3D_SM4_OP_DCL_OUTPUT_SIV, VSIR_OP_DCL_OUTPUT_SIV, "", "", + shader_sm4_read_declaration_register_semantic}, + {VKD3D_SM4_OP_DCL_TEMPS, VSIR_OP_DCL_TEMPS, "", "", shader_sm4_read_declaration_count}, - {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VKD3DSIH_DCL_INDEXABLE_TEMP, "", "", + {VKD3D_SM4_OP_DCL_INDEXABLE_TEMP, VSIR_OP_DCL_INDEXABLE_TEMP, "", "", shader_sm4_read_dcl_indexable_temp}, - {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VKD3DSIH_DCL_GLOBAL_FLAGS, "", "", + {VKD3D_SM4_OP_DCL_GLOBAL_FLAGS, VSIR_OP_DCL_GLOBAL_FLAGS, "", "", shader_sm4_read_dcl_global_flags}, - {VKD3D_SM4_OP_LOD, VKD3DSIH_LOD, "f", "f**"}, - {VKD3D_SM4_OP_GATHER4, VKD3DSIH_GATHER4, "u", "f**"}, - {VKD3D_SM4_OP_SAMPLE_POS, VKD3DSIH_SAMPLE_POS, "f", "*u"}, - {VKD3D_SM4_OP_SAMPLE_INFO, VKD3DSIH_SAMPLE_INFO, "f", "*"}, - {VKD3D_SM5_OP_HS_DECLS, VKD3DSIH_HS_DECLS, "", ""}, - {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VKD3DSIH_HS_CONTROL_POINT_PHASE, "", ""}, - {VKD3D_SM5_OP_HS_FORK_PHASE, VKD3DSIH_HS_FORK_PHASE, "", ""}, - {VKD3D_SM5_OP_HS_JOIN_PHASE, VKD3DSIH_HS_JOIN_PHASE, "", ""}, - {VKD3D_SM5_OP_EMIT_STREAM, VKD3DSIH_EMIT_STREAM, "", "f"}, - {VKD3D_SM5_OP_CUT_STREAM, VKD3DSIH_CUT_STREAM, "", "f"}, - {VKD3D_SM5_OP_FCALL, VKD3DSIH_FCALL, "", "O", + {VKD3D_SM4_OP_LOD, VSIR_OP_LOD, "f", "f**"}, + {VKD3D_SM4_OP_GATHER4, VSIR_OP_GATHER4, "u", "f**"}, + {VKD3D_SM4_OP_SAMPLE_POS, VSIR_OP_SAMPLE_POS, "f", "*u"}, + {VKD3D_SM4_OP_SAMPLE_INFO, VSIR_OP_SAMPLE_INFO, "f", "*"}, + {VKD3D_SM5_OP_HS_DECLS, VSIR_OP_HS_DECLS, "", ""}, + {VKD3D_SM5_OP_HS_CONTROL_POINT_PHASE, VSIR_OP_HS_CONTROL_POINT_PHASE, "", ""}, + {VKD3D_SM5_OP_HS_FORK_PHASE, VSIR_OP_HS_FORK_PHASE, "", ""}, + {VKD3D_SM5_OP_HS_JOIN_PHASE, VSIR_OP_HS_JOIN_PHASE, "", ""}, + {VKD3D_SM5_OP_EMIT_STREAM, VSIR_OP_EMIT_STREAM, "", "*"}, + {VKD3D_SM5_OP_CUT_STREAM, VSIR_OP_CUT_STREAM, "", "*"}, + {VKD3D_SM5_OP_FCALL, VSIR_OP_FCALL, "", "O", shader_sm5_read_fcall}, - {VKD3D_SM5_OP_BUFINFO, VKD3DSIH_BUFINFO, "i", "*"}, - {VKD3D_SM5_OP_DERIV_RTX_COARSE, VKD3DSIH_DSX_COARSE, "f", "f"}, - {VKD3D_SM5_OP_DERIV_RTX_FINE, VKD3DSIH_DSX_FINE, "f", "f"}, - {VKD3D_SM5_OP_DERIV_RTY_COARSE, VKD3DSIH_DSY_COARSE, "f", "f"}, - {VKD3D_SM5_OP_DERIV_RTY_FINE, VKD3DSIH_DSY_FINE, "f", "f"}, - {VKD3D_SM5_OP_GATHER4_C, VKD3DSIH_GATHER4_C, "f", "f**f"}, - {VKD3D_SM5_OP_GATHER4_PO, VKD3DSIH_GATHER4_PO, "f", "fi**"}, - {VKD3D_SM5_OP_GATHER4_PO_C, VKD3DSIH_GATHER4_PO_C, "f", "fi**f"}, - {VKD3D_SM5_OP_RCP, VKD3DSIH_RCP, "f", "f"}, - {VKD3D_SM5_OP_F32TOF16, VKD3DSIH_F32TOF16, "u", "f"}, - {VKD3D_SM5_OP_F16TOF32, VKD3DSIH_F16TOF32, "f", "u"}, - {VKD3D_SM5_OP_COUNTBITS, VKD3DSIH_COUNTBITS, "u", "u"}, - {VKD3D_SM5_OP_FIRSTBIT_HI, VKD3DSIH_FIRSTBIT_HI, "u", "u"}, - {VKD3D_SM5_OP_FIRSTBIT_LO, VKD3DSIH_FIRSTBIT_LO, "u", "u"}, - {VKD3D_SM5_OP_FIRSTBIT_SHI, VKD3DSIH_FIRSTBIT_SHI, "u", "i"}, - {VKD3D_SM5_OP_UBFE, VKD3DSIH_UBFE, "u", "iiu"}, - {VKD3D_SM5_OP_IBFE, VKD3DSIH_IBFE, "i", "iii"}, - {VKD3D_SM5_OP_BFI, VKD3DSIH_BFI, "u", "iiuu"}, - {VKD3D_SM5_OP_BFREV, VKD3DSIH_BFREV, "u", "u"}, - {VKD3D_SM5_OP_SWAPC, VKD3DSIH_SWAPC, "ff", "uff"}, - {VKD3D_SM5_OP_DCL_STREAM, VKD3DSIH_DCL_STREAM, "", "O"}, - {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VKD3DSIH_DCL_FUNCTION_BODY, "", "", + {VKD3D_SM5_OP_BUFINFO, VSIR_OP_BUFINFO, "i", "*"}, + {VKD3D_SM5_OP_DERIV_RTX_COARSE, VSIR_OP_DSX_COARSE, "f", "f"}, + {VKD3D_SM5_OP_DERIV_RTX_FINE, VSIR_OP_DSX_FINE, "f", "f"}, + {VKD3D_SM5_OP_DERIV_RTY_COARSE, VSIR_OP_DSY_COARSE, "f", "f"}, + {VKD3D_SM5_OP_DERIV_RTY_FINE, VSIR_OP_DSY_FINE, "f", "f"}, + {VKD3D_SM5_OP_GATHER4_C, VSIR_OP_GATHER4_C, "f", "f**f"}, + {VKD3D_SM5_OP_GATHER4_PO, VSIR_OP_GATHER4_PO, "f", "fi**"}, + {VKD3D_SM5_OP_GATHER4_PO_C, VSIR_OP_GATHER4_PO_C, "f", "fi**f"}, + {VKD3D_SM5_OP_RCP, VSIR_OP_RCP, "f", "f"}, + {VKD3D_SM5_OP_F32TOF16, VSIR_OP_F32TOF16, "u", "f"}, + {VKD3D_SM5_OP_F16TOF32, VSIR_OP_F16TOF32, "f", "u"}, + {VKD3D_SM5_OP_COUNTBITS, VSIR_OP_COUNTBITS, "u", "u"}, + {VKD3D_SM5_OP_FIRSTBIT_HI, VSIR_OP_FIRSTBIT_HI, "u", "u"}, + {VKD3D_SM5_OP_FIRSTBIT_LO, VSIR_OP_FIRSTBIT_LO, "u", "u"}, + {VKD3D_SM5_OP_FIRSTBIT_SHI, VSIR_OP_FIRSTBIT_SHI, "u", "i"}, + {VKD3D_SM5_OP_UBFE, VSIR_OP_UBFE, "u", "iiu"}, + {VKD3D_SM5_OP_IBFE, VSIR_OP_IBFE, "i", "iii"}, + {VKD3D_SM5_OP_BFI, VSIR_OP_BFI, "u", "iiuu"}, + {VKD3D_SM5_OP_BFREV, VSIR_OP_BFREV, "u", "u"}, + {VKD3D_SM5_OP_SWAPC, VSIR_OP_SWAPC, "ff", "uff"}, + {VKD3D_SM5_OP_DCL_STREAM, VSIR_OP_DCL_STREAM, "", "*"}, + {VKD3D_SM5_OP_DCL_FUNCTION_BODY, VSIR_OP_DCL_FUNCTION_BODY, "", "", shader_sm5_read_dcl_function_body}, - {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VKD3DSIH_DCL_FUNCTION_TABLE, "", "", + {VKD3D_SM5_OP_DCL_FUNCTION_TABLE, VSIR_OP_DCL_FUNCTION_TABLE, "", "", shader_sm5_read_dcl_function_table}, - {VKD3D_SM5_OP_DCL_INTERFACE, VKD3DSIH_DCL_INTERFACE, "", "", + {VKD3D_SM5_OP_DCL_INTERFACE, VSIR_OP_DCL_INTERFACE, "", "", shader_sm5_read_dcl_interface}, - {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, "", "", + {VKD3D_SM5_OP_DCL_INPUT_CONTROL_POINT_COUNT, VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT, "", "", shader_sm5_read_control_point_count}, - {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", + {VKD3D_SM5_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, "", "", shader_sm5_read_control_point_count}, - {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VKD3DSIH_DCL_TESSELLATOR_DOMAIN, "", "", + {VKD3D_SM5_OP_DCL_TESSELLATOR_DOMAIN, VSIR_OP_DCL_TESSELLATOR_DOMAIN, "", "", shader_sm5_read_dcl_tessellator_domain}, - {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, "", "", + {VKD3D_SM5_OP_DCL_TESSELLATOR_PARTITIONING, VSIR_OP_DCL_TESSELLATOR_PARTITIONING, "", "", shader_sm5_read_dcl_tessellator_partitioning}, - {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", + {VKD3D_SM5_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, "", "", shader_sm5_read_dcl_tessellator_output_primitive}, - {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VKD3DSIH_DCL_HS_MAX_TESSFACTOR, "", "", + {VKD3D_SM5_OP_DCL_HS_MAX_TESSFACTOR, VSIR_OP_DCL_HS_MAX_TESSFACTOR, "", "", shader_sm5_read_dcl_hs_max_tessfactor}, - {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", + {VKD3D_SM5_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, "", "", shader_sm4_read_declaration_count}, - {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", + {VKD3D_SM5_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, "", "", shader_sm4_read_declaration_count}, - {VKD3D_SM5_OP_DCL_THREAD_GROUP, VKD3DSIH_DCL_THREAD_GROUP, "", "", + {VKD3D_SM5_OP_DCL_THREAD_GROUP, VSIR_OP_DCL_THREAD_GROUP, "", "", shader_sm5_read_dcl_thread_group}, - {VKD3D_SM5_OP_DCL_UAV_TYPED, VKD3DSIH_DCL_UAV_TYPED, "", "", + {VKD3D_SM5_OP_DCL_UAV_TYPED, VSIR_OP_DCL_UAV_TYPED, "", "", shader_sm4_read_dcl_resource}, - {VKD3D_SM5_OP_DCL_UAV_RAW, VKD3DSIH_DCL_UAV_RAW, "", "", + {VKD3D_SM5_OP_DCL_UAV_RAW, VSIR_OP_DCL_UAV_RAW, "", "", shader_sm5_read_dcl_uav_raw}, - {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VKD3DSIH_DCL_UAV_STRUCTURED, "", "", + {VKD3D_SM5_OP_DCL_UAV_STRUCTURED, VSIR_OP_DCL_UAV_STRUCTURED, "", "", shader_sm5_read_dcl_uav_structured}, - {VKD3D_SM5_OP_DCL_TGSM_RAW, VKD3DSIH_DCL_TGSM_RAW, "", "", + {VKD3D_SM5_OP_DCL_TGSM_RAW, VSIR_OP_DCL_TGSM_RAW, "", "", shader_sm5_read_dcl_tgsm_raw}, - {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VKD3DSIH_DCL_TGSM_STRUCTURED, "", "", + {VKD3D_SM5_OP_DCL_TGSM_STRUCTURED, VSIR_OP_DCL_TGSM_STRUCTURED, "", "", shader_sm5_read_dcl_tgsm_structured}, - {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VKD3DSIH_DCL_RESOURCE_RAW, "", "", + {VKD3D_SM5_OP_DCL_RESOURCE_RAW, VSIR_OP_DCL_RESOURCE_RAW, "", "", shader_sm5_read_dcl_resource_raw}, - {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VKD3DSIH_DCL_RESOURCE_STRUCTURED, "", "", + {VKD3D_SM5_OP_DCL_RESOURCE_STRUCTURED, VSIR_OP_DCL_RESOURCE_STRUCTURED, "", "", shader_sm5_read_dcl_resource_structured}, - {VKD3D_SM5_OP_LD_UAV_TYPED, VKD3DSIH_LD_UAV_TYPED, "u", "i*"}, - {VKD3D_SM5_OP_STORE_UAV_TYPED, VKD3DSIH_STORE_UAV_TYPED, "*", "iu"}, - {VKD3D_SM5_OP_LD_RAW, VKD3DSIH_LD_RAW, "u", "i*"}, - {VKD3D_SM5_OP_STORE_RAW, VKD3DSIH_STORE_RAW, "*", "uu"}, - {VKD3D_SM5_OP_LD_STRUCTURED, VKD3DSIH_LD_STRUCTURED, "u", "ii*"}, - {VKD3D_SM5_OP_STORE_STRUCTURED, VKD3DSIH_STORE_STRUCTURED, "*", "iiu"}, - {VKD3D_SM5_OP_ATOMIC_AND, VKD3DSIH_ATOMIC_AND, "*", "iu"}, - {VKD3D_SM5_OP_ATOMIC_OR, VKD3DSIH_ATOMIC_OR, "*", "iu"}, - {VKD3D_SM5_OP_ATOMIC_XOR, VKD3DSIH_ATOMIC_XOR, "*", "iu"}, - {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VKD3DSIH_ATOMIC_CMP_STORE, "*", "iuu"}, - {VKD3D_SM5_OP_ATOMIC_IADD, VKD3DSIH_ATOMIC_IADD, "*", "ii"}, - {VKD3D_SM5_OP_ATOMIC_IMAX, VKD3DSIH_ATOMIC_IMAX, "*", "ii"}, - {VKD3D_SM5_OP_ATOMIC_IMIN, VKD3DSIH_ATOMIC_IMIN, "*", "ii"}, - {VKD3D_SM5_OP_ATOMIC_UMAX, VKD3DSIH_ATOMIC_UMAX, "*", "iu"}, - {VKD3D_SM5_OP_ATOMIC_UMIN, VKD3DSIH_ATOMIC_UMIN, "*", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VKD3DSIH_IMM_ATOMIC_ALLOC, "u", "*"}, - {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VKD3DSIH_IMM_ATOMIC_CONSUME, "u", "*"}, - {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VKD3DSIH_IMM_ATOMIC_IADD, "u*", "ii"}, - {VKD3D_SM5_OP_IMM_ATOMIC_AND, VKD3DSIH_IMM_ATOMIC_AND, "u*", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_OR, VKD3DSIH_IMM_ATOMIC_OR, "u*", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VKD3DSIH_IMM_ATOMIC_XOR, "u*", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VKD3DSIH_IMM_ATOMIC_EXCH, "u*", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VKD3DSIH_IMM_ATOMIC_CMP_EXCH, "u*", "iuu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VKD3DSIH_IMM_ATOMIC_IMAX, "i*", "ii"}, - {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VKD3DSIH_IMM_ATOMIC_IMIN, "i*", "ii"}, - {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VKD3DSIH_IMM_ATOMIC_UMAX, "u*", "iu"}, - {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VKD3DSIH_IMM_ATOMIC_UMIN, "u*", "iu"}, - {VKD3D_SM5_OP_SYNC, VKD3DSIH_SYNC, "", "", + {VKD3D_SM5_OP_LD_UAV_TYPED, VSIR_OP_LD_UAV_TYPED, "u", "i*"}, + {VKD3D_SM5_OP_STORE_UAV_TYPED, VSIR_OP_STORE_UAV_TYPED, "*", "iu"}, + {VKD3D_SM5_OP_LD_RAW, VSIR_OP_LD_RAW, "u", "i*"}, + {VKD3D_SM5_OP_STORE_RAW, VSIR_OP_STORE_RAW, "*", "uu"}, + {VKD3D_SM5_OP_LD_STRUCTURED, VSIR_OP_LD_STRUCTURED, "u", "ii*"}, + {VKD3D_SM5_OP_STORE_STRUCTURED, VSIR_OP_STORE_STRUCTURED, "*", "iiu"}, + {VKD3D_SM5_OP_ATOMIC_AND, VSIR_OP_ATOMIC_AND, "*", "iu"}, + {VKD3D_SM5_OP_ATOMIC_OR, VSIR_OP_ATOMIC_OR, "*", "iu"}, + {VKD3D_SM5_OP_ATOMIC_XOR, VSIR_OP_ATOMIC_XOR, "*", "iu"}, + {VKD3D_SM5_OP_ATOMIC_CMP_STORE, VSIR_OP_ATOMIC_CMP_STORE, "*", "iuu"}, + {VKD3D_SM5_OP_ATOMIC_IADD, VSIR_OP_ATOMIC_IADD, "*", "ii"}, + {VKD3D_SM5_OP_ATOMIC_IMAX, VSIR_OP_ATOMIC_IMAX, "*", "ii"}, + {VKD3D_SM5_OP_ATOMIC_IMIN, VSIR_OP_ATOMIC_IMIN, "*", "ii"}, + {VKD3D_SM5_OP_ATOMIC_UMAX, VSIR_OP_ATOMIC_UMAX, "*", "iu"}, + {VKD3D_SM5_OP_ATOMIC_UMIN, VSIR_OP_ATOMIC_UMIN, "*", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_ALLOC, VSIR_OP_IMM_ATOMIC_ALLOC, "u", "*"}, + {VKD3D_SM5_OP_IMM_ATOMIC_CONSUME, VSIR_OP_IMM_ATOMIC_CONSUME, "u", "*"}, + {VKD3D_SM5_OP_IMM_ATOMIC_IADD, VSIR_OP_IMM_ATOMIC_IADD, "u*", "ii"}, + {VKD3D_SM5_OP_IMM_ATOMIC_AND, VSIR_OP_IMM_ATOMIC_AND, "u*", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_OR, VSIR_OP_IMM_ATOMIC_OR, "u*", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_XOR, VSIR_OP_IMM_ATOMIC_XOR, "u*", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_EXCH, VSIR_OP_IMM_ATOMIC_EXCH, "u*", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_CMP_EXCH, VSIR_OP_IMM_ATOMIC_CMP_EXCH, "u*", "iuu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_IMAX, VSIR_OP_IMM_ATOMIC_IMAX, "i*", "ii"}, + {VKD3D_SM5_OP_IMM_ATOMIC_IMIN, VSIR_OP_IMM_ATOMIC_IMIN, "i*", "ii"}, + {VKD3D_SM5_OP_IMM_ATOMIC_UMAX, VSIR_OP_IMM_ATOMIC_UMAX, "u*", "iu"}, + {VKD3D_SM5_OP_IMM_ATOMIC_UMIN, VSIR_OP_IMM_ATOMIC_UMIN, "u*", "iu"}, + {VKD3D_SM5_OP_SYNC, VSIR_OP_SYNC, "", "", shader_sm5_read_sync}, - {VKD3D_SM5_OP_DADD, VKD3DSIH_DADD, "d", "dd"}, - {VKD3D_SM5_OP_DMAX, VKD3DSIH_DMAX, "d", "dd"}, - {VKD3D_SM5_OP_DMIN, VKD3DSIH_DMIN, "d", "dd"}, - {VKD3D_SM5_OP_DMUL, VKD3DSIH_DMUL, "d", "dd"}, - {VKD3D_SM5_OP_DEQ, VKD3DSIH_DEQO, "u", "dd"}, - {VKD3D_SM5_OP_DGE, VKD3DSIH_DGEO, "u", "dd"}, - {VKD3D_SM5_OP_DLT, VKD3DSIH_DLT, "u", "dd"}, - {VKD3D_SM5_OP_DNE, VKD3DSIH_DNE, "u", "dd"}, - {VKD3D_SM5_OP_DMOV, VKD3DSIH_DMOV, "d", "d"}, - {VKD3D_SM5_OP_DMOVC, VKD3DSIH_DMOVC, "d", "udd"}, - {VKD3D_SM5_OP_DTOF, VKD3DSIH_DTOF, "f", "d"}, - {VKD3D_SM5_OP_FTOD, VKD3DSIH_FTOD, "d", "f"}, - {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VKD3DSIH_EVAL_SAMPLE_INDEX, "f", "fi"}, - {VKD3D_SM5_OP_EVAL_CENTROID, VKD3DSIH_EVAL_CENTROID, "f", "f"}, - {VKD3D_SM5_OP_DCL_GS_INSTANCES, VKD3DSIH_DCL_GS_INSTANCES, "", "", + {VKD3D_SM5_OP_DADD, VSIR_OP_DADD, "d", "dd"}, + {VKD3D_SM5_OP_DMAX, VSIR_OP_DMAX, "d", "dd"}, + {VKD3D_SM5_OP_DMIN, VSIR_OP_DMIN, "d", "dd"}, + {VKD3D_SM5_OP_DMUL, VSIR_OP_DMUL, "d", "dd"}, + {VKD3D_SM5_OP_DEQ, VSIR_OP_DEQO, "u", "dd"}, + {VKD3D_SM5_OP_DGE, VSIR_OP_DGEO, "u", "dd"}, + {VKD3D_SM5_OP_DLT, VSIR_OP_DLT, "u", "dd"}, + {VKD3D_SM5_OP_DNE, VSIR_OP_DNE, "u", "dd"}, + {VKD3D_SM5_OP_DMOV, VSIR_OP_DMOV, "d", "d"}, + {VKD3D_SM5_OP_DMOVC, VSIR_OP_DMOVC, "d", "udd"}, + {VKD3D_SM5_OP_DTOF, VSIR_OP_DTOF, "f", "d"}, + {VKD3D_SM5_OP_FTOD, VSIR_OP_FTOD, "d", "f"}, + {VKD3D_SM5_OP_EVAL_SAMPLE_INDEX, VSIR_OP_EVAL_SAMPLE_INDEX, "f", "fi"}, + {VKD3D_SM5_OP_EVAL_CENTROID, VSIR_OP_EVAL_CENTROID, "f", "f"}, + {VKD3D_SM5_OP_DCL_GS_INSTANCES, VSIR_OP_DCL_GS_INSTANCES, "", "", shader_sm4_read_declaration_count}, - {VKD3D_SM5_OP_DDIV, VKD3DSIH_DDIV, "d", "dd"}, - {VKD3D_SM5_OP_DFMA, VKD3DSIH_DFMA, "d", "ddd"}, - {VKD3D_SM5_OP_DRCP, VKD3DSIH_DRCP, "d", "d"}, - {VKD3D_SM5_OP_MSAD, VKD3DSIH_MSAD, "u", "uuu"}, - {VKD3D_SM5_OP_DTOI, VKD3DSIH_DTOI, "i", "d"}, - {VKD3D_SM5_OP_DTOU, VKD3DSIH_DTOU, "u", "d"}, - {VKD3D_SM5_OP_ITOD, VKD3DSIH_ITOD, "d", "i"}, - {VKD3D_SM5_OP_UTOD, VKD3DSIH_UTOD, "d", "u"}, - {VKD3D_SM5_OP_GATHER4_S, VKD3DSIH_GATHER4_S, "uu", "f**"}, - {VKD3D_SM5_OP_GATHER4_C_S, VKD3DSIH_GATHER4_C_S, "fu", "f**f"}, - {VKD3D_SM5_OP_GATHER4_PO_S, VKD3DSIH_GATHER4_PO_S, "fu", "fi**"}, - {VKD3D_SM5_OP_GATHER4_PO_C_S, VKD3DSIH_GATHER4_PO_C_S, "fu", "fi**f"}, - {VKD3D_SM5_OP_LD_S, VKD3DSIH_LD_S, "uu", "i*"}, - {VKD3D_SM5_OP_LD2DMS_S, VKD3DSIH_LD2DMS_S, "uu", "i*i"}, - {VKD3D_SM5_OP_LD_UAV_TYPED_S, VKD3DSIH_LD_UAV_TYPED_S, "uu", "iU"}, - {VKD3D_SM5_OP_LD_RAW_S, VKD3DSIH_LD_RAW_S, "uu", "iU"}, - {VKD3D_SM5_OP_LD_STRUCTURED_S, VKD3DSIH_LD_STRUCTURED_S, "uu", "ii*"}, - {VKD3D_SM5_OP_SAMPLE_LOD_S, VKD3DSIH_SAMPLE_LOD_S, "uu", "f**f"}, - {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VKD3DSIH_SAMPLE_C_LZ_S, "fu", "f**f"}, - {VKD3D_SM5_OP_SAMPLE_CL_S, VKD3DSIH_SAMPLE_CL_S, "uu", "f**f"}, - {VKD3D_SM5_OP_SAMPLE_B_CL_S, VKD3DSIH_SAMPLE_B_CL_S, "uu", "f**ff"}, - {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VKD3DSIH_SAMPLE_GRAD_CL_S, "uu", "f**fff"}, - {VKD3D_SM5_OP_SAMPLE_C_CL_S, VKD3DSIH_SAMPLE_C_CL_S, "fu", "f**ff"}, - {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, + {VKD3D_SM5_OP_DDIV, VSIR_OP_DDIV, "d", "dd"}, + {VKD3D_SM5_OP_DFMA, VSIR_OP_DFMA, "d", "ddd"}, + {VKD3D_SM5_OP_DRCP, VSIR_OP_DRCP, "d", "d"}, + {VKD3D_SM5_OP_MSAD, VSIR_OP_MSAD, "u", "uuu"}, + {VKD3D_SM5_OP_DTOI, VSIR_OP_DTOI, "i", "d"}, + {VKD3D_SM5_OP_DTOU, VSIR_OP_DTOU, "u", "d"}, + {VKD3D_SM5_OP_ITOD, VSIR_OP_ITOD, "d", "i"}, + {VKD3D_SM5_OP_UTOD, VSIR_OP_UTOD, "d", "u"}, + {VKD3D_SM5_OP_GATHER4_S, VSIR_OP_GATHER4_S, "uu", "f**"}, + {VKD3D_SM5_OP_GATHER4_C_S, VSIR_OP_GATHER4_C_S, "fu", "f**f"}, + {VKD3D_SM5_OP_GATHER4_PO_S, VSIR_OP_GATHER4_PO_S, "fu", "fi**"}, + {VKD3D_SM5_OP_GATHER4_PO_C_S, VSIR_OP_GATHER4_PO_C_S, "fu", "fi**f"}, + {VKD3D_SM5_OP_LD_S, VSIR_OP_LD_S, "uu", "i*"}, + {VKD3D_SM5_OP_LD2DMS_S, VSIR_OP_LD2DMS_S, "uu", "i*i"}, + {VKD3D_SM5_OP_LD_UAV_TYPED_S, VSIR_OP_LD_UAV_TYPED_S, "uu", "iU"}, + {VKD3D_SM5_OP_LD_RAW_S, VSIR_OP_LD_RAW_S, "uu", "iU"}, + {VKD3D_SM5_OP_LD_STRUCTURED_S, VSIR_OP_LD_STRUCTURED_S, "uu", "ii*"}, + {VKD3D_SM5_OP_SAMPLE_LOD_S, VSIR_OP_SAMPLE_LOD_S, "uu", "f**f"}, + {VKD3D_SM5_OP_SAMPLE_C_LZ_S, VSIR_OP_SAMPLE_C_LZ_S, "fu", "f**f"}, + {VKD3D_SM5_OP_SAMPLE_CL_S, VSIR_OP_SAMPLE_CL_S, "uu", "f**f"}, + {VKD3D_SM5_OP_SAMPLE_B_CL_S, VSIR_OP_SAMPLE_B_CL_S, "uu", "f**ff"}, + {VKD3D_SM5_OP_SAMPLE_GRAD_CL_S, VSIR_OP_SAMPLE_GRAD_CL_S, "uu", "f**fff"}, + {VKD3D_SM5_OP_SAMPLE_C_CL_S, VSIR_OP_SAMPLE_C_CL_S, "fu", "f**ff"}, + {VKD3D_SM5_OP_CHECK_ACCESS_FULLY_MAPPED, VSIR_OP_CHECK_ACCESS_FULLY_MAPPED, "u", "u"}, };
static const struct vkd3d_sm4_register_type_info register_type_table[] = @@ -1941,7 +1941,7 @@ static const struct vkd3d_sm4_opcode_info *get_info_from_sm4_opcode( static const struct vkd3d_sm4_opcode_info *get_info_from_vsir_opcode( const struct vkd3d_sm4_lookup_tables *lookup, enum vkd3d_shader_opcode vsir_opcode) { - if (vsir_opcode >= VKD3DSIH_COUNT) + if (vsir_opcode >= VSIR_OP_COUNT) return NULL; return lookup->opcode_info_from_vsir[vsir_opcode]; } @@ -1982,25 +1982,25 @@ static enum vkd3d_sm4_stat_field get_stat_field_from_sm4_opcode( return field_info->field; }
-static enum vkd3d_data_type map_data_type(char t) +static enum vsir_data_type map_data_type(char t) { switch (t) { case 'd': - return VKD3D_DATA_DOUBLE; + return VSIR_DATA_F64; case 'f': - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; case 'i': - return VKD3D_DATA_INT; + return VSIR_DATA_I32; case 'u': - return VKD3D_DATA_UINT; + return VSIR_DATA_U32; case 'O': - return VKD3D_DATA_OPAQUE; + return VSIR_DATA_OPAQUE; case '*': - return VKD3D_DATA_UNUSED; + return VSIR_DATA_UNUSED; default: ERR("Invalid data type '%c'.\n", t); - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; } }
@@ -2021,7 +2021,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const reg_idx->offset = *(*ptr)++; else reg_idx->offset = 0; - shader_sm4_read_src_param(priv, ptr, end, VKD3D_DATA_INT, rel_addr); + shader_sm4_read_src_param(priv, ptr, end, VSIR_DATA_I32, rel_addr); } else { @@ -2033,7 +2033,7 @@ static bool shader_sm4_read_reg_idx(struct vkd3d_shader_sm4_parser *priv, const }
static bool shader_sm4_read_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, const uint32_t *end, - enum vkd3d_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) + enum vsir_data_type data_type, struct vkd3d_shader_register *param, enum vkd3d_shader_src_modifier *modifier) { const struct vkd3d_sm4_register_type_info *register_type_info; enum vkd3d_shader_register_type vsir_register_type; @@ -2234,12 +2234,9 @@ bool shader_sm4_is_scalar_register(const struct vkd3d_shader_register *reg) { switch (reg->type) { - case VKD3DSPR_COVERAGE: case VKD3DSPR_DEPTHOUT: case VKD3DSPR_DEPTHOUTGE: case VKD3DSPR_DEPTHOUTLE: - case VKD3DSPR_GSINSTID: - case VKD3DSPR_LOCALTHREADINDEX: case VKD3DSPR_OUTPOINTID: case VKD3DSPR_PRIMID: case VKD3DSPR_SAMPLEMASK: @@ -2286,7 +2283,7 @@ static bool register_is_control_point_input(const struct vkd3d_shader_register * const struct vkd3d_shader_sm4_parser *priv) { return reg->type == VKD3DSPR_INCONTROLPOINT || reg->type == VKD3DSPR_OUTCONTROLPOINT - || (reg->type == VKD3DSPR_INPUT && (priv->phase == VKD3DSIH_HS_CONTROL_POINT_PHASE + || (reg->type == VKD3DSPR_INPUT && (priv->phase == VSIR_OP_HS_CONTROL_POINT_PHASE || priv->p.program->shader_version.type == VKD3D_SHADER_TYPE_GEOMETRY)); }
@@ -2351,7 +2348,7 @@ static bool shader_sm4_validate_input_output_register(struct vkd3d_shader_sm4_pa }
static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, - const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_src_param *src_param) + const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_src_param *src_param) { unsigned int dimension, mask; uint32_t token; @@ -2439,7 +2436,7 @@ static bool shader_sm4_read_src_param(struct vkd3d_shader_sm4_parser *priv, cons }
static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, const uint32_t **ptr, - const uint32_t *end, enum vkd3d_data_type data_type, struct vkd3d_shader_dst_param *dst_param) + const uint32_t *end, enum vsir_data_type data_type, struct vkd3d_shader_dst_param *dst_param) { enum vkd3d_sm4_swizzle_type swizzle_type; enum vkd3d_shader_src_modifier modifier; @@ -2509,7 +2506,7 @@ static bool shader_sm4_read_dst_param(struct vkd3d_shader_sm4_parser *priv, cons break; }
- if (data_type == VKD3D_DATA_DOUBLE) + if (data_type == VSIR_DATA_F64) dst_param->write_mask = vsir_write_mask_64_from_32(dst_param->write_mask); /* Some scalar registers are declared with no write mask in shader bytecode. */ if (!dst_param->write_mask && shader_sm4_is_scalar_register(&dst_param->reg)) @@ -2570,7 +2567,7 @@ static void shader_sm4_read_instruction_modifier(uint32_t modifier, struct vkd3d if (!data_type || (data_type >= ARRAY_SIZE(data_type_table))) { FIXME("Unhandled data type %#x.\n", data_type); - ins->resource_data_type[i] = VKD3D_DATA_FLOAT; + ins->resource_data_type[i] = VSIR_DATA_F32; } else { @@ -2653,16 +2650,16 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(opcode_info = get_info_from_sm4_opcode(&sm4->lookup, opcode))) { FIXME("Unrecognized opcode %#x, opcode_token 0x%08x.\n", opcode, opcode_token); - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; *ptr += len; return; }
vsir_instruction_init(ins, &sm4->p.location, opcode_info->handler_idx); - if (ins->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE || ins->opcode == VKD3DSIH_HS_FORK_PHASE - || ins->opcode == VKD3DSIH_HS_JOIN_PHASE) + if (ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE || ins->opcode == VSIR_OP_HS_FORK_PHASE + || ins->opcode == VSIR_OP_HS_JOIN_PHASE) sm4->phase = ins->opcode; - sm4->has_control_point_phase |= ins->opcode == VKD3DSIH_HS_CONTROL_POINT_PHASE; + sm4->has_control_point_phase |= ins->opcode == VSIR_OP_HS_CONTROL_POINT_PHASE; ins->flags = 0; ins->coissue = false; ins->raw = false; @@ -2675,15 +2672,15 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str { ERR("Failed to allocate src parameters.\n"); vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; return; } ins->resource_type = VKD3D_SHADER_RESOURCE_NONE; ins->resource_stride = 0; - ins->resource_data_type[0] = VKD3D_DATA_FLOAT; - ins->resource_data_type[1] = VKD3D_DATA_FLOAT; - ins->resource_data_type[2] = VKD3D_DATA_FLOAT; - ins->resource_data_type[3] = VKD3D_DATA_FLOAT; + ins->resource_data_type[0] = VSIR_DATA_F32; + ins->resource_data_type[1] = VSIR_DATA_F32; + ins->resource_data_type[2] = VSIR_DATA_F32; + ins->resource_data_type[3] = VSIR_DATA_F32; memset(&ins->texel_offset, 0, sizeof(ins->texel_offset));
p = *ptr; @@ -2717,7 +2714,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str { ERR("Failed to allocate dst parameters.\n"); vkd3d_shader_parser_error(&sm4->p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; return; } for (i = 0; i < ins->dst_count; ++i) @@ -2725,7 +2722,7 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(shader_sm4_read_dst_param(sm4, &p, *ptr, map_data_type(opcode_info->dst_info[i]), &dst_params[i]))) { - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; return; } dst_params[i].modifiers |= instruction_dst_modifier; @@ -2736,17 +2733,21 @@ static void shader_sm4_read_instruction(struct vkd3d_shader_sm4_parser *sm4, str if (!(shader_sm4_read_src_param(sm4, &p, *ptr, map_data_type(opcode_info->src_info[i]), &src_params[i]))) { - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; return; } } }
+ if ((ins->opcode == VSIR_OP_SAMPLE_INFO && ins->flags & VKD3DSI_SAMPLE_INFO_UINT) + || (ins->opcode == VSIR_OP_RESINFO && ins->flags & VKD3DSI_RESINFO_UINT)) + ins->dst[0].reg.data_type = VSIR_DATA_U32; + return;
fail: *ptr = sm4->end; - ins->opcode = VKD3DSIH_INVALID; + ins->opcode = VSIR_OP_INVALID; return; }
@@ -2895,7 +2896,6 @@ static void shader_sm4_validate_default_phase_index_ranges(struct vkd3d_shader_s int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, struct vkd3d_shader_message_context *message_context, struct vsir_program *program) { - struct vkd3d_shader_instruction_array *instructions; struct vkd3d_shader_sm4_parser sm4 = {0}; struct dxbc_shader_desc dxbc_desc = {0}; struct vkd3d_shader_instruction *ins; @@ -2955,26 +2955,22 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con return VKD3D_ERROR_INVALID_SHADER; }
- instructions = &program->instructions; while (sm4.ptr != sm4.end) { - if (!shader_instruction_array_reserve(instructions, instructions->count + 1)) + if (!(ins = vsir_program_append(program))) { - ERR("Failed to allocate instructions.\n"); vkd3d_shader_parser_error(&sm4.p, VKD3D_SHADER_ERROR_TPF_OUT_OF_MEMORY, "Out of memory."); vsir_program_cleanup(program); return VKD3D_ERROR_OUT_OF_MEMORY; } - ins = &instructions->elements[instructions->count]; shader_sm4_read_instruction(&sm4, ins);
- if (ins->opcode == VKD3DSIH_INVALID) + if (ins->opcode == VSIR_OP_INVALID) { WARN("Encountered unrecognized or invalid instruction.\n"); vsir_program_cleanup(program); return VKD3D_ERROR_OUT_OF_MEMORY; } - ++instructions->count; } if (program->shader_version.type == VKD3D_SHADER_TYPE_HULL && !sm4.has_control_point_phase && !sm4.p.failed) @@ -3129,6 +3125,9 @@ bool sm4_sysval_semantic_from_semantic_name(enum vkd3d_shader_sysval_semantic *s {"position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, {"sv_position", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_POSITION}, {"sv_primitiveid", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_PRIMITIVE_ID}, + {"sv_isfrontface", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_IS_FRONT_FACE}, + {"sv_rendertargetarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_RENDER_TARGET_ARRAY_INDEX}, + {"sv_viewportarrayindex", true, VKD3D_SHADER_TYPE_GEOMETRY, VKD3D_SHADER_SV_VIEWPORT_ARRAY_INDEX},
{"sv_outputcontrolpointid", false, VKD3D_SHADER_TYPE_HULL, ~0u}, {"sv_position", false, VKD3D_SHADER_TYPE_HULL, ~0u}, @@ -3255,6 +3254,8 @@ static int signature_element_pointer_compare(const void *x, const void *y) const struct signature_element *f = *(const struct signature_element **)y; int ret;
+ if ((ret = vkd3d_u32_compare(e->stream_index, f->stream_index))) + return ret; if ((ret = vkd3d_u32_compare(e->register_index, f->register_index))) return ret; return vkd3d_u32_compare(e->mask, f->mask); @@ -3263,12 +3264,17 @@ static int signature_element_pointer_compare(const void *x, const void *y) static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_signature *signature, uint32_t tag) { bool has_minimum_precision = tpf->program->global_flags & VKD3DSGF_ENABLE_MINIMUM_PRECISION; - bool output = tag == TAG_OSGN || (tag == TAG_PCSG - && tpf->program->shader_version.type == VKD3D_SHADER_TYPE_HULL); + const struct vkd3d_shader_version *version = &tpf->program->shader_version; const struct signature_element **sorted_elements; struct vkd3d_bytecode_buffer buffer = {0}; + bool has_stream_index, output; unsigned int i;
+ output = tag == TAG_OSGN || (tag == TAG_PCSG && version->type == VKD3D_SHADER_TYPE_HULL); + if (output && version->type == VKD3D_SHADER_TYPE_GEOMETRY && version->major >= 5) + tag = TAG_OSG5; + has_stream_index = tag == TAG_OSG5 || has_minimum_precision; + put_u32(&buffer, signature->element_count); put_u32(&buffer, 8); /* unknown */
@@ -3291,8 +3297,8 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si if (sysval >= VKD3D_SHADER_SV_TARGET) sysval = VKD3D_SHADER_SV_NONE;
- if (has_minimum_precision) - put_u32(&buffer, 0); /* FIXME: stream index */ + if (has_stream_index) + put_u32(&buffer, element->stream_index); put_u32(&buffer, 0); /* name */ put_u32(&buffer, element->semantic_index); put_u32(&buffer, sysval); @@ -3306,13 +3312,16 @@ static void tpf_write_signature(struct tpf_compiler *tpf, const struct shader_si for (i = 0; i < signature->element_count; ++i) { const struct signature_element *element = sorted_elements[i]; + size_t name_index = 2 + i * 6; size_t string_offset;
- string_offset = put_string(&buffer, element->semantic_name); + if (has_stream_index) + name_index += i + 1; if (has_minimum_precision) - set_u32(&buffer, (2 + i * 8 + 1) * sizeof(uint32_t), string_offset); - else - set_u32(&buffer, (2 + i * 6) * sizeof(uint32_t), string_offset); + name_index += i; + + string_offset = put_string(&buffer, element->semantic_name); + set_u32(&buffer, name_index * sizeof(uint32_t), string_offset); }
if (has_minimum_precision) @@ -3822,7 +3831,7 @@ static void tpf_dcl_sampler(const struct tpf_compiler *tpf, const struct vkd3d_s write_sm4_instruction(tpf, &instr); }
-static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_data_type) +static uint32_t pack_resource_data_type(const enum vsir_data_type *resource_data_type) { unsigned int i, k, type = 0;
@@ -3843,9 +3852,8 @@ static uint32_t pack_resource_data_type(const enum vkd3d_data_type *resource_dat
static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { - const struct vkd3d_shader_structured_resource *structured_resource = &ins->declaration.structured_resource; - const struct vkd3d_shader_semantic *semantic = &ins->declaration.semantic; const struct vkd3d_shader_version *version = &tpf->program->shader_version; + const struct vkd3d_shader_resource *resource; const struct vkd3d_sm4_opcode_info *info; struct sm4_instruction instr = {0}; bool uav; @@ -3853,33 +3861,44 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s info = get_info_from_vsir_opcode(&tpf->lookup, ins->opcode); VKD3D_ASSERT(info);
- uav = ins->opcode == VKD3DSIH_DCL_UAV_TYPED - || ins->opcode == VKD3DSIH_DCL_UAV_RAW - || ins->opcode == VKD3DSIH_DCL_UAV_STRUCTURED; + uav = ins->opcode == VSIR_OP_DCL_UAV_TYPED + || ins->opcode == VSIR_OP_DCL_UAV_RAW + || ins->opcode == VSIR_OP_DCL_UAV_STRUCTURED;
instr.opcode = info->opcode;
- instr.dsts[0] = semantic->resource.reg; - instr.dst_count = 1; - - if (ins->opcode == VKD3DSIH_DCL || ins->opcode == VKD3DSIH_DCL_UAV_TYPED) + if (ins->opcode == VSIR_OP_DCL || ins->opcode == VSIR_OP_DCL_UAV_TYPED) { - instr.idx[0] = pack_resource_data_type(semantic->resource_data_type); + instr.idx[0] = pack_resource_data_type(ins->declaration.semantic.resource_data_type); instr.idx_count = 1; + instr.extra_bits |= ins->declaration.semantic.sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT; + resource = &ins->declaration.semantic.resource; } + else if (ins->opcode == VSIR_OP_DCL_RESOURCE_RAW || ins->opcode == VSIR_OP_DCL_UAV_RAW) + { + resource = &ins->declaration.raw_resource.resource; + } + else + { + instr.byte_stride = ins->declaration.structured_resource.byte_stride; + resource = &ins->declaration.structured_resource.resource; + } + + instr.dsts[0] = resource->reg; + instr.dst_count = 1;
if (vkd3d_shader_ver_ge(version, 5, 1)) { - instr.dsts[0].reg.idx[0].offset = semantic->resource.reg.reg.idx[0].offset; - instr.dsts[0].reg.idx[1].offset = semantic->resource.range.first; - instr.dsts[0].reg.idx[2].offset = semantic->resource.range.last; + instr.dsts[0].reg.idx[0].offset = resource->reg.reg.idx[0].offset; + instr.dsts[0].reg.idx[1].offset = resource->range.first; + instr.dsts[0].reg.idx[2].offset = resource->range.last; instr.dsts[0].reg.idx_count = 3;
- instr.idx[instr.idx_count++] = semantic->resource.range.space; + instr.idx[instr.idx_count++] = resource->range.space; } else { - instr.dsts[0].reg.idx[0].offset = semantic->resource.range.first; + instr.dsts[0].reg.idx[0].offset = resource->range.first; instr.dsts[0].reg.idx_count = 1; }
@@ -3887,10 +3906,23 @@ static void tpf_dcl_texture(const struct tpf_compiler *tpf, const struct vkd3d_s instr.extra_bits |= ins->flags << VKD3D_SM5_UAV_FLAGS_SHIFT;
instr.extra_bits |= (sm4_resource_dimension(ins->resource_type) << VKD3D_SM4_RESOURCE_TYPE_SHIFT); - instr.extra_bits |= semantic->sample_count << VKD3D_SM4_RESOURCE_SAMPLE_COUNT_SHIFT;
- if (ins->structured) - instr.byte_stride = structured_resource->byte_stride; + write_sm4_instruction(tpf, &instr); +} + +static void tpf_dcl_tgsm_raw(const struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) +{ + const struct vkd3d_shader_tgsm_raw *tgsm = &ins->declaration.tgsm_raw; + struct sm4_instruction instr = + { + .opcode = VKD3D_SM5_OP_DCL_TGSM_RAW, + + .dsts[0] = tgsm->reg, + .dst_count = 1, + + .idx[0] = tgsm->byte_count, + .idx_count = 1, + };
write_sm4_instruction(tpf, &instr); } @@ -4024,6 +4056,39 @@ static void tpf_write_dcl_vertices_out(const struct tpf_compiler *tpf, unsigned write_sm4_instruction(tpf, &instr); }
+/* Descriptor registers are stored in shader model 5.1 format regardless + * of the program's version. Convert them to the 4.0 format if necessary. */ +static void rewrite_descriptor_register(const struct tpf_compiler *tpf, struct vkd3d_shader_register *reg) +{ + if (vkd3d_shader_ver_ge(&tpf->program->shader_version, 5, 1)) + return; + + switch (reg->type) + { + case VKD3DSPR_CONSTBUFFER: + reg->idx[0] = reg->idx[1]; + reg->idx[1] = reg->idx[2]; + reg->idx_count = 2; + break; + + case VKD3DSPR_RESOURCE: + case VKD3DSPR_SAMPLER: + case VKD3DSPR_UAV: + reg->idx[0] = reg->idx[1]; + reg->idx_count = 1; + break; + + default: + break; + } + + for (unsigned int i = 0; i < reg->idx_count; ++i) + { + if (reg->idx[i].rel_addr) + rewrite_descriptor_register(tpf, ®->idx[i].rel_addr->reg); + } +} + static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_shader_instruction *ins) { struct sm4_instruction_modifier *modifier; @@ -4039,14 +4104,14 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_
if (ins->dst_count != dst_count) { - ERR("Invalid destination count %u for vsir instruction %#x (expected %u).\n", + ERR("Invalid destination count %zu for vsir instruction %#x (expected %u).\n", ins->dst_count, ins->opcode, dst_count); tpf->result = VKD3D_ERROR_INVALID_SHADER; return; } if (ins->src_count != src_count) { - ERR("Invalid source count %u for vsir instruction %#x (expected %u).\n", + ERR("Invalid source count %zu for vsir instruction %#x (expected %u).\n", ins->src_count, ins->opcode, src_count); tpf->result = VKD3D_ERROR_INVALID_SHADER; return; @@ -4060,6 +4125,7 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ for (unsigned int i = 0; i < ins->dst_count; ++i) { instr.dsts[i] = ins->dst[i]; + rewrite_descriptor_register(tpf, &instr.dsts[i].reg);
if (instr.dsts[i].modifiers & VKD3DSPDM_SATURATE) { @@ -4070,7 +4136,10 @@ static void tpf_simple_instruction(struct tpf_compiler *tpf, const struct vkd3d_ } } for (unsigned int i = 0; i < ins->src_count; ++i) + { instr.srcs[i] = ins->src[i]; + rewrite_descriptor_register(tpf, &instr.srcs[i].reg); + }
if (ins->texel_offset.u || ins->texel_offset.v || ins->texel_offset.w) { @@ -4095,177 +4164,188 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ { switch (ins->opcode) { - case VKD3DSIH_DCL_CONSTANT_BUFFER: + case VSIR_OP_DCL_CONSTANT_BUFFER: tpf_dcl_constant_buffer(tpf, ins); break;
- case VKD3DSIH_DCL_TEMPS: + case VSIR_OP_DCL_TEMPS: tpf_dcl_temps(tpf, ins->declaration.count); break;
- case VKD3DSIH_DCL_INDEXABLE_TEMP: + case VSIR_OP_DCL_INDEXABLE_TEMP: tpf_dcl_indexable_temp(tpf, &ins->declaration.indexable_temp); break;
- case VKD3DSIH_DCL_INPUT: + case VSIR_OP_DCL_INPUT: tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT, &ins->declaration.dst, 0); break;
- case VKD3DSIH_DCL_INPUT_PS: + case VSIR_OP_DCL_INPUT_PS: tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS, &ins->declaration.dst, ins->flags); break;
- case VKD3DSIH_DCL_INPUT_PS_SGV: + case VSIR_OP_DCL_INPUT_PS_SGV: tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SGV, &ins->declaration.register_semantic, 0); break;
- case VKD3DSIH_DCL_INPUT_PS_SIV: + case VSIR_OP_DCL_INPUT_PS_SIV: tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_PS_SIV, &ins->declaration.register_semantic, ins->flags); break;
- case VKD3DSIH_DCL_INPUT_SGV: + case VSIR_OP_DCL_INPUT_SGV: tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SGV, &ins->declaration.register_semantic, 0); break;
- case VKD3DSIH_DCL_INPUT_SIV: + case VSIR_OP_DCL_INPUT_SIV: tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_INPUT_SIV, &ins->declaration.register_semantic, 0); break;
- case VKD3DSIH_DCL_OUTPUT: + case VSIR_OP_DCL_OUTPUT: tpf_dcl_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT, &ins->declaration.dst, 0); break;
- case VKD3DSIH_DCL_OUTPUT_SIV: + case VSIR_OP_DCL_OUTPUT_SGV: + tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SGV, &ins->declaration.register_semantic, 0); + break; + + case VSIR_OP_DCL_OUTPUT_SIV: tpf_dcl_siv_semantic(tpf, VKD3D_SM4_OP_DCL_OUTPUT_SIV, &ins->declaration.register_semantic, 0); break;
- case VKD3DSIH_DCL_SAMPLER: + case VSIR_OP_DCL_SAMPLER: tpf_dcl_sampler(tpf, ins); break;
- case VKD3DSIH_DCL: - case VKD3DSIH_DCL_RESOURCE_RAW: - case VKD3DSIH_DCL_UAV_RAW: - case VKD3DSIH_DCL_UAV_STRUCTURED: - case VKD3DSIH_DCL_UAV_TYPED: + case VSIR_OP_DCL_TGSM_RAW: + tpf_dcl_tgsm_raw(tpf, ins); + break; + + case VSIR_OP_DCL: + case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_UAV_RAW: + case VSIR_OP_DCL_UAV_STRUCTURED: + case VSIR_OP_DCL_UAV_TYPED: tpf_dcl_texture(tpf, ins); break;
- case VKD3DSIH_ADD: - case VKD3DSIH_ATOMIC_AND: - case VKD3DSIH_ATOMIC_CMP_STORE: - case VKD3DSIH_ATOMIC_IADD: - case VKD3DSIH_ATOMIC_IMAX: - case VKD3DSIH_ATOMIC_IMIN: - case VKD3DSIH_ATOMIC_UMAX: - case VKD3DSIH_ATOMIC_UMIN: - case VKD3DSIH_ATOMIC_OR: - case VKD3DSIH_ATOMIC_XOR: - case VKD3DSIH_AND: - case VKD3DSIH_BREAK: - case VKD3DSIH_CASE: - case VKD3DSIH_CONTINUE: - case VKD3DSIH_CUT: - case VKD3DSIH_DEFAULT: - case VKD3DSIH_DISCARD: - case VKD3DSIH_DIV: - case VKD3DSIH_DP2: - case VKD3DSIH_DP3: - case VKD3DSIH_DP4: - case VKD3DSIH_DSX: - case VKD3DSIH_DSX_COARSE: - case VKD3DSIH_DSX_FINE: - case VKD3DSIH_DSY: - case VKD3DSIH_DSY_COARSE: - case VKD3DSIH_DSY_FINE: - case VKD3DSIH_ELSE: - case VKD3DSIH_EMIT: - case VKD3DSIH_ENDIF: - case VKD3DSIH_ENDLOOP: - case VKD3DSIH_ENDSWITCH: - case VKD3DSIH_EQO: - case VKD3DSIH_EXP: - case VKD3DSIH_F16TOF32: - case VKD3DSIH_F32TOF16: - case VKD3DSIH_FRC: - case VKD3DSIH_FTOI: - case VKD3DSIH_FTOU: - case VKD3DSIH_GATHER4: - case VKD3DSIH_GATHER4_PO: - case VKD3DSIH_GATHER4_C: - case VKD3DSIH_GATHER4_PO_C: - case VKD3DSIH_GEO: - case VKD3DSIH_HS_CONTROL_POINT_PHASE: - case VKD3DSIH_HS_FORK_PHASE: - case VKD3DSIH_IADD: - case VKD3DSIH_IEQ: - case VKD3DSIH_IF: - case VKD3DSIH_IGE: - case VKD3DSIH_ILT: - case VKD3DSIH_IMAD: - case VKD3DSIH_IMAX: - case VKD3DSIH_IMIN: - case VKD3DSIH_IMM_ATOMIC_AND: - case VKD3DSIH_IMM_ATOMIC_CMP_EXCH: - case VKD3DSIH_IMM_ATOMIC_EXCH: - case VKD3DSIH_IMM_ATOMIC_IADD: - case VKD3DSIH_IMM_ATOMIC_IMAX: - case VKD3DSIH_IMM_ATOMIC_IMIN: - case VKD3DSIH_IMM_ATOMIC_UMAX: - case VKD3DSIH_IMM_ATOMIC_UMIN: - case VKD3DSIH_IMM_ATOMIC_OR: - case VKD3DSIH_IMM_ATOMIC_XOR: - case VKD3DSIH_SYNC: - case VKD3DSIH_IMUL: - case VKD3DSIH_INE: - case VKD3DSIH_INEG: - case VKD3DSIH_ISHL: - case VKD3DSIH_ISHR: - case VKD3DSIH_ITOF: - case VKD3DSIH_LD: - case VKD3DSIH_LD2DMS: - case VKD3DSIH_LD_RAW: - case VKD3DSIH_LD_UAV_TYPED: - case VKD3DSIH_LOG: - case VKD3DSIH_LOOP: - case VKD3DSIH_LTO: - case VKD3DSIH_MAD: - case VKD3DSIH_MAX: - case VKD3DSIH_MIN: - case VKD3DSIH_MOV: - case VKD3DSIH_MOVC: - case VKD3DSIH_MUL: - case VKD3DSIH_NEU: - case VKD3DSIH_NOT: - case VKD3DSIH_OR: - case VKD3DSIH_RCP: - case VKD3DSIH_RESINFO: - case VKD3DSIH_RET: - case VKD3DSIH_ROUND_NE: - case VKD3DSIH_ROUND_NI: - case VKD3DSIH_ROUND_PI: - case VKD3DSIH_ROUND_Z: - case VKD3DSIH_RSQ: - case VKD3DSIH_SAMPLE: - case VKD3DSIH_SAMPLE_B: - case VKD3DSIH_SAMPLE_C: - case VKD3DSIH_SAMPLE_C_LZ: - case VKD3DSIH_SAMPLE_GRAD: - case VKD3DSIH_SAMPLE_INFO: - case VKD3DSIH_SAMPLE_LOD: - case VKD3DSIH_SINCOS: - case VKD3DSIH_SQRT: - case VKD3DSIH_STORE_RAW: - case VKD3DSIH_STORE_UAV_TYPED: - case VKD3DSIH_SWITCH: - case VKD3DSIH_UDIV: - case VKD3DSIH_UGE: - case VKD3DSIH_ULT: - case VKD3DSIH_UMAX: - case VKD3DSIH_UMIN: - case VKD3DSIH_USHR: - case VKD3DSIH_UTOF: - case VKD3DSIH_XOR: + case VSIR_OP_ADD: + case VSIR_OP_ATOMIC_AND: + case VSIR_OP_ATOMIC_CMP_STORE: + case VSIR_OP_ATOMIC_IADD: + case VSIR_OP_ATOMIC_IMAX: + case VSIR_OP_ATOMIC_IMIN: + case VSIR_OP_ATOMIC_UMAX: + case VSIR_OP_ATOMIC_UMIN: + case VSIR_OP_ATOMIC_OR: + case VSIR_OP_ATOMIC_XOR: + case VSIR_OP_AND: + case VSIR_OP_BREAK: + case VSIR_OP_CASE: + case VSIR_OP_CONTINUE: + case VSIR_OP_CUT: + case VSIR_OP_CUT_STREAM: + case VSIR_OP_DCL_STREAM: + case VSIR_OP_DEFAULT: + case VSIR_OP_DISCARD: + case VSIR_OP_DIV: + case VSIR_OP_DP2: + case VSIR_OP_DP3: + case VSIR_OP_DP4: + case VSIR_OP_DSX: + case VSIR_OP_DSX_COARSE: + case VSIR_OP_DSX_FINE: + case VSIR_OP_DSY: + case VSIR_OP_DSY_COARSE: + case VSIR_OP_DSY_FINE: + case VSIR_OP_ELSE: + case VSIR_OP_EMIT: + case VSIR_OP_EMIT_STREAM: + case VSIR_OP_ENDIF: + case VSIR_OP_ENDLOOP: + case VSIR_OP_ENDSWITCH: + case VSIR_OP_EQO: + case VSIR_OP_EXP: + case VSIR_OP_F16TOF32: + case VSIR_OP_F32TOF16: + case VSIR_OP_FRC: + case VSIR_OP_FTOI: + case VSIR_OP_FTOU: + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_PO: + case VSIR_OP_GATHER4_C: + case VSIR_OP_GATHER4_PO_C: + case VSIR_OP_GEO: + case VSIR_OP_HS_CONTROL_POINT_PHASE: + case VSIR_OP_HS_FORK_PHASE: + case VSIR_OP_IADD: + case VSIR_OP_IEQ: + case VSIR_OP_IF: + case VSIR_OP_IGE: + case VSIR_OP_ILT: + case VSIR_OP_IMAD: + case VSIR_OP_IMAX: + case VSIR_OP_IMIN: + case VSIR_OP_IMM_ATOMIC_AND: + case VSIR_OP_IMM_ATOMIC_CMP_EXCH: + case VSIR_OP_IMM_ATOMIC_EXCH: + case VSIR_OP_IMM_ATOMIC_IADD: + case VSIR_OP_IMM_ATOMIC_IMAX: + case VSIR_OP_IMM_ATOMIC_IMIN: + case VSIR_OP_IMM_ATOMIC_UMAX: + case VSIR_OP_IMM_ATOMIC_UMIN: + case VSIR_OP_IMM_ATOMIC_OR: + case VSIR_OP_IMM_ATOMIC_XOR: + case VSIR_OP_SYNC: + case VSIR_OP_IMUL: + case VSIR_OP_INE: + case VSIR_OP_INEG: + case VSIR_OP_ISHL: + case VSIR_OP_ISHR: + case VSIR_OP_ITOF: + case VSIR_OP_LD: + case VSIR_OP_LD2DMS: + case VSIR_OP_LD_RAW: + case VSIR_OP_LD_UAV_TYPED: + case VSIR_OP_LOG: + case VSIR_OP_LOOP: + case VSIR_OP_LTO: + case VSIR_OP_MAD: + case VSIR_OP_MAX: + case VSIR_OP_MIN: + case VSIR_OP_MOV: + case VSIR_OP_MOVC: + case VSIR_OP_MUL: + case VSIR_OP_NEU: + case VSIR_OP_NOT: + case VSIR_OP_OR: + case VSIR_OP_RCP: + case VSIR_OP_RESINFO: + case VSIR_OP_RET: + case VSIR_OP_ROUND_NE: + case VSIR_OP_ROUND_NI: + case VSIR_OP_ROUND_PI: + case VSIR_OP_ROUND_Z: + case VSIR_OP_RSQ: + case VSIR_OP_SAMPLE: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: + case VSIR_OP_SAMPLE_GRAD: + case VSIR_OP_SAMPLE_INFO: + case VSIR_OP_SAMPLE_LOD: + case VSIR_OP_SINCOS: + case VSIR_OP_SQRT: + case VSIR_OP_STORE_RAW: + case VSIR_OP_STORE_UAV_TYPED: + case VSIR_OP_SWITCH: + case VSIR_OP_UDIV: + case VSIR_OP_UGE: + case VSIR_OP_ULT: + case VSIR_OP_UMAX: + case VSIR_OP_UMIN: + case VSIR_OP_USHR: + case VSIR_OP_UTOF: + case VSIR_OP_XOR: tpf_simple_instruction(tpf, ins); break;
@@ -4275,20 +4355,23 @@ static void tpf_handle_instruction(struct tpf_compiler *tpf, const struct vkd3d_ } }
-static void tpf_write_program(struct tpf_compiler *tpf, const struct vsir_program *program) +static void tpf_write_program(struct tpf_compiler *tpf, struct vsir_program *program) { - unsigned int i; + struct vsir_program_iterator it = vsir_program_iterator(&program->instructions); + struct vkd3d_shader_instruction *ins;
if (tpf->program->shader_version.type == VKD3D_SHADER_TYPE_COMPUTE) tpf_dcl_thread_group(tpf, &tpf->program->thread_group_size);
- for (i = 0; i < program->instructions.count; ++i) - tpf_handle_instruction(tpf, &program->instructions.elements[i]); + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) + { + tpf_handle_instruction(tpf, ins); + } }
static void tpf_write_shdr(struct tpf_compiler *tpf) { - const struct vsir_program *program = tpf->program; + struct vsir_program *program = tpf->program; const struct vkd3d_shader_version *version; struct vkd3d_bytecode_buffer buffer = {0}; size_t token_count_position; @@ -4434,6 +4517,12 @@ int tpf_compile(struct vsir_program *program, uint64_t config_flags, const struc size_t i; int ret;
+ if ((ret = vsir_allocate_temp_registers(program, message_context))) + return ret; + + if ((ret = vsir_update_dcl_temps(program, message_context))) + return ret; + tpf.program = program; tpf.buffer = NULL; tpf.stat = &stat; diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c index f56608940db..5fcc836aae1 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_main.c @@ -55,6 +55,39 @@ uint32_t vkd3d_parse_integer(const char *s) return ret; }
+bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source) +{ + char *s; + + if (!(s = vkd3d_strdup(source))) + return false; + + if (!vkd3d_array_reserve((void **)&l->sources, &l->capacity, l->count + 1, sizeof(*l->sources))) + { + vkd3d_free(s); + return false; + } + l->sources[l->count++] = s; + + return true; +} + +void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l) +{ + size_t i; + + for (i = 0; i < l->count; ++i) + { + vkd3d_free((void *)l->sources[i]); + } + vkd3d_free(l->sources); +} + +void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l) +{ + memset(l, 0, sizeof(*l)); +} + void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) { buffer->buffer_size = 16; @@ -85,7 +118,7 @@ void vkd3d_string_buffer_truncate(struct vkd3d_string_buffer *buffer, size_t siz
static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int rc) { - unsigned int new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2; + size_t new_buffer_size = rc >= 0 ? buffer->content_size + rc + 1 : buffer->buffer_size * 2;
if (!vkd3d_array_reserve((void **)&buffer->buffer, &buffer->buffer_size, new_buffer_size, 1)) { @@ -98,7 +131,7 @@ static bool vkd3d_string_buffer_resize(struct vkd3d_string_buffer *buffer, int r
int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args) { - unsigned int rem; + size_t rem; va_list a; int rc;
@@ -133,7 +166,7 @@ int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *f
int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f) { - unsigned int idx = buffer->content_size + 1; + size_t idx = buffer->content_size + 1; int ret;
if (!(ret = vkd3d_string_buffer_printf(buffer, "%.8e", f)) && isfinite(f)) @@ -148,7 +181,7 @@ int vkd3d_string_buffer_print_f32(struct vkd3d_string_buffer *buffer, float f)
int vkd3d_string_buffer_print_f64(struct vkd3d_string_buffer *buffer, double d) { - unsigned int idx = buffer->content_size + 1; + size_t idx = buffer->content_size + 1; int ret;
if (!(ret = vkd3d_string_buffer_printf(buffer, "%.16e", d)) && isfinite(d)) @@ -336,7 +369,10 @@ bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_cont void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_log_level level, const char *format, va_list args) { - if (context->log_level < level) + struct vkd3d_string_buffer *messages = &context->messages; + size_t pos = messages->content_size; + + if (!WARN_ON() && context->log_level < level) return;
if (location) @@ -344,19 +380,26 @@ void vkd3d_shader_vnote(struct vkd3d_shader_message_context *context, const stru const char *source_name = location->source_name ? location->source_name : "<anonymous>";
if (location->line) - vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: ", + vkd3d_string_buffer_printf(messages, "%s:%u:%u: ", source_name, location->line, location->column); else - vkd3d_string_buffer_printf(&context->messages, "%s: ", source_name); + vkd3d_string_buffer_printf(messages, "%s: ", source_name); } - vkd3d_string_buffer_vprintf(&context->messages, format, args); - vkd3d_string_buffer_printf(&context->messages, "\n"); + vkd3d_string_buffer_vprintf(messages, format, args); + vkd3d_string_buffer_printf(messages, "\n"); + + WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); + if (context->log_level < level) + messages->content_size = pos; }
void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format, va_list args) { - if (context->log_level < VKD3D_SHADER_LOG_WARNING) + struct vkd3d_string_buffer *messages = &context->messages; + size_t pos = messages->content_size; + + if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_WARNING) return;
if (location) @@ -364,17 +407,21 @@ void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context, const s const char *source_name = location->source_name ? location->source_name : "<anonymous>";
if (location->line) - vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: W%04u: ", + vkd3d_string_buffer_printf(messages, "%s:%u:%u: W%04u: ", source_name, location->line, location->column, error); else - vkd3d_string_buffer_printf(&context->messages, "%s: W%04u: ", source_name, error); + vkd3d_string_buffer_printf(messages, "%s: W%04u: ", source_name, error); } else { - vkd3d_string_buffer_printf(&context->messages, "W%04u: ", error); + vkd3d_string_buffer_printf(messages, "W%04u: ", error); } - vkd3d_string_buffer_vprintf(&context->messages, format, args); - vkd3d_string_buffer_printf(&context->messages, "\n"); + vkd3d_string_buffer_vprintf(messages, format, args); + vkd3d_string_buffer_printf(messages, "\n"); + + WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); + if (context->log_level < VKD3D_SHADER_LOG_WARNING) + messages->content_size = pos; }
void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, @@ -390,7 +437,10 @@ void vkd3d_shader_warning(struct vkd3d_shader_message_context *context, const st void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, enum vkd3d_shader_error error, const char *format, va_list args) { - if (context->log_level < VKD3D_SHADER_LOG_ERROR) + struct vkd3d_string_buffer *messages = &context->messages; + size_t pos = messages->content_size; + + if (!WARN_ON() && context->log_level < VKD3D_SHADER_LOG_ERROR) return;
if (location) @@ -398,17 +448,21 @@ void vkd3d_shader_verror(struct vkd3d_shader_message_context *context, const str const char *source_name = location->source_name ? location->source_name : "<anonymous>";
if (location->line) - vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: E%04u: ", + vkd3d_string_buffer_printf(messages, "%s:%u:%u: E%04u: ", source_name, location->line, location->column, error); else - vkd3d_string_buffer_printf(&context->messages, "%s: E%04u: ", source_name, error); + vkd3d_string_buffer_printf(messages, "%s: E%04u: ", source_name, error); } else { - vkd3d_string_buffer_printf(&context->messages, "E%04u: ", error); + vkd3d_string_buffer_printf(messages, "E%04u: ", error); } - vkd3d_string_buffer_vprintf(&context->messages, format, args); - vkd3d_string_buffer_printf(&context->messages, "\n"); + vkd3d_string_buffer_vprintf(messages, format, args); + vkd3d_string_buffer_printf(messages, "\n"); + + WARN("%.*s", (int)(messages->content_size - pos), &messages->buffer[pos]); + if (context->log_level < VKD3D_SHADER_LOG_ERROR) + messages->content_size = pos; }
void vkd3d_shader_error(struct vkd3d_shader_message_context *context, const struct vkd3d_shader_location *location, @@ -744,12 +798,28 @@ static int vkd3d_shader_validate_compile_info(const struct vkd3d_shader_compile_ }
static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t config_flags, - struct vkd3d_shader_message_context *message_context, struct vsir_program *program) + const struct shader_dump_data *dump_data, struct vkd3d_shader_message_context *message_context, + struct vsir_program *program, struct vkd3d_shader_code *reflection_data) { + struct vkd3d_shader_compile_info preprocessed_info; + struct vkd3d_shader_code preprocessed; enum vkd3d_result ret;
switch (compile_info->source_type) { + case VKD3D_SHADER_SOURCE_HLSL: + if ((ret = preproc_lexer_parse(compile_info, &preprocessed, message_context)) >= 0) + { + vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC); + + preprocessed_info = *compile_info; + preprocessed_info.source = preprocessed; + ret = hlsl_parse(&preprocessed_info, message_context, program, reflection_data); + + vkd3d_shader_free_shader_code(&preprocessed); + } + break; + case VKD3D_SHADER_SOURCE_D3D_BYTECODE: ret = d3dbc_parse(compile_info, config_flags, message_context, program); break; @@ -780,13 +850,19 @@ static enum vkd3d_result vsir_parse(const struct vkd3d_shader_compile_info *comp
if (TRACE_ON()) vsir_program_trace(program); - - vsir_program_cleanup(program); - return ret; + goto fail; }
- if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE) - ret = vsir_program_transform_early(program, config_flags, compile_info, message_context); + if (compile_info->target_type != VKD3D_SHADER_TARGET_NONE + && (ret = vsir_program_transform_early(program, config_flags, compile_info, message_context)) < 0) + goto fail; + + return ret; + +fail: + vkd3d_shader_free_shader_code(reflection_data); + vsir_program_cleanup(program); + return ret; }
@@ -1018,11 +1094,11 @@ static bool vkd3d_shader_instruction_is_uav_read(const struct vkd3d_shader_instr { enum vkd3d_shader_opcode opcode = instruction->opcode;
- return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR) - || (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR) - || opcode == VKD3DSIH_LD_UAV_TYPED - || (opcode == VKD3DSIH_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV) - || (opcode == VKD3DSIH_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV); + return (VSIR_OP_ATOMIC_AND <= opcode && opcode <= VSIR_OP_ATOMIC_XOR) + || (VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR) + || opcode == VSIR_OP_LD_UAV_TYPED + || (opcode == VSIR_OP_LD_RAW && instruction->src[1].reg.type == VKD3DSPR_UAV) + || (opcode == VSIR_OP_LD_STRUCTURED && instruction->src[2].reg.type == VKD3DSPR_UAV); }
static void vkd3d_shader_scan_record_uav_read(struct vkd3d_shader_scan_context *context, @@ -1035,7 +1111,7 @@ static bool vkd3d_shader_instruction_is_uav_counter(const struct vkd3d_shader_in { enum vkd3d_shader_opcode opcode = instruction->opcode;
- return opcode == VKD3DSIH_IMM_ATOMIC_ALLOC || opcode == VKD3DSIH_IMM_ATOMIC_CONSUME; + return opcode == VSIR_OP_IMM_ATOMIC_ALLOC || opcode == VSIR_OP_IMM_ATOMIC_CONSUME; }
static void vkd3d_shader_scan_record_uav_counter(struct vkd3d_shader_scan_context *context, @@ -1048,8 +1124,8 @@ static bool vkd3d_shader_instruction_is_uav_atomic_op(const struct vkd3d_shader_ { enum vkd3d_shader_opcode opcode = instruction->opcode;
- return (VKD3DSIH_ATOMIC_AND <= opcode && opcode <= VKD3DSIH_ATOMIC_XOR) - || (VKD3DSIH_IMM_ATOMIC_ALLOC <= opcode && opcode <= VKD3DSIH_IMM_ATOMIC_XOR); + return (VSIR_OP_ATOMIC_AND <= opcode && opcode <= VSIR_OP_ATOMIC_XOR) + || (VSIR_OP_IMM_ATOMIC_ALLOC <= opcode && opcode <= VSIR_OP_IMM_ATOMIC_XOR); }
static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_context *context, @@ -1061,7 +1137,7 @@ static void vkd3d_shader_scan_record_uav_atomic_op(struct vkd3d_shader_scan_cont static struct vkd3d_shader_descriptor_info1 *vkd3d_shader_scan_add_descriptor(struct vkd3d_shader_scan_context *context, enum vkd3d_shader_descriptor_type type, const struct vkd3d_shader_register *reg, const struct vkd3d_shader_register_range *range, enum vkd3d_shader_resource_type resource_type, - enum vkd3d_data_type resource_data_type) + enum vsir_data_type resource_data_type) { struct vkd3d_shader_scan_descriptor_info1 *info = context->scan_descriptor_info; struct vkd3d_shader_descriptor_info1 *d; @@ -1097,7 +1173,7 @@ static void vkd3d_shader_scan_constant_buffer_declaration(struct vkd3d_shader_sc struct vkd3d_shader_descriptor_info1 *d;
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, - &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) + &cb->src.reg, &cb->range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) return; d->buffer_size = cb->size; } @@ -1109,7 +1185,7 @@ static void vkd3d_shader_scan_sampler_declaration(struct vkd3d_shader_scan_conte struct vkd3d_shader_descriptor_info1 *d;
if (!(d = vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, - &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED))) + &sampler->src.reg, &sampler->range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED))) return;
if (instruction->flags & VKD3DSI_SAMPLER_COMPARISON_MODE) @@ -1120,9 +1196,9 @@ static void vkd3d_shader_scan_combined_sampler_declaration( struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_semantic *semantic) { vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, &semantic->resource.reg.reg, - &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VKD3D_DATA_UNUSED); + &semantic->resource.range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, &semantic->resource.reg.reg, - &semantic->resource.range, semantic->resource_type, VKD3D_DATA_FLOAT); + &semantic->resource.range, semantic->resource_type, VSIR_DATA_F32); }
const struct vkd3d_shader_descriptor_info1 *vkd3d_shader_find_descriptor( @@ -1210,9 +1286,43 @@ static void vkd3d_shader_scan_combined_sampler_usage(struct vkd3d_shader_scan_co s->sampler_index = sampler_idx; }
+static void vkd3d_shader_scan_sample_instruction(struct vkd3d_shader_scan_context *context, + const struct vkd3d_shader_register *resource, const struct vkd3d_shader_register *sampler) +{ + unsigned int resource_idx = resource->idx[0].offset; + unsigned int sampler_idx = sampler->idx[0].offset; + + vkd3d_shader_scan_combined_sampler_usage(context, resource, sampler); + + if (!context->scan_descriptor_info) + return; + + /* Sample instructions lowered from 1.x texture instructions have no + * DCL, so we need to add the resource if it didn't already exist. + * Such descriptors have a fixed count, type, etc. */ + + if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, + VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource_idx)) + { + struct vkd3d_shader_register_range range = {.first = resource_idx, .last = resource_idx}; + + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SRV, resource, + &range, VKD3D_SHADER_RESOURCE_TEXTURE_2D, VSIR_DATA_F32); + } + + if (!vkd3d_shader_find_descriptor(context->scan_descriptor_info, + VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, sampler_idx)) + { + struct vkd3d_shader_register_range range = {.first = sampler_idx, .last = sampler_idx}; + + vkd3d_shader_scan_add_descriptor(context, VKD3D_SHADER_DESCRIPTOR_TYPE_SAMPLER, resource, + &range, VKD3D_SHADER_RESOURCE_NONE, VSIR_DATA_UNUSED); + } +} + static void vkd3d_shader_scan_resource_declaration(struct vkd3d_shader_scan_context *context, const struct vkd3d_shader_resource *resource, enum vkd3d_shader_resource_type resource_type, - enum vkd3d_data_type resource_data_type, unsigned int sample_count, + enum vsir_data_type resource_data_type, unsigned int sample_count, unsigned int structure_stride, bool raw, uint32_t flags) { struct vkd3d_shader_descriptor_info1 *d; @@ -1260,13 +1370,13 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte
switch (instruction->opcode) { - case VKD3DSIH_DCL_CONSTANT_BUFFER: + case VSIR_OP_DCL_CONSTANT_BUFFER: vkd3d_shader_scan_constant_buffer_declaration(context, instruction); break; - case VKD3DSIH_DCL_SAMPLER: + case VSIR_OP_DCL_SAMPLER: vkd3d_shader_scan_sampler_declaration(context, instruction); break; - case VKD3DSIH_DCL: + case VSIR_OP_DCL: if (instruction->declaration.semantic.resource_type == VKD3D_SHADER_RESOURCE_NONE) break;
@@ -1276,33 +1386,33 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte break; } /* fall through */ - case VKD3DSIH_DCL_UAV_TYPED: + case VSIR_OP_DCL_UAV_TYPED: vkd3d_shader_scan_typed_resource_declaration(context, instruction); break; - case VKD3DSIH_DCL_RESOURCE_RAW: - case VKD3DSIH_DCL_UAV_RAW: + case VSIR_OP_DCL_RESOURCE_RAW: + case VSIR_OP_DCL_UAV_RAW: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.raw_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, 0, true, instruction->flags); + VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0, 0, true, instruction->flags); break; - case VKD3DSIH_DCL_RESOURCE_STRUCTURED: - case VKD3DSIH_DCL_UAV_STRUCTURED: + case VSIR_OP_DCL_RESOURCE_STRUCTURED: + case VSIR_OP_DCL_UAV_STRUCTURED: vkd3d_shader_scan_resource_declaration(context, &instruction->declaration.structured_resource.resource, - VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT, 0, + VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32, 0, instruction->declaration.structured_resource.byte_stride, false, instruction->flags); break; - case VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: + case VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE: context->output_primitive = instruction->declaration.tessellator_output_primitive; break; - case VKD3DSIH_DCL_TESSELLATOR_PARTITIONING: + case VSIR_OP_DCL_TESSELLATOR_PARTITIONING: context->partitioning = instruction->declaration.tessellator_partitioning; break; - case VKD3DSIH_IF: - case VKD3DSIH_IFC: + case VSIR_OP_IF: + case VSIR_OP_IFC: cf_info = vkd3d_shader_scan_push_cf_info(context); cf_info->type = VKD3D_SHADER_BLOCK_IF; cf_info->inside_block = true; break; - case VKD3DSIH_ELSE: + case VSIR_OP_ELSE: if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, @@ -1311,7 +1421,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = true; break; - case VKD3DSIH_ENDIF: + case VSIR_OP_ENDIF: if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_IF) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, @@ -1320,12 +1430,12 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } vkd3d_shader_scan_pop_cf_info(context); break; - case VKD3DSIH_LOOP: + case VSIR_OP_LOOP: cf_info = vkd3d_shader_scan_push_cf_info(context); cf_info->type = VKD3D_SHADER_BLOCK_LOOP; cf_info->inside_block = true; break; - case VKD3DSIH_ENDLOOP: + case VSIR_OP_ENDLOOP: if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_LOOP) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, @@ -1334,11 +1444,11 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } vkd3d_shader_scan_pop_cf_info(context); break; - case VKD3DSIH_SWITCH: + case VSIR_OP_SWITCH: cf_info = vkd3d_shader_scan_push_cf_info(context); cf_info->type = VKD3D_SHADER_BLOCK_SWITCH; break; - case VKD3DSIH_ENDSWITCH: + case VSIR_OP_ENDSWITCH: if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH || cf_info->inside_block) { @@ -1348,7 +1458,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } vkd3d_shader_scan_pop_cf_info(context); break; - case VKD3DSIH_CASE: + case VSIR_OP_CASE: if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH) { @@ -1358,7 +1468,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = true; break; - case VKD3DSIH_DEFAULT: + case VSIR_OP_DEFAULT: if (!(cf_info = vkd3d_shader_scan_get_current_cf_info(context)) || cf_info->type != VKD3D_SHADER_BLOCK_SWITCH) { @@ -1375,7 +1485,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte cf_info->inside_block = true; cf_info->has_default = true; break; - case VKD3DSIH_BREAK: + case VSIR_OP_BREAK: if (!(cf_info = vkd3d_shader_scan_find_innermost_breakable_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, @@ -1384,7 +1494,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = false; break; - case VKD3DSIH_BREAKP: + case VSIR_OP_BREAKP: if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, @@ -1392,7 +1502,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_ERROR_INVALID_SHADER; } break; - case VKD3DSIH_CONTINUE: + case VSIR_OP_CONTINUE: if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, @@ -1401,7 +1511,7 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte } cf_info->inside_block = false; break; - case VKD3DSIH_CONTINUEP: + case VSIR_OP_CONTINUEP: if (!(cf_info = vkd3d_shader_scan_find_innermost_loop_cf_info(context))) { vkd3d_shader_scan_error(context, VKD3D_SHADER_ERROR_TPF_MISMATCHED_CF, @@ -1409,59 +1519,55 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_ERROR_INVALID_SHADER; } break; - case VKD3DSIH_RET: + case VSIR_OP_RET: if (context->cf_info_count) context->cf_info[context->cf_info_count - 1].inside_block = false; break; - case VKD3DSIH_TEX: - if (context->version->major == 1) - sampler_reg = &instruction->dst[0].reg; - else - sampler_reg = &instruction->src[1].reg; - vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg); - break; - case VKD3DSIH_TEXBEM: - case VKD3DSIH_TEXBEML: - case VKD3DSIH_TEXDP3TEX: - case VKD3DSIH_TEXM3x2TEX: - case VKD3DSIH_TEXM3x3SPEC: - case VKD3DSIH_TEXM3x3TEX: - case VKD3DSIH_TEXM3x3VSPEC: - case VKD3DSIH_TEXREG2AR: - case VKD3DSIH_TEXREG2GB: - case VKD3DSIH_TEXREG2RGB: + case VSIR_OP_TEX: + case VSIR_OP_TEXBEM: + case VSIR_OP_TEXBEML: + case VSIR_OP_TEXDP3TEX: + case VSIR_OP_TEXM3x2TEX: + case VSIR_OP_TEXM3x3SPEC: + case VSIR_OP_TEXM3x3TEX: + case VSIR_OP_TEXM3x3VSPEC: + case VSIR_OP_TEXREG2AR: + case VSIR_OP_TEXREG2GB: + case VSIR_OP_TEXREG2RGB: sampler_reg = &instruction->dst[0].reg; vkd3d_shader_scan_combined_sampler_usage(context, sampler_reg, sampler_reg); break; - case VKD3DSIH_GATHER4: - case VKD3DSIH_GATHER4_C: - case VKD3DSIH_SAMPLE: - case VKD3DSIH_SAMPLE_B: - case VKD3DSIH_SAMPLE_C: - case VKD3DSIH_SAMPLE_C_LZ: - case VKD3DSIH_SAMPLE_GRAD: - case VKD3DSIH_SAMPLE_LOD: + case VSIR_OP_GATHER4: + case VSIR_OP_GATHER4_C: + case VSIR_OP_SAMPLE_B: + case VSIR_OP_SAMPLE_C: + case VSIR_OP_SAMPLE_C_LZ: + case VSIR_OP_SAMPLE_GRAD: + case VSIR_OP_SAMPLE_LOD: vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, &instruction->src[2].reg); break; - case VKD3DSIH_GATHER4_PO: - case VKD3DSIH_GATHER4_PO_C: + case VSIR_OP_SAMPLE: + vkd3d_shader_scan_sample_instruction(context, &instruction->src[1].reg, &instruction->src[2].reg); + break; + case VSIR_OP_GATHER4_PO: + case VSIR_OP_GATHER4_PO_C: vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, &instruction->src[3].reg); break; - case VKD3DSIH_LD: - case VKD3DSIH_LD2DMS: + case VSIR_OP_LD: + case VSIR_OP_LD2DMS: vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL); break; - case VKD3DSIH_BUFINFO: - case VKD3DSIH_SAMPLE_INFO: + case VSIR_OP_BUFINFO: + case VSIR_OP_SAMPLE_INFO: if (instruction->src[0].reg.type == VKD3DSPR_RESOURCE) vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[0].reg, NULL); break; - case VKD3DSIH_LD_RAW: - case VKD3DSIH_RESINFO: + case VSIR_OP_LD_RAW: + case VSIR_OP_RESINFO: if (instruction->src[1].reg.type == VKD3DSPR_RESOURCE) vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[1].reg, NULL); break; - case VKD3DSIH_LD_STRUCTURED: + case VSIR_OP_LD_STRUCTURED: if (instruction->src[2].reg.type == VKD3DSPR_RESOURCE) vkd3d_shader_scan_combined_sampler_usage(context, &instruction->src[2].reg, NULL); break; @@ -1498,27 +1604,27 @@ static int vkd3d_shader_scan_instruction(struct vkd3d_shader_scan_context *conte return VKD3D_OK; }
-static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vkd3d_data_type data_type) +static enum vkd3d_shader_resource_data_type vkd3d_resource_data_type_from_data_type(enum vsir_data_type data_type) { switch (data_type) { - case VKD3D_DATA_UNORM: - return VKD3D_SHADER_RESOURCE_DATA_UNORM; - case VKD3D_DATA_SNORM: - return VKD3D_SHADER_RESOURCE_DATA_SNORM; - case VKD3D_DATA_INT: + case VSIR_DATA_F32: + return VKD3D_SHADER_RESOURCE_DATA_FLOAT; + case VSIR_DATA_F64: + return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; + case VSIR_DATA_I32: return VKD3D_SHADER_RESOURCE_DATA_INT; - case VKD3D_DATA_UINT: + case VSIR_DATA_U32: return VKD3D_SHADER_RESOURCE_DATA_UINT; - case VKD3D_DATA_FLOAT: - return VKD3D_SHADER_RESOURCE_DATA_FLOAT; - case VKD3D_DATA_MIXED: + case VSIR_DATA_SNORM: + return VKD3D_SHADER_RESOURCE_DATA_SNORM; + case VSIR_DATA_UNORM: + return VKD3D_SHADER_RESOURCE_DATA_UNORM; + case VSIR_DATA_MIXED: return VKD3D_SHADER_RESOURCE_DATA_MIXED; - case VKD3D_DATA_DOUBLE: - return VKD3D_SHADER_RESOURCE_DATA_DOUBLE; - case VKD3D_DATA_CONTINUED: + case VSIR_DATA_CONTINUED: return VKD3D_SHADER_RESOURCE_DATA_CONTINUED; - case VKD3D_DATA_UNUSED: + case VSIR_DATA_UNUSED: return VKD3D_SHADER_RESOURCE_DATA_NONE; default: ERR("Invalid resource data type %#x.\n", data_type); @@ -1574,12 +1680,13 @@ void vkd3d_shader_free_scan_descriptor_info1(struct vkd3d_shader_scan_descriptor static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_message_context *message_context, bool add_descriptor_info) { + 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_descriptor_info *descriptor_info; struct vkd3d_shader_scan_signature_info *signature_info; - struct vkd3d_shader_instruction *instruction; struct vkd3d_shader_scan_context context; + struct vkd3d_shader_instruction *ins; int ret = VKD3D_OK; unsigned int i;
@@ -1607,10 +1714,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh if (TRACE_ON()) vsir_program_trace(program);
- for (i = 0; i < program->instructions.count; ++i) + for (ins = vsir_program_iterator_head(&it); ins; ins = vsir_program_iterator_next(&it)) { - instruction = &program->instructions.elements[i]; - if ((ret = vkd3d_shader_scan_instruction(&context, instruction)) < 0) + if ((ret = vkd3d_shader_scan_instruction(&context, ins)) < 0) break; }
@@ -1623,8 +1729,8 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh
if (size) { - if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, ®, - &range, VKD3D_SHADER_RESOURCE_BUFFER, VKD3D_DATA_UINT))) + if ((d = vkd3d_shader_scan_add_descriptor(&context, VKD3D_SHADER_DESCRIPTOR_TYPE_CBV, + ®, &range, VKD3D_SHADER_RESOURCE_BUFFER, VSIR_DATA_U32))) d->buffer_size = size * 16; } } @@ -1667,7 +1773,9 @@ static int vsir_program_scan(struct vsir_program *program, const struct vkd3d_sh int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char **messages) { struct vkd3d_shader_message_context message_context; + struct vkd3d_shader_code reflection_data = {0}; struct shader_dump_data dump_data; + struct vsir_program program; int ret;
TRACE("compile_info %p, messages %p.\n", compile_info, messages); @@ -1685,21 +1793,12 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char 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 (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) + if (!(ret = vsir_parse(compile_info, vkd3d_shader_init_config_flags(), + &dump_data, &message_context, &program, &reflection_data))) { - FIXME("HLSL support not implemented.\n"); - ret = VKD3D_ERROR_NOT_IMPLEMENTED; - } - else - { - uint64_t config_flags = vkd3d_shader_init_config_flags(); - struct vsir_program program; - - if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) - { - ret = vsir_program_scan(&program, compile_info, &message_context, false); - vsir_program_cleanup(&program); - } + ret = vsir_program_scan(&program, compile_info, &message_context, false); + vkd3d_shader_free_shader_code(&reflection_data); + vsir_program_cleanup(&program); }
vkd3d_shader_message_context_trace_messages(&message_context); @@ -1709,12 +1808,13 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char return ret; }
-int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, - struct vkd3d_shader_message_context *message_context) +static int vsir_program_compile(struct vsir_program *program, const struct vkd3d_shader_code *reflection_data, + uint64_t config_flags, const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { struct vkd3d_shader_scan_combined_resource_sampler_info combined_sampler_info; struct vkd3d_shader_compile_info scan_info; + enum vsir_asm_flags asm_flags; int ret;
scan_info = *compile_info; @@ -1722,7 +1822,25 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, switch (compile_info->target_type) { case VKD3D_SHADER_TARGET_D3D_ASM: - ret = d3d_asm_compile(program, compile_info, out, VSIR_ASM_FLAG_NONE); + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) + return ret; + asm_flags = VSIR_ASM_FLAG_NONE; + if (program->shader_version.major < 6 && compile_info->source_type != VKD3D_SHADER_SOURCE_DXBC_TPF + && compile_info->source_type != VKD3D_SHADER_SOURCE_D3D_BYTECODE) + asm_flags |= VSIR_ASM_FLAG_ALLOCATE_TEMPS; + ret = d3d_asm_compile(program, compile_info, out, asm_flags, message_context); + break; + + case VKD3D_SHADER_TARGET_D3D_BYTECODE: + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) + return ret; + ret = d3dbc_compile(program, config_flags, compile_info, reflection_data, out, message_context); + break; + + case VKD3D_SHADER_TARGET_DXBC_TPF: + if ((ret = vsir_program_scan(program, &scan_info, message_context, true)) < 0) + return ret; + ret = tpf_compile(program, config_flags, reflection_data, out, message_context); break;
case VKD3D_SHADER_TARGET_GLSL: @@ -1757,10 +1875,11 @@ int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, return ret; }
-static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info, +static int fx_compile(const struct vkd3d_shader_compile_info *compile_info, const struct shader_dump_data *dump_data, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) { + struct vkd3d_shader_compile_info preprocessed_info; struct vkd3d_shader_code preprocessed; int ret;
@@ -1769,7 +1888,9 @@ static int compile_hlsl(const struct vkd3d_shader_compile_info *compile_info,
vkd3d_shader_dump_shader(dump_data, preprocessed.code, preprocessed.size, SHADER_DUMP_TYPE_PREPROC);
- ret = hlsl_compile_shader(&preprocessed, compile_info, out, message_context); + preprocessed_info = *compile_info; + preprocessed_info.source = preprocessed; + ret = hlsl_compile_effect(&preprocessed_info, message_context, out);
vkd3d_shader_free_shader_code(&preprocessed); return ret; @@ -1797,22 +1918,30 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info, 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 (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL) + if (compile_info->source_type == VKD3D_SHADER_SOURCE_HLSL + && compile_info->target_type == VKD3D_SHADER_TARGET_FX) { - ret = compile_hlsl(compile_info, &dump_data, out, &message_context); + ret = fx_compile(compile_info, &dump_data, out, &message_context); } else if (compile_info->source_type == VKD3D_SHADER_SOURCE_FX) { ret = fx_parse(compile_info, out, &message_context); } + else if (compile_info->source_type == VKD3D_SHADER_SOURCE_TX) + { + ret = tx_parse(compile_info, out, &message_context); + } else { uint64_t config_flags = vkd3d_shader_init_config_flags(); + struct vkd3d_shader_code reflection_data = {0}; struct vsir_program program;
- if (!(ret = vsir_parse(compile_info, config_flags, &message_context, &program))) + if (!(ret = vsir_parse(compile_info, config_flags, &dump_data, + &message_context, &program, &reflection_data))) { - ret = vsir_program_compile(&program, config_flags, compile_info, out, &message_context); + ret = vsir_program_compile(&program, &reflection_data, config_flags, compile_info, out, &message_context); + vkd3d_shader_free_shader_code(&reflection_data); vsir_program_cleanup(&program); } } @@ -2013,6 +2142,7 @@ const enum vkd3d_shader_source_type *vkd3d_shader_get_supported_source_types(uns VKD3D_SHADER_SOURCE_D3D_BYTECODE, VKD3D_SHADER_SOURCE_DXBC_DXIL, VKD3D_SHADER_SOURCE_FX, + VKD3D_SHADER_SOURCE_TX, };
TRACE("count %p.\n", count); @@ -2070,6 +2200,9 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_SPIRV_TEXT, # endif VKD3D_SHADER_TARGET_D3D_ASM, +#ifdef VKD3D_SHADER_UNSUPPORTED_MSL + VKD3D_SHADER_TARGET_MSL, +#endif };
static const enum vkd3d_shader_target_type fx_types[] = @@ -2077,6 +2210,11 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( VKD3D_SHADER_TARGET_D3D_ASM, };
+ static const enum vkd3d_shader_target_type tx_types[] = + { + VKD3D_SHADER_TARGET_D3D_ASM, + }; + TRACE("source_type %#x, count %p.\n", source_type, count);
switch (source_type) @@ -2101,6 +2239,10 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types( *count = ARRAY_SIZE(fx_types); return fx_types;
+ case VKD3D_SHADER_SOURCE_TX: + *count = ARRAY_SIZE(tx_types); + return tx_types; + default: *count = 0; return NULL; @@ -2149,7 +2291,7 @@ static struct vkd3d_shader_param_node *shader_param_allocator_node_create( }
static void shader_param_allocator_init(struct vkd3d_shader_param_allocator *allocator, - unsigned int count, unsigned int stride) + size_t count, size_t stride) { allocator->count = max(count, MAX_REG_OUTPUT); allocator->stride = stride; @@ -2170,7 +2312,7 @@ static void shader_param_allocator_destroy(struct vkd3d_shader_param_allocator * } }
-void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count) +void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count) { void *params;
@@ -2196,18 +2338,18 @@ void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, return params; }
-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve) +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(*instructions->elements->dst)); - shader_param_allocator_init(&instructions->src_params, reserve * 2u, sizeof(*instructions->elements->src)); + 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, unsigned int 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))) @@ -2219,7 +2361,7 @@ bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *ins }
bool shader_instruction_array_insert_at(struct vkd3d_shader_instruction_array *instructions, - unsigned int idx, unsigned int count) + size_t idx, size_t count) { VKD3D_ASSERT(idx <= instructions->count);
@@ -2247,7 +2389,7 @@ bool shader_instruction_array_add_icb(struct vkd3d_shader_instruction_array *ins
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, - unsigned int count); + size_t count);
static bool shader_register_clone_relative_addresses(struct vkd3d_shader_register *reg, struct vkd3d_shader_instruction_array *instructions) @@ -2268,10 +2410,10 @@ static bool shader_register_clone_relative_addresses(struct vkd3d_shader_registe
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, - unsigned int count) + size_t count) { struct vkd3d_shader_dst_param *dst_params; - unsigned int i; + size_t i;
if (!(dst_params = shader_dst_param_allocator_get(&instructions->dst_params, count))) return NULL; @@ -2288,10 +2430,10 @@ static struct vkd3d_shader_dst_param *shader_instruction_array_clone_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, - unsigned int count) + size_t count) { struct vkd3d_shader_src_param *src_params; - unsigned int i; + size_t i;
if (!(src_params = shader_src_param_allocator_get(&instructions->src_params, count))) return NULL; @@ -2309,7 +2451,7 @@ static struct vkd3d_shader_src_param *shader_instruction_array_clone_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, - unsigned int dst, unsigned int src) + size_t dst, size_t src) { struct vkd3d_shader_instruction *ins = &instructions->elements[dst];
diff --git a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h index 3b4fb626fcc..e758c16b3d4 100644 --- a/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h +++ b/libs/vkd3d/libs/vkd3d-shader/vkd3d_shader_private.h @@ -174,6 +174,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_HLSL_INVALID_MAX_VERTEX_COUNT = 5042, VKD3D_SHADER_ERROR_HLSL_MISSING_PRIMITIVE_TYPE = 5043, VKD3D_SHADER_ERROR_HLSL_MISPLACED_STREAM_OUTPUT = 5044, + VKD3D_SHADER_ERROR_HLSL_MISSING_INPUT_PATCH = 5045,
VKD3D_SHADER_WARNING_HLSL_IMPLICIT_TRUNCATION = 5300, VKD3D_SHADER_WARNING_HLSL_DIVISION_BY_ZERO = 5301, @@ -182,6 +183,8 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_HLSL_NON_FINITE_RESULT = 5304, VKD3D_SHADER_WARNING_HLSL_IGNORED_ATTRIBUTE = 5305, VKD3D_SHADER_WARNING_HLSL_IGNORED_DEFAULT_VALUE = 5306, + VKD3D_SHADER_WARNING_HLSL_IGNORED_MODIFIER = 5307, + VKD3D_SHADER_WARNING_HLSL_OVERRIDDEN_SEMANTIC = 5308,
VKD3D_SHADER_ERROR_GLSL_INTERNAL = 6000, VKD3D_SHADER_ERROR_GLSL_BINDING_NOT_FOUND = 6001, @@ -222,6 +225,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_DXIL_INVALID_PROPERTIES = 8017, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCES = 8018, VKD3D_SHADER_ERROR_DXIL_INVALID_RESOURCE_HANDLE = 8019, + VKD3D_SHADER_ERROR_DXIL_INVALID_CONSTANT = 8020,
VKD3D_SHADER_WARNING_DXIL_UNKNOWN_MAGIC_NUMBER = 8300, VKD3D_SHADER_WARNING_DXIL_UNKNOWN_SHADER_TYPE = 8301, @@ -236,7 +240,7 @@ enum vkd3d_shader_error VKD3D_SHADER_WARNING_DXIL_UNDEFINED_OPERAND = 8310,
VKD3D_SHADER_ERROR_VSIR_NOT_IMPLEMENTED = 9000, - VKD3D_SHADER_ERROR_VSIR_INVALID_HANDLER = 9001, + VKD3D_SHADER_ERROR_VSIR_INVALID_OPCODE = 9001, VKD3D_SHADER_ERROR_VSIR_INVALID_REGISTER_TYPE = 9002, VKD3D_SHADER_ERROR_VSIR_INVALID_WRITE_MASK = 9003, VKD3D_SHADER_ERROR_VSIR_INVALID_MODIFIERS = 9004, @@ -262,6 +266,7 @@ enum vkd3d_shader_error VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_TYPE = 9024, VKD3D_SHADER_ERROR_VSIR_INVALID_RESOURCE_TYPE = 9025, VKD3D_SHADER_ERROR_VSIR_INVALID_DESCRIPTOR_COUNT = 9026, + VKD3D_SHADER_ERROR_VSIR_INVALID_FLAGS = 9027,
VKD3D_SHADER_WARNING_VSIR_DYNAMIC_DESCRIPTOR_ARRAY = 9300,
@@ -278,334 +283,345 @@ enum vkd3d_shader_error
enum vkd3d_shader_opcode { - VKD3DSIH_ABS, - VKD3DSIH_ACOS, - VKD3DSIH_ADD, - VKD3DSIH_AND, - VKD3DSIH_ASIN, - VKD3DSIH_ATAN, - VKD3DSIH_ATOMIC_AND, - VKD3DSIH_ATOMIC_CMP_STORE, - VKD3DSIH_ATOMIC_IADD, - VKD3DSIH_ATOMIC_IMAX, - VKD3DSIH_ATOMIC_IMIN, - VKD3DSIH_ATOMIC_OR, - VKD3DSIH_ATOMIC_UMAX, - VKD3DSIH_ATOMIC_UMIN, - VKD3DSIH_ATOMIC_XOR, - VKD3DSIH_BEM, - VKD3DSIH_BFI, - VKD3DSIH_BFREV, - VKD3DSIH_BRANCH, - VKD3DSIH_BREAK, - VKD3DSIH_BREAKC, - VKD3DSIH_BREAKP, - VKD3DSIH_BUFINFO, - VKD3DSIH_CALL, - VKD3DSIH_CALLNZ, - VKD3DSIH_CASE, - VKD3DSIH_CHECK_ACCESS_FULLY_MAPPED, - VKD3DSIH_CMP, - VKD3DSIH_CND, - VKD3DSIH_CONTINUE, - VKD3DSIH_CONTINUEP, - VKD3DSIH_COUNTBITS, - VKD3DSIH_CRS, - VKD3DSIH_CUT, - VKD3DSIH_CUT_STREAM, - VKD3DSIH_DADD, - VKD3DSIH_DCL, - VKD3DSIH_DCL_CONSTANT_BUFFER, - VKD3DSIH_DCL_FUNCTION_BODY, - VKD3DSIH_DCL_FUNCTION_TABLE, - VKD3DSIH_DCL_GLOBAL_FLAGS, - VKD3DSIH_DCL_GS_INSTANCES, - VKD3DSIH_DCL_HS_FORK_PHASE_INSTANCE_COUNT, - VKD3DSIH_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, - VKD3DSIH_DCL_HS_MAX_TESSFACTOR, - VKD3DSIH_DCL_IMMEDIATE_CONSTANT_BUFFER, - VKD3DSIH_DCL_INDEX_RANGE, - VKD3DSIH_DCL_INDEXABLE_TEMP, - VKD3DSIH_DCL_INPUT, - VKD3DSIH_DCL_INPUT_CONTROL_POINT_COUNT, - VKD3DSIH_DCL_INPUT_PRIMITIVE, - VKD3DSIH_DCL_INPUT_PS, - VKD3DSIH_DCL_INPUT_PS_SGV, - VKD3DSIH_DCL_INPUT_PS_SIV, - VKD3DSIH_DCL_INPUT_SGV, - VKD3DSIH_DCL_INPUT_SIV, - VKD3DSIH_DCL_INTERFACE, - VKD3DSIH_DCL_OUTPUT, - VKD3DSIH_DCL_OUTPUT_CONTROL_POINT_COUNT, - VKD3DSIH_DCL_OUTPUT_SIV, - VKD3DSIH_DCL_OUTPUT_TOPOLOGY, - VKD3DSIH_DCL_RESOURCE_RAW, - VKD3DSIH_DCL_RESOURCE_STRUCTURED, - VKD3DSIH_DCL_SAMPLER, - VKD3DSIH_DCL_STREAM, - VKD3DSIH_DCL_TEMPS, - VKD3DSIH_DCL_TESSELLATOR_DOMAIN, - VKD3DSIH_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, - VKD3DSIH_DCL_TESSELLATOR_PARTITIONING, - VKD3DSIH_DCL_TGSM_RAW, - VKD3DSIH_DCL_TGSM_STRUCTURED, - VKD3DSIH_DCL_THREAD_GROUP, - VKD3DSIH_DCL_UAV_RAW, - VKD3DSIH_DCL_UAV_STRUCTURED, - VKD3DSIH_DCL_UAV_TYPED, - VKD3DSIH_DCL_VERTICES_OUT, - VKD3DSIH_DDIV, - VKD3DSIH_DEF, - VKD3DSIH_DEFAULT, - VKD3DSIH_DEFB, - VKD3DSIH_DEFI, - VKD3DSIH_DEQO, - VKD3DSIH_DFMA, - VKD3DSIH_DGEO, - VKD3DSIH_DISCARD, - VKD3DSIH_DIV, - VKD3DSIH_DLT, - VKD3DSIH_DMAX, - VKD3DSIH_DMIN, - VKD3DSIH_DMOV, - VKD3DSIH_DMOVC, - VKD3DSIH_DMUL, - VKD3DSIH_DNE, - VKD3DSIH_DP2, - VKD3DSIH_DP2ADD, - VKD3DSIH_DP3, - VKD3DSIH_DP4, - VKD3DSIH_DRCP, - VKD3DSIH_DST, - VKD3DSIH_DSX, - VKD3DSIH_DSX_COARSE, - VKD3DSIH_DSX_FINE, - VKD3DSIH_DSY, - VKD3DSIH_DSY_COARSE, - VKD3DSIH_DSY_FINE, - VKD3DSIH_DTOF, - VKD3DSIH_DTOI, - VKD3DSIH_DTOU, - VKD3DSIH_ELSE, - VKD3DSIH_EMIT, - VKD3DSIH_EMIT_STREAM, - VKD3DSIH_ENDIF, - VKD3DSIH_ENDLOOP, - VKD3DSIH_ENDREP, - VKD3DSIH_ENDSWITCH, - VKD3DSIH_EQO, - VKD3DSIH_EQU, - VKD3DSIH_EVAL_CENTROID, - VKD3DSIH_EVAL_SAMPLE_INDEX, - VKD3DSIH_EXP, - VKD3DSIH_EXPP, - VKD3DSIH_F16TOF32, - VKD3DSIH_F32TOF16, - VKD3DSIH_FCALL, - VKD3DSIH_FIRSTBIT_HI, - VKD3DSIH_FIRSTBIT_LO, - VKD3DSIH_FIRSTBIT_SHI, - VKD3DSIH_FRC, - VKD3DSIH_FREM, - VKD3DSIH_FTOD, - VKD3DSIH_FTOI, - VKD3DSIH_FTOU, - VKD3DSIH_GATHER4, - VKD3DSIH_GATHER4_C, - VKD3DSIH_GATHER4_C_S, - VKD3DSIH_GATHER4_PO, - VKD3DSIH_GATHER4_PO_C, - VKD3DSIH_GATHER4_PO_C_S, - VKD3DSIH_GATHER4_PO_S, - VKD3DSIH_GATHER4_S, - VKD3DSIH_GEO, - VKD3DSIH_GEU, - VKD3DSIH_HCOS, - VKD3DSIH_HS_CONTROL_POINT_PHASE, - VKD3DSIH_HS_DECLS, - VKD3DSIH_HS_FORK_PHASE, - VKD3DSIH_HS_JOIN_PHASE, - VKD3DSIH_HSIN, - VKD3DSIH_HTAN, - VKD3DSIH_IADD, - VKD3DSIH_IBFE, - VKD3DSIH_IDIV, - VKD3DSIH_IEQ, - VKD3DSIH_IF, - VKD3DSIH_IFC, - VKD3DSIH_IGE, - VKD3DSIH_ILT, - VKD3DSIH_IMAD, - VKD3DSIH_IMAX, - VKD3DSIH_IMIN, - VKD3DSIH_IMM_ATOMIC_ALLOC, - VKD3DSIH_IMM_ATOMIC_AND, - VKD3DSIH_IMM_ATOMIC_CMP_EXCH, - VKD3DSIH_IMM_ATOMIC_CONSUME, - VKD3DSIH_IMM_ATOMIC_EXCH, - VKD3DSIH_IMM_ATOMIC_IADD, - VKD3DSIH_IMM_ATOMIC_IMAX, - VKD3DSIH_IMM_ATOMIC_IMIN, - VKD3DSIH_IMM_ATOMIC_OR, - VKD3DSIH_IMM_ATOMIC_UMAX, - VKD3DSIH_IMM_ATOMIC_UMIN, - VKD3DSIH_IMM_ATOMIC_XOR, - VKD3DSIH_IMUL, - VKD3DSIH_INE, - VKD3DSIH_INEG, - VKD3DSIH_ISFINITE, - VKD3DSIH_ISHL, - VKD3DSIH_ISHR, - VKD3DSIH_ISINF, - VKD3DSIH_ISNAN, - VKD3DSIH_ITOD, - VKD3DSIH_ITOF, - VKD3DSIH_ITOI, - VKD3DSIH_LABEL, - VKD3DSIH_LD, - VKD3DSIH_LD2DMS, - VKD3DSIH_LD2DMS_S, - VKD3DSIH_LD_RAW, - VKD3DSIH_LD_RAW_S, - VKD3DSIH_LD_S, - VKD3DSIH_LD_STRUCTURED, - VKD3DSIH_LD_STRUCTURED_S, - VKD3DSIH_LD_UAV_TYPED, - VKD3DSIH_LD_UAV_TYPED_S, - VKD3DSIH_LIT, - VKD3DSIH_LOD, - VKD3DSIH_LOG, - VKD3DSIH_LOGP, - VKD3DSIH_LOOP, - VKD3DSIH_LRP, - VKD3DSIH_LTO, - VKD3DSIH_LTU, - VKD3DSIH_M3x2, - VKD3DSIH_M3x3, - VKD3DSIH_M3x4, - VKD3DSIH_M4x3, - VKD3DSIH_M4x4, - VKD3DSIH_MAD, - VKD3DSIH_MAX, - VKD3DSIH_MIN, - VKD3DSIH_MOV, - VKD3DSIH_MOVA, - VKD3DSIH_MOVC, - VKD3DSIH_MSAD, - VKD3DSIH_MUL, - VKD3DSIH_NEO, - VKD3DSIH_NEU, - VKD3DSIH_NOP, - VKD3DSIH_NOT, - VKD3DSIH_NRM, - VKD3DSIH_OR, - VKD3DSIH_ORD, - VKD3DSIH_PHASE, - VKD3DSIH_PHI, - VKD3DSIH_POW, - VKD3DSIH_QUAD_READ_ACROSS_D, - VKD3DSIH_QUAD_READ_ACROSS_X, - VKD3DSIH_QUAD_READ_ACROSS_Y, - VKD3DSIH_QUAD_READ_LANE_AT, - VKD3DSIH_RCP, - VKD3DSIH_REP, - VKD3DSIH_RESINFO, - VKD3DSIH_RET, - VKD3DSIH_RETP, - VKD3DSIH_ROUND_NE, - VKD3DSIH_ROUND_NI, - VKD3DSIH_ROUND_PI, - VKD3DSIH_ROUND_Z, - VKD3DSIH_RSQ, - VKD3DSIH_SAMPLE, - VKD3DSIH_SAMPLE_B, - VKD3DSIH_SAMPLE_B_CL_S, - VKD3DSIH_SAMPLE_C, - VKD3DSIH_SAMPLE_C_CL_S, - VKD3DSIH_SAMPLE_C_LZ, - VKD3DSIH_SAMPLE_C_LZ_S, - VKD3DSIH_SAMPLE_CL_S, - VKD3DSIH_SAMPLE_GRAD, - VKD3DSIH_SAMPLE_GRAD_CL_S, - VKD3DSIH_SAMPLE_INFO, - VKD3DSIH_SAMPLE_LOD, - VKD3DSIH_SAMPLE_LOD_S, - VKD3DSIH_SAMPLE_POS, - VKD3DSIH_SETP, - VKD3DSIH_SGE, - VKD3DSIH_SGN, - VKD3DSIH_SINCOS, - VKD3DSIH_SLT, - VKD3DSIH_SQRT, - VKD3DSIH_STORE_RAW, - VKD3DSIH_STORE_STRUCTURED, - VKD3DSIH_STORE_UAV_TYPED, - VKD3DSIH_SUB, - VKD3DSIH_SWAPC, - VKD3DSIH_SWITCH, - VKD3DSIH_SWITCH_MONOLITHIC, - VKD3DSIH_SYNC, - VKD3DSIH_TAN, - VKD3DSIH_TEX, - VKD3DSIH_TEXBEM, - VKD3DSIH_TEXBEML, - VKD3DSIH_TEXCOORD, - VKD3DSIH_TEXDEPTH, - VKD3DSIH_TEXDP3, - VKD3DSIH_TEXDP3TEX, - VKD3DSIH_TEXKILL, - VKD3DSIH_TEXLDD, - VKD3DSIH_TEXLDL, - VKD3DSIH_TEXM3x2DEPTH, - VKD3DSIH_TEXM3x2PAD, - VKD3DSIH_TEXM3x2TEX, - VKD3DSIH_TEXM3x3, - VKD3DSIH_TEXM3x3DIFF, - VKD3DSIH_TEXM3x3PAD, - VKD3DSIH_TEXM3x3SPEC, - VKD3DSIH_TEXM3x3TEX, - VKD3DSIH_TEXM3x3VSPEC, - VKD3DSIH_TEXREG2AR, - VKD3DSIH_TEXREG2GB, - VKD3DSIH_TEXREG2RGB, - VKD3DSIH_UBFE, - VKD3DSIH_UDIV, - VKD3DSIH_UGE, - VKD3DSIH_ULT, - VKD3DSIH_UMAX, - VKD3DSIH_UMIN, - VKD3DSIH_UMUL, - VKD3DSIH_UNO, - VKD3DSIH_USHR, - VKD3DSIH_UTOD, - VKD3DSIH_UTOF, - VKD3DSIH_UTOU, - VKD3DSIH_WAVE_ACTIVE_ALL_EQUAL, - VKD3DSIH_WAVE_ACTIVE_BALLOT, - VKD3DSIH_WAVE_ACTIVE_BIT_AND, - VKD3DSIH_WAVE_ACTIVE_BIT_OR, - VKD3DSIH_WAVE_ACTIVE_BIT_XOR, - VKD3DSIH_WAVE_ALL_BIT_COUNT, - VKD3DSIH_WAVE_ALL_TRUE, - VKD3DSIH_WAVE_ANY_TRUE, - VKD3DSIH_WAVE_IS_FIRST_LANE, - VKD3DSIH_WAVE_OP_ADD, - VKD3DSIH_WAVE_OP_IMAX, - VKD3DSIH_WAVE_OP_IMIN, - VKD3DSIH_WAVE_OP_MAX, - VKD3DSIH_WAVE_OP_MIN, - VKD3DSIH_WAVE_OP_MUL, - VKD3DSIH_WAVE_OP_UMAX, - VKD3DSIH_WAVE_OP_UMIN, - VKD3DSIH_WAVE_PREFIX_BIT_COUNT, - VKD3DSIH_WAVE_READ_LANE_AT, - VKD3DSIH_WAVE_READ_LANE_FIRST, - VKD3DSIH_XOR, - - VKD3DSIH_INVALID, - - VKD3DSIH_COUNT, -}; + VSIR_OP_ABS, + VSIR_OP_ACOS, + VSIR_OP_ADD, + VSIR_OP_AND, + VSIR_OP_ASIN, + VSIR_OP_ATAN, + VSIR_OP_ATOMIC_AND, + VSIR_OP_ATOMIC_CMP_STORE, + VSIR_OP_ATOMIC_IADD, + VSIR_OP_ATOMIC_IMAX, + VSIR_OP_ATOMIC_IMIN, + VSIR_OP_ATOMIC_OR, + VSIR_OP_ATOMIC_UMAX, + VSIR_OP_ATOMIC_UMIN, + VSIR_OP_ATOMIC_XOR, + VSIR_OP_BEM, + VSIR_OP_BFI, + VSIR_OP_BFREV, + VSIR_OP_BRANCH, + VSIR_OP_BREAK, + VSIR_OP_BREAKC, + VSIR_OP_BREAKP, + VSIR_OP_BUFINFO, + VSIR_OP_CALL, + VSIR_OP_CALLNZ, + VSIR_OP_CASE, + VSIR_OP_CHECK_ACCESS_FULLY_MAPPED, + VSIR_OP_CMP, + VSIR_OP_CND, + VSIR_OP_CONTINUE, + VSIR_OP_CONTINUEP, + VSIR_OP_COS, + VSIR_OP_COUNTBITS, + VSIR_OP_CRS, + VSIR_OP_CUT, + VSIR_OP_CUT_STREAM, + VSIR_OP_DADD, + VSIR_OP_DCL, + VSIR_OP_DCL_CONSTANT_BUFFER, + VSIR_OP_DCL_FUNCTION_BODY, + VSIR_OP_DCL_FUNCTION_TABLE, + VSIR_OP_DCL_GLOBAL_FLAGS, + VSIR_OP_DCL_GS_INSTANCES, + VSIR_OP_DCL_HS_FORK_PHASE_INSTANCE_COUNT, + VSIR_OP_DCL_HS_JOIN_PHASE_INSTANCE_COUNT, + VSIR_OP_DCL_HS_MAX_TESSFACTOR, + VSIR_OP_DCL_IMMEDIATE_CONSTANT_BUFFER, + VSIR_OP_DCL_INDEX_RANGE, + VSIR_OP_DCL_INDEXABLE_TEMP, + VSIR_OP_DCL_INPUT, + VSIR_OP_DCL_INPUT_CONTROL_POINT_COUNT, + VSIR_OP_DCL_INPUT_PRIMITIVE, + VSIR_OP_DCL_INPUT_PS, + VSIR_OP_DCL_INPUT_PS_SGV, + VSIR_OP_DCL_INPUT_PS_SIV, + VSIR_OP_DCL_INPUT_SGV, + VSIR_OP_DCL_INPUT_SIV, + VSIR_OP_DCL_INTERFACE, + VSIR_OP_DCL_OUTPUT, + VSIR_OP_DCL_OUTPUT_CONTROL_POINT_COUNT, + VSIR_OP_DCL_OUTPUT_SGV, + VSIR_OP_DCL_OUTPUT_SIV, + VSIR_OP_DCL_OUTPUT_TOPOLOGY, + VSIR_OP_DCL_RESOURCE_RAW, + VSIR_OP_DCL_RESOURCE_STRUCTURED, + VSIR_OP_DCL_SAMPLER, + VSIR_OP_DCL_STREAM, + VSIR_OP_DCL_TEMPS, + VSIR_OP_DCL_TESSELLATOR_DOMAIN, + VSIR_OP_DCL_TESSELLATOR_OUTPUT_PRIMITIVE, + VSIR_OP_DCL_TESSELLATOR_PARTITIONING, + VSIR_OP_DCL_TGSM_RAW, + VSIR_OP_DCL_TGSM_STRUCTURED, + VSIR_OP_DCL_THREAD_GROUP, + VSIR_OP_DCL_UAV_RAW, + VSIR_OP_DCL_UAV_STRUCTURED, + VSIR_OP_DCL_UAV_TYPED, + VSIR_OP_DCL_VERTICES_OUT, + VSIR_OP_DDIV, + VSIR_OP_DEF, + VSIR_OP_DEFAULT, + VSIR_OP_DEFB, + VSIR_OP_DEFI, + VSIR_OP_DEQO, + VSIR_OP_DFMA, + VSIR_OP_DGEO, + VSIR_OP_DISCARD, + VSIR_OP_DIV, + VSIR_OP_DLT, + VSIR_OP_DMAX, + VSIR_OP_DMIN, + VSIR_OP_DMOV, + VSIR_OP_DMOVC, + VSIR_OP_DMUL, + VSIR_OP_DNE, + VSIR_OP_DP2, + VSIR_OP_DP2ADD, + VSIR_OP_DP3, + VSIR_OP_DP4, + VSIR_OP_DRCP, + VSIR_OP_DST, + VSIR_OP_DSX, + VSIR_OP_DSX_COARSE, + VSIR_OP_DSX_FINE, + VSIR_OP_DSY, + VSIR_OP_DSY_COARSE, + VSIR_OP_DSY_FINE, + VSIR_OP_DTOF, + VSIR_OP_DTOI, + VSIR_OP_DTOU, + VSIR_OP_ELSE, + VSIR_OP_EMIT, + VSIR_OP_EMIT_STREAM, + VSIR_OP_ENDIF, + VSIR_OP_ENDLOOP, + VSIR_OP_ENDREP, + VSIR_OP_ENDSWITCH, + VSIR_OP_EQO, + VSIR_OP_EQU, + VSIR_OP_EVAL_CENTROID, + VSIR_OP_EVAL_SAMPLE_INDEX, + VSIR_OP_EXP, + VSIR_OP_EXPP, + VSIR_OP_F16TOF32, + VSIR_OP_F32TOF16, + VSIR_OP_FCALL, + VSIR_OP_FIRSTBIT_HI, + VSIR_OP_FIRSTBIT_LO, + VSIR_OP_FIRSTBIT_SHI, + VSIR_OP_FRC, + VSIR_OP_FREM, + VSIR_OP_FTOD, + VSIR_OP_FTOI, + VSIR_OP_FTOU, + VSIR_OP_GATHER4, + VSIR_OP_GATHER4_C, + VSIR_OP_GATHER4_C_S, + VSIR_OP_GATHER4_PO, + VSIR_OP_GATHER4_PO_C, + VSIR_OP_GATHER4_PO_C_S, + VSIR_OP_GATHER4_PO_S, + VSIR_OP_GATHER4_S, + VSIR_OP_GEO, + VSIR_OP_GEU, + VSIR_OP_HCOS, + VSIR_OP_HS_CONTROL_POINT_PHASE, + VSIR_OP_HS_DECLS, + VSIR_OP_HS_FORK_PHASE, + VSIR_OP_HS_JOIN_PHASE, + VSIR_OP_HSIN, + VSIR_OP_HTAN, + VSIR_OP_IADD, + VSIR_OP_IBFE, + VSIR_OP_IDIV, + VSIR_OP_IEQ, + VSIR_OP_IF, + VSIR_OP_IFC, + VSIR_OP_IGE, + VSIR_OP_ILT, + VSIR_OP_IMAD, + VSIR_OP_IMAX, + VSIR_OP_IMIN, + VSIR_OP_IMM_ATOMIC_ALLOC, + VSIR_OP_IMM_ATOMIC_AND, + VSIR_OP_IMM_ATOMIC_CMP_EXCH, + VSIR_OP_IMM_ATOMIC_CONSUME, + VSIR_OP_IMM_ATOMIC_EXCH, + VSIR_OP_IMM_ATOMIC_IADD, + VSIR_OP_IMM_ATOMIC_IMAX, + VSIR_OP_IMM_ATOMIC_IMIN, + VSIR_OP_IMM_ATOMIC_OR, + VSIR_OP_IMM_ATOMIC_UMAX, + VSIR_OP_IMM_ATOMIC_UMIN, + VSIR_OP_IMM_ATOMIC_XOR, + VSIR_OP_IMUL, + VSIR_OP_IMUL_LOW, + VSIR_OP_INE, + VSIR_OP_INEG, + VSIR_OP_IREM, + VSIR_OP_ISFINITE, + VSIR_OP_ISHL, + VSIR_OP_ISHR, + VSIR_OP_ISINF, + VSIR_OP_ISNAN, + VSIR_OP_ITOD, + VSIR_OP_ITOF, + VSIR_OP_ITOI, + VSIR_OP_LABEL, + VSIR_OP_LD, + VSIR_OP_LD2DMS, + VSIR_OP_LD2DMS_S, + VSIR_OP_LD_RAW, + VSIR_OP_LD_RAW_S, + VSIR_OP_LD_S, + VSIR_OP_LD_STRUCTURED, + VSIR_OP_LD_STRUCTURED_S, + VSIR_OP_LD_UAV_TYPED, + VSIR_OP_LD_UAV_TYPED_S, + VSIR_OP_LIT, + VSIR_OP_LOD, + VSIR_OP_LOG, + VSIR_OP_LOGP, + VSIR_OP_LOOP, + VSIR_OP_LRP, + VSIR_OP_LTO, + VSIR_OP_LTU, + VSIR_OP_M3x2, + VSIR_OP_M3x3, + VSIR_OP_M3x4, + VSIR_OP_M4x3, + VSIR_OP_M4x4, + VSIR_OP_MAD, + VSIR_OP_MAX, + VSIR_OP_MIN, + VSIR_OP_MOV, + VSIR_OP_MOVA, + VSIR_OP_MOVC, + VSIR_OP_MSAD, + VSIR_OP_MUL, + VSIR_OP_NEO, + VSIR_OP_NEU, + VSIR_OP_NOP, + VSIR_OP_NOT, + VSIR_OP_NRM, + VSIR_OP_OR, + VSIR_OP_ORD, + VSIR_OP_PHASE, + VSIR_OP_PHI, + VSIR_OP_POW, + VSIR_OP_QUAD_READ_ACROSS_D, + VSIR_OP_QUAD_READ_ACROSS_X, + VSIR_OP_QUAD_READ_ACROSS_Y, + VSIR_OP_QUAD_READ_LANE_AT, + VSIR_OP_RCP, + VSIR_OP_REP, + VSIR_OP_RESINFO, + VSIR_OP_RET, + VSIR_OP_RETP, + VSIR_OP_ROUND_NE, + VSIR_OP_ROUND_NI, + VSIR_OP_ROUND_PI, + VSIR_OP_ROUND_Z, + VSIR_OP_RSQ, + VSIR_OP_SAMPLE, + VSIR_OP_SAMPLE_B, + VSIR_OP_SAMPLE_B_CL_S, + VSIR_OP_SAMPLE_C, + VSIR_OP_SAMPLE_C_CL_S, + VSIR_OP_SAMPLE_C_LZ, + VSIR_OP_SAMPLE_C_LZ_S, + VSIR_OP_SAMPLE_CL_S, + VSIR_OP_SAMPLE_GRAD, + VSIR_OP_SAMPLE_GRAD_CL_S, + VSIR_OP_SAMPLE_INFO, + VSIR_OP_SAMPLE_LOD, + VSIR_OP_SAMPLE_LOD_S, + VSIR_OP_SAMPLE_POS, + VSIR_OP_SETP, + VSIR_OP_SGE, + VSIR_OP_SGN, + VSIR_OP_SIN, + VSIR_OP_SINCOS, + VSIR_OP_SLT, + VSIR_OP_SQRT, + VSIR_OP_STORE_RAW, + VSIR_OP_STORE_STRUCTURED, + VSIR_OP_STORE_UAV_TYPED, + VSIR_OP_SUB, + VSIR_OP_SWAPC, + VSIR_OP_SWITCH, + VSIR_OP_SWITCH_MONOLITHIC, + VSIR_OP_SYNC, + VSIR_OP_TAN, + VSIR_OP_TEX, + VSIR_OP_TEXBEM, + VSIR_OP_TEXBEML, + VSIR_OP_TEXCOORD, + VSIR_OP_TEXCRD, + VSIR_OP_TEXDEPTH, + VSIR_OP_TEXDP3, + VSIR_OP_TEXDP3TEX, + VSIR_OP_TEXKILL, + VSIR_OP_TEXLD, + VSIR_OP_TEXLDD, + VSIR_OP_TEXLDL, + VSIR_OP_TEXM3x2DEPTH, + VSIR_OP_TEXM3x2PAD, + VSIR_OP_TEXM3x2TEX, + VSIR_OP_TEXM3x3, + VSIR_OP_TEXM3x3DIFF, + VSIR_OP_TEXM3x3PAD, + VSIR_OP_TEXM3x3SPEC, + VSIR_OP_TEXM3x3TEX, + VSIR_OP_TEXM3x3VSPEC, + VSIR_OP_TEXREG2AR, + VSIR_OP_TEXREG2GB, + VSIR_OP_TEXREG2RGB, + VSIR_OP_UBFE, + VSIR_OP_UDIV, + VSIR_OP_UDIV_SIMPLE, + VSIR_OP_UGE, + VSIR_OP_ULT, + VSIR_OP_UMAX, + VSIR_OP_UMIN, + VSIR_OP_UMUL, + VSIR_OP_UNO, + VSIR_OP_UREM, + VSIR_OP_USHR, + VSIR_OP_UTOD, + VSIR_OP_UTOF, + VSIR_OP_UTOU, + VSIR_OP_WAVE_ACTIVE_ALL_EQUAL, + VSIR_OP_WAVE_ACTIVE_BALLOT, + VSIR_OP_WAVE_ACTIVE_BIT_AND, + VSIR_OP_WAVE_ACTIVE_BIT_OR, + VSIR_OP_WAVE_ACTIVE_BIT_XOR, + VSIR_OP_WAVE_ALL_BIT_COUNT, + VSIR_OP_WAVE_ALL_TRUE, + VSIR_OP_WAVE_ANY_TRUE, + VSIR_OP_WAVE_IS_FIRST_LANE, + VSIR_OP_WAVE_OP_ADD, + VSIR_OP_WAVE_OP_IMAX, + VSIR_OP_WAVE_OP_IMIN, + VSIR_OP_WAVE_OP_MAX, + VSIR_OP_WAVE_OP_MIN, + VSIR_OP_WAVE_OP_MUL, + VSIR_OP_WAVE_OP_UMAX, + VSIR_OP_WAVE_OP_UMIN, + VSIR_OP_WAVE_PREFIX_BIT_COUNT, + VSIR_OP_WAVE_READ_LANE_AT, + VSIR_OP_WAVE_READ_LANE_FIRST, + VSIR_OP_XOR, + + VSIR_OP_INVALID, + + VSIR_OP_COUNT, +}; + +const char *vsir_opcode_get_name(enum vkd3d_shader_opcode op, const char *error);
enum vkd3d_shader_register_type { @@ -692,46 +708,51 @@ enum vkd3d_shader_register_precision VKD3D_SHADER_REGISTER_PRECISION_INVALID = ~0u, };
-enum vkd3d_data_type +enum vsir_data_type { - VKD3D_DATA_FLOAT, - VKD3D_DATA_INT, - VKD3D_DATA_UINT, - VKD3D_DATA_UNORM, - VKD3D_DATA_SNORM, - VKD3D_DATA_OPAQUE, - VKD3D_DATA_MIXED, - VKD3D_DATA_DOUBLE, - VKD3D_DATA_CONTINUED, - VKD3D_DATA_UNUSED, - VKD3D_DATA_UINT8, - VKD3D_DATA_UINT64, - VKD3D_DATA_BOOL, - VKD3D_DATA_UINT16, - VKD3D_DATA_HALF, + VSIR_DATA_BOOL, + + VSIR_DATA_F16, + VSIR_DATA_F32, + VSIR_DATA_F64, + + VSIR_DATA_I32, + + VSIR_DATA_U8, + VSIR_DATA_U16, + VSIR_DATA_U32, + VSIR_DATA_U64, + + VSIR_DATA_SNORM, + VSIR_DATA_UNORM, + + VSIR_DATA_OPAQUE, + VSIR_DATA_MIXED, + VSIR_DATA_CONTINUED, + VSIR_DATA_UNUSED,
- VKD3D_DATA_COUNT, + VSIR_DATA_TYPE_COUNT, };
-static inline bool data_type_is_integer(enum vkd3d_data_type data_type) +static inline bool data_type_is_integer(enum vsir_data_type data_type) { - return data_type == VKD3D_DATA_INT || data_type == VKD3D_DATA_UINT8 || data_type == VKD3D_DATA_UINT16 - || data_type == VKD3D_DATA_UINT || data_type == VKD3D_DATA_UINT64; + 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; }
-static inline bool data_type_is_bool(enum vkd3d_data_type data_type) +static inline bool data_type_is_bool(enum vsir_data_type data_type) { - return data_type == VKD3D_DATA_BOOL; + return data_type == VSIR_DATA_BOOL; }
-static inline bool data_type_is_floating_point(enum vkd3d_data_type data_type) +static inline bool data_type_is_floating_point(enum vsir_data_type data_type) { - return data_type == VKD3D_DATA_HALF || data_type == VKD3D_DATA_FLOAT || data_type == VKD3D_DATA_DOUBLE; + return data_type == VSIR_DATA_F16 || data_type == VSIR_DATA_F32 || data_type == VSIR_DATA_F64; }
-static inline bool data_type_is_64_bit(enum vkd3d_data_type data_type) +static inline bool data_type_is_64_bit(enum vsir_data_type data_type) { - return data_type == VKD3D_DATA_DOUBLE || data_type == VKD3D_DATA_UINT64; + return data_type == VSIR_DATA_F64 || data_type == VSIR_DATA_U64; }
enum vsir_dimension @@ -916,6 +937,16 @@ enum vkd3d_shader_type
struct vkd3d_shader_message_context;
+struct vkd3d_shader_source_list +{ + const char **sources; + size_t capacity, count; +}; + +bool vkd3d_shader_source_list_append(struct vkd3d_shader_source_list *l, const char *source); +void vkd3d_shader_source_list_cleanup(struct vkd3d_shader_source_list *l); +void vkd3d_shader_source_list_init(struct vkd3d_shader_source_list *l); + struct vkd3d_shader_version { enum vkd3d_shader_type type; @@ -926,7 +957,7 @@ struct vkd3d_shader_version struct vkd3d_shader_immediate_constant_buffer { unsigned int register_idx; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; /* total count is element_count * component_count */ unsigned int element_count; unsigned int component_count; @@ -939,7 +970,7 @@ struct vkd3d_shader_indexable_temp unsigned int register_idx; unsigned int register_size; unsigned int alignment; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; unsigned int component_count; bool has_function_scope; const struct vkd3d_shader_immediate_constant_buffer *initialiser; @@ -958,13 +989,13 @@ struct vkd3d_shader_register enum vkd3d_shader_register_type type; enum vkd3d_shader_register_precision precision; bool non_uniform; - enum vkd3d_data_type data_type; + enum vsir_data_type data_type; struct vkd3d_shader_register_index idx[3]; unsigned int idx_count; enum vsir_dimension dimension; /* known address alignment for optimisation, or zero */ unsigned int alignment; - union + union vsir_immediate_constant { uint32_t immconst_u32[VKD3D_VEC4_SIZE]; float immconst_f32[VKD3D_VEC4_SIZE]; @@ -975,7 +1006,7 @@ struct vkd3d_shader_register };
void vsir_register_init(struct vkd3d_shader_register *reg, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count); + enum vsir_data_type data_type, unsigned int idx_count);
static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_register *reg) { @@ -992,6 +1023,20 @@ static inline bool vsir_register_is_descriptor(const struct vkd3d_shader_registe } }
+static inline enum vkd3d_shader_register_type vsir_register_type_from_sysval_input( + enum vkd3d_shader_sysval_semantic sysval) +{ + switch (sysval) + { + case VKD3D_SHADER_SV_PRIMITIVE_ID: + return VKD3DSPR_PRIMID; + case VKD3D_SHADER_SV_COVERAGE: + return VKD3DSPR_COVERAGE; + default: + return VKD3DSPR_INPUT; + } +} + struct vkd3d_shader_dst_param { struct vkd3d_shader_register reg; @@ -1008,9 +1053,9 @@ struct vkd3d_shader_src_param };
void vsir_src_param_init(struct vkd3d_shader_src_param *param, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count); + enum vsir_data_type data_type, unsigned int idx_count); void vsir_dst_param_init(struct vkd3d_shader_dst_param *param, enum vkd3d_shader_register_type reg_type, - enum vkd3d_data_type data_type, unsigned int idx_count); + enum vsir_data_type data_type, unsigned int idx_count); void vsir_dst_param_init_null(struct vkd3d_shader_dst_param *dst); void vsir_src_param_init_label(struct vkd3d_shader_src_param *param, unsigned int label_id);
@@ -1056,7 +1101,7 @@ struct vkd3d_shader_semantic unsigned int usage_idx; enum vkd3d_shader_resource_type resource_type; unsigned int sample_count; - enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]; + enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE]; struct vkd3d_shader_resource resource; };
@@ -1262,14 +1307,14 @@ struct vkd3d_shader_instruction struct vkd3d_shader_location location; enum vkd3d_shader_opcode opcode; uint32_t flags; - unsigned int dst_count; - unsigned int src_count; + size_t dst_count; + size_t src_count; struct vkd3d_shader_dst_param *dst; struct vkd3d_shader_src_param *src; struct vkd3d_shader_texel_offset texel_offset; enum vkd3d_shader_resource_type resource_type; unsigned int resource_stride; - enum vkd3d_data_type resource_data_type[VKD3D_VEC4_SIZE]; + enum vsir_data_type resource_data_type[VKD3D_VEC4_SIZE]; bool coissue, structured, raw; const struct vkd3d_shader_src_param *predicate; union @@ -1332,12 +1377,6 @@ static inline bool register_is_constant_or_undef(const struct vkd3d_shader_regis return register_is_constant(reg) || register_is_undef(reg); }
-static inline bool register_is_scalar_constant_zero(const struct vkd3d_shader_register *reg) -{ - return register_is_constant(reg) && reg->dimension == VSIR_DIMENSION_SCALAR - && (data_type_is_64_bit(reg->data_type) ? !reg->u.immconst_u64[0] : !reg->u.immconst_u32[0]); -} - static inline bool register_is_numeric_array(const struct vkd3d_shader_register *reg) { return (reg->type == VKD3DSPR_IMMCONSTBUFFER || reg->type == VKD3DSPR_IDXTEMP @@ -1364,22 +1403,22 @@ struct vkd3d_shader_param_allocator { struct vkd3d_shader_param_node *head; struct vkd3d_shader_param_node *current; - unsigned int count; - unsigned int stride; - unsigned int index; + size_t count; + size_t stride; + size_t index; };
-void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, unsigned int count); +void *shader_param_allocator_get(struct vkd3d_shader_param_allocator *allocator, size_t count);
static inline struct vkd3d_shader_src_param *shader_src_param_allocator_get( - struct vkd3d_shader_param_allocator *allocator, unsigned int count) + struct vkd3d_shader_param_allocator *allocator, size_t count) { VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_src_param)); return shader_param_allocator_get(allocator, count); }
static inline struct vkd3d_shader_dst_param *shader_dst_param_allocator_get( - struct vkd3d_shader_param_allocator *allocator, unsigned int count) + struct vkd3d_shader_param_allocator *allocator, size_t count) { VKD3D_ASSERT(allocator->stride == sizeof(struct vkd3d_shader_dst_param)); return shader_param_allocator_get(allocator, count); @@ -1400,16 +1439,77 @@ struct vkd3d_shader_instruction_array struct vkd3d_shader_src_param *outpointid_param; };
-bool shader_instruction_array_init(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); -bool shader_instruction_array_reserve(struct vkd3d_shader_instruction_array *instructions, unsigned int reserve); +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, - unsigned int idx, unsigned int count); + 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, - unsigned int dst, unsigned int src); + size_t dst, size_t src); void shader_instruction_array_destroy(struct vkd3d_shader_instruction_array *instructions);
+struct vsir_program_iterator +{ + struct vkd3d_shader_instruction_array *array; + size_t idx; +}; + +static inline struct vsir_program_iterator vsir_program_iterator(struct vkd3d_shader_instruction_array *array) +{ + return (struct vsir_program_iterator){ .array = array }; +} + +static inline struct vkd3d_shader_instruction *vsir_program_iterator_current( + struct vsir_program_iterator *iterator) +{ + if (iterator->idx >= iterator->array->count) + return NULL; + + return &iterator->array->elements[iterator->idx]; +} + +static inline struct vkd3d_shader_instruction *vsir_program_iterator_head( + struct vsir_program_iterator *iterator) +{ + iterator->idx = 0; + + return vsir_program_iterator_current(iterator); +} + +static inline struct vkd3d_shader_instruction *vsir_program_iterator_tail(struct vsir_program_iterator *iterator) +{ + iterator->idx = iterator->array->count - 1; + + return vsir_program_iterator_current(iterator); +} + +static inline struct vkd3d_shader_instruction *vsir_program_iterator_next( + struct vsir_program_iterator *iterator) +{ + if (iterator->idx < iterator->array->count || iterator->idx == SIZE_MAX) + ++iterator->idx; + + return vsir_program_iterator_current(iterator); +} + +static inline struct vkd3d_shader_instruction *vsir_program_iterator_prev( + struct vsir_program_iterator *iterator) +{ + if (iterator->idx != SIZE_MAX) + --iterator->idx; + + return vsir_program_iterator_current(iterator); +} + +/* When insertion takes place, argument `it' is updated to point to the same + * instruction as before the insertion, but all other iterators and pointers + * to the same container are invalidated and cannot be used any more. */ +static inline bool vsir_program_iterator_insert_after(struct vsir_program_iterator *it, size_t count) +{ + return shader_instruction_array_insert_at(it->array, it->idx + 1, count); +} + enum vkd3d_shader_config_flags { VKD3D_SHADER_CONFIG_FLAG_FORCE_VALIDATION = 0x00000001, @@ -1436,7 +1536,7 @@ struct vkd3d_shader_descriptor_info1 unsigned int register_index; unsigned int register_id; enum vkd3d_shader_resource_type resource_type; - enum vkd3d_data_type resource_data_type; + enum vsir_data_type resource_data_type; unsigned int flags; unsigned int sample_count; unsigned int buffer_size; @@ -1496,19 +1596,23 @@ struct vsir_program
struct vsir_features features;
+ struct vkd3d_shader_source_list source_files; const char **block_names; size_t block_name_count; };
-void vsir_program_cleanup(struct vsir_program *program); -int vsir_program_compile(struct vsir_program *program, uint64_t config_flags, - const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, +enum vkd3d_result vsir_allocate_temp_registers(struct vsir_program *program, + struct vkd3d_shader_message_context *message_context); +enum vkd3d_result vsir_update_dcl_temps(struct vsir_program *program, struct vkd3d_shader_message_context *message_context); +void vsir_program_cleanup(struct vsir_program *program); const struct vkd3d_shader_parameter1 *vsir_program_get_parameter( const struct vsir_program *program, enum vkd3d_shader_parameter_name name); bool vsir_program_init(struct vsir_program *program, const struct vkd3d_shader_compile_info *compile_info, const struct vkd3d_shader_version *version, unsigned int reserve, enum vsir_control_flow_type cf_type, enum vsir_normalisation_level normalisation_level); +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); 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); enum vkd3d_result vsir_program_transform_early(struct vsir_program *program, uint64_t config_flags, @@ -1521,6 +1625,16 @@ bool vsir_instruction_init_with_params(struct vsir_program *program, struct vkd3d_shader_instruction *ins, const struct vkd3d_shader_location *location, enum vkd3d_shader_opcode opcode, unsigned int dst_count, unsigned int src_count);
+static inline struct vkd3d_shader_instruction *vsir_program_append(struct vsir_program *program) +{ + struct vkd3d_shader_instruction_array *array = &program->instructions; + + if (!shader_instruction_array_insert_at(array, array->count, 1)) + return NULL; + + return &array->elements[array->count - 1]; +} + static inline struct vkd3d_shader_dst_param *vsir_program_get_dst_params( struct vsir_program *program, unsigned int count) { @@ -1548,7 +1662,7 @@ void vkd3d_shader_parser_init(struct vkd3d_shader_parser *parser, struct vsir_pr void vkd3d_shader_parser_warning(struct vkd3d_shader_parser *parser, enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(3, 4);
-void vsir_program_trace(const struct vsir_program *program); +void vsir_program_trace(struct vsir_program *program);
const char *shader_get_type_prefix(enum vkd3d_shader_type type);
@@ -1571,11 +1685,12 @@ enum vsir_asm_flags VSIR_ASM_FLAG_DUMP_ALL_INDICES = 0x2, VSIR_ASM_FLAG_DUMP_SIGNATURES = 0x4, VSIR_ASM_FLAG_DUMP_DESCRIPTORS = 0x8, + VSIR_ASM_FLAG_ALLOCATE_TEMPS = 0x10, };
-enum vkd3d_result d3d_asm_compile(const struct vsir_program *program, - const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, enum vsir_asm_flags flags); +enum vkd3d_result d3d_asm_compile(struct vsir_program *program, + const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, + enum vsir_asm_flags flags, struct vkd3d_shader_message_context *message_context); void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer); struct vkd3d_string_buffer *vkd3d_string_buffer_get(struct vkd3d_string_buffer_cache *list); void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer); @@ -1682,6 +1797,8 @@ int tpf_parse(const struct vkd3d_shader_compile_info *compile_info, uint64_t con struct vkd3d_shader_message_context *message_context, struct vsir_program *program); int fx_parse(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); +int tx_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
void free_dxbc_shader_desc(struct dxbc_shader_desc *desc);
@@ -1723,54 +1840,55 @@ void vkd3d_compute_md5(const void *dxbc, size_t size, uint32_t checksum[4], enum int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info, struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context);
-int hlsl_compile_shader(const struct vkd3d_shader_code *hlsl, const struct vkd3d_shader_compile_info *compile_info, - struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context); +int hlsl_compile_effect(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_code *out); +int hlsl_parse(const struct vkd3d_shader_compile_info *compile_info, + struct vkd3d_shader_message_context *message_context, + struct vsir_program *program, struct vkd3d_shader_code *reflection_data);
-static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( - enum vkd3d_data_type data_type) +static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type( enum vsir_data_type data_type) { switch (data_type) { - case VKD3D_DATA_HALF: /* Minimum precision. TODO: native 16-bit */ - case VKD3D_DATA_FLOAT: - case VKD3D_DATA_UNORM: - case VKD3D_DATA_SNORM: + case VSIR_DATA_BOOL: + return VKD3D_SHADER_COMPONENT_BOOL; + case VSIR_DATA_F16: /* Minimum precision. TODO: native 16-bit */ + case VSIR_DATA_F32: + case VSIR_DATA_SNORM: + case VSIR_DATA_UNORM: return VKD3D_SHADER_COMPONENT_FLOAT; - case VKD3D_DATA_UINT16: /* Minimum precision. TODO: native 16-bit */ - case VKD3D_DATA_UINT: - return VKD3D_SHADER_COMPONENT_UINT; - case VKD3D_DATA_INT: - return VKD3D_SHADER_COMPONENT_INT; - case VKD3D_DATA_DOUBLE: + case VSIR_DATA_F64: return VKD3D_SHADER_COMPONENT_DOUBLE; - case VKD3D_DATA_UINT64: + case VSIR_DATA_I32: + return VKD3D_SHADER_COMPONENT_INT; + case VSIR_DATA_U16: /* Minimum precision. TODO: native 16-bit */ + case VSIR_DATA_U32: + return VKD3D_SHADER_COMPONENT_UINT; + case VSIR_DATA_U64: return VKD3D_SHADER_COMPONENT_UINT64; - case VKD3D_DATA_BOOL: - return VKD3D_SHADER_COMPONENT_BOOL; default: FIXME("Unhandled data type %#x.\n", data_type); /* fall-through */ - case VKD3D_DATA_MIXED: + case VSIR_DATA_MIXED: return VKD3D_SHADER_COMPONENT_UINT; } }
-static inline enum vkd3d_data_type vkd3d_data_type_from_component_type( - enum vkd3d_shader_component_type component_type) +static inline enum vsir_data_type vsir_data_type_from_component_type(enum vkd3d_shader_component_type component_type) { switch (component_type) { case VKD3D_SHADER_COMPONENT_FLOAT: - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; case VKD3D_SHADER_COMPONENT_UINT: - return VKD3D_DATA_UINT; + return VSIR_DATA_U32; case VKD3D_SHADER_COMPONENT_INT: - return VKD3D_DATA_INT; + return VSIR_DATA_I32; case VKD3D_SHADER_COMPONENT_DOUBLE: - return VKD3D_DATA_DOUBLE; + return VSIR_DATA_F64; default: FIXME("Unhandled component type %#x.\n", component_type); - return VKD3D_DATA_FLOAT; + return VSIR_DATA_F32; } }
@@ -1779,14 +1897,6 @@ static inline bool component_type_is_64_bit(enum vkd3d_shader_component_type com return component_type == VKD3D_SHADER_COMPONENT_DOUBLE || component_type == VKD3D_SHADER_COMPONENT_UINT64; }
-enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval_indexed(enum vkd3d_shader_sysval_semantic sysval, - unsigned int index); - -static inline enum vkd3d_shader_input_sysval_semantic vkd3d_siv_from_sysval(enum vkd3d_shader_sysval_semantic sysval) -{ - return vkd3d_siv_from_sysval_indexed(sysval, 0); -} - static inline unsigned int vsir_write_mask_get_component_idx(uint32_t write_mask) { unsigned int i; @@ -1853,6 +1963,8 @@ static inline uint32_t vsir_write_mask_32_from_64(uint32_t write_mask64) } }
+const char *debug_vsir_writemask(unsigned int writemask); + static inline uint32_t vsir_swizzle_64_from_32(uint32_t swizzle32) { switch (swizzle32) @@ -1902,6 +2014,12 @@ static inline unsigned int vsir_swizzle_get_component(uint32_t swizzle, unsigned return (swizzle >> VKD3D_SHADER_SWIZZLE_SHIFT(idx)) & VKD3D_SHADER_SWIZZLE_MASK; }
+static inline void vsir_swizzle_set_component(uint32_t *swizzle, unsigned int idx, unsigned int component) +{ + *swizzle &= ~(VKD3D_SHADER_SWIZZLE_MASK << VKD3D_SHADER_SWIZZLE_SHIFT(idx)); + *swizzle |= component << VKD3D_SHADER_SWIZZLE_SHIFT(idx); +} + static inline unsigned int vkd3d_compact_swizzle(uint32_t swizzle, uint32_t write_mask) { unsigned int i, compacted_swizzle = 0; diff --git a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c index f2b18b665f8..f2967835b62 100644 --- a/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c +++ b/libs/vkd3d/libs/vkd3d-utils/vkd3d_utils_main.c @@ -269,7 +269,7 @@ HRESULT WINAPI D3DCompile2VKD3D(const void *data, SIZE_T data_size, const char *
option = &options[0]; option->name = VKD3D_SHADER_COMPILE_OPTION_API_VERSION; - option->value = VKD3D_SHADER_API_VERSION_1_16; + option->value = VKD3D_SHADER_API_VERSION_1_17;
compile_info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; compile_info.next = &preprocess_info; @@ -433,7 +433,7 @@ HRESULT WINAPI D3DPreprocess(const void *data, SIZE_T size, const char *filename
static const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, };
TRACE("data %p, size %"PRIuPTR", filename %s, macros %p, include %p, preprocessed_blob %p, messages_blob %p.\n", @@ -979,7 +979,7 @@ HRESULT WINAPI D3DDisassemble(const void *data, SIZE_T data_size,
static const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, };
TRACE("data %p, data_size %"PRIuPTR", flags %#x, comments %p, blob %p.\n", diff --git a/libs/vkd3d/libs/vkd3d/command.c b/libs/vkd3d/libs/vkd3d/command.c index e487ed0b9ad..074d8430585 100644 --- a/libs/vkd3d/libs/vkd3d/command.c +++ b/libs/vkd3d/libs/vkd3d/command.c @@ -4221,13 +4221,21 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo TRACE("iface %p, viewport_count %u, viewports %p.\n", iface, viewport_count, viewports);
if (viewport_count > ARRAY_SIZE(vk_viewports)) - { FIXME("Viewport count %u > D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE.\n", viewport_count); - viewport_count = ARRAY_SIZE(vk_viewports); - }
- for (i = 0; i < viewport_count; ++i) + for (i = 0; i < ARRAY_SIZE(vk_viewports); ++i) { + if (i >= viewport_count) + { + vk_viewports[i].x = 0.0f; + vk_viewports[i].y = 0.0f; + vk_viewports[i].width = 1.0f; + vk_viewports[i].height = 1.0f; + vk_viewports[i].minDepth = 0.0f; + vk_viewports[i].maxDepth = 0.0f; + continue; + } + vk_viewports[i].x = viewports[i].TopLeftX; vk_viewports[i].y = viewports[i].TopLeftY + viewports[i].Height; vk_viewports[i].width = viewports[i].Width; @@ -4245,7 +4253,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetViewports(ID3D12GraphicsCo }
vk_procs = &list->device->vk_procs; - VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, viewport_count, vk_viewports)); + VK_CALL(vkCmdSetViewport(list->vk_command_buffer, 0, ARRAY_SIZE(vk_viewports), vk_viewports)); }
static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12GraphicsCommandList6 *iface, @@ -4264,6 +4272,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic rect_count = ARRAY_SIZE(vk_rects); }
+ memset(vk_rects, 0, sizeof(vk_rects)); for (i = 0; i < rect_count; ++i) { vk_rects[i].offset.x = rects[i].left; @@ -4273,7 +4282,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_RSSetScissorRects(ID3D12Graphic }
vk_procs = &list->device->vk_procs; - VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, rect_count, vk_rects)); + VK_CALL(vkCmdSetScissor(list->vk_command_buffer, 0, ARRAY_SIZE(vk_rects), vk_rects)); }
static void STDMETHODCALLTYPE d3d12_command_list_OMSetBlendFactor(ID3D12GraphicsCommandList6 *iface, diff --git a/libs/vkd3d/libs/vkd3d/device.c b/libs/vkd3d/libs/vkd3d/device.c index b2636fd5585..67f84aafa29 100644 --- a/libs/vkd3d/libs/vkd3d/device.c +++ b/libs/vkd3d/libs/vkd3d/device.c @@ -5193,7 +5193,12 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommands(ID3D12Device FIXME("iface %p, num_meta_commands %p, command_desc %p stub!\n", iface, num_meta_commands, command_desc);
- return E_NOTIMPL; + if (!num_meta_commands) + return E_INVALIDARG; + + *num_meta_commands = 0; + + return S_OK; }
static HRESULT STDMETHODCALLTYPE d3d12_device_EnumerateMetaCommandParameters(ID3D12Device9 *iface, diff --git a/libs/vkd3d/libs/vkd3d/resource.c b/libs/vkd3d/libs/vkd3d/resource.c index cb184986f2a..7946445ad07 100644 --- a/libs/vkd3d/libs/vkd3d/resource.c +++ b/libs/vkd3d/libs/vkd3d/resource.c @@ -310,6 +310,9 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface) struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); unsigned int refcount = vkd3d_atomic_increment_u32(&heap->refcount);
+ if (refcount == 1) + vkd3d_atomic_increment_u32(&heap->internal_refcount); + TRACE("%p increasing refcount to %u.\n", heap, refcount);
VKD3D_ASSERT(!heap->is_private); @@ -342,6 +345,12 @@ static void d3d12_heap_destroy(struct d3d12_heap *heap) d3d12_device_release(device); }
+static void d3d12_heap_decref(struct d3d12_heap *heap) +{ + if (!vkd3d_atomic_decrement_u32(&heap->internal_refcount)) + d3d12_heap_destroy(heap); +} + static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) { struct d3d12_heap *heap = impl_from_ID3D12Heap(iface); @@ -350,18 +359,12 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_Release(ID3D12Heap *iface) TRACE("%p decreasing refcount to %u.\n", heap, refcount);
/* A heap must not be destroyed until all contained resources are destroyed. */ - if (!refcount && !heap->resource_count) - d3d12_heap_destroy(heap); + if (!refcount) + d3d12_heap_decref(heap);
return refcount; }
-static void d3d12_heap_resource_destroyed(struct d3d12_heap *heap) -{ - if (!vkd3d_atomic_decrement_u32(&heap->resource_count) && (!heap->refcount || heap->is_private)) - d3d12_heap_destroy(heap); -} - static HRESULT STDMETHODCALLTYPE d3d12_heap_GetPrivateData(ID3D12Heap *iface, REFGUID guid, UINT *data_size, void *data) { @@ -487,7 +490,7 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap,
heap->ID3D12Heap_iface.lpVtbl = &d3d12_heap_vtbl; heap->refcount = 1; - heap->resource_count = 0; + heap->internal_refcount = 1;
heap->is_private = !!resource;
@@ -555,8 +558,6 @@ static HRESULT d3d12_heap_init(struct d3d12_heap *heap, heap->device = device; if (!heap->is_private) d3d12_device_add_ref(heap->device); - else - heap->resource_count = 1;
if (d3d12_heap_get_memory_property_flags(heap) & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) { @@ -998,7 +999,7 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 d3d12_resource_tile_info_cleanup(resource);
if (resource->heap) - d3d12_heap_resource_destroyed(resource->heap); + d3d12_heap_decref(resource->heap); }
static ULONG d3d12_resource_incref(struct d3d12_resource *resource) @@ -2200,7 +2201,7 @@ static HRESULT vkd3d_bind_heap_memory(struct d3d12_device *device, { resource->heap = heap; resource->heap_offset = heap_offset; - vkd3d_atomic_increment_u32(&heap->resource_count); + vkd3d_atomic_increment_u32(&heap->internal_refcount); } else { @@ -2491,20 +2492,41 @@ static void descriptor_writes_free_object_refs(struct descriptor_writes *writes, writes->held_ref_count = 0; }
+static enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type( + VkDescriptorType type) +{ + static const enum vkd3d_vk_descriptor_set_index table[] = + { + [VK_DESCRIPTOR_TYPE_SAMPLER] = VKD3D_SET_INDEX_SAMPLER, + [VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER] = VKD3D_SET_INDEX_COUNT, + [VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE] = VKD3D_SET_INDEX_SAMPLED_IMAGE, + [VK_DESCRIPTOR_TYPE_STORAGE_IMAGE] = VKD3D_SET_INDEX_STORAGE_IMAGE, + [VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER] = VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER, + [VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER] = VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER, + [VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER] = VKD3D_SET_INDEX_UNIFORM_BUFFER, + }; + + VKD3D_ASSERT(type < ARRAY_SIZE(table)); + VKD3D_ASSERT(table[type] < VKD3D_SET_INDEX_COUNT); + + return table[type]; +} + static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_heap *descriptor_heap, - uint32_t dst_array_element, struct descriptor_writes *writes, struct d3d12_device *device) + uint32_t dst_array_element, struct descriptor_writes *writes, struct d3d12_device *device, + VkDescriptorType type) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct d3d12_descriptor_heap_vk_set *descriptor_set; - enum vkd3d_vk_descriptor_set_index set, end; + enum vkd3d_vk_descriptor_set_index set; unsigned int i = writes->count;
- end = device->vk_info.EXT_mutable_descriptor_type ? VKD3D_SET_INDEX_MUTABLE - : VKD3D_SET_INDEX_STORAGE_IMAGE; /* Binding a shader with the wrong null descriptor type works in Windows. * To support that here we must write one to all applicable Vulkan sets. */ - for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= end; ++set) + for (set = VKD3D_SET_INDEX_UNIFORM_BUFFER; set <= VKD3D_SET_INDEX_STORAGE_IMAGE; ++set) { + if (device->vk_info.EXT_mutable_descriptor_type) + set = vkd3d_vk_descriptor_set_index_from_vk_descriptor_type(type); descriptor_set = &descriptor_heap->vk_descriptor_sets[set]; writes->vk_descriptor_writes[i].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; writes->vk_descriptor_writes[i].pNext = NULL; @@ -2545,6 +2567,8 @@ static void d3d12_desc_write_vk_heap_null_descriptor(struct d3d12_descriptor_hea VK_CALL(vkUpdateDescriptorSets(device->vk_device, i, writes->vk_descriptor_writes, 0, NULL)); descriptor_writes_free_object_refs(writes, device); i = 0; + if (device->vk_info.EXT_mutable_descriptor_type) + break; }
writes->count = i; @@ -2609,7 +2633,7 @@ static void d3d12_desc_write_vk_heap(struct d3d12_descriptor_heap *descriptor_he break; } if (is_null && device->vk_info.EXT_robustness2) - return d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap, dst_array_element, writes, device); + return d3d12_desc_write_vk_heap_null_descriptor(descriptor_heap, dst_array_element, writes, device, type);
++i; if (u.header->magic == VKD3D_DESCRIPTOR_MAGIC_UAV && u.view->v.vk_counter_view) @@ -4223,17 +4247,6 @@ static const struct ID3D12DescriptorHeapVtbl d3d12_descriptor_heap_vtbl = d3d12_descriptor_heap_GetGPUDescriptorHandleForHeapStart, };
-const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[] = -{ - VKD3D_SET_INDEX_SAMPLER, - VKD3D_SET_INDEX_COUNT, - VKD3D_SET_INDEX_SAMPLED_IMAGE, - VKD3D_SET_INDEX_STORAGE_IMAGE, - VKD3D_SET_INDEX_UNIFORM_TEXEL_BUFFER, - VKD3D_SET_INDEX_STORAGE_TEXEL_BUFFER, - VKD3D_SET_INDEX_UNIFORM_BUFFER, -}; - static HRESULT d3d12_descriptor_heap_create_descriptor_pool(struct d3d12_descriptor_heap *descriptor_heap, struct d3d12_device *device, const D3D12_DESCRIPTOR_HEAP_DESC *desc) { diff --git a/libs/vkd3d/libs/vkd3d/state.c b/libs/vkd3d/libs/vkd3d/state.c index 819185796c0..6bbd6533b74 100644 --- a/libs/vkd3d/libs/vkd3d/state.c +++ b/libs/vkd3d/libs/vkd3d/state.c @@ -2383,13 +2383,15 @@ static HRESULT create_shader_stage(struct d3d12_device *device, const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; struct vkd3d_shader_compile_info compile_info; struct VkShaderModuleCreateInfo shader_desc; + struct vkd3d_shader_dxbc_desc dxbc_desc; struct vkd3d_shader_code spirv = {0}; + char source_name[33]; VkResult vr; int ret;
const struct vkd3d_shader_compile_option options[] = { - {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_16}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, {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)}, @@ -2416,6 +2418,16 @@ static HRESULT create_shader_stage(struct d3d12_device *device, compile_info.log_level = VKD3D_SHADER_LOG_NONE; compile_info.source_name = NULL;
+ if ((ret = vkd3d_shader_parse_dxbc(&(struct vkd3d_shader_code){code->pShaderBytecode, code->BytecodeLength}, + 0, &dxbc_desc, NULL)) >= 0) + { + sprintf(source_name, "%08x%08x%08x%08x", dxbc_desc.checksum[0], + dxbc_desc.checksum[1], dxbc_desc.checksum[2], dxbc_desc.checksum[3]); + vkd3d_shader_free_dxbc(&dxbc_desc); + TRACE("Compiling shader "%s".\n", source_name); + compile_info.source_name = source_name; + } + if ((ret = vkd3d_shader_parse_dxbc_source_type(&compile_info.source, &compile_info.source_type, NULL)) < 0 || (ret = vkd3d_shader_compile(&compile_info, &spirv, NULL)) < 0) { @@ -2444,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_16}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, {VKD3D_SHADER_COMPILE_OPTION_TYPED_UAV, typed_uav_compile_option(device)}, };
@@ -3220,17 +3232,6 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s uint32_t mask; HRESULT hr;
- static const DWORD default_ps_code[] = - { -#if 0 - ps_4_0 - ret -#endif - 0x43425844, 0x19cbf606, 0x18f562b9, 0xdaeed4db, 0xc324aa46, 0x00000001, 0x00000060, 0x00000003, - 0x0000002c, 0x0000003c, 0x0000004c, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f, - 0x00000008, 0x00000000, 0x00000008, 0x52444853, 0x0000000c, 0x00000040, 0x00000003, 0x0100003e, - }; - static const D3D12_SHADER_BYTECODE default_ps = {default_ps_code, sizeof(default_ps_code)}; static const struct { enum VkShaderStageFlagBits stage; @@ -3389,11 +3390,10 @@ static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *s
if (!desc->ps.pShaderBytecode) { - if (FAILED(hr = create_shader_stage(device, &graphics->stages[graphics->stage_count], - VK_SHADER_STAGE_FRAGMENT_BIT, &default_ps, NULL))) - goto fail; - - ++graphics->stage_count; + for (i = 0; i < rt_count; i++) + { + graphics->blend_attachments[i].colorWriteMask = 0; + } } }
@@ -3971,9 +3971,9 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta .sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, .pNext = NULL, .flags = 0, - .viewportCount = 1, + .viewportCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, .pViewports = NULL, - .scissorCount = 1, + .scissorCount = D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE, .pScissors = NULL, }; static const VkDynamicState dynamic_states[] = @@ -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_16}, + {VKD3D_SHADER_COMPILE_OPTION_API_VERSION, VKD3D_SHADER_API_VERSION_1_17}, };
info.type = VKD3D_SHADER_STRUCTURE_TYPE_COMPILE_INFO; diff --git a/libs/vkd3d/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/libs/vkd3d/vkd3d_private.h index 7e54738b19e..9fb6834158f 100644 --- a/libs/vkd3d/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/libs/vkd3d/vkd3d_private.h @@ -436,7 +436,7 @@ struct d3d12_heap { ID3D12Heap ID3D12Heap_iface; unsigned int refcount; - unsigned int resource_count; + unsigned int internal_refcount;
bool is_private; D3D12_HEAP_DESC desc; @@ -827,17 +827,6 @@ enum vkd3d_vk_descriptor_set_index VKD3D_SET_INDEX_COUNT };
-extern const enum vkd3d_vk_descriptor_set_index vk_descriptor_set_index_table[]; - -static inline enum vkd3d_vk_descriptor_set_index vkd3d_vk_descriptor_set_index_from_vk_descriptor_type( - VkDescriptorType type) -{ - VKD3D_ASSERT(type <= VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); - VKD3D_ASSERT(vk_descriptor_set_index_table[type] < VKD3D_SET_INDEX_COUNT); - - return vk_descriptor_set_index_table[type]; -} - struct vkd3d_vk_descriptor_heap_layout { VkDescriptorType type;