From 5f69f7512695bd7b26f83ed9872be45159a46cf6 Mon Sep 17 00:00:00 2001 From: David Neto Date: Mon, 5 Mar 2018 13:34:13 -0500 Subject: [PATCH] Support SPV_GOOGLE_decorate_string and SPV_GOOGLE_hlsl_functionality1 This commit add assembling, disassembling, and basic validation for two Google extensions to better support HLSL translation. --- source/opcode.cpp | 2 + source/operand.cpp | 3 ++ source/opt/reflect.h | 3 +- source/val/validation_state.cpp | 3 ++ test/enum_string_mapping_test.cpp | 38 ++++++++------- test/text_to_binary.extension_test.cpp | 45 +++++++++++++++-- test/val/val_extensions_test.cpp | 89 +++++++++++++++++++++------------- utils/generate_grammar_tables.py | 2 + 8 files changed, 128 insertions(+), 57 deletions(-) diff --git a/source/opcode.cpp b/source/opcode.cpp index cacb005..ae9d024 100644 --- a/source/opcode.cpp +++ b/source/opcode.cpp @@ -330,6 +330,8 @@ bool spvOpcodeIsDecoration(const SpvOp opcode) { case SpvOpMemberDecorate: case SpvOpGroupDecorate: case SpvOpGroupMemberDecorate: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorateStringGOOGLE: return true; default: break; diff --git a/source/operand.cpp b/source/operand.cpp index 8959f5b..180cb7f 100644 --- a/source/operand.cpp +++ b/source/operand.cpp @@ -405,6 +405,9 @@ std::function spvOperandCanBeForwardDeclaredFunction( case SpvOpSelectionMerge: case SpvOpDecorate: case SpvOpMemberDecorate: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorateStringGOOGLE: case SpvOpTypeStruct: case SpvOpBranch: case SpvOpLoopMerge: diff --git a/source/opt/reflect.h b/source/opt/reflect.h index 35961d6..ef2d849 100644 --- a/source/opt/reflect.h +++ b/source/opt/reflect.h @@ -39,7 +39,8 @@ inline bool IsDebugLineInst(SpvOp opcode) { } inline bool IsAnnotationInst(SpvOp opcode) { return (opcode >= SpvOpDecorate && opcode <= SpvOpGroupMemberDecorate) || - opcode == SpvOpDecorateId; + opcode == SpvOpDecorateId || opcode == SpvOpDecorateStringGOOGLE || + opcode == SpvOpMemberDecorateStringGOOGLE; } inline bool IsTypeInst(SpvOp opcode) { return (opcode >= SpvOpTypeVoid && opcode <= SpvOpTypeForwardPointer) || diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index ed4cd70..36bfbc2 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -73,6 +73,9 @@ bool IsInstructionInLayoutSection(ModuleLayoutSection layout, SpvOp op) { case SpvOpGroupDecorate: case SpvOpGroupMemberDecorate: case SpvOpDecorationGroup: + case SpvOpDecorateId: + case SpvOpDecorateStringGOOGLE: + case SpvOpMemberDecorateStringGOOGLE: out = true; break; default: break; diff --git a/test/enum_string_mapping_test.cpp b/test/enum_string_mapping_test.cpp index 4e46fb4..f7f1ef5 100644 --- a/test/enum_string_mapping_test.cpp +++ b/test/enum_string_mapping_test.cpp @@ -67,23 +67,27 @@ TEST_P(CapabilityTest, TestCapabilityToString) { INSTANTIATE_TEST_CASE_P( AllExtensions, ExtensionTest, - ValuesIn(std::vector>( - {{Extension::kSPV_KHR_16bit_storage, "SPV_KHR_16bit_storage"}, - {Extension::kSPV_KHR_device_group, "SPV_KHR_device_group"}, - {Extension::kSPV_KHR_multiview, "SPV_KHR_multiview"}, - {Extension::kSPV_KHR_shader_ballot, "SPV_KHR_shader_ballot"}, - {Extension::kSPV_KHR_shader_draw_parameters, - "SPV_KHR_shader_draw_parameters"}, - {Extension::kSPV_KHR_subgroup_vote, "SPV_KHR_subgroup_vote"}, - {Extension::kSPV_NVX_multiview_per_view_attributes, - "SPV_NVX_multiview_per_view_attributes"}, - {Extension::kSPV_NV_geometry_shader_passthrough, - "SPV_NV_geometry_shader_passthrough"}, - {Extension::kSPV_NV_sample_mask_override_coverage, - "SPV_NV_sample_mask_override_coverage"}, - {Extension::kSPV_NV_stereo_view_rendering, - "SPV_NV_stereo_view_rendering"}, - {Extension::kSPV_NV_viewport_array2, "SPV_NV_viewport_array2"}}))); + ValuesIn(std::vector>({ + {Extension::kSPV_KHR_16bit_storage, "SPV_KHR_16bit_storage"}, + {Extension::kSPV_KHR_device_group, "SPV_KHR_device_group"}, + {Extension::kSPV_KHR_multiview, "SPV_KHR_multiview"}, + {Extension::kSPV_KHR_shader_ballot, "SPV_KHR_shader_ballot"}, + {Extension::kSPV_KHR_shader_draw_parameters, + "SPV_KHR_shader_draw_parameters"}, + {Extension::kSPV_KHR_subgroup_vote, "SPV_KHR_subgroup_vote"}, + {Extension::kSPV_NVX_multiview_per_view_attributes, + "SPV_NVX_multiview_per_view_attributes"}, + {Extension::kSPV_NV_geometry_shader_passthrough, + "SPV_NV_geometry_shader_passthrough"}, + {Extension::kSPV_NV_sample_mask_override_coverage, + "SPV_NV_sample_mask_override_coverage"}, + {Extension::kSPV_NV_stereo_view_rendering, + "SPV_NV_stereo_view_rendering"}, + {Extension::kSPV_NV_viewport_array2, "SPV_NV_viewport_array2"}, + {Extension::kSPV_GOOGLE_decorate_string, "SPV_GOOGLE_decorate_string"}, + {Extension::kSPV_GOOGLE_hlsl_functionality1, + "SPV_GOOGLE_hlsl_functionality1"}, + }))); INSTANTIATE_TEST_CASE_P(UnknownExtensions, UnknownExtensionTest, Values("", "SPV_KHR_", "SPV_KHR_device_group_ERROR", diff --git a/test/text_to_binary.extension_test.cpp b/test/text_to_binary.extension_test.cpp index 032c38e..6689bee 100644 --- a/test/text_to_binary.extension_test.cpp +++ b/test/text_to_binary.extension_test.cpp @@ -24,14 +24,14 @@ namespace { -using spvtest::Concatenate; -using spvtest::MakeInstruction; -using spvtest::MakeVector; -using spvtest::TextToBinaryTest; using ::testing::Combine; using ::testing::Eq; using ::testing::Values; using ::testing::ValuesIn; +using spvtest::Concatenate; +using spvtest::MakeInstruction; +using spvtest::MakeVector; +using spvtest::TextToBinaryTest; TEST_F(TextToBinaryTest, InvalidExtInstImportName) { EXPECT_THAT(CompileFailure("%1 = OpExtInstImport \"Haskell.std\""), @@ -430,4 +430,41 @@ INSTANTIATE_TEST_CASE_P( {SpvCapabilityVariablePointersStorageBuffer})}, })), ); +// SPV_GOOGLE_decorate_string + +INSTANTIATE_TEST_CASE_P( + SPV_GOOGLE_decorate_string, ExtensionRoundTripTest, + Combine( + // We'll get coverage over operand tables by trying the universal + // environments, and at least one specific environment. + Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0), + ValuesIn(std::vector{ + {"OpDecorateStringGOOGLE %1 HlslSemanticGOOGLE \"ABC\"\n", + MakeInstruction(SpvOpDecorateStringGOOGLE, + {1, SpvDecorationHlslSemanticGOOGLE}, + MakeVector("ABC"))}, + {"OpMemberDecorateStringGOOGLE %1 3 HlslSemanticGOOGLE \"DEF\"\n", + MakeInstruction(SpvOpMemberDecorateStringGOOGLE, + {1, 3, SpvDecorationHlslSemanticGOOGLE}, + MakeVector("DEF"))}, + })), ); + +// SPV_GOOGLE_hlsl_functionality1 + +INSTANTIATE_TEST_CASE_P( + SPV_GOOGLE_hlsl_functionality1, ExtensionRoundTripTest, + Combine( + // We'll get coverage over operand tables by trying the universal + // environments, and at least one specific environment. + Values(SPV_ENV_UNIVERSAL_1_0, SPV_ENV_UNIVERSAL_1_1, + SPV_ENV_UNIVERSAL_1_2, SPV_ENV_VULKAN_1_0), + // HlslSemanticGOOGLE is tested in SPV_GOOGLE_decorate_string, since + // they are coupled together. + ValuesIn(std::vector{ + {"OpDecorateId %1 HlslCounterBufferGOOGLE %2\n", + MakeInstruction(SpvOpDecorateId, + {1, SpvDecorationHlslCounterBufferGOOGLE, 2})}, + })), ); + } // anonymous namespace diff --git a/test/val/val_extensions_test.cpp b/test/val/val_extensions_test.cpp index bd3998c..a83af43 100644 --- a/test/val/val_extensions_test.cpp +++ b/test/val/val_extensions_test.cpp @@ -60,7 +60,8 @@ INSTANTIATE_TEST_CASE_P( "SPV_AMD_gpu_shader_int16", "SPV_KHR_post_depth_coverage", "SPV_KHR_shader_atomic_counter_ops", "SPV_EXT_shader_stencil_export", "SPV_EXT_shader_viewport_index_layer", - "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_fragment_mask")); + "SPV_AMD_shader_image_load_store_lod", "SPV_AMD_shader_fragment_mask", + "SPV_GOOGLE_decorate_string", "SPV_GOOGLE_hlsl_functionality1")); INSTANTIATE_TEST_CASE_P(FailSilently, ValidateUnknownExtensions, Values("ERROR_unknown_extension", "SPV_KHR_", @@ -107,7 +108,6 @@ TEST_F(ValidateExtensionCapabilities, DeclCapabilityFailure) { EXPECT_THAT(getDiagnosticString(), HasSubstr("SPV_KHR_device_group")); } - using ValidateAMDShaderBallotCapabilities = spvtest::ValidateBase; // Returns a vector of strings for the prefix of a SPIR-V assembly shader @@ -139,38 +139,56 @@ std::vector ShaderPartsForAMDShaderBallot() { // of ShaderPartsForAMDShaderBallot. std::vector AMDShaderBallotGroupInstructions() { return std::vector{ - "%iadd_reduce = OpGroupIAddNonUniformAMD %uint %scope Reduce %uint_const", - "%iadd_iscan = OpGroupIAddNonUniformAMD %uint %scope InclusiveScan %uint_const", - "%iadd_escan = OpGroupIAddNonUniformAMD %uint %scope ExclusiveScan %uint_const", - - "%fadd_reduce = OpGroupFAddNonUniformAMD %float %scope Reduce %float_const", - "%fadd_iscan = OpGroupFAddNonUniformAMD %float %scope InclusiveScan %float_const", - "%fadd_escan = OpGroupFAddNonUniformAMD %float %scope ExclusiveScan %float_const", - - "%fmin_reduce = OpGroupFMinNonUniformAMD %float %scope Reduce %float_const", - "%fmin_iscan = OpGroupFMinNonUniformAMD %float %scope InclusiveScan %float_const", - "%fmin_escan = OpGroupFMinNonUniformAMD %float %scope ExclusiveScan %float_const", - - "%umin_reduce = OpGroupUMinNonUniformAMD %uint %scope Reduce %uint_const", - "%umin_iscan = OpGroupUMinNonUniformAMD %uint %scope InclusiveScan %uint_const", - "%umin_escan = OpGroupUMinNonUniformAMD %uint %scope ExclusiveScan %uint_const", - - "%smin_reduce = OpGroupUMinNonUniformAMD %int %scope Reduce %int_const", - "%smin_iscan = OpGroupUMinNonUniformAMD %int %scope InclusiveScan %int_const", - "%smin_escan = OpGroupUMinNonUniformAMD %int %scope ExclusiveScan %int_const", - - "%fmax_reduce = OpGroupFMaxNonUniformAMD %float %scope Reduce %float_const", - "%fmax_iscan = OpGroupFMaxNonUniformAMD %float %scope InclusiveScan %float_const", - "%fmax_escan = OpGroupFMaxNonUniformAMD %float %scope ExclusiveScan %float_const", - - "%umax_reduce = OpGroupUMaxNonUniformAMD %uint %scope Reduce %uint_const", - "%umax_iscan = OpGroupUMaxNonUniformAMD %uint %scope InclusiveScan %uint_const", - "%umax_escan = OpGroupUMaxNonUniformAMD %uint %scope ExclusiveScan %uint_const", - - "%smax_reduce = OpGroupUMaxNonUniformAMD %int %scope Reduce %int_const", - "%smax_iscan = OpGroupUMaxNonUniformAMD %int %scope InclusiveScan %int_const", - "%smax_escan = OpGroupUMaxNonUniformAMD %int %scope ExclusiveScan %int_const" - }; + "%iadd_reduce = OpGroupIAddNonUniformAMD %uint %scope Reduce %uint_const", + "%iadd_iscan = OpGroupIAddNonUniformAMD %uint %scope InclusiveScan " + "%uint_const", + "%iadd_escan = OpGroupIAddNonUniformAMD %uint %scope ExclusiveScan " + "%uint_const", + + "%fadd_reduce = OpGroupFAddNonUniformAMD %float %scope Reduce " + "%float_const", + "%fadd_iscan = OpGroupFAddNonUniformAMD %float %scope InclusiveScan " + "%float_const", + "%fadd_escan = OpGroupFAddNonUniformAMD %float %scope ExclusiveScan " + "%float_const", + + "%fmin_reduce = OpGroupFMinNonUniformAMD %float %scope Reduce " + "%float_const", + "%fmin_iscan = OpGroupFMinNonUniformAMD %float %scope InclusiveScan " + "%float_const", + "%fmin_escan = OpGroupFMinNonUniformAMD %float %scope ExclusiveScan " + "%float_const", + + "%umin_reduce = OpGroupUMinNonUniformAMD %uint %scope Reduce %uint_const", + "%umin_iscan = OpGroupUMinNonUniformAMD %uint %scope InclusiveScan " + "%uint_const", + "%umin_escan = OpGroupUMinNonUniformAMD %uint %scope ExclusiveScan " + "%uint_const", + + "%smin_reduce = OpGroupUMinNonUniformAMD %int %scope Reduce %int_const", + "%smin_iscan = OpGroupUMinNonUniformAMD %int %scope InclusiveScan " + "%int_const", + "%smin_escan = OpGroupUMinNonUniformAMD %int %scope ExclusiveScan " + "%int_const", + + "%fmax_reduce = OpGroupFMaxNonUniformAMD %float %scope Reduce " + "%float_const", + "%fmax_iscan = OpGroupFMaxNonUniformAMD %float %scope InclusiveScan " + "%float_const", + "%fmax_escan = OpGroupFMaxNonUniformAMD %float %scope ExclusiveScan " + "%float_const", + + "%umax_reduce = OpGroupUMaxNonUniformAMD %uint %scope Reduce %uint_const", + "%umax_iscan = OpGroupUMaxNonUniformAMD %uint %scope InclusiveScan " + "%uint_const", + "%umax_escan = OpGroupUMaxNonUniformAMD %uint %scope ExclusiveScan " + "%uint_const", + + "%smax_reduce = OpGroupUMaxNonUniformAMD %int %scope Reduce %int_const", + "%smax_iscan = OpGroupUMaxNonUniformAMD %int %scope InclusiveScan " + "%int_const", + "%smax_escan = OpGroupUMaxNonUniformAMD %int %scope ExclusiveScan " + "%int_const"}; } TEST_P(ValidateAMDShaderBallotCapabilities, ExpectSuccess) { @@ -188,7 +206,8 @@ INSTANTIATE_TEST_CASE_P(ExpectSuccess, ValidateAMDShaderBallotCapabilities, ValuesIn(AMDShaderBallotGroupInstructions())); TEST_P(ValidateAMDShaderBallotCapabilities, ExpectFailure) { - // Fail because the module does not specify the SPV_AMD_shader_ballot extension. + // Fail because the module does not specify the SPV_AMD_shader_ballot + // extension. auto parts = ShaderPartsForAMDShaderBallot(); const string assembly = diff --git a/utils/generate_grammar_tables.py b/utils/generate_grammar_tables.py index f83b113..46ccf93 100755 --- a/utils/generate_grammar_tables.py +++ b/utils/generate_grammar_tables.py @@ -53,6 +53,8 @@ SPV_EXT_shader_stencil_export SPV_EXT_shader_viewport_index_layer SPV_AMD_shader_image_load_store_lod SPV_AMD_shader_fragment_mask +SPV_GOOGLE_decorate_string +SPV_GOOGLE_hlsl_functionality1 """ -- 2.7.4