Skip to content

Commit

Permalink
layer: Add InputAttachmentIndex SPIR-V check
Browse files Browse the repository at this point in the history
  • Loading branch information
spencer-lunarg committed May 13, 2024
1 parent e12f3bb commit d5bed3e
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
5 changes: 5 additions & 0 deletions layers/core_checks/cc_spirv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1819,6 +1819,11 @@ bool CoreChecks::ValidateShaderDescriptorVariable(const spirv::Module &module_st

if (variable.decorations.Has(spirv::DecorationSet::input_attachment_bit)) {
skip |= ValidateShaderInputAttachment(module_state, pipeline, variable, loc);
} else if (!enabled_features.dynamicRenderingLocalRead && variable.info.image_dim == spv::DimSubpassData) {
skip |= LogError("VUID-RuntimeSpirv-None-09558", module_state.handle(), loc,
"dynamicRenderingLocalRead was not enabled, but the OpTypeImage with Dim::SubpassData is missing the "
"InputAttachmentIndex decoration.\n%s\n",
variable.base_type.Describe().c_str());
}
}
return skip;
Expand Down
57 changes: 57 additions & 0 deletions tests/unit/shader_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1784,4 +1784,61 @@ TEST_F(NegativeShaderInterface, MultipleFragmentAttachment) {
m_errorMonitor->SetDesiredWarning("Undefined-Value-ShaderInputNotProduced");
pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
}

TEST_F(NegativeShaderInterface, MissingInputAttachmentIndex) {
RETURN_IF_SKIP(Init());
InitRenderTarget();

// layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];
// layout(location=0) out vec4 color;
// void main() {
// color = subpassLoad(xs[0]);
// }
//
// missing OpDecorate %xs InputAttachmentIndex 0
const char *fsSource = R"(
OpCapability Shader
OpCapability InputAttachment
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %color
OpExecutionMode %main OriginUpperLeft
OpDecorate %color Location 0
OpDecorate %xs DescriptorSet 0
OpDecorate %xs Binding 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%10 = OpTypeImage %float SubpassData 0 0 0 2 Unknown
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
%_arr_10_uint_1 = OpTypeArray %10 %uint_1
%_ptr_UniformConstant__arr_10_uint_1 = OpTypePointer UniformConstant %_arr_10_uint_1
%xs = OpVariable %_ptr_UniformConstant__arr_10_uint_1 UniformConstant
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%v2int = OpTypeVector %int 2
%22 = OpConstantComposite %v2int %int_0 %int_0
%main = OpFunction %void None %3
%5 = OpLabel
%19 = OpAccessChain %_ptr_UniformConstant_10 %xs %int_0
%20 = OpLoad %10 %19
%23 = OpImageRead %v4float %20 %22
OpStore %color %23
OpReturn
OpFunctionEnd
)";

VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);

CreatePipelineHelper pipe(*this);
pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
m_errorMonitor->SetDesiredWarning("VUID-RuntimeSpirv-None-09558");
pipe.CreateGraphicsPipeline();
m_errorMonitor->VerifyFound();
}
61 changes: 61 additions & 0 deletions tests/unit/shader_interface_positive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1422,4 +1422,65 @@ TEST_F(PositiveShaderInterface, MultipleFragmentAttachment) {
pipe.cb_ci_.pAttachments = cb_as;
pipe.gp_ci_.renderPass = rp.Handle();
pipe.CreateGraphicsPipeline();
}

TEST_F(PositiveShaderInterface, MissingInputAttachmentIndex) {
TEST_DESCRIPTION("You don't need InputAttachmentIndexif using dynamicRenderingLocalRead");
SetTargetApiVersion(VK_API_VERSION_1_2);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
AddRequiredFeature(vkt::Feature::dynamicRendering);
AddRequiredFeature(vkt::Feature::dynamicRenderingLocalRead);
RETURN_IF_SKIP(Init());
InitRenderTarget();

// layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];
// layout(location=0) out vec4 color;
// void main() {
// color = subpassLoad(xs[0]);
// }
//
// missing OpDecorate %xs InputAttachmentIndex 0
const char *fsSource = R"(
OpCapability Shader
OpCapability InputAttachment
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %color %xs
OpExecutionMode %main OriginUpperLeft
OpDecorate %color Location 0
OpDecorate %xs DescriptorSet 0
OpDecorate %xs Binding 0
%void = OpTypeVoid
%3 = OpTypeFunction %void
%float = OpTypeFloat 32
%v4float = OpTypeVector %float 4
%_ptr_Output_v4float = OpTypePointer Output %v4float
%color = OpVariable %_ptr_Output_v4float Output
%10 = OpTypeImage %float SubpassData 0 0 0 2 Unknown
%uint = OpTypeInt 32 0
%uint_1 = OpConstant %uint 1
%_arr_10_uint_1 = OpTypeArray %10 %uint_1
%_ptr_UniformConstant__arr_10_uint_1 = OpTypePointer UniformConstant %_arr_10_uint_1
%xs = OpVariable %_ptr_UniformConstant__arr_10_uint_1 UniformConstant
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
%v2int = OpTypeVector %int 2
%22 = OpConstantComposite %v2int %int_0 %int_0
%main = OpFunction %void None %3
%5 = OpLabel
%19 = OpAccessChain %_ptr_UniformConstant_10 %xs %int_0
%20 = OpLoad %10 %19
%23 = OpImageRead %v4float %20 %22
OpStore %color %23
OpReturn
OpFunctionEnd
)";

VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_2, SPV_SOURCE_ASM);

CreatePipelineHelper pipe(*this);
pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
pipe.CreateGraphicsPipeline();
}

0 comments on commit d5bed3e

Please sign in to comment.