Skip to content

Commit 0045b01

Browse files
authored
opt: Add VulkanMemoryModelDeviceScope to trim (KhronosGroup#5544)
Add the VulkanMemoryModelDeviceScope capability to the capability trimming pass. According the the spec, "If the Vulkan memory model is declared and any instruction uses Device scope, the VulkanMemoryModelDeviceScope capability must be declared." Since this case, based on the type of an operand, is not covered by the JSON grammar, it is added explicitly.
1 parent ef2f432 commit 0045b01

File tree

4 files changed

+95
-1
lines changed

4 files changed

+95
-1
lines changed

source/opt/ir_context.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,8 @@ class IRContext {
229229
inline void AddExtInstImport(std::unique_ptr<Instruction>&& e);
230230
// Set the memory model for this module.
231231
inline void SetMemoryModel(std::unique_ptr<Instruction>&& m);
232+
// Get the memory model for this module.
233+
inline const Instruction* GetMemoryModel() const;
232234
// Appends an entry point instruction to this module.
233235
inline void AddEntryPoint(std::unique_ptr<Instruction>&& e);
234236
// Appends an execution mode instruction to this module.
@@ -1156,6 +1158,10 @@ void IRContext::SetMemoryModel(std::unique_ptr<Instruction>&& m) {
11561158
module()->SetMemoryModel(std::move(m));
11571159
}
11581160

1161+
const Instruction* IRContext::GetMemoryModel() const {
1162+
return module()->GetMemoryModel();
1163+
}
1164+
11591165
void IRContext::AddEntryPoint(std::unique_ptr<Instruction>&& e) {
11601166
module()->AddEntryPoint(std::move(e));
11611167
}

source/opt/trim_capabilities_pass.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,17 @@ void TrimCapabilitiesPass::addInstructionRequirementsForOperand(
448448
return;
449449
}
450450

451+
// If the Vulkan memory model is declared and any instruction uses Device
452+
// scope, the VulkanMemoryModelDeviceScope capability must be declared. This
453+
// rule cannot be covered by the grammar, so must be checked explicitly.
454+
if (operand.type == SPV_OPERAND_TYPE_SCOPE_ID) {
455+
const Instruction* memory_model = context()->GetMemoryModel();
456+
if (memory_model && memory_model->GetSingleWordInOperand(1u) ==
457+
uint32_t(spv::MemoryModel::Vulkan)) {
458+
capabilities->insert(spv::Capability::VulkanMemoryModelDeviceScope);
459+
}
460+
}
461+
451462
// case 1: Operand is a single value, can directly lookup.
452463
if (!spvOperandIsConcreteMask(operand.type)) {
453464
const spv_operand_desc_t* desc = {};

source/opt/trim_capabilities_pass.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,8 @@ class TrimCapabilitiesPass : public Pass {
9797
spv::Capability::StorageInputOutput16,
9898
spv::Capability::StoragePushConstant16,
9999
spv::Capability::StorageUniform16,
100-
spv::Capability::StorageUniformBufferBlock16
100+
spv::Capability::StorageUniformBufferBlock16,
101+
spv::Capability::VulkanMemoryModelDeviceScope
101102
// clang-format on
102103
};
103104

test/opt/trim_capabilities_pass_test.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2584,6 +2584,82 @@ TEST_F(TrimCapabilitiesPassTest, UInt16_RemainsWhenUsed) {
25842584
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
25852585
}
25862586

2587+
TEST_F(TrimCapabilitiesPassTest,
2588+
VulkanMemoryModelDeviceScope_RemovedWhenUnused) {
2589+
const std::string kTest = R"(
2590+
OpCapability VulkanMemoryModelDeviceScope
2591+
; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScope
2592+
OpCapability Shader
2593+
OpMemoryModel Logical GLSL450
2594+
OpEntryPoint GLCompute %1 "main"
2595+
%void = OpTypeVoid
2596+
%3 = OpTypeFunction %void
2597+
%1 = OpFunction %void None %3
2598+
%6 = OpLabel
2599+
OpReturn
2600+
OpFunctionEnd;
2601+
)";
2602+
const auto result =
2603+
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2604+
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2605+
}
2606+
2607+
TEST_F(TrimCapabilitiesPassTest,
2608+
VulkanMemoryModelDeviceScope_RemovedWhenUsedWithGLSL450) {
2609+
const std::string kTest = R"(
2610+
OpCapability VulkanMemoryModelDeviceScope
2611+
; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScope
2612+
OpCapability Shader
2613+
OpCapability ShaderClockKHR
2614+
OpCapability Int64
2615+
OpExtension "SPV_KHR_shader_clock"
2616+
OpMemoryModel Logical GLSL450
2617+
OpEntryPoint GLCompute %main "main"
2618+
OpExecutionMode %main LocalSize 1 2 4
2619+
%void = OpTypeVoid
2620+
%uint = OpTypeInt 32 0
2621+
%ulong = OpTypeInt 64 0
2622+
%uint_1 = OpConstant %uint 1
2623+
%3 = OpTypeFunction %void
2624+
%main = OpFunction %void None %3
2625+
%6 = OpLabel
2626+
%22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
2627+
OpReturn
2628+
OpFunctionEnd
2629+
)";
2630+
const auto result =
2631+
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2632+
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
2633+
}
2634+
2635+
TEST_F(TrimCapabilitiesPassTest,
2636+
VulkanMemoryModelDeviceScope_RemainsWhenUsedWithVulkan) {
2637+
const std::string kTest = R"(
2638+
OpCapability VulkanMemoryModelDeviceScope
2639+
; CHECK: OpCapability VulkanMemoryModelDeviceScope
2640+
OpCapability Shader
2641+
OpCapability ShaderClockKHR
2642+
OpCapability Int64
2643+
OpExtension "SPV_KHR_shader_clock"
2644+
OpMemoryModel Logical Vulkan
2645+
OpEntryPoint GLCompute %main "main"
2646+
OpExecutionMode %main LocalSize 1 2 4
2647+
%void = OpTypeVoid
2648+
%uint = OpTypeInt 32 0
2649+
%ulong = OpTypeInt 64 0
2650+
%uint_1 = OpConstant %uint 1
2651+
%3 = OpTypeFunction %void
2652+
%main = OpFunction %void None %3
2653+
%6 = OpLabel
2654+
%22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
2655+
OpReturn
2656+
OpFunctionEnd
2657+
)";
2658+
const auto result =
2659+
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
2660+
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
2661+
}
2662+
25872663
} // namespace
25882664
} // namespace opt
25892665
} // namespace spvtools

0 commit comments

Comments
 (0)