mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-24 00:40:14 +00:00
spirv-val: Add remaining Component decoration validation (#4966)
This commit is contained in:
parent
b53d3a6be3
commit
ecd5b9c167
@ -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 " << last_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 " << (sum_component - 1)
|
||||
<< " gets larger than 3";
|
||||
}
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -6884,6 +6884,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) {
|
||||
@ -6988,6 +6996,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"));
|
||||
@ -6999,6 +7009,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"));
|
||||
@ -7021,11 +7033,100 @@ 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
|
||||
@ -7096,6 +7197,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"));
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user