1 // Copyright (c) 2023 LunarG Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // Bindless Check Instrumentation Tests.
16 // Tests ending with V2 use version 2 record format.
17 
18 #include <string>
19 #include <vector>
20 
21 #include "test/opt/pass_fixture.h"
22 #include "test/opt/pass_utils.h"
23 
24 namespace spvtools {
25 namespace opt {
26 namespace {
27 
28 using SwitchDescriptorSetTest = PassTest<::testing::Test>;
29 
TEST_F(SwitchDescriptorSetTest,Basic)30 TEST_F(SwitchDescriptorSetTest, Basic) {
31   // #version 450
32   // #extension GL_EXT_buffer_reference : enable
33   //
34   // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct;
35   //
36   // layout(set = 7, binding = 7) uniform ufoo {
37   //     bufStruct data;
38   //     uint offset;
39   // } u_info;
40   //
41   // layout(buffer_reference, std140) buffer bufStruct {
42   //     layout(offset = 0) int a[2];
43   //     layout(offset = 32) int b;
44   // };
45   //
46   // void main() {
47   //     u_info.data.b = 0xca7;
48   // }
49 
50   const std::string spirv = R"(
51 OpCapability Shader
52 OpCapability PhysicalStorageBufferAddresses
53 OpExtension "SPV_EXT_physical_storage_buffer"
54 %1 = OpExtInstImport "GLSL.std.450"
55 OpMemoryModel PhysicalStorageBuffer64 GLSL450
56 OpEntryPoint GLCompute %main "main"
57 OpExecutionMode %main LocalSize 1 1 1
58 OpSource GLSL 450
59 OpSourceExtension "GL_EXT_buffer_reference"
60 OpName %main "main"
61 OpName %ufoo "ufoo"
62 OpMemberName %ufoo 0 "data"
63 OpMemberName %ufoo 1 "offset"
64 OpName %bufStruct "bufStruct"
65 OpMemberName %bufStruct 0 "a"
66 OpMemberName %bufStruct 1 "b"
67 OpName %u_info "u_info"
68 OpMemberDecorate %ufoo 0 Offset 0
69 OpMemberDecorate %ufoo 1 Offset 8
70 OpDecorate %ufoo Block
71 OpDecorate %_arr_int_uint_2 ArrayStride 16
72 OpMemberDecorate %bufStruct 0 Offset 0
73 OpMemberDecorate %bufStruct 1 Offset 32
74 OpDecorate %bufStruct Block
75 OpDecorate %u_info DescriptorSet 7
76 ;CHECK: OpDecorate %u_info DescriptorSet 31
77 OpDecorate %u_info Binding 7
78 ;CHECK: OpDecorate %u_info Binding 7
79 %void = OpTypeVoid
80 %3 = OpTypeFunction %void
81 OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
82 %uint = OpTypeInt 32 0
83 %ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint
84 %int = OpTypeInt 32 1
85 %uint_2 = OpConstant %uint 2
86 %_arr_int_uint_2 = OpTypeArray %int %uint_2
87 %bufStruct = OpTypeStruct %_arr_int_uint_2 %int
88 %_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct
89 %_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
90 %u_info = OpVariable %_ptr_Uniform_ufoo Uniform
91 %int_0 = OpConstant %int 0
92 %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
93 %int_1 = OpConstant %int 1
94 %int_3239 = OpConstant %int 3239
95 %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
96 %main = OpFunction %void None %3
97 %5 = OpLabel
98 %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
99 %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
100 %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
101 OpReturn
102 OpFunctionEnd
103 )";
104   // clang-format off
105 
106   SinglePassRunAndMatch<SwitchDescriptorSetPass>(spirv, true, 7, 31);
107 }
108 
109 
110 // Make sure DescriptorSet decorations that don't match the requested number
111 // are left unchanged.
TEST_F(SwitchDescriptorSetTest,Unchanged)112 TEST_F(SwitchDescriptorSetTest, Unchanged) {
113   // #version 450
114   // #extension GL_EXT_buffer_reference : enable
115   //
116   // layout(buffer_reference, buffer_reference_align = 16) buffer bufStruct;
117   //
118   // layout(set = 11, binding = 7) uniform ufoo {
119   //     bufStruct data;
120   //     uint offset;
121   // } u_info;
122   //
123   // layout(buffer_reference, std140) buffer bufStruct {
124   //     layout(offset = 0) int a[2];
125   //     layout(offset = 32) int b;
126   // };
127   //
128   // void main() {
129   //     u_info.data.b = 0xca7;
130   // }
131 
132   const std::string spirv = R"(
133 OpCapability Shader
134 OpCapability PhysicalStorageBufferAddresses
135 OpExtension "SPV_EXT_physical_storage_buffer"
136 %1 = OpExtInstImport "GLSL.std.450"
137 OpMemoryModel PhysicalStorageBuffer64 GLSL450
138 OpEntryPoint GLCompute %main "main"
139 OpExecutionMode %main LocalSize 1 1 1
140 OpSource GLSL 450
141 OpSourceExtension "GL_EXT_buffer_reference"
142 OpName %main "main"
143 OpName %ufoo "ufoo"
144 OpMemberName %ufoo 0 "data"
145 OpMemberName %ufoo 1 "offset"
146 OpName %bufStruct "bufStruct"
147 OpMemberName %bufStruct 0 "a"
148 OpMemberName %bufStruct 1 "b"
149 OpName %u_info "u_info"
150 OpMemberDecorate %ufoo 0 Offset 0
151 OpMemberDecorate %ufoo 1 Offset 8
152 OpDecorate %ufoo Block
153 OpDecorate %_arr_int_uint_2 ArrayStride 16
154 OpMemberDecorate %bufStruct 0 Offset 0
155 OpMemberDecorate %bufStruct 1 Offset 32
156 OpDecorate %bufStruct Block
157 OpDecorate %u_info DescriptorSet 11
158 ;CHECK: OpDecorate %u_info DescriptorSet 11
159 OpDecorate %u_info Binding 7
160 ;CHECK: OpDecorate %u_info Binding 7
161 %void = OpTypeVoid
162 %3 = OpTypeFunction %void
163 OpTypeForwardPointer %_ptr_PhysicalStorageBuffer_bufStruct PhysicalStorageBuffer
164 %uint = OpTypeInt 32 0
165 %ufoo = OpTypeStruct %_ptr_PhysicalStorageBuffer_bufStruct %uint
166 %int = OpTypeInt 32 1
167 %uint_2 = OpConstant %uint 2
168 %_arr_int_uint_2 = OpTypeArray %int %uint_2
169 %bufStruct = OpTypeStruct %_arr_int_uint_2 %int
170 %_ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer PhysicalStorageBuffer %bufStruct
171 %_ptr_Uniform_ufoo = OpTypePointer Uniform %ufoo
172 %u_info = OpVariable %_ptr_Uniform_ufoo Uniform
173 %int_0 = OpConstant %int 0
174 %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct = OpTypePointer Uniform %_ptr_PhysicalStorageBuffer_bufStruct
175 %int_1 = OpConstant %int 1
176 %int_3239 = OpConstant %int 3239
177 %_ptr_PhysicalStorageBuffer_int = OpTypePointer PhysicalStorageBuffer %int
178 %main = OpFunction %void None %3
179 %5 = OpLabel
180 %17 = OpAccessChain %_ptr_Uniform__ptr_PhysicalStorageBuffer_bufStruct %u_info %int_0
181 %18 = OpLoad %_ptr_PhysicalStorageBuffer_bufStruct %17
182 %22 = OpAccessChain %_ptr_PhysicalStorageBuffer_int %18 %int_1
183 OpReturn
184 OpFunctionEnd
185 )";
186   // clang-format off
187 
188   SinglePassRunAndMatch<SwitchDescriptorSetPass>(spirv, true, 7, 31);
189 }
190 
191 }  // namespace
192 }  // namespace opt
193 }  // namespace spvtools
194