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
24namespace spvtools {
25namespace opt {
26namespace {
27
28using SwitchDescriptorSetTest = PassTest<::testing::Test>;
29
30TEST_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"(
51OpCapability Shader
52OpCapability PhysicalStorageBufferAddresses
53OpExtension "SPV_EXT_physical_storage_buffer"
54%1 = OpExtInstImport "GLSL.std.450"
55OpMemoryModel PhysicalStorageBuffer64 GLSL450
56OpEntryPoint GLCompute %main "main"
57OpExecutionMode %main LocalSize 1 1 1
58OpSource GLSL 450
59OpSourceExtension "GL_EXT_buffer_reference"
60OpName %main "main"
61OpName %ufoo "ufoo"
62OpMemberName %ufoo 0 "data"
63OpMemberName %ufoo 1 "offset"
64OpName %bufStruct "bufStruct"
65OpMemberName %bufStruct 0 "a"
66OpMemberName %bufStruct 1 "b"
67OpName %u_info "u_info"
68OpMemberDecorate %ufoo 0 Offset 0
69OpMemberDecorate %ufoo 1 Offset 8
70OpDecorate %ufoo Block
71OpDecorate %_arr_int_uint_2 ArrayStride 16
72OpMemberDecorate %bufStruct 0 Offset 0
73OpMemberDecorate %bufStruct 1 Offset 32
74OpDecorate %bufStruct Block
75OpDecorate %u_info DescriptorSet 7
76;CHECK: OpDecorate %u_info DescriptorSet 31
77OpDecorate %u_info Binding 7
78;CHECK: OpDecorate %u_info Binding 7
79%void = OpTypeVoid
80%3 = OpTypeFunction %void
81OpTypeForwardPointer %_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
101OpReturn
102OpFunctionEnd
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.
112TEST_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"(
133OpCapability Shader
134OpCapability PhysicalStorageBufferAddresses
135OpExtension "SPV_EXT_physical_storage_buffer"
136%1 = OpExtInstImport "GLSL.std.450"
137OpMemoryModel PhysicalStorageBuffer64 GLSL450
138OpEntryPoint GLCompute %main "main"
139OpExecutionMode %main LocalSize 1 1 1
140OpSource GLSL 450
141OpSourceExtension "GL_EXT_buffer_reference"
142OpName %main "main"
143OpName %ufoo "ufoo"
144OpMemberName %ufoo 0 "data"
145OpMemberName %ufoo 1 "offset"
146OpName %bufStruct "bufStruct"
147OpMemberName %bufStruct 0 "a"
148OpMemberName %bufStruct 1 "b"
149OpName %u_info "u_info"
150OpMemberDecorate %ufoo 0 Offset 0
151OpMemberDecorate %ufoo 1 Offset 8
152OpDecorate %ufoo Block
153OpDecorate %_arr_int_uint_2 ArrayStride 16
154OpMemberDecorate %bufStruct 0 Offset 0
155OpMemberDecorate %bufStruct 1 Offset 32
156OpDecorate %bufStruct Block
157OpDecorate %u_info DescriptorSet 11
158;CHECK: OpDecorate %u_info DescriptorSet 11
159OpDecorate %u_info Binding 7
160;CHECK: OpDecorate %u_info Binding 7
161%void = OpTypeVoid
162%3 = OpTypeFunction %void
163OpTypeForwardPointer %_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
183OpReturn
184OpFunctionEnd
185)";
186  // clang-format off
187
188  SinglePassRunAndMatch<SwitchDescriptorSetPass>(spirv, true, 7, 31);
189}
190
191}  // namespace
192}  // namespace opt
193}  // namespace spvtools
194