diff options
author | Spencer Fricke <115671160+spencer-lunarg@users.noreply.github.com> | 2022-10-17 23:54:39 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-17 23:54:39 +0300 |
commit | ecd5b9c167ad03dcd4b3211d209581f40e03c608 (patch) | |
tree | dc2163f70acab618a444ac664416ff05c644e490 | |
parent | b53d3a6be38b032dedbc72639dfc6249b5e92697 (diff) |
spirv-val: Add remaining Component decoration validation (#4966)
-rw-r--r-- | source/val/validate_decorations.cpp | 45 | ||||
-rw-r--r-- | source/val/validation_state.cpp | 10 | ||||
-rw-r--r-- | test/val/val_decoration_test.cpp | 107 | ||||
-rw-r--r-- | test/val/val_interfaces_test.cpp | 2 |
4 files changed, 152 insertions, 12 deletions
diff --git a/source/val/validate_decorations.cpp b/source/val/validate_decorations.cpp index 75058501e..81c9094c0 100644 --- a/source/val/validate_decorations.cpp +++ b/source/val/validate_decorations.cpp @@ -1625,6 +1625,8 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, const Instruction& inst, const Decoration& decoration) { assert(inst.id() && "Parser ensures the target of the decoration has an ID"); + assert(decoration.params().size() == 1 && + "Grammar ensures Component has one parameter"); uint32_t type_id; if (decoration.struct_member_index() == Decoration::kInvalidMember) { @@ -1673,23 +1675,48 @@ spv_result_t CheckComponentDecoration(ValidationState_t& vstate, if (!vstate.IsIntScalarOrVectorType(type_id) && !vstate.IsFloatScalarOrVectorType(type_id)) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4924) << "Component decoration specified for type " << vstate.getIdName(type_id) << " that is not a scalar or vector"; } - // For 16-, and 32-bit types, it is invalid if this sequence of components - // gets larger than 3. + const auto component = decoration.params()[0]; + if (component > 3) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4920) + << "Component decoration value must not be greater than 3"; + } + + const auto dimension = vstate.GetDimension(type_id); const auto bit_width = vstate.GetBitWidth(type_id); if (bit_width == 16 || bit_width == 32) { - assert(decoration.params().size() == 1 && - "Grammar ensures Component has one parameter"); - - const auto component = decoration.params()[0]; - const auto last_component = component + vstate.GetDimension(type_id) - 1; - if (last_component > 3) { + const auto sum_component = component + dimension; + if (sum_component > 4) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4921) + << "Sequence of components starting with " << component + << " and ending with " << (sum_component - 1) + << " gets larger than 3"; + } + } else if (bit_width == 64) { + if (dimension > 2) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << "Component decoration only allowed on 64-bit scalar and " + "2-component vector"; + } + if (component == 1 || component == 3) { + return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4923) + << "Component decoration value must not be 1 or 3 for 64-bit " + "data types"; + } + // 64-bit is double per component dimension + const auto sum_component = component + (2 * dimension); + if (sum_component > 4) { return vstate.diag(SPV_ERROR_INVALID_ID, &inst) + << vstate.VkErrorID(4922) << "Sequence of components starting with " << component - << " and ending with " << last_component + << " and ending with " << (sum_component - 1) << " gets larger than 3"; } } diff --git a/source/val/validation_state.cpp b/source/val/validation_state.cpp index d5ddc9c10..a5f1de055 100644 --- a/source/val/validation_state.cpp +++ b/source/val/validation_state.cpp @@ -2094,6 +2094,16 @@ std::string ValidationState_t::VkErrorID(uint32_t id, return VUID_WRAP(VUID-StandaloneSpirv-Location-04918); case 4919: return VUID_WRAP(VUID-StandaloneSpirv-Location-04919); + case 4920: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04920); + case 4921: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04921); + case 4922: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04922); + case 4923: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04923); + case 4924: + return VUID_WRAP(VUID-StandaloneSpirv-Component-04924); case 6201: return VUID_WRAP(VUID-StandaloneSpirv-Flat-06201); case 6202: diff --git a/test/val/val_decoration_test.cpp b/test/val/val_decoration_test.cpp index 28ee970a1..076267088 100644 --- a/test/val/val_decoration_test.cpp +++ b/test/val/val_decoration_test.cpp @@ -6885,6 +6885,8 @@ OpFunctionEnd CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04924")); + EXPECT_THAT(getDiagnosticString(), HasSubstr("Component decoration specified for type")); EXPECT_THAT(getDiagnosticString(), HasSubstr("is not a scalar or vector")); } @@ -6893,6 +6895,7 @@ std::string ShaderWithComponentDecoration(const std::string& type, const std::string& decoration) { return R"( OpCapability Shader +OpCapability Int64 OpMemoryModel Logical GLSL450 OpEntryPoint Fragment %main "main" %entryPointOutput OpExecutionMode %main OriginUpperLeft @@ -6905,6 +6908,9 @@ OpDecorate %entryPointOutput )" + %v3float = OpTypeVector %float 3 %v4float = OpTypeVector %float 4 %uint = OpTypeInt 32 0 +%uint64 = OpTypeInt 64 0 +%v2uint64 = OpTypeVector %uint64 2 +%v3uint64 = OpTypeVector %uint64 3 %uint_2 = OpConstant %uint 2 %arr_v3float_uint_2 = OpTypeArray %v3float %uint_2 %float_0 = OpConstant %float 0 @@ -6960,8 +6966,10 @@ TEST_F(ValidateDecorations, ComponentDecorationIntBad4Vulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); EXPECT_THAT(getDiagnosticString(), - HasSubstr("Sequence of components starting with 4 " - "and ending with 4 gets larger than 3")); + AnyVUID("VUID-StandaloneSpirv-Component-04920")); + EXPECT_THAT( + getDiagnosticString(), + HasSubstr("Component decoration value must not be greater than 3")); } TEST_F(ValidateDecorations, ComponentDecorationVector3GoodVulkan) { @@ -6989,6 +6997,8 @@ TEST_F(ValidateDecorations, ComponentDecorationVector4Bad1Vulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04921")); + EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 1 " "and ending with 4 gets larger than 3")); } @@ -7000,6 +7010,8 @@ TEST_F(ValidateDecorations, ComponentDecorationVector4Bad3Vulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04921")); + EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 3 " "and ending with 6 gets larger than 3")); } @@ -7022,10 +7034,99 @@ TEST_F(ValidateDecorations, ComponentDecorationArrayBadVulkan) { CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04921")); + EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 2 " "and ending with 4 gets larger than 3")); } +TEST_F(ValidateDecorations, ComponentDecoration64ScalarGoodVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("uint64", "Component 0"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env)); +} + +TEST_F(ValidateDecorations, ComponentDecoration64Scalar1BadVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("uint64", "Component 1"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04923")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Component decoration value must not be 1 or 3 for " + "64-bit data types")); +} + +TEST_F(ValidateDecorations, ComponentDecoration64Scalar2GoodVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("uint64", "Component 2"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env)); +} + +TEST_F(ValidateDecorations, ComponentDecoration64Scalar3BadVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("uint64", "Component 3"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04923")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Component decoration value must not be 1 or 3 for " + "64-bit data types")); +} + +TEST_F(ValidateDecorations, ComponentDecoration64Vec0GoodVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 0"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_SUCCESS, ValidateAndRetrieveValidationState(env)); +} + +TEST_F(ValidateDecorations, ComponentDecoration64Vec1BadVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 1"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04923")); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Component decoration value must not be 1 or 3 for " + "64-bit data types")); +} + +TEST_F(ValidateDecorations, ComponentDecoration64Vec2BadVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("v2uint64", "Component 2"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); + EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04922")); + HasSubstr( + "Sequence of components starting with 2 " + "and ending with 6 gets larger than 3"); +} + +TEST_F(ValidateDecorations, ComponentDecoration64VecWideBadVulkan) { + const spv_target_env env = SPV_ENV_VULKAN_1_0; + std::string spirv = ShaderWithComponentDecoration("v3uint64", "Component 0"); + + CompileSuccessfully(spirv, env); + EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); + EXPECT_THAT(getDiagnosticString(), + HasSubstr("Component decoration only allowed on 64-bit scalar " + "and 2-component vector")); +} + TEST_F(ValidateDecorations, ComponentDecorationBlockGood) { std::string spirv = R"( OpCapability Shader @@ -7097,6 +7198,8 @@ OpFunctionEnd CompileSuccessfully(spirv, env); EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateAndRetrieveValidationState(env)); EXPECT_THAT(getDiagnosticString(), + AnyVUID("VUID-StandaloneSpirv-Component-04921")); + EXPECT_THAT(getDiagnosticString(), HasSubstr("Sequence of components starting with 2 " "and ending with 4 gets larger than 3")); } diff --git a/test/val/val_interfaces_test.cpp b/test/val/val_interfaces_test.cpp index 22a0e7c34..175652872 100644 --- a/test/val/val_interfaces_test.cpp +++ b/test/val/val_interfaces_test.cpp @@ -1456,7 +1456,7 @@ OpDecorate %struct Block OpMemberDecorate %struct 0 Location 0 OpMemberDecorate %struct 0 Component 0 OpMemberDecorate %struct 1 Location 0 -OpMemberDecorate %struct 1 Component 1 +OpMemberDecorate %struct 1 Component 2 %void = OpTypeVoid %void_fn = OpTypeFunction %void %float = OpTypeFloat 32 |