Add-support-for-SPV_NVX_raytracing
diff --git a/SPIRV/GLSL.ext.NV.h b/SPIRV/GLSL.ext.NV.h
index 9c551d1..1904bac 100644
--- a/SPIRV/GLSL.ext.NV.h
+++ b/SPIRV/GLSL.ext.NV.h
@@ -33,7 +33,7 @@
 enum Capability;
 
 static const int GLSLextNVVersion = 100;
-static const int GLSLextNVRevision = 9;
+static const int GLSLextNVRevision = 10;
 
 //SPV_NV_sample_mask_override_coverage
 const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
@@ -66,4 +66,7 @@
 //SPV_NV_mesh_shader
 const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
 
-#endif  // #ifndef GLSLextNV_H
\ No newline at end of file
+//SPV_NVX_raytracing
+const char* const E_SPV_NVX_raytracing = "SPV_NVX_raytracing";
+
+#endif  // #ifndef GLSLextNV_H
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 11d8e31..d1b23d8 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -276,6 +276,12 @@
     case EShLangFragment:         return spv::ExecutionModelFragment;
     case EShLangCompute:          return spv::ExecutionModelGLCompute;
 #ifdef NV_EXTENSIONS
+    case EShLangRayGenNV:         return spv::ExecutionModelRayGenerationNVX;
+    case EShLangIntersectNV:      return spv::ExecutionModelIntersectionNVX;
+    case EShLangAnyHitNV:         return spv::ExecutionModelAnyHitNVX;
+    case EShLangClosestHitNV:     return spv::ExecutionModelClosestHitNVX;
+    case EShLangMissNV:           return spv::ExecutionModelMissNVX;
+    case EShLangCallableNV:       return spv::ExecutionModelCallableNVX;
     case EShLangTaskNV:           return spv::ExecutionModelTaskNV;
     case EShLangMeshNV:           return spv::ExecutionModelMeshNV;
 #endif
@@ -328,6 +334,11 @@
         case glslang::EvqBuffer:       return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
         case glslang::EvqVaryingIn:    return spv::DecorationBlock;
         case glslang::EvqVaryingOut:   return spv::DecorationBlock;
+#ifdef NV_EXTENSIONS
+        case glslang::EvqPayloadNV:    return spv::DecorationBlock;
+        case glslang::EvqPayloadInNV:  return spv::DecorationBlock;
+        case glslang::EvqHitAttrNV:    return spv::DecorationBlock;
+#endif
         default:
             assert(0);
             break;
@@ -396,6 +407,12 @@
                     assert(type.getQualifier().layoutPacking == glslang::ElpNone);
                 }
                 return spv::DecorationMax;
+#ifdef NV_EXTENSIONS
+            case glslang::EvqPayloadNV:
+            case glslang::EvqPayloadInNV:
+            case glslang::EvqHitAttrNV:
+                return spv::DecorationMax;
+#endif
             default:
                 assert(0);
                 return spv::DecorationMax;
@@ -847,6 +864,34 @@
         builder.addExtension(spv::E_SPV_EXT_fragment_fully_covered);
         builder.addCapability(spv::CapabilityFragmentFullyCoveredEXT);
         return spv::BuiltInFullyCoveredEXT;
+
+    // raytracing
+    case glslang::EbvLaunchIdNV:
+        return spv::BuiltInLaunchIdNVX;
+    case glslang::EbvLaunchSizeNV:
+        return spv::BuiltInLaunchSizeNVX;
+    case glslang::EbvWorldRayOriginNV:
+        return spv::BuiltInWorldRayOriginNVX;
+    case glslang::EbvWorldRayDirectionNV:
+        return spv::BuiltInWorldRayDirectionNVX;
+    case glslang::EbvObjectRayOriginNV:
+        return spv::BuiltInObjectRayOriginNVX;
+    case glslang::EbvObjectRayDirectionNV:
+        return spv::BuiltInObjectRayDirectionNVX;
+    case glslang::EbvRayTminNV:
+        return spv::BuiltInRayTminNVX;
+    case glslang::EbvRayTmaxNV:
+        return spv::BuiltInRayTmaxNVX;
+    case glslang::EbvInstanceCustomIndexNV:
+        return spv::BuiltInInstanceCustomIndexNVX;
+    case glslang::EbvHitTNV:
+        return spv::BuiltInHitTNVX;
+    case glslang::EbvHitKindNV:
+        return spv::BuiltInHitKindNVX;
+    case glslang::EbvObjectToWorldNV:
+        return spv::BuiltInObjectToWorldNVX;
+    case glslang::EbvWorldToObjectNV:
+        return spv::BuiltInWorldToObjectNVX;
     case glslang::EbvBaryCoordNV:
         builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
         builder.addCapability(spv::CapabilityFragmentBarycentricNV);
@@ -1027,6 +1072,10 @@
     if (type.getQualifier().isUniformOrBuffer()) {
         if (type.getQualifier().layoutPushConstant)
             return spv::StorageClassPushConstant;
+#ifdef NV_EXTENSIONS
+        if (type.getQualifier().layoutShaderRecordNV)
+            return spv::StorageClassShaderRecordBufferNVX;
+#endif
         if (type.getBasicType() == glslang::EbtBlock)
             return spv::StorageClassUniform;
         return spv::StorageClassUniformConstant;
@@ -1037,6 +1086,11 @@
     case glslang::EvqGlobal:        return spv::StorageClassPrivate;
     case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
     case glslang::EvqTemporary:     return spv::StorageClassFunction;
+#ifdef NV_EXTENSIONS
+    case glslang::EvqPayloadNV:     return spv::StorageClassRayPayloadNVX;
+    case glslang::EvqPayloadInNV:   return spv::StorageClassIncomingRayPayloadNVX;
+    case glslang::EvqHitAttrNV:     return spv::StorageClassHitAttributeNVX;
+#endif
     default:
         assert(0);
         break;
@@ -1092,7 +1146,11 @@
 {
     // uniform and buffer blocks are included, unless it is a push_constant
     if (type.getBasicType() == glslang::EbtBlock)
-        return type.getQualifier().isUniformOrBuffer() && ! type.getQualifier().layoutPushConstant;
+        return type.getQualifier().isUniformOrBuffer() &&
+#ifdef NV_EXTENSIONS
+        ! type.getQualifier().layoutShaderRecordNV &&
+#endif
+        ! type.getQualifier().layoutPushConstant;
 
     // non block...
     // basically samplerXXX/subpass/sampler/texture are all included
@@ -1358,6 +1416,15 @@
         break;
 
 #ifdef NV_EXTENSIONS
+    case EShLangRayGenNV:
+    case EShLangIntersectNV:
+    case EShLangAnyHitNV:
+    case EShLangClosestHitNV:
+    case EShLangMissNV:
+    case EShLangCallableNV:
+        builder.addCapability(spv::CapabilityRaytracingNVX);
+        builder.addExtension("SPV_NVX_raytracing");
+        break;
     case EShLangTaskNV:
     case EShLangMeshNV:
         builder.addCapability(spv::CapabilityMeshShadingNV);
@@ -2189,6 +2256,9 @@
         break;
 
 #ifdef NV_EXTENSIONS
+    case glslang::EOpIgnoreIntersectionNV:
+    case glslang::EOpTerminateRayNV:
+    case glslang::EOpTraceNV:
     case glslang::EOpWritePackedPrimitiveIndices4x8NV:
         noReturnValue = true;
         break;
@@ -2860,6 +2930,11 @@
         builder.addCapability(spv::CapabilityAtomicStorage);
         spvType = builder.makeUintType(32);
         break;
+#ifdef NV_EXTENSIONS
+    case glslang::EbtAccStructNV:
+        spvType = builder.makeAccelerationStructureNVType();
+        break;
+#endif
     case glslang::EbtSampler:
         {
             const glslang::TSampler& sampler = type.getSampler();
@@ -6784,6 +6859,18 @@
         break;
 
 #ifdef NV_EXTENSIONS
+    case glslang::EOpReportIntersectionNV:
+    {
+        typeId = builder.makeBoolType();
+        opCode = spv::OpReportIntersectionNVX;
+    }
+    break;
+    case glslang::EOpTraceNV:
+    {
+        builder.createNoResultOp(spv::OpTraceNVX, operands);
+        return 0;
+    }
+    break;
     case glslang::EOpWritePackedPrimitiveIndices4x8NV:
         builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands);
         return 0;
@@ -6962,6 +7049,14 @@
         return builder.setPrecision(id, precision);
     }
 #endif
+#ifdef NV_EXTENSIONS
+    case glslang::EOpIgnoreIntersectionNV:
+        builder.createNoResultOp(spv::OpIgnoreIntersectionNVX);
+        return 0;
+    case glslang::EOpTerminateRayNV:
+        builder.createNoResultOp(spv::OpTerminateRayNVX);
+        return 0;
+#endif
     default:
         logger->missingFunctionality("unknown operation with no arguments");
         return 0;
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index c13f77f..e74c7b9 100644
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -503,6 +503,21 @@
     return type->getResultId();
 }
 
+#ifdef NV_EXTENSIONS
+Id Builder::makeAccelerationStructureNVType()
+{
+    Instruction *type;
+    if (groupedTypes[OpTypeAccelerationStructureNVX].size() == 0) {
+        type = new Instruction(getUniqueId(), NoType, OpTypeAccelerationStructureNVX);
+        constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
+        module.mapInstruction(type);
+    } else {
+        type = groupedTypes[OpTypeAccelerationStructureNVX].back();
+    }
+
+    return type->getResultId();
+}
+#endif
 Id Builder::getDerefTypeId(Id resultId) const
 {
     Id typeId = getTypeId(resultId);
@@ -1377,7 +1392,7 @@
     buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
 }
 
-// An opcode that has multiple operands, no result id, and no type
+// An opcode that has one or more operands, no result id, and no type
 void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
 {
     Instruction* op = new Instruction(opCode);
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index 94533e4..bfa6b61 100644
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -131,6 +131,11 @@
     Id makeSamplerType();
     Id makeSampledImageType(Id imageType);
 
+#ifdef NV_EXTENSIONS
+    // accelerationStructureNV type
+    Id makeAccelerationStructureNVType();
+#endif
+
     // For querying about types.
     Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
     Id getDerefTypeId(Id resultId) const;
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index dc46c95..57d23d6 100644
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -104,6 +104,16 @@
 #endif
 
     default: return "Bad";
+
+#ifdef NV_EXTENSIONS
+    case ExecutionModelRayGenerationNVX: return "RayGenerationNVX";
+    case ExecutionModelIntersectionNVX:  return "IntersectionNVX";
+    case ExecutionModelAnyHitNVX:        return "AnyHitNVX";
+    case ExecutionModelClosestHitNVX:    return "ClosestHitNVX";
+    case ExecutionModelMissNVX:          return "MissNVX";
+    case ExecutionModelCallableNVX:      return "CallableNVX";
+#endif
+
     }
 }
 
@@ -201,6 +211,13 @@
     case 11: return "Image";
     case 12: return "StorageBuffer";
 
+#ifdef NV_EXTENSIONS
+    case StorageClassRayPayloadNVX:         return "RayPayloadNVX";
+    case StorageClassHitAttributeNVX:       return "HitAttributeNVX";
+    case StorageClassIncomingRayPayloadNVX: return "IncomingRayPayloadNVX";
+    case StorageClassShaderRecordBufferNVX: return "ShaderRecordBufferNVX";
+#endif
+
     default: return "Bad";
     }
 }
@@ -350,13 +367,26 @@
 #endif
 
 #ifdef NV_EXTENSIONS
-    case 5253: return "ViewportMaskNV";
-    case 5257: return "SecondaryPositionNV";
-    case 5258: return "SecondaryViewportMaskNV";
-    case 5261: return "PositionPerViewNV";
-    case 5262: return "ViewportMaskPerViewNV";
-    case BuiltInBaryCoordNV:        return "BaryCoordNV";
-    case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
+    case BuiltInLaunchIdNVX:                return "LaunchIdNVX";
+    case BuiltInLaunchSizeNVX:              return "LaunchSizeNVX";
+    case BuiltInWorldRayOriginNVX:          return "WorldRayOriginNVX";
+    case BuiltInWorldRayDirectionNVX:       return "WorldRayDirectionNVX";
+    case BuiltInObjectRayOriginNVX:         return "ObjectRayOriginNVX";
+    case BuiltInObjectRayDirectionNVX:      return "ObjectRayDirectionNVX";
+    case BuiltInRayTminNVX:                 return "RayTminNVX";
+    case BuiltInRayTmaxNVX:                 return "RayTmaxNVX";
+    case BuiltInInstanceCustomIndexNVX:     return "InstanceCustomIndexNVX";
+    case BuiltInObjectToWorldNVX:           return "ObjectToWorldNVX";
+    case BuiltInWorldToObjectNVX:           return "WorldToObjectNVX";
+    case BuiltInHitTNVX:                    return "HitTNVX";
+    case BuiltInHitKindNVX:                 return "HitKindNVX";
+    case BuiltInViewportMaskNV:             return "ViewportMaskNV";
+    case BuiltInSecondaryPositionNV:        return "SecondaryPositionNV";
+    case BuiltInSecondaryViewportMaskNV:    return "SecondaryViewportMaskNV";
+    case BuiltInPositionPerViewNV:          return "PositionPerViewNV";
+    case BuiltInViewportMaskPerViewNV:      return "ViewportMaskPerViewNV";
+    case BuiltInBaryCoordNV:                return "BaryCoordNV";
+    case BuiltInBaryCoordNoPerspNV:         return "BaryCoordNoPerspNV";
 #endif
 
     case 5264: return "FullyCoveredEXT";
@@ -857,6 +887,7 @@
     case CapabilityShaderStereoViewNV:              return "ShaderStereoViewNV";
     case CapabilityPerViewAttributesNV:             return "PerViewAttributesNV";
     case CapabilityGroupNonUniformPartitionedNV:    return "GroupNonUniformPartitionedNV";
+    case CapabilityRaytracingNVX:                   return "RaytracingNVX";
     case CapabilityComputeDerivativeGroupQuadsNV:   return "ComputeDerivativeGroupQuadsNV";
     case CapabilityComputeDerivativeGroupLinearNV:  return "ComputeDerivativeGroupLinearNV";
     case CapabilityFragmentBarycentricNV:           return "FragmentBarycentricNV";
@@ -1274,6 +1305,11 @@
 
 #ifdef NV_EXTENSIONS
     case OpGroupNonUniformPartitionNV:       return "OpGroupNonUniformPartitionNV";
+    case OpReportIntersectionNVX:            return "OpReportIntersectionNVX";
+    case OpIgnoreIntersectionNVX:            return "OpIgnoreIntersectionNVX";
+    case OpTerminateRayNVX:                  return "OpTerminateRayNVX";
+    case OpTraceNVX:                         return "OpTraceNVX";
+    case OpTypeAccelerationStructureNVX:     return "OpTypeAccelerationStructureNVX";
     case OpImageSampleFootprintNV:           return "OpImageSampleFootprintNV";
     case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
 #endif
@@ -2622,6 +2658,28 @@
 
 #ifdef NV_EXTENSIONS
     InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X");
+
+    InstructionDesc[OpTypeAccelerationStructureNVX].setResultAndType(true, false);
+
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'NV Acceleration Structure'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'Ray Flags'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'Cull Mask'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'SBT Record Offset'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'SBT Record Stride'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'Miss Index'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'Ray Origin'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'TMin'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'Ray Direction'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'TMax'");
+    InstructionDesc[OpTraceNVX].operands.push(OperandId, "'Payload'");
+    InstructionDesc[OpTraceNVX].setResultAndType(false, false);
+
+    InstructionDesc[OpReportIntersectionNVX].operands.push(OperandId, "'Hit Parameter'");
+    InstructionDesc[OpReportIntersectionNVX].operands.push(OperandId, "'Hit Kind'");
+
+    InstructionDesc[OpIgnoreIntersectionNVX].setResultAndType(false, false);
+
+    InstructionDesc[OpTerminateRayNVX].setResultAndType(false, false);
     
     InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
     InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");