3165 lines
130 KiB
C++
3165 lines
130 KiB
C++
// Copyright (c) 2023 Google Inc.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#include "spirv-tools/optimizer.hpp"
|
|
#include "test/opt/pass_fixture.h"
|
|
#include "test/opt/pass_utils.h"
|
|
|
|
namespace spvtools {
|
|
namespace opt {
|
|
namespace {
|
|
|
|
using TrimCapabilitiesPassTest = PassTest<::testing::Test>;
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, CheckKnownAliasTransformations) {
|
|
// Those are expected changes caused by the test process:
|
|
// - SPV is assembled. -> capability goes from text to number.
|
|
// - SPV is optimized.
|
|
// - SPV is disassembled -> capability goes from number to text.
|
|
// - CHECK rule compares both text versions.
|
|
// Because some capabilities share the same number (aliases), the text
|
|
// compared with the CHECK rules depends on which alias is the first on the
|
|
// SPIRV-Headers enum. This could change, and we want to easily distinguish
|
|
// real failure from alias order change. This test is only here to list known
|
|
// alias transformations. If this test breaks, it's not a bug in the
|
|
// optimization pass, but just the SPIRV-Headers enum order that has changed.
|
|
// If that happens, tests needs to be updated to the correct alias is used in
|
|
// the CHECK rule.
|
|
const std::string kTest = R"(
|
|
OpCapability Linkage
|
|
OpCapability StorageUniform16
|
|
OpCapability StorageUniformBufferBlock16
|
|
OpCapability ShaderViewportIndexLayerNV
|
|
OpCapability FragmentBarycentricNV
|
|
OpCapability ShadingRateNV
|
|
OpCapability ShaderNonUniformEXT
|
|
OpCapability RuntimeDescriptorArrayEXT
|
|
OpCapability InputAttachmentArrayDynamicIndexingEXT
|
|
OpCapability UniformTexelBufferArrayDynamicIndexingEXT
|
|
OpCapability StorageTexelBufferArrayDynamicIndexingEXT
|
|
OpCapability UniformBufferArrayNonUniformIndexingEXT
|
|
OpCapability SampledImageArrayNonUniformIndexingEXT
|
|
OpCapability StorageBufferArrayNonUniformIndexingEXT
|
|
OpCapability StorageImageArrayNonUniformIndexingEXT
|
|
OpCapability InputAttachmentArrayNonUniformIndexingEXT
|
|
OpCapability UniformTexelBufferArrayNonUniformIndexingEXT
|
|
OpCapability StorageTexelBufferArrayNonUniformIndexingEXT
|
|
OpCapability VulkanMemoryModelKHR
|
|
OpCapability VulkanMemoryModelDeviceScopeKHR
|
|
OpCapability PhysicalStorageBufferAddressesEXT
|
|
OpCapability DemoteToHelperInvocationEXT
|
|
OpCapability DotProductInputAllKHR
|
|
OpCapability DotProductInput4x8BitKHR
|
|
OpCapability DotProductInput4x8BitPackedKHR
|
|
OpCapability DotProductKHR
|
|
OpCapability ComputeDerivativeGroupQuadsKHR
|
|
OpCapability ComputeDerivativeGroupLinearKHR
|
|
; CHECK: OpCapability Linkage
|
|
; CHECK-NOT: OpCapability StorageUniform16
|
|
; CHECK-NOT: OpCapability StorageUniformBufferBlock16
|
|
; CHECK-NOT: OpCapability ShaderViewportIndexLayerNV
|
|
; CHECK-NOT: OpCapability FragmentBarycentricNV
|
|
; CHECK-NOT: OpCapability ShadingRateNV
|
|
; CHECK-NOT: OpCapability ShaderNonUniformEXT
|
|
; CHECK-NOT: OpCapability RuntimeDescriptorArrayEXT
|
|
; CHECK-NOT: OpCapability InputAttachmentArrayDynamicIndexingEXT
|
|
; CHECK-NOT: OpCapability UniformTexelBufferArrayDynamicIndexingEXT
|
|
; CHECK-NOT: OpCapability StorageTexelBufferArrayDynamicIndexingEXT
|
|
; CHECK-NOT: OpCapability UniformBufferArrayNonUniformIndexingEXT
|
|
; CHECK-NOT: OpCapability SampledImageArrayNonUniformIndexingEXT
|
|
; CHECK-NOT: OpCapability StorageBufferArrayNonUniformIndexingEXT
|
|
; CHECK-NOT: OpCapability StorageImageArrayNonUniformIndexingEXT
|
|
; CHECK-NOT: OpCapability InputAttachmentArrayNonUniformIndexingEXT
|
|
; CHECK-NOT: OpCapability UniformTexelBufferArrayNonUniformIndexingEXT
|
|
; CHECK-NOT: OpCapability StorageTexelBufferArrayNonUniformIndexingEXT
|
|
; CHECK-NOT: OpCapability VulkanMemoryModelKHR
|
|
; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScopeKHR
|
|
; CHECK-NOT: OpCapability PhysicalStorageBufferAddressesEXT
|
|
; CHECK-NOT: OpCapability DemoteToHelperInvocationEXT
|
|
; CHECK-NOT: OpCapability DotProductInputAllKHR
|
|
; CHECK-NOT: OpCapability DotProductInput4x8BitKHR
|
|
; CHECK-NOT: OpCapability DotProductInput4x8BitPackedKHR
|
|
; CHECK-NOT: OpCapability DotProductKHR
|
|
; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsKHR
|
|
; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearKHR
|
|
; CHECK: OpCapability UniformAndStorageBuffer16BitAccess
|
|
; CHECK: OpCapability StorageBuffer16BitAccess
|
|
; CHECK: OpCapability ShaderViewportIndexLayerEXT
|
|
; CHECK: OpCapability FragmentBarycentricKHR
|
|
; CHECK: OpCapability FragmentDensityEXT
|
|
; CHECK: OpCapability ShaderNonUniform
|
|
; CHECK: OpCapability RuntimeDescriptorArray
|
|
; CHECK: OpCapability InputAttachmentArrayDynamicIndexing
|
|
; CHECK: OpCapability UniformTexelBufferArrayDynamicIndexing
|
|
; CHECK: OpCapability StorageTexelBufferArrayDynamicIndexing
|
|
; CHECK: OpCapability UniformBufferArrayNonUniformIndexing
|
|
; CHECK: OpCapability SampledImageArrayNonUniformIndexing
|
|
; CHECK: OpCapability StorageBufferArrayNonUniformIndexing
|
|
; CHECK: OpCapability StorageImageArrayNonUniformIndexing
|
|
; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing
|
|
; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndexing
|
|
; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing
|
|
; CHECK: OpCapability VulkanMemoryModel
|
|
; CHECK: OpCapability VulkanMemoryModelDeviceScope
|
|
; CHECK: OpCapability PhysicalStorageBufferAddresses
|
|
; CHECK: OpCapability DemoteToHelperInvocation
|
|
; CHECK: OpCapability DotProductInputAll
|
|
; CHECK: OpCapability DotProductInput4x8Bit
|
|
; CHECK: OpCapability DotProductInput4x8BitPacked
|
|
; CHECK: OpCapability DotProduct
|
|
OpMemoryModel Logical Vulkan
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_3);
|
|
const auto result =
|
|
SinglePassRunAndMatch<EmptyPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, LinkagePreventsChanges) {
|
|
const std::string kTest = R"(
|
|
OpCapability Linkage
|
|
OpCapability ClipDistance
|
|
OpCapability CullDistance
|
|
OpCapability DemoteToHelperInvocation
|
|
OpCapability DeviceGroup
|
|
OpCapability DrawParameters
|
|
OpCapability Float16
|
|
OpCapability Float64
|
|
OpCapability FragmentBarycentricKHR
|
|
OpCapability FragmentFullyCoveredEXT
|
|
OpCapability FragmentShadingRateKHR
|
|
OpCapability GroupNonUniform
|
|
OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformBallot
|
|
OpCapability GroupNonUniformQuad
|
|
OpCapability GroupNonUniformShuffle
|
|
OpCapability Image1D
|
|
OpCapability ImageBuffer
|
|
OpCapability ImageGatherExtended
|
|
OpCapability ImageMSArray
|
|
OpCapability ImageQuery
|
|
OpCapability InputAttachment
|
|
OpCapability InputAttachmentArrayNonUniformIndexing
|
|
OpCapability Int16
|
|
OpCapability Int64
|
|
OpCapability Int64Atomics
|
|
OpCapability Int64ImageEXT
|
|
OpCapability MeshShadingNV
|
|
OpCapability MinLod
|
|
OpCapability MultiView
|
|
OpCapability MultiViewport
|
|
OpCapability PhysicalStorageBufferAddresses
|
|
OpCapability RayQueryKHR
|
|
OpCapability RayTracingKHR
|
|
OpCapability RayTracingNV
|
|
OpCapability RayTraversalPrimitiveCullingKHR
|
|
OpCapability RuntimeDescriptorArray
|
|
OpCapability SampleMaskPostDepthCoverage
|
|
OpCapability SampleRateShading
|
|
OpCapability Sampled1D
|
|
OpCapability SampledBuffer
|
|
OpCapability SampledImageArrayNonUniformIndexing
|
|
OpCapability Shader
|
|
OpCapability ShaderClockKHR
|
|
OpCapability ShaderLayer
|
|
OpCapability ShaderNonUniform
|
|
OpCapability ShaderViewportIndex
|
|
OpCapability ShaderViewportIndexLayerEXT
|
|
OpCapability SparseResidency
|
|
OpCapability StencilExportEXT
|
|
OpCapability StorageImageArrayNonUniformIndexingEXT
|
|
OpCapability StorageImageExtendedFormats
|
|
OpCapability StorageImageReadWithoutFormat
|
|
OpCapability StorageImageWriteWithoutFormat
|
|
OpCapability StorageInputOutput16
|
|
OpCapability StoragePushConstant16
|
|
OpCapability StorageTexelBufferArrayNonUniformIndexing
|
|
OpCapability StorageUniform16
|
|
OpCapability StorageUniformBufferBlock16
|
|
OpCapability Tessellation
|
|
OpCapability UniformTexelBufferArrayNonUniformIndexing
|
|
OpCapability VulkanMemoryModel
|
|
OpExtension "SPV_EXT_fragment_fully_covered"
|
|
OpExtension "SPV_EXT_shader_image_int64"
|
|
OpExtension "SPV_EXT_shader_stencil_export"
|
|
OpExtension "SPV_EXT_shader_viewport_index_layer"
|
|
OpExtension "SPV_KHR_fragment_shader_barycentric"
|
|
OpExtension "SPV_KHR_fragment_shading_rate"
|
|
OpExtension "SPV_KHR_post_depth_coverage"
|
|
OpExtension "SPV_KHR_ray_query"
|
|
OpExtension "SPV_KHR_ray_tracing"
|
|
OpExtension "SPV_KHR_shader_clock"
|
|
OpExtension "SPV_NV_mesh_shader"
|
|
OpExtension "SPV_NV_ray_tracing"
|
|
OpExtension "SPV_NV_viewport_array2"
|
|
; CHECK: OpCapability Linkage
|
|
; CHECK: OpCapability ClipDistance
|
|
; CHECK: OpCapability CullDistance
|
|
; CHECK: OpCapability DemoteToHelperInvocation
|
|
; CHECK: OpCapability DeviceGroup
|
|
; CHECK: OpCapability DrawParameters
|
|
; CHECK: OpCapability Float16
|
|
; CHECK: OpCapability Float64
|
|
; CHECK: OpCapability FragmentBarycentricKHR
|
|
; CHECK: OpCapability FragmentFullyCoveredEXT
|
|
; CHECK: OpCapability FragmentShadingRateKHR
|
|
; CHECK: OpCapability GroupNonUniform
|
|
; CHECK: OpCapability GroupNonUniformArithmetic
|
|
; CHECK: OpCapability GroupNonUniformBallot
|
|
; CHECK: OpCapability GroupNonUniformQuad
|
|
; CHECK: OpCapability GroupNonUniformShuffle
|
|
; CHECK: OpCapability Image1D
|
|
; CHECK: OpCapability ImageBuffer
|
|
; CHECK: OpCapability ImageGatherExtended
|
|
; CHECK: OpCapability ImageMSArray
|
|
; CHECK: OpCapability ImageQuery
|
|
; CHECK: OpCapability InputAttachment
|
|
; CHECK: OpCapability InputAttachmentArrayNonUniformIndexing
|
|
; CHECK: OpCapability Int16
|
|
; CHECK: OpCapability Int64
|
|
; CHECK: OpCapability Int64Atomics
|
|
; CHECK: OpCapability Int64ImageEXT
|
|
; CHECK: OpCapability MeshShadingNV
|
|
; CHECK: OpCapability MinLod
|
|
; CHECK: OpCapability MultiView
|
|
; CHECK: OpCapability MultiViewport
|
|
; CHECK: OpCapability PhysicalStorageBufferAddresses
|
|
; CHECK: OpCapability RayQueryKHR
|
|
; CHECK: OpCapability RayTracingKHR
|
|
; CHECK: OpCapability RayTracingNV
|
|
; CHECK: OpCapability RayTraversalPrimitiveCullingKHR
|
|
; CHECK: OpCapability RuntimeDescriptorArray
|
|
; CHECK: OpCapability SampleMaskPostDepthCoverage
|
|
; CHECK: OpCapability SampleRateShading
|
|
; CHECK: OpCapability Sampled1D
|
|
; CHECK: OpCapability SampledBuffer
|
|
; CHECK: OpCapability SampledImageArrayNonUniformIndexing
|
|
; CHECK: OpCapability Shader
|
|
; CHECK: OpCapability ShaderClockKHR
|
|
; CHECK: OpCapability ShaderLayer
|
|
; CHECK: OpCapability ShaderNonUniform
|
|
; CHECK: OpCapability ShaderViewportIndex
|
|
; CHECK: OpCapability ShaderViewportIndexLayerEXT
|
|
; CHECK: OpCapability SparseResidency
|
|
; CHECK: OpCapability StencilExportEXT
|
|
; CHECK: OpCapability StorageImageArrayNonUniformIndexing
|
|
; CHECK: OpCapability StorageImageExtendedFormats
|
|
; CHECK: OpCapability StorageImageReadWithoutFormat
|
|
; CHECK: OpCapability StorageImageWriteWithoutFormat
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpCapability StoragePushConstant16
|
|
; CHECK: OpCapability StorageTexelBufferArrayNonUniformIndexing
|
|
; CHECK: OpCapability Tessellation
|
|
; CHECK: OpCapability UniformTexelBufferArrayNonUniformIndex
|
|
; CHECK: OpCapability VulkanMemoryModel
|
|
; CHECK: OpExtension "SPV_EXT_fragment_fully_covered"
|
|
; CHECK: OpExtension "SPV_EXT_shader_image_int64"
|
|
; CHECK: OpExtension "SPV_EXT_shader_stencil_export"
|
|
; CHECK: OpExtension "SPV_EXT_shader_viewport_index_layer"
|
|
; CHECK: OpExtension "SPV_KHR_fragment_shader_barycentric"
|
|
; CHECK: OpExtension "SPV_KHR_fragment_shading_rate"
|
|
; CHECK: OpExtension "SPV_KHR_post_depth_coverage"
|
|
; CHECK: OpExtension "SPV_KHR_ray_query"
|
|
; CHECK: OpExtension "SPV_KHR_ray_tracing"
|
|
; CHECK: OpExtension "SPV_KHR_shader_clock"
|
|
; CHECK: OpExtension "SPV_NV_mesh_shader"
|
|
; CHECK: OpExtension "SPV_NV_ray_tracing"
|
|
; CHECK: OpExtension "SPV_NV_viewport_array2"
|
|
OpMemoryModel Logical Vulkan
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_3);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, KeepShader) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
; CHECK: OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, KeepShaderClockWhenInUse) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Int64
|
|
OpCapability ShaderClockKHR
|
|
OpExtension "SPV_KHR_shader_clock"
|
|
; CHECK: OpCapability ShaderClockKHR
|
|
; CHECK: OpExtension "SPV_KHR_shader_clock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%uint = OpTypeInt 32 0
|
|
%ulong = OpTypeInt 64 0
|
|
%scope = OpConstant %uint 1
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpReadClockKHR %ulong %scope
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, TrimShaderClockWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Int64
|
|
OpCapability ShaderClockKHR
|
|
OpExtension "SPV_KHR_shader_clock"
|
|
; CHECK-NOT: OpCapability ShaderClockKHR
|
|
; CHECK-NOT: OpExtension "SPV_KHR_shader_clock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemains) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Groups
|
|
OpExtension "SPV_AMD_shader_ballot"
|
|
; CHECK: OpCapability Groups
|
|
; CHECK: OpExtension "SPV_AMD_shader_ballot"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%uint = OpTypeInt 32 0
|
|
%1 = OpTypeFunction %void
|
|
%uint_0 = OpConstant %uint 0
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
%4 = OpGroupIAddNonUniformAMD %uint %uint_0 ExclusiveScan %uint_0
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, AMDShaderBallotExtensionRemoved) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Groups
|
|
OpExtension "SPV_AMD_shader_ballot"
|
|
; CHECK-NOT: OpCapability Groups
|
|
; CHECK-NOT: OpExtension "SPV_AMD_shader_ballot"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, MinLod_RemovedIfNotUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Sampled1D
|
|
OpCapability MinLod
|
|
; CHECK-NOT: OpCapability MinLod
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%float = OpTypeFloat 32
|
|
%v3float = OpTypeVector %float 3
|
|
%v4float = OpTypeVector %float 4
|
|
%type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f
|
|
%ptr_type_image = OpTypePointer UniformConstant %type_image
|
|
%type_sampler = OpTypeSampler
|
|
%ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
|
|
%float_0 = OpConstant %float 0
|
|
%float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
|
%image = OpVariable %ptr_type_image UniformConstant
|
|
%sampler = OpVariable %ptr_type_sampler UniformConstant
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
%21 = OpLoad %type_image %image
|
|
%22 = OpLoad %type_sampler %sampler
|
|
%24 = OpSampledImage %type_sampled_image %21 %22
|
|
%25 = OpImageSampleImplicitLod %v4float %24 %float_000
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, MinLod_RemainsWithOpImageSampleImplicitLod) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Sampled1D
|
|
OpCapability MinLod
|
|
; CHECK: OpCapability MinLod
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%float = OpTypeFloat 32
|
|
%v3float = OpTypeVector %float 3
|
|
%v4float = OpTypeVector %float 4
|
|
%type_image = OpTypeImage %float Cube 2 0 0 1 Rgba32f
|
|
%ptr_type_image = OpTypePointer UniformConstant %type_image
|
|
%type_sampler = OpTypeSampler
|
|
%ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
|
|
%float_0 = OpConstant %float 0
|
|
%float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
|
%image = OpVariable %ptr_type_image UniformConstant
|
|
%sampler = OpVariable %ptr_type_sampler UniformConstant
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
%21 = OpLoad %type_image %image
|
|
%22 = OpLoad %type_sampler %sampler
|
|
%24 = OpSampledImage %type_sampled_image %21 %22
|
|
%25 = OpImageSampleImplicitLod %v4float %24 %float_000 MinLod %float_0
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
MinLod_RemainsWithOpImageSparseSampleImplicitLod) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability SparseResidency
|
|
OpCapability ImageGatherExtended
|
|
OpCapability MinLod
|
|
; CHECK: OpCapability MinLod
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %2 "main"
|
|
OpExecutionMode %2 OriginUpperLeft
|
|
%void = OpTypeVoid
|
|
%uint = OpTypeInt 32 0
|
|
%float = OpTypeFloat 32
|
|
%v2float = OpTypeVector %float 2
|
|
%v3float = OpTypeVector %float 3
|
|
%v4float = OpTypeVector %float 4
|
|
%type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
|
|
%ptr_type_image = OpTypePointer UniformConstant %type_image
|
|
%type_sampler = OpTypeSampler
|
|
%ptr_type_sampler = OpTypePointer UniformConstant %type_sampler
|
|
%type_sampled_image = OpTypeSampledImage %type_image
|
|
%sparse_struct = OpTypeStruct %uint %v4float
|
|
%float_0 = OpConstant %float 0
|
|
%float_00 = OpConstantComposite %v2float %float_0 %float_0
|
|
%float_000 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
|
%image = OpVariable %ptr_type_image UniformConstant
|
|
%sampler = OpVariable %ptr_type_sampler UniformConstant
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
%21 = OpLoad %type_image %image
|
|
%22 = OpLoad %type_sampler %sampler
|
|
%24 = OpSampledImage %type_sampled_image %21 %22
|
|
%25 = OpImageSparseSampleImplicitLod %sparse_struct %24 %float_00 MinLod %float_0
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, MinLod_DetectsMinLodWithBitmaskImageOperand) {
|
|
const std::string kTest = R"(
|
|
OpCapability MinLod
|
|
; CHECK: OpCapability MinLod
|
|
OpCapability Shader
|
|
OpCapability SparseResidency
|
|
OpCapability ImageGatherExtended
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %1 "main"
|
|
OpExecutionMode %1 OriginUpperLeft
|
|
%type_sampler = OpTypeSampler
|
|
%int = OpTypeInt 32 1
|
|
%float = OpTypeFloat 32
|
|
%v2int = OpTypeVector %int 2
|
|
%v2float = OpTypeVector %float 2
|
|
%v4float = OpTypeVector %float 4
|
|
%ptr_sampler = OpTypePointer UniformConstant %type_sampler
|
|
%type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
|
|
%ptr_image = OpTypePointer UniformConstant %type_image
|
|
%void = OpTypeVoid
|
|
%uint = OpTypeInt 32 0
|
|
%type_sampled_image = OpTypeSampledImage %type_image
|
|
%type_struct = OpTypeStruct %uint %v4float
|
|
|
|
%int_1 = OpConstant %int 1
|
|
%float_0 = OpConstant %float 0
|
|
%float_1 = OpConstant %float 1
|
|
%8 = OpConstantComposite %v2float %float_0 %float_0
|
|
%12 = OpConstantComposite %v2int %int_1 %int_1
|
|
|
|
%2 = OpVariable %ptr_sampler UniformConstant
|
|
%3 = OpVariable %ptr_image UniformConstant
|
|
%27 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %27
|
|
%28 = OpLabel
|
|
%29 = OpLoad %type_image %3
|
|
%30 = OpLoad %type_sampler %2
|
|
%31 = OpSampledImage %type_sampled_image %29 %30
|
|
%32 = OpImageSparseSampleImplicitLod %type_struct %31 %8 ConstOffset|MinLod %12 %float_0
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointer_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%ptr = OpTypePointer Input %half
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointer_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%ptr = OpTypePointer Input %half
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%uint = OpTypeInt 32 0
|
|
%uint_1 = OpConstant %uint 1
|
|
%array = OpTypeArray %half %uint_1
|
|
%ptr = OpTypePointer Input %array
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerArray_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%uint = OpTypeInt 32 0
|
|
%uint_1 = OpConstant %uint 1
|
|
%array = OpTypeArray %half %uint_1
|
|
%ptr = OpTypePointer Input %array
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Input %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerStruct_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Input %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%float = OpTypeFloat 32
|
|
%struct = OpTypeStruct %float %half
|
|
%parent = OpTypeStruct %float %struct
|
|
%ptr = OpTypePointer Input %parent
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerStructOfStruct_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%float = OpTypeFloat 32
|
|
%struct = OpTypeStruct %float %half
|
|
%parent = OpTypeStruct %float %struct
|
|
%ptr = OpTypePointer Input %parent
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%uint = OpTypeInt 32 0
|
|
%uint_1 = OpConstant %uint 1
|
|
%array = OpTypeArray %struct %uint_1
|
|
%ptr = OpTypePointer Input %array
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerArrayOfStruct_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%uint = OpTypeInt 32 0
|
|
%uint_1 = OpConstant %uint 1
|
|
%array = OpTypeArray %struct %uint_1
|
|
%ptr = OpTypePointer Input %array
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%vector = OpTypeVector %half 4
|
|
%ptr = OpTypePointer Input %vector
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerVector_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%vector = OpTypeVector %half 4
|
|
%ptr = OpTypePointer Input %vector
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%vector = OpTypeVector %half 4
|
|
%matrix = OpTypeMatrix %vector 4
|
|
%ptr = OpTypePointer Input %matrix
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithInputPointerMatrix_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%vector = OpTypeVector %half 4
|
|
%matrix = OpTypeMatrix %vector 4
|
|
%ptr = OpTypePointer Input %matrix
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_IsRemovedWithoutInputPointer) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK-NOT: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%ptr = OpTypePointer Output %half
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemainsWithOutputPointer_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%ptr = OpTypePointer Output %half
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageInputOutput16_RemovedWithoutOutputPointer) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageInputOutput16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK-NOT: OpCapability StorageInputOutput16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StoragePushConstant16_RemainsSimplePointer_Vulkan1_0) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StoragePushConstant16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StoragePushConstant16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%ptr = OpTypePointer PushConstant %half
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StoragePushConstant16_RemainsSimplePointer_Vulkan1_1) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StoragePushConstant16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK: OpCapability StoragePushConstant16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%ptr = OpTypePointer PushConstant %half
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, StoragePushConstant16_RemovedSimplePointer) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StoragePushConstant16
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
; CHECK-NOT: OpCapability StoragePushConstant16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%ptr = OpTypePointer Function %half
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_0) {
|
|
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
|
|
static_assert(spv::Capability::StorageUniformBufferBlock16 ==
|
|
spv::Capability::StorageBuffer16BitAccess);
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
; CHECK: OpCapability StorageBuffer16BitAccess
|
|
; `-> StorageUniformBufferBlock16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
OpDecorate %struct BufferBlock
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Uniform %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageUniformBufferBlock16_RemainsSimplePointer_Vulkan1_1) {
|
|
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
|
|
static_assert(spv::Capability::StorageUniformBufferBlock16 ==
|
|
spv::Capability::StorageBuffer16BitAccess);
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
; CHECK: OpCapability StorageBuffer16BitAccess
|
|
; `-> StorageUniformBufferBlock16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
OpDecorate %struct BufferBlock
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Uniform %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageUniformBufferBlock16_RemovedSimplePointer) {
|
|
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
|
|
static_assert(spv::Capability::StorageUniformBufferBlock16 ==
|
|
spv::Capability::StorageBuffer16BitAccess);
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
; CHECK-NOT: OpCapability StorageBuffer16BitAccess
|
|
; `-> StorageUniformBufferBlock16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Function %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_0) {
|
|
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
|
|
static_assert(spv::Capability::StorageUniformBufferBlock16 ==
|
|
spv::Capability::StorageBuffer16BitAccess);
|
|
static_assert(spv::Capability::StorageUniform16 ==
|
|
spv::Capability::UniformAndStorageBuffer16BitAccess);
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpCapability UniformAndStorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
; CHECK: OpCapability StorageBuffer16BitAccess
|
|
; `-> StorageUniformBufferBlock16
|
|
; CHECK-NOT: OpCapability UniformAndStorageBuffer16BitAccess
|
|
; `-> StorageUniform16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
OpDecorate %struct BufferBlock
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Uniform %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageUniform16_RemovedWithBufferBlockPointer_Vulkan1_1) {
|
|
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
|
|
static_assert(spv::Capability::StorageUniformBufferBlock16 ==
|
|
spv::Capability::StorageBuffer16BitAccess);
|
|
static_assert(spv::Capability::StorageUniform16 ==
|
|
spv::Capability::UniformAndStorageBuffer16BitAccess);
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpCapability UniformAndStorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
; CHECK: OpCapability StorageBuffer16BitAccess
|
|
; `-> StorageUniformBufferBlock16
|
|
; CHECK-NOT: OpCapability UniformAndStorageBuffer16BitAccess
|
|
; `-> StorageUniform16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
OpDecorate %struct BufferBlock
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Uniform %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_0) {
|
|
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
|
|
static_assert(spv::Capability::StorageUniformBufferBlock16 ==
|
|
spv::Capability::StorageBuffer16BitAccess);
|
|
static_assert(spv::Capability::StorageUniform16 ==
|
|
spv::Capability::UniformAndStorageBuffer16BitAccess);
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpCapability UniformAndStorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
; CHECK-NOT: OpCapability StorageBuffer16BitAccess
|
|
; `-> StorageUniformBufferBlock16
|
|
; CHECK: OpCapability UniformAndStorageBuffer16BitAccess
|
|
; `-> StorageUniform16
|
|
; CHECK: OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Uniform %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_0);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageUniform16_RemovedWithNonBlockUniformPointer_Vulkan1_1) {
|
|
// See https://github.com/KhronosGroup/SPIRV-Tools/issues/5354
|
|
static_assert(spv::Capability::StorageUniformBufferBlock16 ==
|
|
spv::Capability::StorageBuffer16BitAccess);
|
|
static_assert(spv::Capability::StorageUniform16 ==
|
|
spv::Capability::UniformAndStorageBuffer16BitAccess);
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability Float16
|
|
OpCapability StorageBuffer16BitAccess
|
|
OpCapability UniformAndStorageBuffer16BitAccess
|
|
OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
; CHECK-NOT: OpCapability StorageBuffer16BitAccess
|
|
; `-> StorageUniformBufferBlock16
|
|
; CHECK: OpCapability UniformAndStorageBuffer16BitAccess
|
|
; `-> StorageUniform16
|
|
; CHECK-NOT: OpExtension "SPV_KHR_16bit_storage"
|
|
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %2 "main"
|
|
%void = OpTypeVoid
|
|
%half = OpTypeFloat 16
|
|
%struct = OpTypeStruct %half
|
|
%ptr = OpTypePointer Uniform %struct
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
SetTargetEnv(SPV_ENV_VULKAN_1_1);
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, FragmentShaderInterlock_RemovedIfNotUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability FragmentShaderPixelInterlockEXT
|
|
OpCapability FragmentShaderSampleInterlockEXT
|
|
OpCapability FragmentShaderShadingRateInterlockEXT
|
|
OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
|
|
; CHECK-NOT: OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
FragmentShaderPixelInterlock_RemainsWhenOrderedIsUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability FragmentShaderPixelInterlockEXT
|
|
OpCapability FragmentShaderSampleInterlockEXT
|
|
OpCapability FragmentShaderShadingRateInterlockEXT
|
|
OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
; CHECK: OpCapability FragmentShaderPixelInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
|
|
; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
OpExecutionMode %main PixelInterlockOrderedEXT
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpBeginInvocationInterlockEXT
|
|
OpEndInvocationInterlockEXT
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
FragmentShaderPixelInterlock_RemainsWhenUnorderedIsUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability FragmentShaderPixelInterlockEXT
|
|
OpCapability FragmentShaderSampleInterlockEXT
|
|
OpCapability FragmentShaderShadingRateInterlockEXT
|
|
OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
; CHECK: OpCapability FragmentShaderPixelInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
|
|
; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
OpExecutionMode %main PixelInterlockUnorderedEXT
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpBeginInvocationInterlockEXT
|
|
OpEndInvocationInterlockEXT
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
FragmentShaderSampleInterlock_RemainsWhenOrderedIsUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability FragmentShaderPixelInterlockEXT
|
|
OpCapability FragmentShaderSampleInterlockEXT
|
|
OpCapability FragmentShaderShadingRateInterlockEXT
|
|
OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
|
|
; CHECK: OpCapability FragmentShaderSampleInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
|
|
; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
OpExecutionMode %main SampleInterlockOrderedEXT
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpBeginInvocationInterlockEXT
|
|
OpEndInvocationInterlockEXT
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
FragmentShaderSampleInterlock_RemainsWhenUnorderedIsUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability FragmentShaderPixelInterlockEXT
|
|
OpCapability FragmentShaderSampleInterlockEXT
|
|
OpCapability FragmentShaderShadingRateInterlockEXT
|
|
OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
|
|
; CHECK: OpCapability FragmentShaderSampleInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderShadingRateInterlockEXT
|
|
; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
OpExecutionMode %main SampleInterlockUnorderedEXT
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpBeginInvocationInterlockEXT
|
|
OpEndInvocationInterlockEXT
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
FragmentShaderShadingRateInterlock_RemainsWhenOrderedIsUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability FragmentShaderPixelInterlockEXT
|
|
OpCapability FragmentShaderSampleInterlockEXT
|
|
OpCapability FragmentShaderShadingRateInterlockEXT
|
|
OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
|
|
; CHECK: OpCapability FragmentShaderShadingRateInterlockEXT
|
|
; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
OpExecutionMode %main ShadingRateInterlockOrderedEXT
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpBeginInvocationInterlockEXT
|
|
OpEndInvocationInterlockEXT
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
FragmentShaderShadingRateInterlock_RemainsWhenUnorderedIsUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability FragmentShaderPixelInterlockEXT
|
|
OpCapability FragmentShaderSampleInterlockEXT
|
|
OpCapability FragmentShaderShadingRateInterlockEXT
|
|
OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
; CHECK-NOT: OpCapability FragmentShaderPixelInterlockEXT
|
|
; CHECK-NOT: OpCapability FragmentShaderSampleInterlockEXT
|
|
; CHECK: OpCapability FragmentShaderShadingRateInterlockEXT
|
|
; CHECK: OpExtension "SPV_EXT_fragment_shader_interlock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
OpExecutionMode %main ShadingRateInterlockUnorderedEXT
|
|
%void = OpTypeVoid
|
|
%1 = OpTypeFunction %void
|
|
%2 = OpFunction %void None %1
|
|
%3 = OpLabel
|
|
OpBeginInvocationInterlockEXT
|
|
OpEndInvocationInterlockEXT
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Int64_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability Int64
|
|
; CHECK-NOT: OpCapability Int64
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Int64_RemainsWhenUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Int64
|
|
; CHECK: OpCapability Int64
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%int = OpTypeInt 64 0
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability RayQueryKHR
|
|
OpExtension "SPV_KHR_ray_query"
|
|
; CHECK-NOT: OpCapability RayQueryKHR
|
|
; CHECK-NOT: OpExtension "SPV_KHR_ray_query"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Vertex %main "main" %out_var_TEXCOORD1
|
|
OpSource HLSL 660
|
|
OpName %out_var_TEXCOORD1 "out.var.TEXCOORD1"
|
|
OpName %main "main"
|
|
OpDecorate %out_var_TEXCOORD1 Flat
|
|
OpDecorate %out_var_TEXCOORD1 Location 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_1234 = OpConstant %uint 1234
|
|
%_ptr_Output_uint = OpTypePointer Output %uint
|
|
%void = OpTypeVoid
|
|
%7 = OpTypeFunction %void
|
|
%out_var_TEXCOORD1 = OpVariable %_ptr_Output_uint Output
|
|
%main = OpFunction %void None %7
|
|
%8 = OpLabel
|
|
OpStore %out_var_TEXCOORD1 %uint_1234
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
RayQueryKHR_RemainsWhenAccelerationStructureIsPresent) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability RayQueryKHR
|
|
OpExtension "SPV_KHR_ray_query"
|
|
; CHECK: OpCapability RayQueryKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_query"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
OpDecorate %var_bvh DescriptorSet 0
|
|
OpDecorate %var_bvh Binding 0
|
|
%bvh = OpTypeAccelerationStructureKHR
|
|
%ptr_bvh = OpTypePointer UniformConstant %bvh
|
|
%void = OpTypeVoid
|
|
%20 = OpTypeFunction %void
|
|
%var_bvh = OpVariable %ptr_bvh UniformConstant
|
|
%main = OpFunction %void None %20
|
|
%30 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenRayQueryTypeIsPresent) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability RayQueryKHR
|
|
OpExtension "SPV_KHR_ray_query"
|
|
; CHECK: OpCapability RayQueryKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_query"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%query = OpTypeRayQueryKHR
|
|
%void = OpTypeVoid
|
|
%20 = OpTypeFunction %void
|
|
%ptr_query = OpTypePointer Function %query
|
|
%main = OpFunction %void None %20
|
|
%30 = OpLabel
|
|
%var_query = OpVariable %ptr_query Function
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, RayQueryKHR_RemainsWhenUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability RayQueryKHR
|
|
OpExtension "SPV_KHR_ray_query"
|
|
; CHECK: OpCapability RayQueryKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_query"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
OpDecorate %bvh DescriptorSet 0
|
|
OpDecorate %bvh Binding 0
|
|
OpDecorate %output DescriptorSet 0
|
|
OpDecorate %output Binding 1
|
|
OpDecorate %_runtimearr_float ArrayStride 4
|
|
OpMemberDecorate %type_RWStructuredBuffer_float 0 Offset 0
|
|
OpDecorate %type_RWStructuredBuffer_float BufferBlock
|
|
%float = OpTypeFloat 32
|
|
%float_0 = OpConstant %float 0
|
|
%int = OpTypeInt 32 1
|
|
%v3float = OpTypeVector %float 3
|
|
%12 = OpConstantComposite %v3float %float_0 %float_0 %float_0
|
|
%int_0 = OpConstant %int 0
|
|
%uint = OpTypeInt 32 0
|
|
%uint_0 = OpConstant %uint 0
|
|
%uint_1 = OpConstant %uint 1
|
|
%accelerationStructureKHR = OpTypeAccelerationStructureKHR
|
|
%_ptr_UniformConstant_accelerationStructureKHR = OpTypePointer UniformConstant %accelerationStructureKHR
|
|
%_runtimearr_float = OpTypeRuntimeArray %float
|
|
%type_RWStructuredBuffer_float = OpTypeStruct %_runtimearr_float
|
|
%_ptr_Uniform_type_RWStructuredBuffer_float = OpTypePointer Uniform %type_RWStructuredBuffer_float
|
|
%void = OpTypeVoid
|
|
%20 = OpTypeFunction %void
|
|
%rayQueryKHR = OpTypeRayQueryKHR
|
|
%_ptr_Function_rayQueryKHR = OpTypePointer Function %rayQueryKHR
|
|
%bool = OpTypeBool
|
|
%_ptr_Uniform_float = OpTypePointer Uniform %float
|
|
%bvh = OpVariable %_ptr_UniformConstant_accelerationStructureKHR UniformConstant
|
|
%output = OpVariable %_ptr_Uniform_type_RWStructuredBuffer_float Uniform
|
|
%main = OpFunction %void None %20
|
|
%24 = OpLabel
|
|
%25 = OpVariable %_ptr_Function_rayQueryKHR Function
|
|
%26 = OpLoad %accelerationStructureKHR %bvh
|
|
OpRayQueryInitializeKHR %25 %26 %uint_0 %uint_0 %12 %float_0 %12 %float_0
|
|
%27 = OpRayQueryProceedKHR %bool %25
|
|
%28 = OpRayQueryGetIntersectionTypeKHR %uint %25 %uint_1
|
|
%29 = OpIEqual %bool %28 %uint_1
|
|
OpSelectionMerge %30 None
|
|
OpBranchConditional %29 %31 %30
|
|
%31 = OpLabel
|
|
%32 = OpAccessChain %_ptr_Uniform_float %output %int_0 %uint_0
|
|
OpStore %32 %float_0
|
|
OpBranch %30
|
|
%30 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
RayTracingKHR_RemainsWithIntersectionExecutionMode) {
|
|
const std::string kTest = R"(
|
|
OpCapability RayTracingKHR
|
|
OpExtension "SPV_KHR_ray_tracing"
|
|
; CHECK: OpCapability RayTracingKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_tracing"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint IntersectionKHR %main "main"
|
|
OpSource HLSL 660
|
|
OpName %main "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%4 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
RayTracingKHR_RemainsWithClosestHitExecutionMode) {
|
|
const std::string kTest = R"(
|
|
OpCapability RayTracingKHR
|
|
OpExtension "SPV_KHR_ray_tracing"
|
|
; CHECK: OpCapability RayTracingKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_tracing"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint ClosestHitKHR %main "main" %a
|
|
OpSource HLSL 630
|
|
OpName %Payload "Payload"
|
|
OpMemberName %Payload 0 "color"
|
|
OpName %a "a"
|
|
OpName %main "main"
|
|
%float = OpTypeFloat 32
|
|
%v4float = OpTypeVector %float 4
|
|
%Payload = OpTypeStruct %v4float
|
|
%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
|
|
%void = OpTypeVoid
|
|
%8 = OpTypeFunction %void
|
|
%a = OpVariable %ptr_payload IncomingRayPayloadKHR
|
|
%main = OpFunction %void None %8
|
|
%9 = OpLabel
|
|
%10 = OpLoad %Payload %a
|
|
OpStore %a %10
|
|
OpReturn
|
|
OpFunctionEnd
|
|
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithAnyHitExecutionMode) {
|
|
const std::string kTest = R"(
|
|
OpCapability RayTracingKHR
|
|
OpExtension "SPV_KHR_ray_tracing"
|
|
; CHECK: OpCapability RayTracingKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_tracing"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint AnyHitKHR %main "main" %a
|
|
OpSource HLSL 630
|
|
OpName %Payload "Payload"
|
|
OpMemberName %Payload 0 "color"
|
|
OpName %a "a"
|
|
OpName %main "main"
|
|
%float = OpTypeFloat 32
|
|
%v4float = OpTypeVector %float 4
|
|
%Payload = OpTypeStruct %v4float
|
|
%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
|
|
%void = OpTypeVoid
|
|
%8 = OpTypeFunction %void
|
|
%a = OpVariable %ptr_payload IncomingRayPayloadKHR
|
|
%main = OpFunction %void None %8
|
|
%9 = OpLabel
|
|
%10 = OpLoad %Payload %a
|
|
OpStore %a %10
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, RayTracingKHR_RemainsWithMissExecutionMode) {
|
|
const std::string kTest = R"(
|
|
OpCapability RayTracingKHR
|
|
OpExtension "SPV_KHR_ray_tracing"
|
|
; CHECK: OpCapability RayTracingKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_tracing"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint MissKHR %main "main" %a
|
|
OpSource HLSL 630
|
|
OpName %Payload "Payload"
|
|
OpMemberName %Payload 0 "color"
|
|
OpName %a "a"
|
|
OpName %main "main"
|
|
%float = OpTypeFloat 32
|
|
%v4float = OpTypeVector %float 4
|
|
%Payload = OpTypeStruct %v4float
|
|
%ptr_payload = OpTypePointer IncomingRayPayloadKHR %Payload
|
|
%void = OpTypeVoid
|
|
%8 = OpTypeFunction %void
|
|
%a = OpVariable %ptr_payload IncomingRayPayloadKHR
|
|
%main = OpFunction %void None %8
|
|
%9 = OpLabel
|
|
%10 = OpLoad %Payload %a
|
|
OpStore %a %10
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
RayTracingKHR_RemainsWithRayGenerationExecutionMode) {
|
|
const std::string kTest = R"(
|
|
OpCapability RayTracingKHR
|
|
OpExtension "SPV_KHR_ray_tracing"
|
|
; CHECK: OpCapability RayTracingKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_tracing"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint RayGenerationKHR %main "main"
|
|
OpSource HLSL 630
|
|
OpName %main "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%4 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
RayTracingKHR_RemainsWithCallableExecutionMode) {
|
|
const std::string kTest = R"(
|
|
; CHECK: OpCapability RayTracingKHR
|
|
; CHECK: OpExtension "SPV_KHR_ray_tracing"
|
|
OpCapability RayTracingKHR
|
|
OpExtension "SPV_KHR_ray_tracing"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint CallableKHR %main "main" %a
|
|
OpSource HLSL 660
|
|
OpName %Payload "Payload"
|
|
OpMemberName %Payload 0 "data"
|
|
OpName %a "a"
|
|
OpName %main "main"
|
|
%float = OpTypeFloat 32
|
|
%v4float = OpTypeVector %float 4
|
|
%Payload = OpTypeStruct %v4float
|
|
%ptr_payload = OpTypePointer IncomingCallableDataKHR %Payload
|
|
%void = OpTypeVoid
|
|
%8 = OpTypeFunction %void
|
|
%a = OpVariable %ptr_payload IncomingCallableDataKHR
|
|
%main = OpFunction %void None %8
|
|
%9 = OpLabel
|
|
%10 = OpLoad %Payload %a
|
|
OpStore %a %10
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
ImageMSArray_RemainsIfSampledIs2AndArrayedIs1) {
|
|
const std::string kTest = R"(
|
|
OpCapability ImageMSArray
|
|
; CHECK: OpCapability ImageMSArray
|
|
OpCapability Shader
|
|
OpCapability StorageImageMultisample
|
|
OpCapability StorageImageReadWithoutFormat
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main"
|
|
OpExecutionMode %main OriginUpperLeft
|
|
OpDecorate %var_image DescriptorSet 0
|
|
OpDecorate %var_image Binding 1
|
|
%void = OpTypeVoid
|
|
%func = OpTypeFunction %void
|
|
%f32 = OpTypeFloat 32
|
|
%u32 = OpTypeInt 32 0
|
|
%uint_2 = OpConstant %u32 2
|
|
%uint_1 = OpConstant %u32 1
|
|
%v2uint = OpTypeVector %u32 2
|
|
%v4float = OpTypeVector %f32 4
|
|
%image = OpTypeImage %f32 2D 2 1 1 2 Unknown
|
|
%ptr_image = OpTypePointer UniformConstant %image
|
|
%10 = OpConstantComposite %v2uint %uint_1 %uint_2
|
|
%var_image = OpVariable %ptr_image UniformConstant
|
|
%main = OpFunction %void None %func
|
|
%main_lab = OpLabel
|
|
%18 = OpLoad %image %var_image
|
|
%19 = OpImageRead %v4float %18 %10 Sample %uint_2
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfNotUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability ImageMSArray
|
|
; CHECK-NOT: OpCapability ImageMSArray
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main" %out_var_SV_Target
|
|
OpExecutionMode %main OriginUpperLeft
|
|
OpSource HLSL 660
|
|
OpName %out_var_SV_Target "out.var.SV_Target"
|
|
OpName %main "main"
|
|
OpDecorate %out_var_SV_Target Location 0
|
|
%float = OpTypeFloat 32
|
|
%v4float = OpTypeVector %float 4
|
|
%_ptr_Output_v4float = OpTypePointer Output %v4float
|
|
%void = OpTypeVoid
|
|
%7 = OpTypeFunction %void
|
|
%out_var_SV_Target = OpVariable %_ptr_Output_v4float Output
|
|
%main = OpFunction %void None %7
|
|
%8 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfArrayedIsNot1) {
|
|
const std::string kTest = R"(
|
|
OpCapability ImageMSArray
|
|
; CHECK-NOT: OpCapability ImageMSArray
|
|
OpCapability Shader
|
|
OpCapability StorageImageMultisample
|
|
OpCapability StorageImageReadWithoutFormat
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main"
|
|
OpExecutionMode %main OriginUpperLeft
|
|
OpDecorate %var_image DescriptorSet 0
|
|
OpDecorate %var_image Binding 1
|
|
%void = OpTypeVoid
|
|
%func = OpTypeFunction %void
|
|
%f32 = OpTypeFloat 32
|
|
%u32 = OpTypeInt 32 0
|
|
%uint_2 = OpConstant %u32 2
|
|
%uint_1 = OpConstant %u32 1
|
|
%v2uint = OpTypeVector %u32 2
|
|
%v4float = OpTypeVector %f32 4
|
|
%image = OpTypeImage %f32 2D 2 0 1 2 Unknown
|
|
%ptr_image = OpTypePointer UniformConstant %image
|
|
%10 = OpConstantComposite %v2uint %uint_1 %uint_2
|
|
%var_image = OpVariable %ptr_image UniformConstant
|
|
%main = OpFunction %void None %func
|
|
%main_lab = OpLabel
|
|
%18 = OpLoad %image %var_image
|
|
%19 = OpImageRead %v4float %18 %10 Sample %uint_2
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, ImageMSArray_RemovedIfSampledNot2) {
|
|
const std::string kTest = R"(
|
|
OpCapability ImageMSArray
|
|
; CHECK-NOT: OpCapability ImageMSArray
|
|
OpCapability Shader
|
|
OpCapability StorageImageReadWithoutFormat
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %main "main"
|
|
OpExecutionMode %main OriginUpperLeft
|
|
OpDecorate %var_image DescriptorSet 0
|
|
OpDecorate %var_image Binding 1
|
|
%void = OpTypeVoid
|
|
%func = OpTypeFunction %void
|
|
%f32 = OpTypeFloat 32
|
|
%u32 = OpTypeInt 32 0
|
|
%uint_3 = OpConstant %u32 3
|
|
%uint_2 = OpConstant %u32 2
|
|
%uint_1 = OpConstant %u32 1
|
|
%v3uint = OpTypeVector %u32 3
|
|
%v4float = OpTypeVector %f32 4
|
|
%image = OpTypeImage %f32 2D 2 1 0 2 Unknown
|
|
%ptr_image = OpTypePointer UniformConstant %image
|
|
%10 = OpConstantComposite %v3uint %uint_1 %uint_2 %uint_3
|
|
%var_image = OpVariable %ptr_image UniformConstant
|
|
%main = OpFunction %void None %func
|
|
%main_lab = OpLabel
|
|
%18 = OpLoad %image %var_image
|
|
%19 = OpImageRead %v4float %18 %10
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Float64_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability Float64
|
|
; CHECK-NOT: OpCapability Float64
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Float64_RemainsWhenUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Float64
|
|
; CHECK: OpCapability Float64
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%float = OpTypeFloat 64
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
ComputeDerivativeGroupQuads_ReamainsWithExecMode) {
|
|
const std::string kTest = R"(
|
|
OpCapability ComputeDerivativeGroupQuadsKHR
|
|
OpCapability ComputeDerivativeGroupLinearKHR
|
|
; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearKHR
|
|
; CHECK: OpCapability ComputeDerivativeGroupQuadsKHR
|
|
; CHECK-NOT: OpCapability ComputeDerivativeGroupLinearKHR
|
|
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<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
ComputeDerivativeGroupLinear_ReamainsWithExecMode) {
|
|
const std::string kTest = R"(
|
|
OpCapability ComputeDerivativeGroupLinearKHR
|
|
OpCapability ComputeDerivativeGroupQuadsKHR
|
|
; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsKHR
|
|
; CHECK: OpCapability ComputeDerivativeGroupLinearKHR
|
|
; CHECK-NOT: OpCapability ComputeDerivativeGroupQuadsKHR
|
|
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<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageImageReadWithoutFormat_RemovedIfUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability StorageImageReadWithoutFormat
|
|
; CHECK-NOT: OpCapability StorageImageReadWithoutFormat
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %PSMain "PSMain" %out_var
|
|
OpExecutionMode %PSMain OriginUpperLeft
|
|
OpDecorate %out_var Location 0
|
|
%float = OpTypeFloat 32
|
|
%float4 = OpTypeVector %float 4
|
|
%float_0 = OpConstant %float 0
|
|
%float4_0000 = OpConstantComposite %float4 %float_0 %float_0 %float_0 %float_0
|
|
%ptr_float4 = OpTypePointer Output %float4
|
|
%void = OpTypeVoid
|
|
%9 = OpTypeFunction %void
|
|
%out_var = OpVariable %ptr_float4 Output
|
|
%PSMain = OpFunction %void None %9
|
|
%10 = OpLabel
|
|
OpStore %out_var %float4_0000
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageImageReadWithoutFormat_RemovedIfUnusedOpImageFetch) {
|
|
const std::string kTest = R"(
|
|
OpCapability StorageImageReadWithoutFormat
|
|
; CHECK-NOT: OpCapability StorageImageReadWithoutFormat
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %PSMain "PSMain" %out_var
|
|
OpExecutionMode %PSMain OriginUpperLeft
|
|
OpDecorate %out_var Location 0
|
|
OpDecorate %texture DescriptorSet 0
|
|
OpDecorate %texture Binding 1
|
|
%float = OpTypeFloat 32
|
|
%float4 = OpTypeVector %float 4
|
|
%int = OpTypeInt 32 1
|
|
%int2 = OpTypeVector %int 2
|
|
%type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
|
|
%ptr_image = OpTypePointer UniformConstant %type_image
|
|
%int_0 = OpConstant %int 0
|
|
%int2_00 = OpConstantComposite %int2 %int_0 %int_0
|
|
%ptr_float4 = OpTypePointer Output %float4
|
|
%void = OpTypeVoid
|
|
%9 = OpTypeFunction %void
|
|
%texture = OpVariable %ptr_image UniformConstant
|
|
%out_var = OpVariable %ptr_float4 Output
|
|
%PSMain = OpFunction %void None %9
|
|
%10 = OpLabel
|
|
%11 = OpLoad %type_image %texture
|
|
%12 = OpImageFetch %float4 %11 %int2_00 Lod %int_0
|
|
OpStore %out_var %12
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageImageReadWithoutFormat_RemainsWhenRequiredWithRead) {
|
|
const std::string kTest = R"(
|
|
OpCapability StorageImageReadWithoutFormat
|
|
; CHECK: OpCapability StorageImageReadWithoutFormat
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %PSMain "PSMain" %out_var
|
|
OpExecutionMode %PSMain OriginUpperLeft
|
|
OpDecorate %out_var Location 0
|
|
OpDecorate %texture DescriptorSet 0
|
|
OpDecorate %texture Binding 1
|
|
%float = OpTypeFloat 32
|
|
%float4 = OpTypeVector %float 4
|
|
%int = OpTypeInt 32 1
|
|
%int2 = OpTypeVector %int 2
|
|
%type_image = OpTypeImage %float 2D 2 0 0 1 Unknown
|
|
%ptr_image = OpTypePointer UniformConstant %type_image
|
|
%int_0 = OpConstant %int 0
|
|
%int2_00 = OpConstantComposite %int2 %int_0 %int_0
|
|
%ptr_float4 = OpTypePointer Output %float4
|
|
%void = OpTypeVoid
|
|
%9 = OpTypeFunction %void
|
|
%texture = OpVariable %ptr_image UniformConstant
|
|
%out_var = OpVariable %ptr_float4 Output
|
|
%PSMain = OpFunction %void None %9
|
|
%10 = OpLabel
|
|
%11 = OpLoad %type_image %texture
|
|
%12 = OpImageRead %float4 %11 %int2_00 Lod %int_0
|
|
OpStore %out_var %12
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageImageReadWithoutFormat_RemainsWhenRequiredWithSparseRead) {
|
|
const std::string kTest = R"(
|
|
OpCapability StorageImageReadWithoutFormat
|
|
; CHECK: OpCapability StorageImageReadWithoutFormat
|
|
OpCapability SparseResidency
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %PSMain "PSMain"
|
|
OpExecutionMode %PSMain OriginUpperLeft
|
|
OpDecorate %texture DescriptorSet 0
|
|
OpDecorate %texture Binding 1
|
|
%float = OpTypeFloat 32
|
|
%float4 = OpTypeVector %float 4
|
|
%int = OpTypeInt 32 1
|
|
%int2 = OpTypeVector %int 2
|
|
%type_image = OpTypeImage %float 2D 2 0 0 2 Unknown
|
|
%struct = OpTypeStruct %int %float4
|
|
%ptr_image = OpTypePointer UniformConstant %type_image
|
|
%int_0 = OpConstant %int 0
|
|
%int2_00 = OpConstantComposite %int2 %int_0 %int_0
|
|
%void = OpTypeVoid
|
|
%9 = OpTypeFunction %void
|
|
%texture = OpVariable %ptr_image UniformConstant
|
|
%PSMain = OpFunction %void None %9
|
|
%10 = OpLabel
|
|
%11 = OpLoad %type_image %texture
|
|
%12 = OpImageSparseRead %struct %11 %int2_00
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
StorageImageReadWithoutFormat_RemovedWithReadOnSubpassData) {
|
|
const std::string kTest = R"(
|
|
OpCapability StorageImageReadWithoutFormat
|
|
; CHECK-NOT: OpCapability StorageImageReadWithoutFormat
|
|
OpCapability InputAttachment
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint Fragment %PSMain "PSMain" %out_var
|
|
OpExecutionMode %PSMain OriginUpperLeft
|
|
OpDecorate %out_var Location 0
|
|
OpDecorate %texture DescriptorSet 0
|
|
OpDecorate %texture Binding 1
|
|
%float = OpTypeFloat 32
|
|
%float4 = OpTypeVector %float 4
|
|
%int = OpTypeInt 32 1
|
|
%int2 = OpTypeVector %int 2
|
|
%type_image = OpTypeImage %float SubpassData 2 0 0 2 Unknown
|
|
%ptr_image = OpTypePointer UniformConstant %type_image
|
|
%int_0 = OpConstant %int 0
|
|
%int2_00 = OpConstantComposite %int2 %int_0 %int_0
|
|
%ptr_float4 = OpTypePointer Output %float4
|
|
%void = OpTypeVoid
|
|
%9 = OpTypeFunction %void
|
|
%texture = OpVariable %ptr_image UniformConstant
|
|
%out_var = OpVariable %ptr_float4 Output
|
|
%PSMain = OpFunction %void None %9
|
|
%10 = OpLabel
|
|
%11 = OpLoad %type_image %texture
|
|
%12 = OpImageRead %float4 %11 %int2_00
|
|
OpStore %out_var %12
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, PhysicalStorageBuffer_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability PhysicalStorageBufferAddresses
|
|
; CHECK-NOT: OpCapability PhysicalStorageBufferAddresses
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
PhysicalStorageBuffer_RemainsWithOpTypeForwardPointer) {
|
|
const std::string kTest = R"(
|
|
OpCapability PhysicalStorageBufferAddresses
|
|
; CHECK: OpCapability PhysicalStorageBufferAddresses
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%int = OpTypeInt 32 0
|
|
%struct = OpTypeStruct %int
|
|
OpTypeForwardPointer %ptr PhysicalStorageBuffer
|
|
%ptr = OpTypePointer PhysicalStorageBuffer %struct
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
PhysicalStorageBuffer_RemainsWithPhysicalStorageBufferStorage) {
|
|
const std::string kTest = R"(
|
|
OpCapability PhysicalStorageBufferAddresses
|
|
; CHECK: OpCapability PhysicalStorageBufferAddresses
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%int = OpTypeInt 32 0
|
|
%struct = OpTypeStruct %int
|
|
%ptr = OpTypePointer PhysicalStorageBuffer %struct
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
PhysicalStorageBuffer_RemainsWithRestrictDecoration) {
|
|
const std::string kTest = R"(
|
|
OpCapability PhysicalStorageBufferAddresses
|
|
; CHECK: OpCapability PhysicalStorageBufferAddresses
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
OpDecorate %var RestrictPointer
|
|
%void = OpTypeVoid
|
|
%int = OpTypeInt 32 0
|
|
%struct = OpTypeStruct %int
|
|
%ptr = OpTypePointer Function %struct
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%var = OpVariable %ptr Function
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
PhysicalStorageBuffer_RemainsWithAliasedDecoration) {
|
|
const std::string kTest = R"(
|
|
OpCapability PhysicalStorageBufferAddresses
|
|
; CHECK: OpCapability PhysicalStorageBufferAddresses
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
OpDecorate %var AliasedPointer
|
|
%void = OpTypeVoid
|
|
%int = OpTypeInt 32 0
|
|
%struct = OpTypeStruct %int
|
|
%ptr = OpTypePointer Function %struct
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%var = OpVariable %ptr Function
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Float16_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability Float16
|
|
; CHECK-NOT: OpCapability Float16
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Float16_RemainsWhenUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Float16
|
|
; CHECK: OpCapability Float16
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%float = OpTypeFloat 16
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Int16_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability Int16
|
|
; CHECK-NOT: OpCapability Int16
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, Int16_RemainsWhenUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Int16
|
|
; CHECK: OpCapability Int16
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%int = OpTypeInt 16 1
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, UInt16_RemainsWhenUsed) {
|
|
const std::string kTest = R"(
|
|
OpCapability Int16
|
|
; CHECK: OpCapability Int16
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%uint = OpTypeInt 16 0
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
VulkanMemoryModelDeviceScope_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability VulkanMemoryModelDeviceScope
|
|
; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScope
|
|
OpCapability Shader
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %1 "main"
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%1 = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
VulkanMemoryModelDeviceScope_RemovedWhenUsedWithGLSL450) {
|
|
const std::string kTest = R"(
|
|
OpCapability VulkanMemoryModelDeviceScope
|
|
; CHECK-NOT: OpCapability VulkanMemoryModelDeviceScope
|
|
OpCapability Shader
|
|
OpCapability ShaderClockKHR
|
|
OpCapability Int64
|
|
OpExtension "SPV_KHR_shader_clock"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%uint = OpTypeInt 32 0
|
|
%ulong = OpTypeInt 64 0
|
|
%uint_1 = OpConstant %uint 1
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
VulkanMemoryModelDeviceScope_RemainsWhenUsedWithVulkan) {
|
|
const std::string kTest = R"(
|
|
OpCapability VulkanMemoryModelDeviceScope
|
|
; CHECK: OpCapability VulkanMemoryModelDeviceScope
|
|
OpCapability Shader
|
|
OpCapability ShaderClockKHR
|
|
OpCapability Int64
|
|
OpExtension "SPV_KHR_shader_clock"
|
|
OpMemoryModel Logical Vulkan
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%uint = OpTypeInt 32 0
|
|
%ulong = OpTypeInt 64 0
|
|
%uint_1 = OpConstant %uint 1
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%22 = OpReadClockKHR %ulong %uint_1 ; Device Scope
|
|
OpReturn
|
|
OpFunctionEnd
|
|
)";
|
|
const auto result =
|
|
SinglePassRunAndMatch<TrimCapabilitiesPass>(kTest, /* skip_nop= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithoutChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest, GroupNonUniform_RemovedWhenUnused) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK-NOT: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
GroupNonUniform_RemainsGroupNonUniformWhenInUse) {
|
|
const std::string kTest = R"(
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK-NOT: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK: OpCapability GroupNonUniform
|
|
OpCapability Shader
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpGroupNonUniformElect %bool %scope_subgroup
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
GroupNonUniformVote_Remains_OpGroupNonUniformAll) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK-NOT: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpGroupNonUniformAll %bool %scope_subgroup %true
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
GroupNonUniformVote_Remains_OpGroupNonUniformAny) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK-NOT: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpGroupNonUniformAny %bool %scope_subgroup %true
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ false);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
GroupNonUniformArithmetic_Remains_OpGroupNonUniformIAdd_Reduce) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%uint_1 = OpConstant %uint 1
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpGroupNonUniformIAdd %uint %scope_subgroup Reduce %uint_1
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ true);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
GroupNonUniformArithmetic_Remains_OpGroupNonUniformIAdd_InclusiveScan) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%uint_1 = OpConstant %uint 1
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpGroupNonUniformIAdd %uint %scope_subgroup InclusiveScan %uint_1
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ true);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
GroupNonUniformArithmetic_Remains_OpGroupNonUniformIAdd_ExclusiveScan) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%uint_1 = OpConstant %uint 1
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpGroupNonUniformIAdd %uint %scope_subgroup ExclusiveScan %uint_1
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ true);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
TEST_F(TrimCapabilitiesPassTest,
|
|
GroupNonUniformClustered_Remains_OpGroupNonUniformIAdd_ClusteredReduce) {
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK-NOT: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%uint_1 = OpConstant %uint 1
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = OpGroupNonUniformIAdd %uint %scope_subgroup ClusteredReduce %uint_1 %uint_1
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ true);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
struct SubgroupTestCase {
|
|
// The result type of the subgroup instruction.
|
|
std::string resultType;
|
|
// The opcode of the subgroup instruction.
|
|
std::string opcode;
|
|
// The actual operand of the subgroup instruction.
|
|
std::string operand;
|
|
};
|
|
|
|
static const std::vector<SubgroupTestCase> kSubgroupTestCases{
|
|
// clang-format off
|
|
{ "uint", "OpGroupNonUniformIAdd", "uint_1" },
|
|
{ "float", "OpGroupNonUniformFAdd", "float_1" },
|
|
{ "uint", "OpGroupNonUniformIMul", "uint_1" },
|
|
{ "float", "OpGroupNonUniformFMul", "float_1" },
|
|
{ "int", "OpGroupNonUniformSMin", "int_1" },
|
|
{ "uint", "OpGroupNonUniformUMin", "uint_1" },
|
|
{ "float", "OpGroupNonUniformFMin", "float_1" },
|
|
{ "int", "OpGroupNonUniformSMax", "int_1" },
|
|
{ "uint", "OpGroupNonUniformUMax", "uint_1" },
|
|
{ "float", "OpGroupNonUniformFMax", "float_1" },
|
|
{ "uint", "OpGroupNonUniformBitwiseAnd", "uint_1" },
|
|
{ "uint", "OpGroupNonUniformBitwiseOr", "uint_1" },
|
|
{ "uint", "OpGroupNonUniformBitwiseXor", "uint_1" },
|
|
{ "bool", "OpGroupNonUniformLogicalAnd", "true" },
|
|
{ "bool", "OpGroupNonUniformLogicalOr", "true" },
|
|
{ "bool", "OpGroupNonUniformLogicalXor", "true" }
|
|
// clang-format on
|
|
};
|
|
|
|
using TrimCapabilitiesPassTestSubgroupNV_Unsigned = PassTest<
|
|
::testing::TestWithParam<std::tuple<SubgroupTestCase, std::string>>>;
|
|
TEST_P(TrimCapabilitiesPassTestSubgroupNV_Unsigned,
|
|
GroupNonUniformPartitionedNV_Remains) {
|
|
SubgroupTestCase test_case = std::get<0>(GetParam());
|
|
const std::string operation = std::get<1>(GetParam());
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK-NOT: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%int = OpTypeInt 32 1
|
|
%float = OpTypeFloat 32
|
|
%v4uint = OpTypeVector %uint 4
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%uint_1 = OpConstant %uint 1
|
|
%int_1 = OpConstant %int 1
|
|
%float_1 = OpConstant %float 1
|
|
%uint4_1111 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = )" + test_case.opcode +
|
|
" %" + test_case.resultType + " %scope_subgroup " +
|
|
operation + " %" + test_case.operand +
|
|
R"( %uint4_1111
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ true);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
TrimCapabilitiesPassTestSubgroupNV_Unsigned_I,
|
|
TrimCapabilitiesPassTestSubgroupNV_Unsigned,
|
|
::testing::Combine(::testing::ValuesIn(kSubgroupTestCases),
|
|
::testing::Values("PartitionedReduceNV",
|
|
"PartitionedInclusiveScanNV",
|
|
"PartitionedExclusiveScanNV")),
|
|
[](const ::testing::TestParamInfo<
|
|
TrimCapabilitiesPassTestSubgroupNV_Unsigned::ParamType>& info) {
|
|
return std::get<0>(info.param).opcode + "_" + std::get<1>(info.param);
|
|
});
|
|
|
|
using TrimCapabilitiesPassTestSubgroupArithmetic_Unsigned = PassTest<
|
|
::testing::TestWithParam<std::tuple<SubgroupTestCase, std::string>>>;
|
|
TEST_P(TrimCapabilitiesPassTestSubgroupArithmetic_Unsigned,
|
|
GroupNonUniformPartitionedArithmetic_Remains) {
|
|
SubgroupTestCase test_case = std::get<0>(GetParam());
|
|
const std::string operation = std::get<1>(GetParam());
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK-NOT: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%int = OpTypeInt 32 1
|
|
%float = OpTypeFloat 32
|
|
%v4uint = OpTypeVector %uint 4
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%uint_1 = OpConstant %uint 1
|
|
%int_1 = OpConstant %int 1
|
|
%float_1 = OpConstant %float 1
|
|
%uint4_1111 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = )" + test_case.opcode +
|
|
" %" + test_case.resultType + " %scope_subgroup " +
|
|
operation + " %" + test_case.operand + R"( %uint_1
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ true);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
TrimCapabilitiesPassTestSubgroupArithmetic_Unsigned_I,
|
|
TrimCapabilitiesPassTestSubgroupArithmetic_Unsigned,
|
|
::testing::Combine(::testing::ValuesIn(kSubgroupTestCases),
|
|
::testing::Values("Reduce", "InclusiveScan",
|
|
"ExclusiveScan")),
|
|
[](const ::testing::TestParamInfo<
|
|
TrimCapabilitiesPassTestSubgroupArithmetic_Unsigned::ParamType>& info) {
|
|
return std::get<0>(info.param).opcode + "_" + std::get<1>(info.param);
|
|
});
|
|
|
|
using TrimCapabilitiesPassTestSubgroupClustered_Unsigned = PassTest<
|
|
::testing::TestWithParam<std::tuple<SubgroupTestCase, std::string>>>;
|
|
TEST_P(TrimCapabilitiesPassTestSubgroupClustered_Unsigned,
|
|
GroupNonUniformPartitionedClustered_Remains) {
|
|
SubgroupTestCase test_case = std::get<0>(GetParam());
|
|
const std::string operation = std::get<1>(GetParam());
|
|
|
|
const std::string kTest = R"(
|
|
OpCapability Shader
|
|
OpCapability GroupNonUniformVote
|
|
; CHECK-NOT: OpCapability GroupNonUniformVote
|
|
OpCapability GroupNonUniformArithmetic
|
|
; CHECK-NOT: OpCapability GroupNonUniformArithmetic
|
|
OpCapability GroupNonUniformClustered
|
|
; CHECK: OpCapability GroupNonUniformClustered
|
|
OpCapability GroupNonUniformPartitionedNV
|
|
; CHECK-NOT: OpCapability GroupNonUniformPartitionedNV
|
|
OpCapability GroupNonUniform
|
|
; CHECK-NOT: OpCapability GroupNonUniform
|
|
OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
; CHECK-NOT: OpExtension "SPV_NV_shader_subgroup_partitioned"
|
|
OpMemoryModel Logical GLSL450
|
|
OpEntryPoint GLCompute %main "main"
|
|
OpExecutionMode %main LocalSize 1 2 4
|
|
%void = OpTypeVoid
|
|
%bool = OpTypeBool
|
|
%uint = OpTypeInt 32 0
|
|
%int = OpTypeInt 32 1
|
|
%float = OpTypeFloat 32
|
|
%v4uint = OpTypeVector %uint 4
|
|
%scope_subgroup = OpConstant %uint 3
|
|
%uint_1 = OpConstant %uint 1
|
|
%int_1 = OpConstant %int 1
|
|
%float_1 = OpConstant %float 1
|
|
%uint4_1111 = OpConstantComposite %v4uint %uint_1 %uint_1 %uint_1 %uint_1
|
|
%true = OpConstantTrue %bool
|
|
%3 = OpTypeFunction %void
|
|
%main = OpFunction %void None %3
|
|
%6 = OpLabel
|
|
%7 = )" + test_case.opcode +
|
|
" %" + test_case.resultType + " %scope_subgroup " +
|
|
operation + " %" + test_case.operand + R"( %uint_1
|
|
OpReturn
|
|
OpFunctionEnd;
|
|
)";
|
|
const auto result = SinglePassRunAndMatch<TrimCapabilitiesPass>(
|
|
kTest, /* do_validation= */ true);
|
|
EXPECT_EQ(std::get<1>(result), Pass::Status::SuccessWithChange);
|
|
}
|
|
|
|
INSTANTIATE_TEST_SUITE_P(
|
|
TrimCapabilitiesPassTestSubgroupClustered_Unsigned_I,
|
|
TrimCapabilitiesPassTestSubgroupClustered_Unsigned,
|
|
::testing::Combine(::testing::ValuesIn(kSubgroupTestCases),
|
|
::testing::Values("ClusteredReduce")),
|
|
[](const ::testing::TestParamInfo<
|
|
TrimCapabilitiesPassTestSubgroupClustered_Unsigned::ParamType>& info) {
|
|
return std::get<0>(info.param).opcode + "_" + std::get<1>(info.param);
|
|
});
|
|
|
|
} // namespace
|
|
} // namespace opt
|
|
} // namespace spvtools
|