1/*
2 * Copyright © 2020 Valve Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23#include "helpers.h"
24
25TEST_F(spirv_test, opload_volatile)
26{
27   /*
28               OpCapability Shader
29          %1 = OpExtInstImport "GLSL.std.450"
30               OpMemoryModel Logical GLSL450
31               OpEntryPoint GLCompute %4 "main"
32               OpExecutionMode %4 LocalSize 1 1 1
33               OpMemberDecorate %_struct_7 0 Offset 0
34               OpDecorate %_struct_7 BufferBlock
35               OpDecorate %9 DescriptorSet 0
36               OpDecorate %9 Binding 0
37       %void = OpTypeVoid
38          %3 = OpTypeFunction %void
39       %uint = OpTypeInt 32 0
40  %_struct_7 = OpTypeStruct %uint
41%_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
42          %9 = OpVariable %_ptr_Uniform__struct_7 Uniform
43        %int = OpTypeInt 32 1
44      %int_0 = OpConstant %int 0
45%_ptr_Uniform_uint = OpTypePointer Uniform %uint
46          %4 = OpFunction %void None %3
47          %5 = OpLabel
48         %13 = OpAccessChain %_ptr_Uniform_uint %9 %int_0
49         %14 = OpLoad %uint %13 Volatile
50               OpStore %13 %14
51               OpReturn
52               OpFunctionEnd
53   */
54   static const uint32_t words[] = {
55      0x07230203, 0x00010300, 0x00070000, 0x0000000f, 0x00000000, 0x00020011,
56      0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
57      0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005,
58      0x00000002, 0x6e69616d, 0x00000000, 0x00060010, 0x00000002, 0x00000011,
59      0x00000001, 0x00000001, 0x00000001, 0x00050048, 0x00000003, 0x00000000,
60      0x00000023, 0x00000000, 0x00030047, 0x00000003, 0x00000003, 0x00040047,
61      0x00000004, 0x00000022, 0x00000000, 0x00040047, 0x00000004, 0x00000021,
62      0x00000000, 0x00020013, 0x00000005, 0x00030021, 0x00000006, 0x00000005,
63      0x00040015, 0x00000007, 0x00000020, 0x00000000, 0x0003001e, 0x00000003,
64      0x00000007, 0x00040020, 0x00000008, 0x00000002, 0x00000003, 0x0004003b,
65      0x00000008, 0x00000004, 0x00000002, 0x00040015, 0x00000009, 0x00000020,
66      0x00000001, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000, 0x00040020,
67      0x0000000b, 0x00000002, 0x00000007, 0x00050036, 0x00000005, 0x00000002,
68      0x00000000, 0x00000006, 0x000200f8, 0x0000000c, 0x00050041, 0x0000000b,
69      0x0000000d, 0x00000004, 0x0000000a, 0x0005003d, 0x00000007, 0x0000000e,
70      0x0000000d, 0x00000001, 0x0003003e, 0x0000000d, 0x0000000e, 0x000100fd,
71      0x00010038,
72   };
73
74   get_nir(sizeof(words) / sizeof(words[0]), words);
75
76   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_load_deref);
77   ASSERT_NE(intrinsic, nullptr);
78   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
79}
80
81TEST_F(spirv_test, opstore_volatile)
82{
83   /*
84               OpCapability Shader
85          %1 = OpExtInstImport "GLSL.std.450"
86               OpMemoryModel Logical GLSL450
87               OpEntryPoint GLCompute %4 "main"
88               OpExecutionMode %4 LocalSize 1 1 1
89               OpMemberDecorate %_struct_7 0 Offset 0
90               OpDecorate %_struct_7 BufferBlock
91               OpDecorate %9 DescriptorSet 0
92               OpDecorate %9 Binding 0
93       %void = OpTypeVoid
94          %3 = OpTypeFunction %void
95       %uint = OpTypeInt 32 0
96  %_struct_7 = OpTypeStruct %uint
97%_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
98          %9 = OpVariable %_ptr_Uniform__struct_7 Uniform
99        %int = OpTypeInt 32 1
100      %int_0 = OpConstant %int 0
101%_ptr_Uniform_uint = OpTypePointer Uniform %uint
102          %4 = OpFunction %void None %3
103          %5 = OpLabel
104         %13 = OpAccessChain %_ptr_Uniform_uint %9 %int_0
105         %14 = OpLoad %uint %13
106               OpStore %13 %14 Volatile
107               OpReturn
108               OpFunctionEnd
109   */
110   static const uint32_t words[] = {
111      0x07230203, 0x00010300, 0x00070000, 0x0000000f, 0x00000000, 0x00020011,
112      0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
113      0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005,
114      0x00000002, 0x6e69616d, 0x00000000, 0x00060010, 0x00000002, 0x00000011,
115      0x00000001, 0x00000001, 0x00000001, 0x00050048, 0x00000003, 0x00000000,
116      0x00000023, 0x00000000, 0x00030047, 0x00000003, 0x00000003, 0x00040047,
117      0x00000004, 0x00000022, 0x00000000, 0x00040047, 0x00000004, 0x00000021,
118      0x00000000, 0x00020013, 0x00000005, 0x00030021, 0x00000006, 0x00000005,
119      0x00040015, 0x00000007, 0x00000020, 0x00000000, 0x0003001e, 0x00000003,
120      0x00000007, 0x00040020, 0x00000008, 0x00000002, 0x00000003, 0x0004003b,
121      0x00000008, 0x00000004, 0x00000002, 0x00040015, 0x00000009, 0x00000020,
122      0x00000001, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000, 0x00040020,
123      0x0000000b, 0x00000002, 0x00000007, 0x00050036, 0x00000005, 0x00000002,
124      0x00000000, 0x00000006, 0x000200f8, 0x0000000c, 0x00050041, 0x0000000b,
125      0x0000000d, 0x00000004, 0x0000000a, 0x0004003d, 0x00000007, 0x0000000e,
126      0x0000000d, 0x0004003e, 0x0000000d, 0x0000000e, 0x00000001, 0x000100fd,
127      0x00010038,
128   };
129
130   get_nir(sizeof(words) / sizeof(words[0]), words);
131
132   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_store_deref);
133   ASSERT_NE(intrinsic, nullptr);
134   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
135}
136
137TEST_F(spirv_test, opcopymemory_volatile_both)
138{
139   /*
140               OpCapability Shader
141          %1 = OpExtInstImport "GLSL.std.450"
142               OpMemoryModel Logical GLSL450
143               OpEntryPoint GLCompute %4 "main"
144               OpExecutionMode %4 LocalSize 1 1 1
145               OpMemberDecorate %_struct_7 0 Offset 0
146               OpDecorate %_struct_7 BufferBlock
147               OpDecorate %9 DescriptorSet 0
148               OpDecorate %9 Binding 0
149       %void = OpTypeVoid
150          %3 = OpTypeFunction %void
151       %uint = OpTypeInt 32 0
152  %_struct_7 = OpTypeStruct %uint
153%_ptr_Uniform__struct_7 = OpTypePointer Uniform %_struct_7
154          %9 = OpVariable %_ptr_Uniform__struct_7 Uniform
155        %int = OpTypeInt 32 1
156      %int_0 = OpConstant %int 0
157%_ptr_Uniform_uint = OpTypePointer Uniform %uint
158          %4 = OpFunction %void None %3
159          %5 = OpLabel
160         %13 = OpAccessChain %_ptr_Uniform_uint %9 %int_0
161               OpCopyMemory %13 %13 Volatile
162               OpReturn
163               OpFunctionEnd
164   */
165   static const uint32_t words[] = {
166      0x07230203, 0x00010300, 0x00070000, 0x0000000e, 0x00000000, 0x00020011,
167      0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
168      0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0005000f, 0x00000005,
169      0x00000002, 0x6e69616d, 0x00000000, 0x00060010, 0x00000002, 0x00000011,
170      0x00000001, 0x00000001, 0x00000001, 0x00050048, 0x00000003, 0x00000000,
171      0x00000023, 0x00000000, 0x00030047, 0x00000003, 0x00000003, 0x00040047,
172      0x00000004, 0x00000022, 0x00000000, 0x00040047, 0x00000004, 0x00000021,
173      0x00000000, 0x00020013, 0x00000005, 0x00030021, 0x00000006, 0x00000005,
174      0x00040015, 0x00000007, 0x00000020, 0x00000000, 0x0003001e, 0x00000003,
175      0x00000007, 0x00040020, 0x00000008, 0x00000002, 0x00000003, 0x0004003b,
176      0x00000008, 0x00000004, 0x00000002, 0x00040015, 0x00000009, 0x00000020,
177      0x00000001, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000, 0x00040020,
178      0x0000000b, 0x00000002, 0x00000007, 0x00050036, 0x00000005, 0x00000002,
179      0x00000000, 0x00000006, 0x000200f8, 0x0000000c, 0x00050041, 0x0000000b,
180      0x0000000d, 0x00000004, 0x0000000a, 0x0004003f, 0x0000000d, 0x0000000d,
181      0x00000001, 0x000100fd, 0x00010038,
182   };
183
184   get_nir(sizeof(words) / sizeof(words[0]), words);
185
186   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_load_deref);
187   ASSERT_NE(intrinsic, nullptr);
188   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
189
190   intrinsic = find_intrinsic(nir_intrinsic_store_deref);
191   ASSERT_NE(intrinsic, nullptr);
192   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
193}
194
195TEST_F(spirv_test, opcopymemory_volatile_target)
196{
197   /*
198               OpCapability Shader
199          %1 = OpExtInstImport "GLSL.std.450"
200               OpMemoryModel Logical GLSL450
201               OpEntryPoint GLCompute %4 "main" %9
202               OpExecutionMode %4 LocalSize 1 1 1
203               OpMemberDecorate %_struct_7 0 Offset 0
204               OpDecorate %_struct_7 Block
205               OpDecorate %9 DescriptorSet 0
206               OpDecorate %9 Binding 0
207       %void = OpTypeVoid
208          %3 = OpTypeFunction %void
209       %uint = OpTypeInt 32 0
210  %_struct_7 = OpTypeStruct %uint
211%_ptr_StorageBuffer__struct_7 = OpTypePointer StorageBuffer %_struct_7
212          %9 = OpVariable %_ptr_StorageBuffer__struct_7 StorageBuffer
213        %int = OpTypeInt 32 1
214      %int_0 = OpConstant %int 0
215%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
216          %4 = OpFunction %void None %3
217          %5 = OpLabel
218         %13 = OpAccessChain %_ptr_StorageBuffer_uint %9 %int_0
219               OpCopyMemory %13 %13 Volatile None
220               OpReturn
221               OpFunctionEnd
222   */
223   static const uint32_t words[] = {
224      0x07230203, 0x00010500, 0x00070000, 0x0000000e, 0x00000000, 0x00020011,
225      0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
226      0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0006000f, 0x00000005,
227      0x00000002, 0x6e69616d, 0x00000000, 0x00000003, 0x00060010, 0x00000002,
228      0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00050048, 0x00000004,
229      0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000004, 0x00000002,
230      0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00040047, 0x00000003,
231      0x00000021, 0x00000000, 0x00020013, 0x00000005, 0x00030021, 0x00000006,
232      0x00000005, 0x00040015, 0x00000007, 0x00000020, 0x00000000, 0x0003001e,
233      0x00000004, 0x00000007, 0x00040020, 0x00000008, 0x0000000c, 0x00000004,
234      0x0004003b, 0x00000008, 0x00000003, 0x0000000c, 0x00040015, 0x00000009,
235      0x00000020, 0x00000001, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000,
236      0x00040020, 0x0000000b, 0x0000000c, 0x00000007, 0x00050036, 0x00000005,
237      0x00000002, 0x00000000, 0x00000006, 0x000200f8, 0x0000000c, 0x00050041,
238      0x0000000b, 0x0000000d, 0x00000003, 0x0000000a, 0x0005003f, 0x0000000d,
239      0x0000000d, 0x00000001, 0x00000000, 0x000100fd, 0x00010038,
240   };
241
242   get_nir(sizeof(words) / sizeof(words[0]), words);
243
244   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_load_deref);
245   ASSERT_NE(intrinsic, nullptr);
246   EXPECT_EQ(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
247
248   intrinsic = find_intrinsic(nir_intrinsic_store_deref);
249   ASSERT_NE(intrinsic, nullptr);
250   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
251}
252
253TEST_F(spirv_test, opcopymemory_volatile_source)
254{
255   /*
256               OpCapability Shader
257          %1 = OpExtInstImport "GLSL.std.450"
258               OpMemoryModel Logical GLSL450
259               OpEntryPoint GLCompute %4 "main" %9
260               OpExecutionMode %4 LocalSize 1 1 1
261               OpMemberDecorate %_struct_7 0 Offset 0
262               OpDecorate %_struct_7 Block
263               OpDecorate %9 DescriptorSet 0
264               OpDecorate %9 Binding 0
265       %void = OpTypeVoid
266          %3 = OpTypeFunction %void
267       %uint = OpTypeInt 32 0
268  %_struct_7 = OpTypeStruct %uint
269%_ptr_StorageBuffer__struct_7 = OpTypePointer StorageBuffer %_struct_7
270          %9 = OpVariable %_ptr_StorageBuffer__struct_7 StorageBuffer
271        %int = OpTypeInt 32 1
272      %int_0 = OpConstant %int 0
273%_ptr_StorageBuffer_uint = OpTypePointer StorageBuffer %uint
274          %4 = OpFunction %void None %3
275          %5 = OpLabel
276         %13 = OpAccessChain %_ptr_StorageBuffer_uint %9 %int_0
277               OpCopyMemory %13 %13 None Volatile
278               OpReturn
279               OpFunctionEnd
280   */
281   static const uint32_t words[] = {
282      0x07230203, 0x00010500, 0x00070000, 0x0000000e, 0x00000000, 0x00020011,
283      0x00000001, 0x0006000b, 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e,
284      0x00000000, 0x0003000e, 0x00000000, 0x00000001, 0x0006000f, 0x00000005,
285      0x00000002, 0x6e69616d, 0x00000000, 0x00000003, 0x00060010, 0x00000002,
286      0x00000011, 0x00000001, 0x00000001, 0x00000001, 0x00050048, 0x00000004,
287      0x00000000, 0x00000023, 0x00000000, 0x00030047, 0x00000004, 0x00000002,
288      0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00040047, 0x00000003,
289      0x00000021, 0x00000000, 0x00020013, 0x00000005, 0x00030021, 0x00000006,
290      0x00000005, 0x00040015, 0x00000007, 0x00000020, 0x00000000, 0x0003001e,
291      0x00000004, 0x00000007, 0x00040020, 0x00000008, 0x0000000c, 0x00000004,
292      0x0004003b, 0x00000008, 0x00000003, 0x0000000c, 0x00040015, 0x00000009,
293      0x00000020, 0x00000001, 0x0004002b, 0x00000009, 0x0000000a, 0x00000000,
294      0x00040020, 0x0000000b, 0x0000000c, 0x00000007, 0x00050036, 0x00000005,
295      0x00000002, 0x00000000, 0x00000006, 0x000200f8, 0x0000000c, 0x00050041,
296      0x0000000b, 0x0000000d, 0x00000003, 0x0000000a, 0x0005003f, 0x0000000d,
297      0x0000000d, 0x00000000, 0x00000001, 0x000100fd, 0x00010038,
298   };
299
300   get_nir(sizeof(words) / sizeof(words[0]), words);
301
302   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_load_deref);
303   ASSERT_NE(intrinsic, nullptr);
304   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
305
306   intrinsic = find_intrinsic(nir_intrinsic_store_deref);
307   ASSERT_NE(intrinsic, nullptr);
308   EXPECT_EQ(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
309}
310
311TEST_F(spirv_test, opimageread_volatile)
312{
313   /*
314               OpCapability Shader
315               OpCapability VulkanMemoryModel
316          %1 = OpExtInstImport "GLSL.std.450"
317               OpMemoryModel Logical Vulkan
318               OpEntryPoint GLCompute %4 "main" %9
319               OpExecutionMode %4 LocalSize 1 1 1
320               OpDecorate %9 DescriptorSet 0
321               OpDecorate %9 Binding 1
322       %void = OpTypeVoid
323          %3 = OpTypeFunction %void
324       %uint = OpTypeInt 32 0
325          %7 = OpTypeImage %uint 2D 0 0 0 2 R32ui
326%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
327          %9 = OpVariable %_ptr_UniformConstant_7 UniformConstant
328        %int = OpTypeInt 32 1
329      %v2int = OpTypeVector %int 2
330      %int_0 = OpConstant %int 0
331         %14 = OpConstantComposite %v2int %int_0 %int_0
332     %v4uint = OpTypeVector %uint 4
333     %v3uint = OpTypeVector %uint 3
334     %uint_1 = OpConstant %uint 1
335          %4 = OpFunction %void None %3
336          %5 = OpLabel
337         %10 = OpLoad %7 %9
338         %15 = OpLoad %7 %9
339         %17 = OpImageRead %v4uint %15 %14 VolatileTexel
340               OpImageWrite %10 %14 %17
341               OpReturn
342               OpFunctionEnd
343   */
344   static const uint32_t words[] = {
345      0x07230203, 0x00010500, 0x00070000, 0x00000014, 0x00000000, 0x00020011,
346      0x00000001, 0x00020011, 0x000014e1, 0x0006000b, 0x00000001, 0x4c534c47,
347      0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000003,
348      0x0006000f, 0x00000005, 0x00000002, 0x6e69616d, 0x00000000, 0x00000003,
349      0x00060010, 0x00000002, 0x00000011, 0x00000001, 0x00000001, 0x00000001,
350      0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00040047, 0x00000003,
351      0x00000021, 0x00000001, 0x00020013, 0x00000004, 0x00030021, 0x00000005,
352      0x00000004, 0x00040015, 0x00000006, 0x00000020, 0x00000000, 0x00090019,
353      0x00000007, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
354      0x00000002, 0x00000021, 0x00040020, 0x00000008, 0x00000000, 0x00000007,
355      0x0004003b, 0x00000008, 0x00000003, 0x00000000, 0x00040015, 0x00000009,
356      0x00000020, 0x00000001, 0x00040017, 0x0000000a, 0x00000009, 0x00000002,
357      0x0004002b, 0x00000009, 0x0000000b, 0x00000000, 0x0005002c, 0x0000000a,
358      0x0000000c, 0x0000000b, 0x0000000b, 0x00040017, 0x0000000d, 0x00000006,
359      0x00000004, 0x00040017, 0x0000000e, 0x00000006, 0x00000003, 0x0004002b,
360      0x00000006, 0x0000000f, 0x00000001, 0x00050036, 0x00000004, 0x00000002,
361      0x00000000, 0x00000005, 0x000200f8, 0x00000010, 0x0004003d, 0x00000007,
362      0x00000011, 0x00000003, 0x0004003d, 0x00000007, 0x00000012, 0x00000003,
363      0x00060062, 0x0000000d, 0x00000013, 0x00000012, 0x0000000c, 0x00000800,
364      0x00040063, 0x00000011, 0x0000000c, 0x00000013, 0x000100fd, 0x00010038,
365   };
366
367   get_nir(sizeof(words) / sizeof(words[0]), words);
368
369   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_image_deref_load, 0);
370   ASSERT_NE(intrinsic, nullptr);
371   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
372}
373
374TEST_F(spirv_test, opimagewrite_volatile)
375{
376   /*
377               OpCapability Shader
378               OpCapability VulkanMemoryModel
379          %1 = OpExtInstImport "GLSL.std.450"
380               OpMemoryModel Logical Vulkan
381               OpEntryPoint GLCompute %4 "main" %9
382               OpExecutionMode %4 LocalSize 1 1 1
383               OpDecorate %9 DescriptorSet 0
384               OpDecorate %9 Binding 1
385       %void = OpTypeVoid
386          %3 = OpTypeFunction %void
387       %uint = OpTypeInt 32 0
388          %7 = OpTypeImage %uint 2D 0 0 0 2 R32ui
389%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
390          %9 = OpVariable %_ptr_UniformConstant_7 UniformConstant
391        %int = OpTypeInt 32 1
392      %v2int = OpTypeVector %int 2
393      %int_0 = OpConstant %int 0
394         %14 = OpConstantComposite %v2int %int_0 %int_0
395     %v4uint = OpTypeVector %uint 4
396     %v3uint = OpTypeVector %uint 3
397     %uint_1 = OpConstant %uint 1
398          %4 = OpFunction %void None %3
399          %5 = OpLabel
400         %10 = OpLoad %7 %9
401         %15 = OpLoad %7 %9
402         %17 = OpImageRead %v4uint %15 %14
403               OpImageWrite %10 %14 %17 VolatileTexel
404               OpReturn
405               OpFunctionEnd
406   */
407   static const uint32_t words[] = {
408      0x07230203, 0x00010500, 0x00070000, 0x00000014, 0x00000000, 0x00020011,
409      0x00000001, 0x00020011, 0x000014e1, 0x0006000b, 0x00000001, 0x4c534c47,
410      0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000003,
411      0x0006000f, 0x00000005, 0x00000002, 0x6e69616d, 0x00000000, 0x00000003,
412      0x00060010, 0x00000002, 0x00000011, 0x00000001, 0x00000001, 0x00000001,
413      0x00040047, 0x00000003, 0x00000022, 0x00000000, 0x00040047, 0x00000003,
414      0x00000021, 0x00000001, 0x00020013, 0x00000004, 0x00030021, 0x00000005,
415      0x00000004, 0x00040015, 0x00000006, 0x00000020, 0x00000000, 0x00090019,
416      0x00000007, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000,
417      0x00000002, 0x00000021, 0x00040020, 0x00000008, 0x00000000, 0x00000007,
418      0x0004003b, 0x00000008, 0x00000003, 0x00000000, 0x00040015, 0x00000009,
419      0x00000020, 0x00000001, 0x00040017, 0x0000000a, 0x00000009, 0x00000002,
420      0x0004002b, 0x00000009, 0x0000000b, 0x00000000, 0x0005002c, 0x0000000a,
421      0x0000000c, 0x0000000b, 0x0000000b, 0x00040017, 0x0000000d, 0x00000006,
422      0x00000004, 0x00040017, 0x0000000e, 0x00000006, 0x00000003, 0x0004002b,
423      0x00000006, 0x0000000f, 0x00000001, 0x00050036, 0x00000004, 0x00000002,
424      0x00000000, 0x00000005, 0x000200f8, 0x00000010, 0x0004003d, 0x00000007,
425      0x00000011, 0x00000003, 0x0004003d, 0x00000007, 0x00000012, 0x00000003,
426      0x00050062, 0x0000000d, 0x00000013, 0x00000012, 0x0000000c, 0x00050063,
427      0x00000011, 0x0000000c, 0x00000013, 0x00000800, 0x000100fd, 0x00010038,
428   };
429
430   get_nir(sizeof(words) / sizeof(words[0]), words);
431
432   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_image_deref_store, 0);
433   ASSERT_NE(intrinsic, nullptr);
434   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
435}
436
437TEST_F(spirv_test, opatomicload_image_volatile)
438{
439   /*
440               OpCapability Shader
441               OpCapability VulkanMemoryModel
442               OpCapability VulkanMemoryModelDeviceScope
443          %1 = OpExtInstImport "GLSL.std.450"
444               OpMemoryModel Logical Vulkan
445               OpEntryPoint GLCompute %2 "main" %3
446               OpExecutionMode %2 LocalSize 1 1 1
447               OpDecorate %3 DescriptorSet 0
448               OpDecorate %3 Binding 1
449       %void = OpTypeVoid
450          %7 = OpTypeFunction %void
451       %uint = OpTypeInt 32 0
452         %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui
453%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
454          %3 = OpVariable %_ptr_UniformConstant_10 UniformConstant
455        %int = OpTypeInt 32 1
456      %v2int = OpTypeVector %int 2
457      %int_0 = OpConstant %int 0
458         %15 = OpConstantComposite %v2int %int_0 %int_0
459      %int_1 = OpConstant %int 1
460     %uint_0 = OpConstant %uint 0
461%_ptr_Image_uint = OpTypePointer Image %uint
462     %uint_1 = OpConstant %uint 1
463  %uint_2048 = OpConstant %uint 2048
464 %uint_34816 = OpConstant %uint 34816
465     %v3uint = OpTypeVector %uint 3
466          %2 = OpFunction %void None %7
467         %29 = OpLabel
468         %30 = OpImageTexelPointer %_ptr_Image_uint %3 %15 %uint_0
469         %31 = OpAtomicLoad %uint %30 %int_1 %uint_34816
470               OpAtomicStore %30 %int_1 %uint_2048 %31
471               OpReturn
472               OpFunctionEnd
473   */
474   static const uint32_t words[] = {
475      0x07230203, 0x00010500, 0x00070000, 0x00000017, 0x00000000, 0x00020011,
476      0x00000001, 0x00020011, 0x000014e1, 0x00020011, 0x000014e2, 0x0006000b,
477      0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e,
478      0x00000000, 0x00000003, 0x0006000f, 0x00000005, 0x00000002, 0x6e69616d,
479      0x00000000, 0x00000003, 0x00060010, 0x00000002, 0x00000011, 0x00000001,
480      0x00000001, 0x00000001, 0x00040047, 0x00000003, 0x00000022, 0x00000000,
481      0x00040047, 0x00000003, 0x00000021, 0x00000001, 0x00020013, 0x00000004,
482      0x00030021, 0x00000005, 0x00000004, 0x00040015, 0x00000006, 0x00000020,
483      0x00000000, 0x00090019, 0x00000007, 0x00000006, 0x00000001, 0x00000000,
484      0x00000000, 0x00000000, 0x00000002, 0x00000021, 0x00040020, 0x00000008,
485      0x00000000, 0x00000007, 0x0004003b, 0x00000008, 0x00000003, 0x00000000,
486      0x00040015, 0x00000009, 0x00000020, 0x00000001, 0x00040017, 0x0000000a,
487      0x00000009, 0x00000002, 0x0004002b, 0x00000009, 0x0000000b, 0x00000000,
488      0x0005002c, 0x0000000a, 0x0000000c, 0x0000000b, 0x0000000b, 0x0004002b,
489      0x00000009, 0x0000000d, 0x00000001, 0x0004002b, 0x00000006, 0x0000000e,
490      0x00000000, 0x00040020, 0x0000000f, 0x0000000b, 0x00000006, 0x0004002b,
491      0x00000006, 0x00000010, 0x00000001, 0x0004002b, 0x00000006, 0x00000011,
492      0x00000800, 0x0004002b, 0x00000006, 0x00000012, 0x00008800, 0x00040017,
493      0x00000013, 0x00000006, 0x00000003, 0x00050036, 0x00000004, 0x00000002,
494      0x00000000, 0x00000005, 0x000200f8, 0x00000014, 0x0006003c, 0x0000000f,
495      0x00000015, 0x00000003, 0x0000000c, 0x0000000e, 0x000600e3, 0x00000006,
496      0x00000016, 0x00000015, 0x0000000d, 0x00000012, 0x000500e4, 0x00000015,
497      0x0000000d, 0x00000011, 0x00000016, 0x000100fd, 0x00010038,
498   };
499
500   get_nir(sizeof(words) / sizeof(words[0]), words);
501
502   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_image_deref_load, 0);
503   ASSERT_NE(intrinsic, nullptr);
504   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
505}
506
507TEST_F(spirv_test, opatomicstore_image_volatile)
508{
509   /*
510               OpCapability Shader
511               OpCapability VulkanMemoryModel
512               OpCapability VulkanMemoryModelDeviceScope
513          %1 = OpExtInstImport "GLSL.std.450"
514               OpMemoryModel Logical Vulkan
515               OpEntryPoint GLCompute %2 "main" %3
516               OpExecutionMode %2 LocalSize 1 1 1
517               OpDecorate %3 DescriptorSet 0
518               OpDecorate %3 Binding 1
519       %void = OpTypeVoid
520          %7 = OpTypeFunction %void
521       %uint = OpTypeInt 32 0
522         %10 = OpTypeImage %uint 2D 0 0 0 2 R32ui
523%_ptr_UniformConstant_10 = OpTypePointer UniformConstant %10
524          %3 = OpVariable %_ptr_UniformConstant_10 UniformConstant
525        %int = OpTypeInt 32 1
526      %v2int = OpTypeVector %int 2
527      %int_0 = OpConstant %int 0
528         %15 = OpConstantComposite %v2int %int_0 %int_0
529      %int_1 = OpConstant %int 1
530     %uint_0 = OpConstant %uint 0
531%_ptr_Image_uint = OpTypePointer Image %uint
532     %uint_1 = OpConstant %uint 1
533  %uint_2048 = OpConstant %uint 2048
534 %uint_34816 = OpConstant %uint 34816
535     %v3uint = OpTypeVector %uint 3
536          %2 = OpFunction %void None %7
537         %29 = OpLabel
538         %30 = OpImageTexelPointer %_ptr_Image_uint %3 %15 %uint_0
539         %31 = OpAtomicLoad %uint %30 %int_1 %uint_2048
540               OpAtomicStore %30 %int_1 %uint_34816 %31
541               OpReturn
542               OpFunctionEnd
543   */
544   static const uint32_t words[] = {
545      0x07230203, 0x00010500, 0x00070000, 0x00000017, 0x00000000, 0x00020011,
546      0x00000001, 0x00020011, 0x000014e1, 0x00020011, 0x000014e2, 0x0006000b,
547      0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e,
548      0x00000000, 0x00000003, 0x0006000f, 0x00000005, 0x00000002, 0x6e69616d,
549      0x00000000, 0x00000003, 0x00060010, 0x00000002, 0x00000011, 0x00000001,
550      0x00000001, 0x00000001, 0x00040047, 0x00000003, 0x00000022, 0x00000000,
551      0x00040047, 0x00000003, 0x00000021, 0x00000001, 0x00020013, 0x00000004,
552      0x00030021, 0x00000005, 0x00000004, 0x00040015, 0x00000006, 0x00000020,
553      0x00000000, 0x00090019, 0x00000007, 0x00000006, 0x00000001, 0x00000000,
554      0x00000000, 0x00000000, 0x00000002, 0x00000021, 0x00040020, 0x00000008,
555      0x00000000, 0x00000007, 0x0004003b, 0x00000008, 0x00000003, 0x00000000,
556      0x00040015, 0x00000009, 0x00000020, 0x00000001, 0x00040017, 0x0000000a,
557      0x00000009, 0x00000002, 0x0004002b, 0x00000009, 0x0000000b, 0x00000000,
558      0x0005002c, 0x0000000a, 0x0000000c, 0x0000000b, 0x0000000b, 0x0004002b,
559      0x00000009, 0x0000000d, 0x00000001, 0x0004002b, 0x00000006, 0x0000000e,
560      0x00000000, 0x00040020, 0x0000000f, 0x0000000b, 0x00000006, 0x0004002b,
561      0x00000006, 0x00000010, 0x00000001, 0x0004002b, 0x00000006, 0x00000011,
562      0x00000800, 0x0004002b, 0x00000006, 0x00000012, 0x00008800, 0x00040017,
563      0x00000013, 0x00000006, 0x00000003, 0x00050036, 0x00000004, 0x00000002,
564      0x00000000, 0x00000005, 0x000200f8, 0x00000014, 0x0006003c, 0x0000000f,
565      0x00000015, 0x00000003, 0x0000000c, 0x0000000e, 0x000600e3, 0x00000006,
566      0x00000016, 0x00000015, 0x0000000d, 0x00000011, 0x000500e4, 0x00000015,
567      0x0000000d, 0x00000012, 0x00000016, 0x000100fd, 0x00010038,
568   };
569
570   get_nir(sizeof(words) / sizeof(words[0]), words);
571
572   nir_intrinsic_instr *intrinsic = find_intrinsic(nir_intrinsic_image_deref_store, 0);
573   ASSERT_NE(intrinsic, nullptr);
574   EXPECT_NE(nir_intrinsic_access(intrinsic) & ACCESS_VOLATILE, 0);
575}
576