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