diff --git a/source/opt/instrument_pass.cpp b/source/opt/instrument_pass.cpp index aaa9c1f9a..032cd280a 100644 --- a/source/opt/instrument_pass.cpp +++ b/source/opt/instrument_pass.cpp @@ -17,6 +17,7 @@ #include "instrument_pass.h" #include "source/cfa.h" +#include "source/spirv_constant.h" namespace { @@ -394,6 +395,13 @@ uint32_t InstrumentPass::GetOutputBufferId() { deco_mgr->AddDecorationVal(output_buffer_id_, SpvDecorationBinding, GetOutputBufferBinding()); AddStorageBufferExt(); + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // Add the new buffer to all entry points. + for (auto& entry : get_module()->entry_points()) { + entry.AddOperand({SPV_OPERAND_TYPE_ID, {output_buffer_id_}}); + context()->AnalyzeUses(&entry); + } + } } return output_buffer_id_; } @@ -431,6 +439,13 @@ uint32_t InstrumentPass::GetInputBufferId() { deco_mgr->AddDecorationVal(input_buffer_id_, SpvDecorationBinding, GetInputBufferBinding()); AddStorageBufferExt(); + if (get_module()->version() >= SPV_SPIRV_VERSION_WORD(1, 4)) { + // Add the new buffer to all entry points. + for (auto& entry : get_module()->entry_points()) { + entry.AddOperand({SPV_OPERAND_TYPE_ID, {input_buffer_id_}}); + context()->AnalyzeUses(&entry); + } + } } return input_buffer_id_; } diff --git a/test/opt/inst_bindless_check_test.cpp b/test/opt/inst_bindless_check_test.cpp index deea1edcd..88d5f196d 100644 --- a/test/opt/inst_bindless_check_test.cpp +++ b/test/opt/inst_bindless_check_test.cpp @@ -2512,6 +2512,120 @@ OpFunctionEnd true); } +TEST_F(InstBindlessTest, SPV14AddToEntryPoint) { + const std::string text = R"( +; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]] +; CHECK: OpDecorate [[v1]] DescriptorSet 7 +; CHECK: OpDecorate [[v2]] DescriptorSet 7 +; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer +; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer +OpCapability Shader +OpExtension "SPV_EXT_descriptor_indexing" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var +OpExecutionMode %foo OriginUpperLeft +OpDecorate %image_var DescriptorSet 0 +OpDecorate %image_var Binding 0 +OpDecorate %sampler_var DescriptorSet 0 +OpDecorate %sampler_var Binding 1 +OpDecorate %gid DescriptorSet 0 +OpDecorate %gid Binding 2 +OpDecorate %struct Block +OpMemberDecorate %struct 0 Offset 0 +%void = OpTypeVoid +%int = OpTypeInt 32 0 +%int_0 = OpConstant %int 0 +%v3int = OpTypeVector %int 3 +%float = OpTypeFloat 32 +%v3float = OpTypeVector %float 3 +%v4float = OpTypeVector %float 4 +%struct = OpTypeStruct %v3int +%ptr_ssbo_struct = OpTypePointer StorageBuffer %struct +%ptr_ssbo_v3int = OpTypePointer StorageBuffer %v3int +%gid = OpVariable %ptr_ssbo_struct StorageBuffer +%image = OpTypeImage %float 3D 0 0 0 1 Unknown +%ptr_uc_image = OpTypePointer UniformConstant %image +%sampler = OpTypeSampler +%ptr_uc_sampler = OpTypePointer UniformConstant %sampler +%image_var = OpVariable %ptr_uc_image UniformConstant +%sampler_var = OpVariable %ptr_uc_sampler UniformConstant +%sampled = OpTypeSampledImage %image +%void_fn = OpTypeFunction %void +%foo = OpFunction %void None %void_fn +%entry = OpLabel +%ld_image = OpLoad %image %image_var +%ld_sampler = OpLoad %sampler %sampler_var +%gep = OpAccessChain %ptr_ssbo_v3int %gid %int_0 +%ld_gid = OpLoad %v3int %gep +%convert = OpConvertUToF %v3float %ld_gid +%sampled_image = OpSampledImage %sampled %ld_image %ld_sampler +%sample = OpImageSampleImplicitLod %v4float %sampled_image %convert +OpReturn +OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4); + SinglePassRunAndMatch(text, true); +} + +TEST_F(InstBindlessTest, SPV14AddToEntryPoints) { + const std::string text = R"( +; CHECK: OpEntryPoint Fragment {{%\w+}} "foo" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]] +; CHECK: OpEntryPoint Fragment {{%\w+}} "bar" {{%\w+}} {{%\w+}} {{%\w+}} [[v1:%\w+]] [[v2:%\w+]] +; CHECK: OpDecorate [[v1]] DescriptorSet 7 +; CHECK: OpDecorate [[v2]] DescriptorSet 7 +; CHECK: [[v1]] = OpVariable {{%\w+}} StorageBuffer +; CHECK: [[v2]] = OpVariable {{%\w+}} StorageBuffer +OpCapability Shader +OpExtension "SPV_EXT_descriptor_indexing" +OpMemoryModel Logical GLSL450 +OpEntryPoint Fragment %foo "foo" %gid %image_var %sampler_var +OpEntryPoint Fragment %foo "bar" %gid %image_var %sampler_var +OpExecutionMode %foo OriginUpperLeft +OpDecorate %image_var DescriptorSet 0 +OpDecorate %image_var Binding 0 +OpDecorate %sampler_var DescriptorSet 0 +OpDecorate %sampler_var Binding 1 +OpDecorate %gid DescriptorSet 0 +OpDecorate %gid Binding 2 +OpDecorate %struct Block +OpMemberDecorate %struct 0 Offset 0 +%void = OpTypeVoid +%int = OpTypeInt 32 0 +%int_0 = OpConstant %int 0 +%v3int = OpTypeVector %int 3 +%float = OpTypeFloat 32 +%v3float = OpTypeVector %float 3 +%v4float = OpTypeVector %float 4 +%struct = OpTypeStruct %v3int +%ptr_ssbo_struct = OpTypePointer StorageBuffer %struct +%ptr_ssbo_v3int = OpTypePointer StorageBuffer %v3int +%gid = OpVariable %ptr_ssbo_struct StorageBuffer +%image = OpTypeImage %float 3D 0 0 0 1 Unknown +%ptr_uc_image = OpTypePointer UniformConstant %image +%sampler = OpTypeSampler +%ptr_uc_sampler = OpTypePointer UniformConstant %sampler +%image_var = OpVariable %ptr_uc_image UniformConstant +%sampler_var = OpVariable %ptr_uc_sampler UniformConstant +%sampled = OpTypeSampledImage %image +%void_fn = OpTypeFunction %void +%foo = OpFunction %void None %void_fn +%entry = OpLabel +%ld_image = OpLoad %image %image_var +%ld_sampler = OpLoad %sampler %sampler_var +%gep = OpAccessChain %ptr_ssbo_v3int %gid %int_0 +%ld_gid = OpLoad %v3int %gep +%convert = OpConvertUToF %v3float %ld_gid +%sampled_image = OpSampledImage %sampled %ld_image %ld_sampler +%sample = OpImageSampleImplicitLod %v4float %sampled_image %convert +OpReturn +OpFunctionEnd +)"; + + SetTargetEnv(SPV_ENV_VULKAN_1_1_SPIRV_1_4); + SinglePassRunAndMatch(text, true); +} + // TODO(greg-lunarg): Add tests to verify handling of these cases: // // Compute shader