1 // Copyright (c) 2022 The Khronos Group 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 // Tests instructions from SPV_NV_shader_invocation_reorder.
16 
17 #include <sstream>
18 #include <string>
19 
20 #include "gmock/gmock.h"
21 #include "test/val/val_fixtures.h"
22 
23 namespace spvtools {
24 namespace val {
25 namespace {
26 
27 using ::testing::HasSubstr;
28 using ::testing::Values;
29 
30 using ValidateRayTracingReorderNV = spvtest::ValidateBase<bool>;
31 
GenerateReorderThreadCode(const std::string& body = �, const std::string& declarations = �)32 std::string GenerateReorderThreadCode(const std::string& body = "",
33                                       const std::string& declarations = "") {
34   std::ostringstream ss;
35   ss << R"(
36             OpCapability RayTracingKHR
37             OpCapability ShaderInvocationReorderNV
38             OpExtension "SPV_KHR_ray_tracing"
39             OpExtension "SPV_NV_shader_invocation_reorder"
40        %1 = OpExtInstImport "GLSL.std.450"
41             OpMemoryModel Logical GLSL450
42             OpEntryPoint RayGenerationNV %main "main" %hObj
43             OpSourceExtension "GL_EXT_ray_tracing"
44             OpSourceExtension "GL_NV_shader_invocation_reorder"
45             OpName %main "main"
46     %void = OpTypeVoid
47        %3 = OpTypeFunction %void
48        %6 = OpTypeHitObjectNV
49 %_ptr_Private_6 = OpTypePointer Private %6
50     %hObj = OpVariable %_ptr_Private_6 Private
51     )";
52   ss << declarations;
53 
54   ss << R"(
55    %main  = OpFunction %void None %3
56      %5   = OpLabel
57     )";
58 
59   ss << body;
60 
61   ss << R"(
62             OpReturn
63             OpFunctionEnd
64     )";
65   return ss.str();
66 }
67 
TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHintNV)68 TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHintNV) {
69   const std::string declarations = R"(
70              %uint = OpTypeInt 32 0
71            %uint_4 = OpConstant %uint 4
72   )";
73 
74   const std::string body = R"(
75     OpReorderThreadWithHintNV %uint_4 %uint_4
76   )";
77 
78   CompileSuccessfully(GenerateReorderThreadCode(body, declarations).c_str(),
79                       SPV_ENV_VULKAN_1_2);
80   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
81 }
82 
TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHitObjectNV)83 TEST_F(ValidateRayTracingReorderNV, ReorderThreadWithHitObjectNV) {
84   const std::string declarations = R"(
85       %uint = OpTypeInt 32 0
86     %uint_4 = OpConstant %uint 4
87     %uint_2 = OpConstant %uint 2
88   )";
89 
90   const std::string body = R"(
91              OpReorderThreadWithHitObjectNV %hObj
92              OpReorderThreadWithHitObjectNV %hObj %uint_4 %uint_2
93   )";
94 
95   CompileSuccessfully(GenerateReorderThreadCode(body, declarations).c_str(),
96                       SPV_ENV_VULKAN_1_2);
97   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
98 }
99 
GenerateReorderShaderCode( const std::string& body = �, const std::string& declarations = �, const std::string execution_model = �)100 std::string GenerateReorderShaderCode(
101     const std::string& body = "", const std::string& declarations = "",
102     const std::string execution_model = "RayGenerationKHR") {
103   std::ostringstream ss;
104   ss << R"(
105                OpCapability RayTracingKHR
106                OpCapability ShaderInvocationReorderNV
107                OpExtension "SPV_KHR_ray_tracing"
108                OpExtension "SPV_NV_shader_invocation_reorder"
109           %1 = OpExtInstImport "GLSL.std.450"
110                OpMemoryModel Logical GLSL450
111                OpEntryPoint )"
112      << execution_model
113      << R"( %main "main" %attr %_ %hObj %payload %__0 %as %__1
114                OpSource GLSL 460
115                OpSourceExtension "GL_EXT_ray_tracing"
116                OpSourceExtension "GL_NV_shader_invocation_reorder"
117                OpName %main "main"
118                OpName %attr "attr"
119                OpName %hBlock "hBlock"
120                OpMemberName %hBlock 0 "attrval"
121                OpName %_ ""
122                OpName %hObj "hObj"
123                OpName %payload "payload"
124                OpName %pBlock "pBlock"
125                OpMemberName %pBlock 0 "val1"
126                OpMemberName %pBlock 1 "val2"
127                OpName %__0 ""
128                OpName %as "as"
129                OpName %block "block"
130                OpMemberName %block 0 "op"
131                OpName %__1 ""
132                OpDecorate %hBlock Block
133                OpDecorate %pBlock Block
134                OpDecorate %as DescriptorSet 0
135                OpDecorate %as Binding 0
136                OpMemberDecorate %block 0 Offset 0
137                OpDecorate %block Block
138                OpDecorate %__1 DescriptorSet 0
139                OpDecorate %__1 Binding 1
140        %void = OpTypeVoid
141           %3 = OpTypeFunction %void
142       %float = OpTypeFloat 32
143     %v2float = OpTypeVector %float 2
144 %_ptr_HitObjectAttributeNV_v2float = OpTypePointer HitObjectAttributeNV %v2float
145        %attr = OpVariable %_ptr_HitObjectAttributeNV_v2float HitObjectAttributeNV
146     %float_1 = OpConstant %float 1
147          %11 = OpConstantComposite %v2float %float_1 %float_1
148      %hBlock = OpTypeStruct %float
149 %_ptr_HitObjectAttributeNV_hBlock = OpTypePointer HitObjectAttributeNV %hBlock
150           %_ = OpVariable %_ptr_HitObjectAttributeNV_hBlock HitObjectAttributeNV
151         %int = OpTypeInt 32 1
152       %int_0 = OpConstant %int 0
153     %float_2 = OpConstant %float 2
154 %_ptr_HitObjectAttributeNV_float = OpTypePointer HitObjectAttributeNV %float
155              %20 = OpTypeHitObjectNV
156     %_ptr_Private_20 = OpTypePointer Private %20
157            %hObj = OpVariable %_ptr_Private_20 Private
158              %23 = OpTypeAccelerationStructureKHR
159     %_ptr_UniformConstant_23 = OpTypePointer UniformConstant %23
160              %as = OpVariable %_ptr_UniformConstant_23 UniformConstant
161     %v4float = OpTypeVector %float 4
162 %_ptr_RayPayloadNV_v4float = OpTypePointer RayPayloadNV %v4float
163     %payload = OpVariable %_ptr_RayPayloadNV_v4float RayPayloadNV
164      %pBlock = OpTypeStruct %v2float %v2float
165 %_ptr_RayPayloadNV_pBlock = OpTypePointer RayPayloadNV %pBlock
166         %__0 = OpVariable %_ptr_RayPayloadNV_pBlock RayPayloadNV
167       %block = OpTypeStruct %float
168 %_ptr_StorageBuffer_block = OpTypePointer StorageBuffer %block
169         %__1 = OpVariable %_ptr_StorageBuffer_block StorageBuffer
170        )";
171 
172   ss << declarations;
173 
174   ss << R"(
175         %main = OpFunction %void None %3
176           %5 = OpLabel
177          )";
178 
179   ss << body;
180 
181   ss << R"(
182                OpReturn
183                OpFunctionEnd)";
184   return ss.str();
185 }
186 
TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayNV)187 TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayNV) {
188   const std::string declarations = R"(
189        %uint = OpTypeInt 32 0
190      %uint_1 = OpConstant %uint 1
191     %v3float = OpTypeVector %float 3
192   %float_0_5 = OpConstant %float 0.5
193          %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
194          %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
195       %int_1 = OpConstant %int 1
196   )";
197 
198   const std::string body = R"(
199   OpStore %attr %11
200   %26 = OpLoad %23 %as
201   OpHitObjectTraceRayNV %hObj %26 %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %31 %float_0_5 %32 %float_1 %payload
202   )";
203 
204   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
205                       SPV_ENV_VULKAN_1_2);
206   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
207 }
208 
TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayMotionNV)209 TEST_F(ValidateRayTracingReorderNV, HitObjectTraceRayMotionNV) {
210   const std::string declarations = R"(
211         %uint = OpTypeInt 32 0
212       %uint_1 = OpConstant %uint 1
213      %v3float = OpTypeVector %float 3
214    %float_0_5 = OpConstant %float 0.5
215           %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
216           %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
217     %float_10 = OpConstant %float 10
218        %int_2 = OpConstant %int 2
219   )";
220 
221   const std::string body = R"(
222       OpStore %attr %11
223       %26 = OpLoad %23 %as
224       OpHitObjectTraceRayMotionNV %hObj %26 %uint_1 %uint_1 %uint_1 %uint_1 %uint_1 %31 %float_0_5 %32 %float_1 %float_10 %__0
225   )";
226 
227   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
228                       SPV_ENV_VULKAN_1_2);
229   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
230 }
231 
TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitNV)232 TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitNV) {
233   const std::string declarations = R"(
234         %int_1 = OpConstant %int 1
235         %uint = OpTypeInt 32 0
236       %uint_2 = OpConstant %uint 2
237      %v3float = OpTypeVector %float 3
238    %float_0_5 = OpConstant %float 0.5
239           %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
240           %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
241     %float_10 = OpConstant %float 10
242        %int_2 = OpConstant %int 2
243   )";
244 
245   const std::string body = R"(
246       OpStore %attr %11
247       %26 = OpLoad %23 %as
248       OpHitObjectRecordHitNV %hObj %26 %int_1 %int_1 %int_1 %uint_2 %uint_2 %uint_2 %31 %float_1 %32 %float_2 %attr
249   )";
250 
251   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
252                       SPV_ENV_VULKAN_1_2);
253   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
254 }
255 
TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitWithIndexNV)256 TEST_F(ValidateRayTracingReorderNV, HitObjectRecordHitWithIndexNV) {
257   const std::string declarations = R"(
258         %int_1 = OpConstant %int 1
259         %uint = OpTypeInt 32 0
260       %uint_2 = OpConstant %uint 2
261      %v3float = OpTypeVector %float 3
262    %float_0_5 = OpConstant %float 0.5
263           %31 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
264           %32 = OpConstantComposite %v3float %float_1 %float_1 %float_1
265     %float_10 = OpConstant %float 10
266        %int_2 = OpConstant %int 2
267   )";
268 
269   const std::string body = R"(
270       OpStore %attr %11
271       %26 = OpLoad %23 %as
272       OpHitObjectRecordHitWithIndexNV %hObj %26 %int_1 %int_1 %int_1 %uint_2 %uint_2 %31 %float_1 %32 %float_2 %_
273   )";
274 
275   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
276                       SPV_ENV_VULKAN_1_2);
277   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
278 }
279 
TEST_F(ValidateRayTracingReorderNV, HitObjectRecordEmptyNV)280 TEST_F(ValidateRayTracingReorderNV, HitObjectRecordEmptyNV) {
281   const std::string body = R"(
282       OpHitObjectRecordEmptyNV %hObj
283   )";
284 
285   CompileSuccessfully(GenerateReorderShaderCode(body).c_str(),
286                       SPV_ENV_VULKAN_1_2);
287   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
288 }
289 
TEST_F(ValidateRayTracingReorderNV, HitObjectRecordMissNV)290 TEST_F(ValidateRayTracingReorderNV, HitObjectRecordMissNV) {
291   const std::string declarations = R"(
292          %uint = OpTypeInt 32 0
293        %uint_1 = OpConstant %uint 1
294       %v3float = OpTypeVector %float 3
295     %float_0_5 = OpConstant %float 0.5
296            %29 = OpConstantComposite %v3float %float_0_5 %float_0_5 %float_0_5
297     %float_1_5 = OpConstant %float 1.5
298            %31 = OpConstantComposite %v3float %float_1_5 %float_1_5 %float_1_5
299       %float_5 = OpConstant %float 5
300   )";
301 
302   const std::string body = R"(
303       OpHitObjectRecordMissNV %hObj %uint_1 %29 %float_2 %31 %float_5
304   )";
305 
306   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
307                       SPV_ENV_VULKAN_1_2);
308   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
309 }
310 
TEST_F(ValidateRayTracingReorderNV, HitObjectIsHitNV)311 TEST_F(ValidateRayTracingReorderNV, HitObjectIsHitNV) {
312   const std::string declarations = R"(
313         %bool = OpTypeBool
314         %_ptr_StorageBuffer_float = OpTypePointer StorageBuffer %float
315   )";
316 
317   const std::string body = R"(
318       %26 = OpHitObjectIsHitNV %bool %hObj
319             OpSelectionMerge %28 None
320             OpBranchConditional %26 %27 %28
321       %27 = OpLabel
322       %33 = OpAccessChain %_ptr_StorageBuffer_float %__1 %int_0
323             OpStore %33 %float_1
324             OpBranch %28
325       %28 = OpLabel
326   )";
327 
328   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
329                       SPV_ENV_VULKAN_1_2);
330   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
331 }
332 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMaxNV)333 TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMaxNV) {
334   const std::string declarations = R"(
335         %_ptr_Function_float = OpTypePointer Function %float
336   )";
337 
338   const std::string body = R"(
339       %tmin = OpVariable %_ptr_Function_float Function
340       %12 = OpHitObjectGetRayTMaxNV %float %hObj
341       OpStore %tmin %12
342   )";
343 
344   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
345                       SPV_ENV_VULKAN_1_2);
346   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
347 }
348 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMinNV)349 TEST_F(ValidateRayTracingReorderNV, HitObjectGetRayTMinNV) {
350   const std::string declarations = R"(
351         %_ptr_Function_float = OpTypePointer Function %float
352   )";
353 
354   const std::string body = R"(
355       %tmin = OpVariable %_ptr_Function_float Function
356       %12 = OpHitObjectGetRayTMinNV %float %hObj
357       OpStore %tmin %12
358   )";
359 
360   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
361                       SPV_ENV_VULKAN_1_2);
362   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
363 }
364 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayOriginNV)365 TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayOriginNV) {
366   const std::string declarations = R"(
367         %v3float = OpTypeVector %float 3
368         %_ptr_Function_v3float = OpTypePointer Function %v3float
369   )";
370 
371   const std::string body = R"(
372       %orig = OpVariable %_ptr_Function_v3float Function
373       %13 = OpHitObjectGetWorldRayOriginNV %v3float %hObj
374       OpStore %orig %13
375   )";
376 
377   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
378                       SPV_ENV_VULKAN_1_2);
379   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
380 }
381 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayOriginNV)382 TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayOriginNV) {
383   const std::string declarations = R"(
384         %v3float = OpTypeVector %float 3
385         %_ptr_Function_v3float = OpTypePointer Function %v3float
386   )";
387 
388   const std::string body = R"(
389       %oorig = OpVariable %_ptr_Function_v3float Function
390       %13 = OpHitObjectGetObjectRayOriginNV %v3float %hObj
391       OpStore %oorig %13
392   )";
393 
394   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
395                       SPV_ENV_VULKAN_1_2);
396   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
397 }
398 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayDirectionNV)399 TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldRayDirectionNV) {
400   const std::string declarations = R"(
401         %v3float = OpTypeVector %float 3
402         %_ptr_Function_v3float = OpTypePointer Function %v3float
403   )";
404 
405   const std::string body = R"(
406       %dir = OpVariable %_ptr_Function_v3float Function
407       %13 = OpHitObjectGetWorldRayDirectionNV %v3float %hObj
408       OpStore %dir %13
409   )";
410 
411   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
412                       SPV_ENV_VULKAN_1_2);
413   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
414 }
415 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayDirectionNV)416 TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectRayDirectionNV) {
417   const std::string declarations = R"(
418         %v3float = OpTypeVector %float 3
419         %_ptr_Function_v3float = OpTypePointer Function %v3float
420   )";
421 
422   const std::string body = R"(
423       %odir = OpVariable %_ptr_Function_v3float Function
424       %13 = OpHitObjectGetObjectRayDirectionNV %v3float %hObj
425       OpStore %odir %13
426   )";
427 
428   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
429                       SPV_ENV_VULKAN_1_2);
430   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
431 }
432 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectToWorldNV)433 TEST_F(ValidateRayTracingReorderNV, HitObjectGetObjectToWorldNV) {
434   const std::string declarations = R"(
435         %v3float = OpTypeVector %float 3
436         %mat4v3float = OpTypeMatrix %v3float 4
437         %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
438   )";
439 
440   const std::string body = R"(
441       %otw = OpVariable %_ptr_Function_mat4v3float Function
442       %14 = OpHitObjectGetObjectToWorldNV %mat4v3float %hObj
443       OpStore %otw %14
444   )";
445 
446   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
447                       SPV_ENV_VULKAN_1_2);
448   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
449 }
450 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldToObjectNV)451 TEST_F(ValidateRayTracingReorderNV, HitObjectGetWorldToObjectNV) {
452   const std::string declarations = R"(
453         %v3float = OpTypeVector %float 3
454         %mat4v3float = OpTypeMatrix %v3float 4
455         %_ptr_Function_mat4v3float = OpTypePointer Function %mat4v3float
456   )";
457 
458   const std::string body = R"(
459       %wto = OpVariable %_ptr_Function_mat4v3float Function
460       %14 = OpHitObjectGetWorldToObjectNV %mat4v3float %hObj
461       OpStore %wto %14
462   )";
463 
464   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
465                       SPV_ENV_VULKAN_1_2);
466   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
467 }
468 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceCustomIndexNV)469 TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceCustomIndexNV) {
470   const std::string declarations = R"(
471         %_ptr_Function_int = OpTypePointer Function %int
472   )";
473 
474   const std::string body = R"(
475       %id = OpVariable %_ptr_Function_int Function
476       %12 = OpHitObjectGetInstanceCustomIndexNV %int %hObj
477       OpStore %id %12
478   )";
479 
480   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
481                       SPV_ENV_VULKAN_1_2);
482   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
483 }
484 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceIdNV)485 TEST_F(ValidateRayTracingReorderNV, HitObjectGetInstanceIdNV) {
486   const std::string declarations = R"(
487         %_ptr_Function_int = OpTypePointer Function %int
488   )";
489 
490   const std::string body = R"(
491       %id = OpVariable %_ptr_Function_int Function
492       %12 = OpHitObjectGetInstanceIdNV %int %hObj
493       OpStore %id %12
494   )";
495 
496   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
497                       SPV_ENV_VULKAN_1_2);
498   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
499 }
500 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetPrimitiveIndexNV)501 TEST_F(ValidateRayTracingReorderNV, HitObjectGetPrimitiveIndexNV) {
502   const std::string declarations = R"(
503         %_ptr_Function_int = OpTypePointer Function %int
504   )";
505 
506   const std::string body = R"(
507       %id = OpVariable %_ptr_Function_int Function
508       %12 = OpHitObjectGetPrimitiveIndexNV %int %hObj
509       OpStore %id %12
510   )";
511 
512   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
513                       SPV_ENV_VULKAN_1_2);
514   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
515 }
516 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetGeometryIndexNV)517 TEST_F(ValidateRayTracingReorderNV, HitObjectGetGeometryIndexNV) {
518   const std::string declarations = R"(
519         %_ptr_Function_int = OpTypePointer Function %int
520   )";
521 
522   const std::string body = R"(
523       %id = OpVariable %_ptr_Function_int Function
524       %12 = OpHitObjectGetGeometryIndexNV %int %hObj
525       OpStore %id %12
526   )";
527 
528   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
529                       SPV_ENV_VULKAN_1_2);
530   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
531 }
532 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetHitKindNV)533 TEST_F(ValidateRayTracingReorderNV, HitObjectGetHitKindNV) {
534   const std::string declarations = R"(
535     %uint = OpTypeInt 32 0
536     %_ptr_Function_uint = OpTypePointer Function %uint
537   )";
538 
539   const std::string body = R"(
540     %uid = OpVariable %_ptr_Function_uint Function
541     %12 = OpHitObjectGetHitKindNV %uint %hObj
542     OpStore %uid %12
543   )";
544 
545   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
546                       SPV_ENV_VULKAN_1_2);
547   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
548 }
549 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetAttributesNV)550 TEST_F(ValidateRayTracingReorderNV, HitObjectGetAttributesNV) {
551   const std::string body = R"(
552     OpHitObjectGetAttributesNV %hObj %attr
553   )";
554 
555   CompileSuccessfully(GenerateReorderShaderCode(body).c_str(),
556                       SPV_ENV_VULKAN_1_2);
557   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
558 }
559 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetShaderRecordBufferHandleNV)560 TEST_F(ValidateRayTracingReorderNV, HitObjectGetShaderRecordBufferHandleNV) {
561   const std::string declarations = R"(
562            %uint = OpTypeInt 32 0
563          %v2uint = OpTypeVector %uint 2
564     %_ptr_Function_v2uint = OpTypePointer Function %v2uint
565   )";
566 
567   const std::string body = R"(
568     %handle = OpVariable %_ptr_Function_v2uint Function
569         %13 = OpHitObjectGetShaderRecordBufferHandleNV %v2uint %hObj
570               OpStore %handle %13
571   )";
572 
573   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
574                       SPV_ENV_VULKAN_1_2);
575   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
576 }
577 
TEST_F(ValidateRayTracingReorderNV, HitObjectGetShaderBindingTableRecordIndexNV)578 TEST_F(ValidateRayTracingReorderNV,
579        HitObjectGetShaderBindingTableRecordIndexNV) {
580   const std::string declarations = R"(
581     %uint = OpTypeInt 32 0
582     %_ptr_Function_uint = OpTypePointer Function %uint
583   )";
584 
585   const std::string body = R"(
586     %rid = OpVariable %_ptr_Function_uint Function
587      %12 = OpHitObjectGetShaderBindingTableRecordIndexNV %uint %hObj
588            OpStore %rid %12
589   )";
590 
591   CompileSuccessfully(GenerateReorderShaderCode(body, declarations).c_str(),
592                       SPV_ENV_VULKAN_1_2);
593   EXPECT_EQ(SPV_SUCCESS, ValidateInstructions(SPV_ENV_VULKAN_1_2));
594 }
595 
596 }  // namespace
597 }  // namespace val
598 }  // namespace spvtools
599