diff --git a/include/spirv-tools/libspirv.h b/include/spirv-tools/libspirv.h index 9ee86ea7b9..7ca9822818 100644 --- a/include/spirv-tools/libspirv.h +++ b/include/spirv-tools/libspirv.h @@ -771,6 +771,11 @@ SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowOffsetTextureOperand( SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowVulkan32BitBitwise( spv_validator_options options, bool val); +// Records whether or not the validator should allow the Linkage +// capability when targeting Vulkan. +SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetAllowVulkanLinkage( + spv_validator_options options, bool val); + // Whether friendly names should be used in validation error messages. SPIRV_TOOLS_EXPORT void spvValidatorOptionsSetFriendlyNames( spv_validator_options options, bool val); diff --git a/include/spirv-tools/libspirv.hpp b/include/spirv-tools/libspirv.hpp index 1b3ed86a80..ee91168991 100644 --- a/include/spirv-tools/libspirv.hpp +++ b/include/spirv-tools/libspirv.hpp @@ -138,6 +138,12 @@ class SPIRV_TOOLS_EXPORT ValidatorOptions { spvValidatorOptionsSetAllowVulkan32BitBitwise(options_, val); } + // Records whether or not the validator should allow the Linkage + // capability when targeting Vulkan. + void SetAllowVulkanLinkage(bool val) { + spvValidatorOptionsSetAllowVulkanLinkage(options_, val); + } + // Records whether or not the validator should relax the rules on pointer // usage in logical addressing mode. // diff --git a/source/spirv_validator_options.cpp b/source/spirv_validator_options.cpp index a9591f6b35..0cd09de265 100644 --- a/source/spirv_validator_options.cpp +++ b/source/spirv_validator_options.cpp @@ -136,6 +136,11 @@ void spvValidatorOptionsSetAllowVulkan32BitBitwise( options->allow_vulkan_32_bit_bitwise = val; } +void spvValidatorOptionsSetAllowVulkanLinkage(spv_validator_options options, + bool val) { + options->allow_vulkan_linkage = val; +} + void spvValidatorOptionsSetFriendlyNames(spv_validator_options options, bool val) { options->use_friendly_names = val; diff --git a/source/spirv_validator_options.h b/source/spirv_validator_options.h index 9f0c125436..6306818332 100644 --- a/source/spirv_validator_options.h +++ b/source/spirv_validator_options.h @@ -51,6 +51,7 @@ struct spv_validator_options_t { allow_offset_texture_operand(false), allow_vulkan_32_bit_bitwise(false), before_hlsl_legalization(false), + allow_vulkan_linkage(false), use_friendly_names(true) {} validator_universal_limits_t universal_limits_; @@ -65,6 +66,7 @@ struct spv_validator_options_t { bool allow_offset_texture_operand; bool allow_vulkan_32_bit_bitwise; bool before_hlsl_legalization; + bool allow_vulkan_linkage; bool use_friendly_names; }; diff --git a/source/val/validate_capability.cpp b/source/val/validate_capability.cpp index 961590c19b..9be4ebdf1f 100644 --- a/source/val/validate_capability.cpp +++ b/source/val/validate_capability.cpp @@ -18,6 +18,7 @@ #include #include "source/opcode.h" +#include "source/spirv_target_env.h" #include "source/table2.h" #include "source/val/instruction.h" #include "source/val/validate.h" @@ -374,6 +375,11 @@ spv_result_t CapabilityPass(ValidationState_t& _, const Instruction* inst) { }; const auto env = _.context()->target_env; + if (spvIsVulkanEnv(env) && capability == uint32_t(spv::Capability::Linkage) && + _.options()->allow_vulkan_linkage) { + return SPV_SUCCESS; + } + const bool opencl_embedded = env == SPV_ENV_OPENCL_EMBEDDED_1_2 || env == SPV_ENV_OPENCL_EMBEDDED_2_0 || env == SPV_ENV_OPENCL_EMBEDDED_2_1 || diff --git a/test/val/val_capability_test.cpp b/test/val/val_capability_test.cpp index 4224596606..7b284b4608 100644 --- a/test/val/val_capability_test.cpp +++ b/test/val/val_capability_test.cpp @@ -2585,6 +2585,19 @@ OpMemoryModel Logical GLSL450 HasSubstr("Capability Linkage is not allowed by Vulkan 1.0")); } +TEST_F(ValidateCapability, Vulkan10AllowLinkage) { + const std::string spirv = R"( +OpCapability Shader +OpCapability Linkage +OpMemoryModel Logical GLSL450 +%u32 = OpTypeInt 32 0 +%i32 = OpTypeInt 32 1 +)"; + CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0); + spvValidatorOptionsSetAllowVulkanLinkage(options_, true); + EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_0)); +} + TEST_F(ValidateCapability, Vulkan10EnabledByExtension) { const std::string spirv = R"( OpCapability Shader diff --git a/test/val/val_validation_state_test.cpp b/test/val/val_validation_state_test.cpp index a5e88deab2..8f09a78056 100644 --- a/test/val/val_validation_state_test.cpp +++ b/test/val/val_validation_state_test.cpp @@ -232,6 +232,11 @@ TEST_F(ValidationStateTest, CheckAccessChainIndexesLimitOption) { EXPECT_EQ(100u, options_->universal_limits_.max_access_chain_indexes); } +TEST_F(ValidationStateTest, CheckAllowVulkanLinkageOption) { + spvValidatorOptionsSetAllowVulkanLinkage(options_, true); + EXPECT_TRUE(options_->allow_vulkan_linkage); +} + TEST_F(ValidationStateTest, CheckNonRecursiveBodyGood) { std::string spirv = std::string(kHeader) + kNonRecursiveBody; CompileSuccessfully(spirv); diff --git a/tools/val/val.cpp b/tools/val/val.cpp index 377fd0b1a2..c2343f8e87 100644 --- a/tools/val/val.cpp +++ b/tools/val/val.cpp @@ -74,6 +74,8 @@ NOTE: The validator is a work in progress. be allowed by the target environment. --allow-vulkan-32-bit-bitwise Allow use of non-32 bit for the Base operand where it would otherwise not be allowed by the target environment. + --allow-vulkan-linkage Allow use of the Linkage capability where it would otherwise not + be allowed by the target environment. --before-hlsl-legalization Allows code patterns that are intended to be fixed by spirv-opt's legalization passes. --version Display validator version information. @@ -220,6 +222,8 @@ int main(int argc, char** argv) { options.SetAllowOffsetTextureOperand(true); } else if (0 == strcmp(cur_arg, "--allow-vulkan-32-bit-bitwise")) { options.SetAllowVulkan32BitBitwise(true); + } else if (0 == strcmp(cur_arg, "--allow-vulkan-linkage")) { + options.SetAllowVulkanLinkage(true); } else if (0 == strcmp(cur_arg, "--relax-struct-store")) { options.SetRelaxStructStore(true); } else if (0 == cur_arg[1]) {