spirv-val: Add more Vulkan VUID labels (#4764)

This commit is contained in:
sfricke-samsung 2022-03-25 08:29:19 -05:00 committed by GitHub
parent a3fbc9331b
commit fa5d424830
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 52 deletions

View File

@ -334,7 +334,7 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec,
sc != SpvStorageClassIncomingCallableDataKHR &&
sc != SpvStorageClassShaderRecordBufferKHR) {
return _.diag(SPV_ERROR_INVALID_ID, target)
<< LogStringForDecoration(dec)
<< _.VkErrorID(6672) << LogStringForDecoration(dec)
<< " decoration must not be applied to this storage class";
}
break;
@ -355,7 +355,7 @@ spv_result_t ValidateDecorationTarget(ValidationState_t& _, SpvDecoration dec,
break;
case SpvDecorationInputAttachmentIndex:
if (sc != SpvStorageClassUniformConstant) {
return fail(0) << "must be in the UniformConstant storage class";
return fail(6678) << "must be in the UniformConstant storage class";
}
break;
case SpvDecorationFlat:

View File

@ -956,41 +956,41 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
const bool storage_buffer = storageClass == SpvStorageClassStorageBuffer;
if (spvIsVulkanEnv(vstate.context()->target_env)) {
// Vulkan 14.5.1: There must be no more than one PushConstant block
// per entry point.
// Vulkan: There must be no more than one PushConstant block per entry
// point.
if (push_constant) {
auto entry_points = vstate.EntryPointReferences(var_id);
for (auto ep_id : entry_points) {
const bool already_used = !uses_push_constant.insert(ep_id).second;
if (already_used) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
<< "Entry point id '" << ep_id
<< vstate.VkErrorID(6674) << "Entry point id '" << ep_id
<< "' uses more than one PushConstant interface.\n"
<< "From Vulkan spec, section 14.5.1:\n"
<< "From Vulkan spec:\n"
<< "There must be no more than one push constant block "
<< "statically used per shader entry point.";
}
}
}
// Vulkan 14.5.2: Check DescriptorSet and Binding decoration for
// Vulkan: Check DescriptorSet and Binding decoration for
// UniformConstant which cannot be a struct.
if (uniform_constant) {
auto entry_points = vstate.EntryPointReferences(var_id);
if (!entry_points.empty() &&
!hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
<< "UniformConstant id '" << var_id
<< vstate.VkErrorID(6677) << "UniformConstant id '" << var_id
<< "' is missing DescriptorSet decoration.\n"
<< "From Vulkan spec, section 14.5.2:\n"
<< "From Vulkan spec:\n"
<< "These variables must have DescriptorSet and Binding "
"decorations specified";
}
if (!entry_points.empty() &&
!hasDecoration(var_id, SpvDecorationBinding, vstate)) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
<< "UniformConstant id '" << var_id
<< vstate.VkErrorID(6677) << "UniformConstant id '" << var_id
<< "' is missing Binding decoration.\n"
<< "From Vulkan spec, section 14.5.2:\n"
<< "From Vulkan spec:\n"
<< "These variables must have DescriptorSet and Binding "
"decorations specified";
}
@ -1051,55 +1051,55 @@ spv_result_t CheckDecorationsOfBuffers(ValidationState_t& vstate) {
hasDecoration(id, SpvDecorationBufferBlock, vstate);
if (storage_buffer && buffer_block) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
<< "Storage buffer id '" << var_id
<< vstate.VkErrorID(6675) << "Storage buffer id '" << var_id
<< " In Vulkan, BufferBlock is disallowed on variables in "
"the StorageBuffer storage class";
}
// Vulkan 14.5.1/2: Check Block decoration for PushConstant, Uniform
// Vulkan: Check Block decoration for PushConstant, Uniform
// and StorageBuffer variables. Uniform can also use BufferBlock.
if (push_constant && !block) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
<< "PushConstant id '" << id
<< vstate.VkErrorID(6675) << "PushConstant id '" << id
<< "' is missing Block decoration.\n"
<< "From Vulkan spec, section 14.5.1:\n"
<< "From Vulkan spec:\n"
<< "Such variables must be identified with a Block "
"decoration";
}
if (storage_buffer && !block) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
<< "StorageBuffer id '" << id
<< vstate.VkErrorID(6675) << "StorageBuffer id '" << id
<< "' is missing Block decoration.\n"
<< "From Vulkan spec, section 14.5.2:\n"
<< "From Vulkan spec:\n"
<< "Such variables must be identified with a Block "
"decoration";
}
if (uniform && !block && !buffer_block) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(id))
<< "Uniform id '" << id
<< vstate.VkErrorID(6676) << "Uniform id '" << id
<< "' is missing Block or BufferBlock decoration.\n"
<< "From Vulkan spec, section 14.5.2:\n"
<< "From Vulkan spec:\n"
<< "Such variables must be identified with a Block or "
"BufferBlock decoration";
}
// Vulkan 14.5.2: Check DescriptorSet and Binding decoration for
// Vulkan: Check DescriptorSet and Binding decoration for
// Uniform and StorageBuffer variables.
if (uniform || storage_buffer) {
auto entry_points = vstate.EntryPointReferences(var_id);
if (!entry_points.empty() &&
!hasDecoration(var_id, SpvDecorationDescriptorSet, vstate)) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
<< sc_str << " id '" << var_id
<< vstate.VkErrorID(6677) << sc_str << " id '" << var_id
<< "' is missing DescriptorSet decoration.\n"
<< "From Vulkan spec, section 14.5.2:\n"
<< "From Vulkan spec:\n"
<< "These variables must have DescriptorSet and Binding "
"decorations specified";
}
if (!entry_points.empty() &&
!hasDecoration(var_id, SpvDecorationBinding, vstate)) {
return vstate.diag(SPV_ERROR_INVALID_ID, vstate.FindDef(var_id))
<< sc_str << " id '" << var_id
<< vstate.VkErrorID(6677) << sc_str << " id '" << var_id
<< "' is missing Binding decoration.\n"
<< "From Vulkan spec, section 14.5.2:\n"
<< "From Vulkan spec:\n"
<< "These variables must have DescriptorSet and Binding "
"decorations specified";
}

View File

@ -980,8 +980,9 @@ spv_result_t ValidateSampledImage(ValidationState_t& _,
if (spvIsVulkanEnv(_.context()->target_env)) {
if (info.sampled != 1) {
return _.diag(SPV_ERROR_INVALID_DATA, inst)
<< "Expected Image 'Sampled' parameter to be 1 "
<< "for Vulkan environment.";
<< _.VkErrorID(6671)
<< "Expected Image 'Sampled' parameter to be 1 for Vulkan "
"environment.";
}
} else {
if (info.sampled != 0 && info.sampled != 1) {

View File

@ -1905,6 +1905,20 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeImage-06214);
case 6491:
return VUID_WRAP(VUID-StandaloneSpirv-DescriptorSet-06491);
case 6671:
return VUID_WRAP(VUID-StandaloneSpirv-OpTypeSampledImage-06671);
case 6672:
return VUID_WRAP(VUID-StandaloneSpirv-Location-06672);
case 6674:
return VUID_WRAP(VUID-StandaloneSpirv-OpEntryPoint-06674);
case 6675:
return VUID_WRAP(VUID-StandaloneSpirv-PushConstant-06675);
case 6676:
return VUID_WRAP(VUID-StandaloneSpirv-Uniform-06676);
case 6677:
return VUID_WRAP(VUID-StandaloneSpirv-UniformConstant-06677);
case 6678:
return VUID_WRAP(VUID-StandaloneSpirv-InputAttachmentIndex-06678);
default:
return ""; // unknown id
}
@ -1912,4 +1926,4 @@ std::string ValidationState_t::VkErrorID(uint32_t id,
}
} // namespace val
} // namespace spvtools
} // namespace spvtools

View File

@ -754,6 +754,8 @@ OpFunctionEnd
CompileSuccessfully(text, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-Location-06672"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("decoration must not be applied to this storage class"));

View File

@ -2686,6 +2686,8 @@ TEST_F(ValidateDecorations, VulkanBufferBlockOnStorageBufferBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("In Vulkan, BufferBlock is disallowed on variables in "
"the StorageBuffer storage class"));
@ -2880,9 +2882,11 @@ TEST_F(ValidateDecorations, VulkanPushConstantMissingBlockBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("PushConstant id '2' is missing Block decoration.\n"
"From Vulkan spec, section 14.5.1:\n"
"From Vulkan spec:\n"
"Such variables must be identified with a Block "
"decoration"));
}
@ -3033,11 +3037,13 @@ TEST_F(ValidateDecorations, VulkanMultiplePushConstantsSingleEntryPointBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-06674"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Entry point id '1' uses more than one PushConstant interface.\n"
"From Vulkan spec, section 14.5.1:\n"
"From Vulkan spec:\n"
"There must be no more than one push constant block "
"statically used per shader entry point."));
}
@ -3144,11 +3150,13 @@ TEST_F(ValidateDecorations,
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-OpEntryPoint-06674"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr(
"Entry point id '1' uses more than one PushConstant interface.\n"
"From Vulkan spec, section 14.5.1:\n"
"From Vulkan spec:\n"
"There must be no more than one push constant block "
"statically used per shader entry point."));
}
@ -3185,9 +3193,11 @@ TEST_F(ValidateDecorations, VulkanUniformMissingDescriptorSetBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Uniform id '3' is missing DescriptorSet decoration.\n"
"From Vulkan spec, section 14.5.2:\n"
"From Vulkan spec:\n"
"These variables must have DescriptorSet and Binding "
"decorations specified"));
}
@ -3224,9 +3234,11 @@ TEST_F(ValidateDecorations, VulkanUniformMissingBindingBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Uniform id '3' is missing Binding decoration.\n"
"From Vulkan spec, section 14.5.2:\n"
"From Vulkan spec:\n"
"These variables must have DescriptorSet and Binding "
"decorations specified"));
}
@ -3256,10 +3268,12 @@ TEST_F(ValidateDecorations, VulkanUniformConstantMissingDescriptorSetBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("UniformConstant id '2' is missing DescriptorSet decoration.\n"
"From Vulkan spec, section 14.5.2:\n"
"From Vulkan spec:\n"
"These variables must have DescriptorSet and Binding "
"decorations specified"));
}
@ -3289,10 +3303,12 @@ TEST_F(ValidateDecorations, VulkanUniformConstantMissingBindingBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("UniformConstant id '2' is missing Binding decoration.\n"
"From Vulkan spec, section 14.5.2:\n"
"From Vulkan spec:\n"
"These variables must have DescriptorSet and Binding "
"decorations specified"));
}
@ -3329,10 +3345,12 @@ TEST_F(ValidateDecorations, VulkanStorageBufferMissingDescriptorSetBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("StorageBuffer id '3' is missing DescriptorSet decoration.\n"
"From Vulkan spec, section 14.5.2:\n"
"From Vulkan spec:\n"
"These variables must have DescriptorSet and Binding "
"decorations specified"));
}
@ -3369,9 +3387,11 @@ TEST_F(ValidateDecorations, VulkanStorageBufferMissingBindingBad) {
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("StorageBuffer id '3' is missing Binding decoration.\n"
"From Vulkan spec, section 14.5.2:\n"
"From Vulkan spec:\n"
"These variables must have DescriptorSet and Binding "
"decorations specified"));
}
@ -3414,10 +3434,12 @@ TEST_F(ValidateDecorations,
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_1);
EXPECT_EQ(SPV_ERROR_INVALID_ID,
ValidateAndRetrieveValidationState(SPV_ENV_VULKAN_1_1));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-UniformConstant-06677"));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("StorageBuffer id '3' is missing DescriptorSet decoration.\n"
"From Vulkan spec, section 14.5.2:\n"
"From Vulkan spec:\n"
"These variables must have DescriptorSet and Binding "
"decorations specified"));
}
@ -7158,7 +7180,9 @@ OpFunctionEnd
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables "
AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec:\nSuch variables "
"must be identified with a Block decoration"));
}
@ -7186,7 +7210,9 @@ OpFunctionEnd
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables "
AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec:\nSuch variables "
"must be identified with a Block decoration"));
}
@ -7215,7 +7241,9 @@ OpFunctionEnd
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables "
AnyVUID("VUID-StandaloneSpirv-PushConstant-06675"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec:\nSuch variables "
"must be identified with a Block decoration"));
}
@ -7287,10 +7315,11 @@ OpFunctionEnd
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables must be "
"identified with a Block or BufferBlock decoration"));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec:\nSuch variables must be "
"identified with a Block or BufferBlock decoration"));
}
TEST_F(ValidateDecorations, VulkanUniformArrayMissingBlock) {
@ -7315,10 +7344,11 @@ OpFunctionEnd
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables must be "
"identified with a Block or BufferBlock decoration"));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec:\nSuch variables must be "
"identified with a Block or BufferBlock decoration"));
}
TEST_F(ValidateDecorations, VulkanUniformRuntimeArrayMissingBlock) {
@ -7344,10 +7374,11 @@ OpFunctionEnd
CompileSuccessfully(spirv, SPV_ENV_VULKAN_1_0);
EXPECT_EQ(SPV_ERROR_INVALID_ID, ValidateInstructions(SPV_ENV_VULKAN_1_0));
EXPECT_THAT(
getDiagnosticString(),
HasSubstr("From Vulkan spec, section 14.5.2:\nSuch variables must be "
"identified with a Block or BufferBlock decoration"));
EXPECT_THAT(getDiagnosticString(),
AnyVUID("VUID-StandaloneSpirv-Uniform-06676"));
EXPECT_THAT(getDiagnosticString(),
HasSubstr("From Vulkan spec:\nSuch variables must be "
"identified with a Block or BufferBlock decoration"));
}
TEST_F(ValidateDecorations, VulkanArrayStrideZero) {

View File

@ -1043,6 +1043,26 @@ TEST_F(ValidateImage, SampledImageNotSampler) {
HasSubstr("Expected Sampler to be of type OpTypeSampler"));
}
TEST_F(ValidateImage, SampledImageIsStorage) {
const std::string declarations = R"(
%type_sampled_image_f32_2d_0002 = OpTypeSampledImage %type_image_f32_2d_0002
)";
const std::string body = R"(
%img = OpLoad %type_image_f32_2d_0002 %uniform_image_f32_2d_0002
%sampler = OpLoad %type_sampler %uniform_sampler
%simg = OpSampledImage %type_sampled_image_f32_2d_0002 %img %sampler
)";
CompileSuccessfully(GenerateShaderCode(body, "", "Fragment", "",
SPV_ENV_UNIVERSAL_1_0, "GLSL450",
declarations)
.c_str());
ASSERT_EQ(SPV_ERROR_INVALID_DATA, ValidateInstructions());
EXPECT_THAT(getDiagnosticString(),
HasSubstr("Sampled image type requires an image type with "
"\"Sampled\" operand set to 0 or 1"));
}
TEST_F(ValidateImage, ImageTexelPointerSuccess) {
const std::string body = R"(
%texel_ptr = OpImageTexelPointer %ptr_Image_u32 %private_image_u32_buffer_0002_r32ui %u32_0 %u32_0