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 
TEST_F(spirv_test, opload_volatile)25 TEST_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 
TEST_F(spirv_test, opstore_volatile)81 TEST_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 
TEST_F(spirv_test, opcopymemory_volatile_both)137 TEST_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 
TEST_F(spirv_test, opcopymemory_volatile_target)195 TEST_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 
TEST_F(spirv_test, opcopymemory_volatile_source)253 TEST_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 
TEST_F(spirv_test, opimageread_volatile)311 TEST_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 
TEST_F(spirv_test, opimagewrite_volatile)374 TEST_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 
TEST_F(spirv_test, opatomicload_image_volatile)437 TEST_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 
TEST_F(spirv_test, opatomicstore_image_volatile)507 TEST_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