Skip to content

Commit d5bed3e

Browse files
layer: Add InputAttachmentIndex SPIR-V check
1 parent e12f3bb commit d5bed3e

File tree

3 files changed

+123
-0
lines changed

3 files changed

+123
-0
lines changed

layers/core_checks/cc_spirv.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1819,6 +1819,11 @@ bool CoreChecks::ValidateShaderDescriptorVariable(const spirv::Module &module_st
18191819

18201820
if (variable.decorations.Has(spirv::DecorationSet::input_attachment_bit)) {
18211821
skip |= ValidateShaderInputAttachment(module_state, pipeline, variable, loc);
1822+
} else if (!enabled_features.dynamicRenderingLocalRead && variable.info.image_dim == spv::DimSubpassData) {
1823+
skip |= LogError("VUID-RuntimeSpirv-None-09558", module_state.handle(), loc,
1824+
"dynamicRenderingLocalRead was not enabled, but the OpTypeImage with Dim::SubpassData is missing the "
1825+
"InputAttachmentIndex decoration.\n%s\n",
1826+
variable.base_type.Describe().c_str());
18221827
}
18231828
}
18241829
return skip;

tests/unit/shader_interface.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,4 +1784,61 @@ TEST_F(NegativeShaderInterface, MultipleFragmentAttachment) {
17841784
m_errorMonitor->SetDesiredWarning("Undefined-Value-ShaderInputNotProduced");
17851785
pipe.CreateGraphicsPipeline();
17861786
m_errorMonitor->VerifyFound();
1787+
}
1788+
1789+
TEST_F(NegativeShaderInterface, MissingInputAttachmentIndex) {
1790+
RETURN_IF_SKIP(Init());
1791+
InitRenderTarget();
1792+
1793+
// layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];
1794+
// layout(location=0) out vec4 color;
1795+
// void main() {
1796+
// color = subpassLoad(xs[0]);
1797+
// }
1798+
//
1799+
// missing OpDecorate %xs InputAttachmentIndex 0
1800+
const char *fsSource = R"(
1801+
OpCapability Shader
1802+
OpCapability InputAttachment
1803+
OpMemoryModel Logical GLSL450
1804+
OpEntryPoint Fragment %main "main" %color
1805+
OpExecutionMode %main OriginUpperLeft
1806+
OpDecorate %color Location 0
1807+
OpDecorate %xs DescriptorSet 0
1808+
OpDecorate %xs Binding 0
1809+
%void = OpTypeVoid
1810+
%3 = OpTypeFunction %void
1811+
%float = OpTypeFloat 32
1812+
%v4float = OpTypeVector %float 4
1813+
%_ptr_Output_v4float = OpTypePointer Output %v4float
1814+
%color = OpVariable %_ptr_Output_v4float Output
1815+
%10 = OpTypeImage %float SubpassData 0 0 0 2 Unknown
1816+
%uint = OpTypeInt 32 0
1817+
%uint_1 = OpConstant %uint 1
1818+
%_arr_10_uint_1 = OpTypeArray %10 %uint_1
1819+
%_ptr_UniformConstant__arr_10_uint_1 = OpTypePointer UniformConstant %_arr_10_uint_1
1820+
%xs = OpVariable %_ptr_UniformConstant__arr_10_uint_1 UniformConstant
1821+
%int = OpTypeInt 32 1
1822+
%int_0 = OpConstant %int 0
1823+
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
1824+
%v2int = OpTypeVector %int 2
1825+
%22 = OpConstantComposite %v2int %int_0 %int_0
1826+
%main = OpFunction %void None %3
1827+
%5 = OpLabel
1828+
%19 = OpAccessChain %_ptr_UniformConstant_10 %xs %int_0
1829+
%20 = OpLoad %10 %19
1830+
%23 = OpImageRead %v4float %20 %22
1831+
OpStore %color %23
1832+
OpReturn
1833+
OpFunctionEnd
1834+
)";
1835+
1836+
VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_0, SPV_SOURCE_ASM);
1837+
1838+
CreatePipelineHelper pipe(*this);
1839+
pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
1840+
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
1841+
m_errorMonitor->SetDesiredWarning("VUID-RuntimeSpirv-None-09558");
1842+
pipe.CreateGraphicsPipeline();
1843+
m_errorMonitor->VerifyFound();
17871844
}

tests/unit/shader_interface_positive.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,4 +1422,65 @@ TEST_F(PositiveShaderInterface, MultipleFragmentAttachment) {
14221422
pipe.cb_ci_.pAttachments = cb_as;
14231423
pipe.gp_ci_.renderPass = rp.Handle();
14241424
pipe.CreateGraphicsPipeline();
1425+
}
1426+
1427+
TEST_F(PositiveShaderInterface, MissingInputAttachmentIndex) {
1428+
TEST_DESCRIPTION("You don't need InputAttachmentIndexif using dynamicRenderingLocalRead");
1429+
SetTargetApiVersion(VK_API_VERSION_1_2);
1430+
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_EXTENSION_NAME);
1431+
AddRequiredExtensions(VK_KHR_DYNAMIC_RENDERING_LOCAL_READ_EXTENSION_NAME);
1432+
AddRequiredFeature(vkt::Feature::dynamicRendering);
1433+
AddRequiredFeature(vkt::Feature::dynamicRenderingLocalRead);
1434+
RETURN_IF_SKIP(Init());
1435+
InitRenderTarget();
1436+
1437+
// layout(input_attachment_index=0, set=0, binding=0) uniform subpassInput xs[1];
1438+
// layout(location=0) out vec4 color;
1439+
// void main() {
1440+
// color = subpassLoad(xs[0]);
1441+
// }
1442+
//
1443+
// missing OpDecorate %xs InputAttachmentIndex 0
1444+
const char *fsSource = R"(
1445+
OpCapability Shader
1446+
OpCapability InputAttachment
1447+
OpMemoryModel Logical GLSL450
1448+
OpEntryPoint Fragment %main "main" %color %xs
1449+
OpExecutionMode %main OriginUpperLeft
1450+
OpDecorate %color Location 0
1451+
OpDecorate %xs DescriptorSet 0
1452+
OpDecorate %xs Binding 0
1453+
%void = OpTypeVoid
1454+
%3 = OpTypeFunction %void
1455+
%float = OpTypeFloat 32
1456+
%v4float = OpTypeVector %float 4
1457+
%_ptr_Output_v4float = OpTypePointer Output %v4float
1458+
%color = OpVariable %_ptr_Output_v4float Output
1459+
%10 = OpTypeImage %float SubpassData 0 0 0 2 Unknown
1460+
%uint = OpTypeInt 32 0
1461+
%uint_1 = OpConstant %uint 1
1462+
%_arr_10_uint_1 = OpTypeArray %10 %uint_1
1463+
%_ptr_UniformConstant__arr_10_uint_1 = OpTypePointer UniformConstant %_arr_10_uint_1
1464+
%xs = OpVariable %_ptr_UniformConstant__arr_10_uint_1 UniformConstant
1465+
%int = OpTypeInt 32 1
1466+
%int_0 = OpConstant %int 0
1467+
%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
1468+
%v2int = OpTypeVector %int 2
1469+
%22 = OpConstantComposite %v2int %int_0 %int_0
1470+
%main = OpFunction %void None %3
1471+
%5 = OpLabel
1472+
%19 = OpAccessChain %_ptr_UniformConstant_10 %xs %int_0
1473+
%20 = OpLoad %10 %19
1474+
%23 = OpImageRead %v4float %20 %22
1475+
OpStore %color %23
1476+
OpReturn
1477+
OpFunctionEnd
1478+
)";
1479+
1480+
VkShaderObj fs(this, fsSource, VK_SHADER_STAGE_FRAGMENT_BIT, SPV_ENV_VULKAN_1_2, SPV_SOURCE_ASM);
1481+
1482+
CreatePipelineHelper pipe(*this);
1483+
pipe.shader_stages_ = {pipe.vs_->GetStageCreateInfo(), fs.GetStageCreateInfo()};
1484+
pipe.dsl_bindings_ = {{0, VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr}};
1485+
pipe.CreateGraphicsPipeline();
14251486
}

0 commit comments

Comments
 (0)