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'");