Add support for EXT_ray_flags_primitive_culling. (#2173)

Fixes issue #2169.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index d17c966..51a7618 100644
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1448,6 +1448,10 @@
         builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
     }
 
+    if (sourceExtensions.find("GL_EXT_ray_flags_primitive_culling") != sourceExtensions.end()) {
+        builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingProvisionalKHR);
+    }
+
     unsigned int mode;
     switch (glslangIntermediate->getStage()) {
     case EShLangVertex:
diff --git a/Test/baseResults/rayQuery-allOps.comp.out b/Test/baseResults/rayQuery-allOps.comp.out
index 01e8696..2ac7cd3 100644
--- a/Test/baseResults/rayQuery-allOps.comp.out
+++ b/Test/baseResults/rayQuery-allOps.comp.out
@@ -1,18 +1,19 @@
 rayQuery-allOps.comp
 // Module Version 10000
 // Generated by (magic number): 80008
-// Id's are bound by 257
+// Id's are bound by 258
 
                               Capability Shader
                               Capability RayQueryProvisionalKHR
+                              Capability RayTraversalPrimitiveCullingProvisionalKHR
                               Extension  "SPV_KHR_ray_query"
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint GLCompute 4  "main"
                               ExecutionMode 4 LocalSize 1 1 1
                               Source GLSL 460
+                              SourceExtension  "GL_EXT_ray_flags_primitive_culling"
                               SourceExtension  "GL_EXT_ray_query"
-                              SourceExtension  "GL_NV_ray_tracing"
                               Name 4  "main"
                               Name 6  "doSomething("
                               Name 10  "Ray"
@@ -34,16 +35,16 @@
                               Name 83  "_mat3x4"
                               Name 143  "t"
                               Name 156  "committedStatus"
-                              Name 240  "o"
-                              Name 242  "d"
-                              Name 252  "Ray"
-                              MemberName 252(Ray) 0  "pos"
-                              MemberName 252(Ray) 1  "tmin"
-                              MemberName 252(Ray) 2  "dir"
-                              MemberName 252(Ray) 3  "tmax"
-                              Name 254  "Rays"
-                              MemberName 254(Rays) 0  "rays"
-                              Name 256  ""
+                              Name 241  "o"
+                              Name 243  "d"
+                              Name 253  "Ray"
+                              MemberName 253(Ray) 0  "pos"
+                              MemberName 253(Ray) 1  "tmin"
+                              MemberName 253(Ray) 2  "dir"
+                              MemberName 253(Ray) 3  "tmax"
+                              Name 255  "Rays"
+                              MemberName 255(Rays) 0  "rays"
+                              Name 257  ""
                               MemberDecorate 15(Log) 0 Offset 0
                               MemberDecorate 15(Log) 1 Offset 4
                               Decorate 15(Log) BufferBlock
@@ -51,15 +52,15 @@
                               Decorate 17 Binding 0
                               Decorate 50(rtas) DescriptorSet 0
                               Decorate 50(rtas) Binding 1
-                              MemberDecorate 252(Ray) 0 Offset 0
-                              MemberDecorate 252(Ray) 1 Offset 12
-                              MemberDecorate 252(Ray) 2 Offset 16
-                              MemberDecorate 252(Ray) 3 Offset 28
-                              Decorate 253 ArrayStride 32
-                              MemberDecorate 254(Rays) 0 Offset 0
-                              Decorate 254(Rays) BufferBlock
-                              Decorate 256 DescriptorSet 0
-                              Decorate 256 Binding 2
+                              MemberDecorate 253(Ray) 0 Offset 0
+                              MemberDecorate 253(Ray) 1 Offset 12
+                              MemberDecorate 253(Ray) 2 Offset 16
+                              MemberDecorate 253(Ray) 3 Offset 28
+                              Decorate 254 ArrayStride 32
+                              MemberDecorate 255(Rays) 0 Offset 0
+                              Decorate 255(Rays) BufferBlock
+                              Decorate 257 DescriptorSet 0
+                              Decorate 257 Binding 2
                2:             TypeVoid
                3:             TypeFunction 2
                8:             TypeFloat 32
@@ -104,11 +105,12 @@
              144:    8(float) Constant 1056964608
              175:     14(int) Constant 1
              198:     14(int) Constant 2
-        252(Ray):             TypeStruct 9(fvec3) 8(float) 9(fvec3) 8(float)
-             253:             TypeRuntimeArray 252(Ray)
-       254(Rays):             TypeStruct 253
-             255:             TypePointer Uniform 254(Rays)
-             256:    255(ptr) Variable Uniform
+             231:     14(int) Constant 256
+        253(Ray):             TypeStruct 9(fvec3) 8(float) 9(fvec3) 8(float)
+             254:             TypeRuntimeArray 253(Ray)
+       255(Rays):             TypeStruct 254
+             256:             TypePointer Uniform 255(Rays)
+             257:    256(ptr) Variable Uniform
          4(main):           2 Function None 3
                5:             Label
          43(ray):     25(ptr) Variable Function
@@ -118,8 +120,8 @@
      83(_mat3x4):     82(ptr) Variable Function
           143(t):     35(ptr) Variable Function
 156(committedStatus):     68(ptr) Variable Function
-          240(o):     29(ptr) Variable Function
-          242(d):     29(ptr) Variable Function
+          241(o):     29(ptr) Variable Function
+          243(d):     29(ptr) Variable Function
               44:     10(Ray) FunctionCall 12(makeRayDesc()
                               Store 43(ray) 44
               51:          48 Load 50(rtas)
@@ -375,36 +377,36 @@
                                 Branch 228
              228:             Label
              230:     14(int) RayQueryGetRayFlagsKHR 47(rayQuery)
-             231:    66(bool) UGreaterThan 230 20
-                              SelectionMerge 233 None
-                              BranchConditional 231 232 233
-             232:               Label
-             234:           2   FunctionCall 6(doSomething()
-                                Branch 233
-             233:             Label
-             235:    8(float) RayQueryGetRayTMinKHR 47(rayQuery)
-             236:    66(bool) FOrdGreaterThan 235 27
-                              SelectionMerge 238 None
-                              BranchConditional 236 237 238
-             237:               Label
-             239:           2   FunctionCall 6(doSomething()
-                                Branch 238
-             238:             Label
-             241:    9(fvec3) RayQueryGetWorldRayOriginKHR 47(rayQuery)
-                              Store 240(o) 241
-             243:    9(fvec3) RayQueryGetWorldRayDirectionKHR 47(rayQuery)
-                              Store 242(d) 243
-             244:     35(ptr) AccessChain 240(o) 20
-             245:    8(float) Load 244
-             246:     35(ptr) AccessChain 242(d) 198
-             247:    8(float) Load 246
-             248:    66(bool) FOrdEqual 245 247
-                              SelectionMerge 250 None
-                              BranchConditional 248 249 250
-             249:               Label
-             251:           2   FunctionCall 6(doSomething()
-                                Branch 250
-             250:             Label
+             232:    66(bool) UGreaterThan 230 231
+                              SelectionMerge 234 None
+                              BranchConditional 232 233 234
+             233:               Label
+             235:           2   FunctionCall 6(doSomething()
+                                Branch 234
+             234:             Label
+             236:    8(float) RayQueryGetRayTMinKHR 47(rayQuery)
+             237:    66(bool) FOrdGreaterThan 236 27
+                              SelectionMerge 239 None
+                              BranchConditional 237 238 239
+             238:               Label
+             240:           2   FunctionCall 6(doSomething()
+                                Branch 239
+             239:             Label
+             242:    9(fvec3) RayQueryGetWorldRayOriginKHR 47(rayQuery)
+                              Store 241(o) 242
+             244:    9(fvec3) RayQueryGetWorldRayDirectionKHR 47(rayQuery)
+                              Store 243(d) 244
+             245:     35(ptr) AccessChain 241(o) 20
+             246:    8(float) Load 245
+             247:     35(ptr) AccessChain 243(d) 198
+             248:    8(float) Load 247
+             249:    66(bool) FOrdEqual 246 248
+                              SelectionMerge 251 None
+                              BranchConditional 249 250 251
+             250:               Label
+             252:           2   FunctionCall 6(doSomething()
+                                Branch 251
+             251:             Label
                               Return
                               FunctionEnd
  6(doSomething():           2 Function None 3
diff --git a/Test/baseResults/spv.ext.ClosestHitShader_Errors.rchit.out b/Test/baseResults/spv.ext.ClosestHitShader_Errors.rchit.out
index 2dc43b9..6c87d1c 100644
--- a/Test/baseResults/spv.ext.ClosestHitShader_Errors.rchit.out
+++ b/Test/baseResults/spv.ext.ClosestHitShader_Errors.rchit.out
@@ -3,7 +3,8 @@
 ERROR: 0:9: 'reportIntersectionEXT' : no matching overloaded function found 
 ERROR: 0:10: 'terminateRayEXT' : no matching overloaded function found 
 ERROR: 0:11: 'ignoreIntersectionEXT' : no matching overloaded function found 
-ERROR: 4 compilation errors.  No code generated.
+ERROR: 0:12: 'gl_RayFlagsSkipAABBEXT' : required extension not requested: GL_EXT_ray_flags_primitive_culling
+ERROR: 5 compilation errors.  No code generated.
 
 
 SPIR-V is not generated for failed compile or link
diff --git a/Test/baseResults/spv.ext.RayGenShader.rgen.out b/Test/baseResults/spv.ext.RayGenShader.rgen.out
index e2d06d4..da16fa4 100644
--- a/Test/baseResults/spv.ext.RayGenShader.rgen.out
+++ b/Test/baseResults/spv.ext.RayGenShader.rgen.out
@@ -1,14 +1,16 @@
 spv.ext.RayGenShader.rgen
 // Module Version 10000
 // Generated by (magic number): 80008
-// Id's are bound by 57
+// Id's are bound by 58
 
+                              Capability RayTraversalPrimitiveCullingProvisionalKHR
                               Capability RayTracingProvisionalKHR
                               Extension  "SPV_KHR_ray_tracing"
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint RayGenerationKHR 4  "main" 11 21
                               Source GLSL 460
+                              SourceExtension  "GL_EXT_ray_flags_primitive_culling"
                               SourceExtension  "GL_EXT_ray_tracing"
                               Name 4  "main"
                               Name 8  "lx"
@@ -18,25 +20,25 @@
                               Name 21  "gl_LaunchSizeEXT"
                               Name 24  "sy"
                               Name 29  "accEXT0"
-                              Name 37  "block"
-                              MemberName 37(block) 0  "dir"
-                              MemberName 37(block) 1  "origin"
-                              Name 39  ""
-                              Name 50  "accEXT1"
-                              Name 53  "imageu"
-                              Name 56  "payload"
+                              Name 38  "block"
+                              MemberName 38(block) 0  "dir"
+                              MemberName 38(block) 1  "origin"
+                              Name 40  ""
+                              Name 51  "accEXT1"
+                              Name 54  "imageu"
+                              Name 57  "payload"
                               Decorate 11(gl_LaunchIDEXT) BuiltIn LaunchIdKHR
                               Decorate 21(gl_LaunchSizeEXT) BuiltIn LaunchSizeKHR
                               Decorate 29(accEXT0) DescriptorSet 0
                               Decorate 29(accEXT0) Binding 0
-                              MemberDecorate 37(block) 0 Offset 0
-                              MemberDecorate 37(block) 1 Offset 16
-                              Decorate 37(block) BufferBlock
-                              Decorate 50(accEXT1) DescriptorSet 0
-                              Decorate 50(accEXT1) Binding 1
-                              Decorate 53(imageu) DescriptorSet 0
-                              Decorate 53(imageu) Binding 2
-                              Decorate 56(payload) Location 0
+                              MemberDecorate 38(block) 0 Offset 0
+                              MemberDecorate 38(block) 1 Offset 16
+                              Decorate 38(block) BufferBlock
+                              Decorate 51(accEXT1) DescriptorSet 0
+                              Decorate 51(accEXT1) Binding 1
+                              Decorate 54(imageu) DescriptorSet 0
+                              Decorate 54(imageu) Binding 2
+                              Decorate 57(payload) Location 0
                2:             TypeVoid
                3:             TypeFunction 2
                6:             TypeInt 32 0
@@ -51,24 +53,25 @@
               27:             TypeAccelerationStructureKHR
               28:             TypePointer UniformConstant 27
      29(accEXT0):     28(ptr) Variable UniformConstant
-              35:             TypeFloat 32
-              36:             TypeVector 35(float) 3
-       37(block):             TypeStruct 36(fvec3) 36(fvec3)
-              38:             TypePointer ShaderRecordBufferKHR 37(block)
-              39:     38(ptr) Variable ShaderRecordBufferKHR
-              40:             TypeInt 32 1
-              41:     40(int) Constant 1
-              42:             TypePointer ShaderRecordBufferKHR 36(fvec3)
-              45:   35(float) Constant 1056964608
-              46:     40(int) Constant 0
-              49:   35(float) Constant 1061158912
-     50(accEXT1):     28(ptr) Variable UniformConstant
-              51:             TypeImage 6(int) 2D nonsampled format:R32ui
-              52:             TypePointer UniformConstant 51
-      53(imageu):     52(ptr) Variable UniformConstant
-              54:             TypeVector 35(float) 4
-              55:             TypePointer RayPayloadKHR 54(fvec4)
-     56(payload):     55(ptr) Variable RayPayloadKHR
+              35:      6(int) Constant 768
+              36:             TypeFloat 32
+              37:             TypeVector 36(float) 3
+       38(block):             TypeStruct 37(fvec3) 37(fvec3)
+              39:             TypePointer ShaderRecordBufferKHR 38(block)
+              40:     39(ptr) Variable ShaderRecordBufferKHR
+              41:             TypeInt 32 1
+              42:     41(int) Constant 1
+              43:             TypePointer ShaderRecordBufferKHR 37(fvec3)
+              46:   36(float) Constant 1056964608
+              47:     41(int) Constant 0
+              50:   36(float) Constant 1061158912
+     51(accEXT1):     28(ptr) Variable UniformConstant
+              52:             TypeImage 6(int) 2D nonsampled format:R32ui
+              53:             TypePointer UniformConstant 52
+      54(imageu):     53(ptr) Variable UniformConstant
+              55:             TypeVector 36(float) 4
+              56:             TypePointer RayPayloadKHR 55(fvec4)
+     57(payload):     56(ptr) Variable RayPayloadKHR
          4(main):           2 Function None 3
                5:             Label
            8(lx):      7(ptr) Variable Function
@@ -92,10 +95,10 @@
               32:      6(int) Load 16(ly)
               33:      6(int) Load 20(sx)
               34:      6(int) Load 24(sy)
-              43:     42(ptr) AccessChain 39 41
-              44:   36(fvec3) Load 43
-              47:     42(ptr) AccessChain 39 46
-              48:   36(fvec3) Load 47
-                              TraceRayKHR 30 31 32 33 34 12 44 45 48 49 41
+              44:     43(ptr) AccessChain 40 42
+              45:   37(fvec3) Load 44
+              48:     43(ptr) AccessChain 40 47
+              49:   37(fvec3) Load 48
+                              TraceRayKHR 30 31 32 33 34 35 45 46 49 50 42
                               Return
                               FunctionEnd
diff --git a/Test/rayQuery-allOps.comp b/Test/rayQuery-allOps.comp
index 9fdf0c0..80f2593 100644
--- a/Test/rayQuery-allOps.comp
+++ b/Test/rayQuery-allOps.comp
@@ -1,6 +1,6 @@
 #version 460
-#extension GL_NV_ray_tracing : enable
 #extension GL_EXT_ray_query : enable
+#extension GL_EXT_ray_flags_primitive_culling : enable
 
 struct Ray
 {
@@ -192,7 +192,7 @@
         doSomething();
     }
 
-    if (rayQueryGetRayFlagsEXT(rayQuery) > 0)
+    if (rayQueryGetRayFlagsEXT(rayQuery) > gl_RayFlagsSkipTrianglesEXT)
     {
         doSomething();
     }
diff --git a/Test/spv.ext.ClosestHitShader_Errors.rchit b/Test/spv.ext.ClosestHitShader_Errors.rchit
index fe484a1..05e05fe 100644
--- a/Test/spv.ext.ClosestHitShader_Errors.rchit
+++ b/Test/spv.ext.ClosestHitShader_Errors.rchit
@@ -9,4 +9,5 @@
     reportIntersectionEXT(1.0, 1U);                          // ERROR, unsupported builtin in stage 
     terminateRayEXT();
     ignoreIntersectionEXT();
+    bool e1 = gl_IncomingRayFlagsEXT == gl_RayFlagsSkipAABBEXT;
 }
diff --git a/Test/spv.ext.RayGenShader.rgen b/Test/spv.ext.RayGenShader.rgen
index cd2de69..c92772e 100644
--- a/Test/spv.ext.RayGenShader.rgen
+++ b/Test/spv.ext.RayGenShader.rgen
@@ -1,5 +1,6 @@
 #version 460
 #extension GL_EXT_ray_tracing : enable
+#extension GL_EXT_ray_flags_primitive_culling : enable
 layout(binding = 0, set = 0) uniform accelerationStructureEXT accEXT0;
 layout(binding = 1, set = 0) uniform accelerationStructureEXT accEXT1; // Unused
 layout(binding = 2, r32ui) shadercallcoherent uniform uimage2D imageu;
@@ -16,5 +17,5 @@
     uint ly = gl_LaunchIDEXT.y;
     uint sx = gl_LaunchSizeEXT.x;
     uint sy = gl_LaunchSizeEXT.y;
-    traceRayEXT(accEXT0, lx, ly, sx, sy, 0u, origin, 0.5f, dir, 0.75f, 1);
+    traceRayEXT(accEXT0, lx, ly, sx, sy, gl_RayFlagsSkipTrianglesEXT | gl_RayFlagsSkipAABBEXT, origin, 0.5f, dir, 0.75f, 1);
 }
diff --git a/Test/spv.ext.RayGenShader_Errors.rgen b/Test/spv.ext.RayGenShader_Errors.rgen
index a480b19..3498342 100644
--- a/Test/spv.ext.RayGenShader_Errors.rgen
+++ b/Test/spv.ext.RayGenShader_Errors.rgen
@@ -34,6 +34,7 @@
     mat4x3 e11 = gl_WorldToObjectEXT;                        // ERROR, unsupported builtin in stage
     float e12 = gl_HitTEXT;                                  // ERROR, unsupported builtin in stage
     float e13 = gl_HitKindEXT;                               // ERROR, unsupported builtin in stage
+    int e14 = gl_RayFlagsSkipAABBEXT;                        // ERROR, unsupported builtin in stage
     reportIntersectionEXT(1.0, 1U);                          // ERROR, unsupported builtin in stage
     ignoreIntersectionEXT();                                 // ERROR, unsupported builtin in stage
     terminateRayEXT();                                       // ERROR, unsupported builtin in stage
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index 865eab2..344594a 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -5457,6 +5457,8 @@
             "const uint gl_RayFlagsCullOpaqueEXT = 64U;"
             "const uint gl_RayFlagsCullNoOpaqueNV = 128U;"
             "const uint gl_RayFlagsCullNoOpaqueEXT = 128U;"
+            "const uint gl_RayFlagsSkipTrianglesEXT = 256U;"
+            "const uint gl_RayFlagsSkipAABBEXT = 512U;"
             "const uint gl_HitKindFrontFacingTriangleEXT = 254U;"
             "const uint gl_HitKindBackFacingTriangleEXT = 255U;"
             "\n";
@@ -7572,6 +7574,8 @@
             symbolTable.setFunctionExtensions("rayQueryGetIntersectionWorldToObjectEXT",                          1, &E_GL_EXT_ray_query);
             symbolTable.setFunctionExtensions("rayQueryGetWorldRayOriginEXT",                                     1, &E_GL_EXT_ray_query);
             symbolTable.setFunctionExtensions("rayQueryGetWorldRayDirectionEXT",                                  1, &E_GL_EXT_ray_query);
+            symbolTable.setVariableExtensions("gl_RayFlagsSkipAABBEXT",                         1, &E_GL_EXT_ray_flags_primitive_culling);
+            symbolTable.setVariableExtensions("gl_RayFlagsSkipTrianglesEXT",                    1, &E_GL_EXT_ray_flags_primitive_culling);
         }
 
         if ((profile != EEsProfile && version >= 130) ||
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 180f5b3..d6b961d 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -293,11 +293,12 @@
     extensionBehavior[E_GL_OES_texture_cube_map_array]   = EBhDisable;
 
     // EXT extensions
-    extensionBehavior[E_GL_EXT_device_group]             = EBhDisable;
-    extensionBehavior[E_GL_EXT_multiview]                = EBhDisable;
-    extensionBehavior[E_GL_EXT_shader_realtime_clock]    = EBhDisable;
-    extensionBehavior[E_GL_EXT_ray_tracing]              = EBhDisable;
-    extensionBehavior[E_GL_EXT_ray_query]                = EBhDisable;
+    extensionBehavior[E_GL_EXT_device_group]                = EBhDisable;
+    extensionBehavior[E_GL_EXT_multiview]                   = EBhDisable;
+    extensionBehavior[E_GL_EXT_shader_realtime_clock]       = EBhDisable;
+    extensionBehavior[E_GL_EXT_ray_tracing]                 = EBhDisable;
+    extensionBehavior[E_GL_EXT_ray_query]                   = EBhDisable;
+    extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable;
 
     // OVR extensions
     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
@@ -438,6 +439,7 @@
             "#define E_GL_EXT_shader_realtime_clock 1\n"
             "#define E_GL_EXT_ray_tracing 1\n"
             "#define E_GL_EXT_ray_query 1\n"
+            "#define E_GL_EXT_ray_flags_primitive_culling 1\n"
 
             "#define GL_AMD_shader_ballot 1\n"
             "#define GL_AMD_shader_trinary_minmax 1\n"
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index e8cebeb..170efb0 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -189,6 +189,7 @@
 const char* const E_GL_EXT_debug_printf                     = "GL_EXT_debug_printf";
 const char* const E_GL_EXT_ray_tracing                      = "GL_EXT_ray_tracing";
 const char* const E_GL_EXT_ray_query                        = "GL_EXT_ray_query";
+const char* const E_GL_EXT_ray_flags_primitive_culling      = "GL_EXT_ray_flags_primitive_culling";
 
 // Arrays of extensions for the above viewportEXTs duplications