diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 55feca811..b372571f5 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -941,6 +941,8 @@ Pass::Status AggressiveDCEPass::Process() { void AggressiveDCEPass::InitExtensions() { extensions_allowlist_.clear(); + + // clang-format off extensions_allowlist_.insert({ "SPV_AMD_shader_explicit_vertex_parameter", "SPV_AMD_shader_trinary_minmax", @@ -1001,7 +1003,9 @@ void AggressiveDCEPass::InitExtensions() { "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add", "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives" }); + // clang-format on } Instruction* AggressiveDCEPass::GetHeaderBranch(BasicBlock* blk) { diff --git a/source/opt/local_access_chain_convert_pass.cpp b/source/opt/local_access_chain_convert_pass.cpp index fac4cea64..ea1bdeeb3 100644 --- a/source/opt/local_access_chain_convert_pass.cpp +++ b/source/opt/local_access_chain_convert_pass.cpp @@ -428,7 +428,8 @@ void LocalAccessChainConvertPass::InitExtensions() { "SPV_KHR_uniform_group_instructions", "SPV_KHR_fragment_shader_barycentric", "SPV_KHR_vulkan_memory_model", "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add", - "SPV_EXT_fragment_shader_interlock"}); + "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives"}); } bool LocalAccessChainConvertPass::AnyIndexIsOutOfBounds( diff --git a/source/opt/local_single_block_elim_pass.cpp b/source/opt/local_single_block_elim_pass.cpp index 0acffda33..7502d0497 100644 --- a/source/opt/local_single_block_elim_pass.cpp +++ b/source/opt/local_single_block_elim_pass.cpp @@ -289,7 +289,8 @@ void LocalSingleBlockLoadStoreElimPass::InitExtensions() { "SPV_KHR_vulkan_memory_model", "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add", - "SPV_EXT_fragment_shader_interlock"}); + "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives"}); } } // namespace opt diff --git a/source/opt/local_single_store_elim_pass.cpp b/source/opt/local_single_store_elim_pass.cpp index 77b3420ce..f6fc2760e 100644 --- a/source/opt/local_single_store_elim_pass.cpp +++ b/source/opt/local_single_store_elim_pass.cpp @@ -139,7 +139,8 @@ void LocalSingleStoreElimPass::InitExtensionAllowList() { "SPV_KHR_vulkan_memory_model", "SPV_NV_bindless_texture", "SPV_EXT_shader_atomic_float_add", - "SPV_EXT_fragment_shader_interlock"}); + "SPV_EXT_fragment_shader_interlock", + "SPV_NV_compute_shader_derivatives"}); } bool LocalSingleStoreElimPass::ProcessVariable(Instruction* var_inst) { std::vector users; diff --git a/source/opt/trim_capabilities_pass.h b/source/opt/trim_capabilities_pass.h index 9202b2e9a..92777a229 100644 --- a/source/opt/trim_capabilities_pass.h +++ b/source/opt/trim_capabilities_pass.h @@ -91,7 +91,9 @@ class TrimCapabilitiesPass : public Pass { spv::Capability::StoragePushConstant16, spv::Capability::StorageUniform16, spv::Capability::StorageUniformBufferBlock16, - spv::Capability::ImageMSArray + spv::Capability::ImageMSArray, + spv::Capability::ComputeDerivativeGroupQuadsNV, + spv::Capability::ComputeDerivativeGroupLinearNV // clang-format on }; diff --git a/test/opt/trim_capabilities_pass_test.cpp b/test/opt/trim_capabilities_pass_test.cpp index 8aaf860dc..8f49c55cb 100644 --- a/test/opt/trim_capabilities_pass_test.cpp +++ b/test/opt/trim_capabilities_pass_test.cpp @@ -63,6 +63,8 @@ TEST_F(TrimCapabilitiesPassTest, CheckKnownAliasTransformations) { OpCapability DotProductInput4x8BitKHR OpCapability DotProductInput4x8BitPackedKHR OpCapability DotProductKHR + OpCapability ComputeDerivativeGroupQuadsNV + OpCapability ComputeDerivativeGroupLinearNV ; CHECK: OpCapability Linkage ; CHECK-NOT: OpCapability StorageUniform16 ; CHECK-NOT: OpCapability StorageUniformBufferBlock16 @@ -89,6 +91,8 @@ TEST_F(TrimCapabilitiesPassTest, CheckKnownAliasTransformations) { ; CHECK-NOT: OpCapability DotProductInput4x8BitKHR ; CHECK-NOT: OpCapability DotProductInput4x8BitPackedKHR ; CHECK-NOT: OpCapability DotProductKHR +; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV +; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV ; CHECK: OpCapability UniformAndStorageBuffer16BitAccess ; CHECK: OpCapability StorageBuffer16BitAccess ; CHECK: OpCapability ShaderViewportIndexLayerEXT @@ -2129,6 +2133,59 @@ TEST_F(TrimCapabilitiesPassTest, Float64_RemainsWhenUsed) { EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange); } +TEST_F(TrimCapabilitiesPassTest, + ComputeDerivativeGroupQuads_ReamainsWithExecMode) { + const std::string kTest = R"( + OpCapability ComputeDerivativeGroupQuadsNV + OpCapability ComputeDerivativeGroupLinearNV +; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV +; CHECK: OpCapability ComputeDerivativeGroupQuadsNV +; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearNV + OpCapability Shader +; CHECK: OpExtension "SPV_NV_compute_shader_derivatives" + OpExtension "SPV_NV_compute_shader_derivatives" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %1 "main" + OpExecutionMode %1 DerivativeGroupQuadsNV + %void = OpTypeVoid + %3 = OpTypeFunction %void + %1 = OpFunction %void None %3 + %6 = OpLabel + OpReturn + OpFunctionEnd + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); +} + +TEST_F(TrimCapabilitiesPassTest, + ComputeDerivativeGroupLinear_ReamainsWithExecMode) { + const std::string kTest = R"( + OpCapability ComputeDerivativeGroupLinearNV + OpCapability ComputeDerivativeGroupQuadsNV +; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV +; CHECK: OpCapability ComputeDerivativeGroupLinearNV +; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsNV + OpCapability Shader +; CHECK: OpExtension "SPV_NV_compute_shader_derivatives" + OpExtension "SPV_NV_compute_shader_derivatives" + OpMemoryModel Logical GLSL450 + OpEntryPoint GLCompute %1 "main" + OpExecutionMode %1 DerivativeGroupLinearNV + %void = OpTypeVoid + %float = OpTypeFloat 64 + %3 = OpTypeFunction %void + %1 = OpFunction %void None %3 + %6 = OpLabel + OpReturn + OpFunctionEnd + )"; + const auto result = + SinglePassRunAndMatch(kTest, /* skip_nop= */ false); + EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange); +} + } // namespace } // namespace opt } // namespace spvtools