diff --git a/docs/SPIR-V.rst b/docs/SPIR-V.rst index d54ea15ab..1de78086a 100644 --- a/docs/SPIR-V.rst +++ b/docs/SPIR-V.rst @@ -3086,7 +3086,7 @@ Miss Stage Callable Stage ~~~~~~~~~~~~~~ -| Callables are generic function calls which can be invoked from either raygeneration, closest-hit, +| Callables are generic function calls which can be invoked from either raygeneration, closest-hit, | miss or callable shader stages. | Entry functions of this stage are annotated with **[shader("callable")]** in HLSL source. | Such entry functions must return void and accept exactly one argument. First argument must be an inout @@ -3173,7 +3173,7 @@ Mesh Interface Variables +-----------------+-------------------------------------------------------------------------+ | HLSL modifier | SPIR-V definition | +=================+=========================================================================+ -| ``indices`` | Maps to SPIR-V intrinsic ``PrimitiveIndicesNV`` | +| ``indices`` | Maps to SPIR-V intrinsic ``PrimitiveIndicesNV`` | | | | | | Defines SPIR-V Execution Mode ``OutputPrimitivesNV `` | +-----------------+-------------------------------------------------------------------------+ @@ -3282,6 +3282,180 @@ Interface Variables ``IncomingCallableData{NV/KHR}`` First argument of entry for Callable stage ================================= =========================================================== +RayQuery +-------- + +Ray Query is subfeature of the DirectX ray tracing and belongs to the DirectX ray tracing spec 1.1 (DXR 1.1). +DirectX add RayQuery object type and its member TraceRayInline() to do the TraceRay() that doesn't +use any seperate ray-tracing shader stages. +Shaders can instantiate RayQuery objects as local variables, the RayQuery object acts as a state +machine for ray query. The shader interacts with the RayQuery object's methods to advance the +query through an acceleration structure and query traversal information + +Refer to following pages for details: +https://microsoft.github.io/DirectX-Specs/d3d/Raytracing.html + +A flow chart for a simple ray query process + +:: + + +------------------------------+ + | RayQuery q | + +------------------------------+ + | + V + +------------------------------+ + | q.TraceRayInline() | + +------------------------------+ + | — — — — — — — — — — — — — + | | | + | | +------------------------+ + | | | Your intersection code | + | | +------------------------+ + | | ^ + V V | + +------------------------------+ +---------------------+ + | q.Proceed() // AS traversal | | q.CandidateType() | + +------------------------------+ +---------------------+ + | | ^ + No | | Yes | + | |_ _ _ _ _ _ _ _ _ _ _ _| + V + +------------------------------+ + | q.CommittedStatus() | + +------------------------------+ + | + V + +----------------------------------+ + | Your Intersection/shader code | + +----------------------------------+ + + +Example: + +.. code:: hlsl + + void main() { + RayQuery q; + q.TraceRayInline(myAccelerationStructure, 0 , 0xff, myRay); + + // Proceed() is AccelerationStructure traversal loop take places + while(q.Proceed()) { + switch(q.CandidateType()) { + // retrieve intersection information/Do the shadering + } + } + + // AccelerationStructure traversal end + // Get the Committed status + switch(q.CommittedStatus()) { + // retrieve intersection information/ Do the shadering + } + } + +Ray Query in SPIRV +~~~~~~~~~~~~~~~~~~ +RayQuery SPIR-V codegen is currently supported via SPV_KHR_ray_query extension +SPIR-V specification for reference: +https://github.com/KhronosGroup/SPIRV-Registry/blob/master/extensions/KHR/SPV_KHR_ray_query.asciidoc + +Object Type +~~~~~~~~~~~ +RayQuery + +RayQuery represents the state of an inline ray tracing call into an acceleration structure. + + +============ ================================ + HLSL Type SPIR-V Opcode +------------ -------------------------------- +``RayQuery`` ``OpTypeRayQueryProvisionalKHR`` +============ ================================ + +RayQuery Mapping to SPIR-V +~~~~~~~~~~~~~~~~~~~~~~~~~~ + ++---------------------------------------------------+-------------------------------------------------------------------------+ +| HLSL RayQuery member Intrinsic | SPIR-V Opcode | ++===================================================+=========================================================================+ +|``.Abort`` | ``OpRayQueryTerminateKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateType`` | ``OpRayQueryGetIntersectionTypeKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateProceduralPrimitiveNonOpaque`` | ``OpRayQueryGetIntersectionCandidateAABBOpaqueKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateInstanceIndex`` | ``OpRayQueryGetIntersectionInstanceIdKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateInstanceID`` | ``OpRayQueryGetIntersectionInstanceCustomIndexKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +| ``.CandidateInstanceContributionToHitGroupIndex`` | ``OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateGeometryIndex`` | ``OpRayQueryGetIntersectionGeometryIndexKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidatePrimitiveIndex`` | ``OpRayQueryGetIntersectionPrimitiveIndexKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateObjectRayOrigin`` | ``OpRayQueryGetIntersectionObjectRayOriginKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateObjectRayDirection`` | ``OpRayQueryGetIntersectionObjectRayDirectionKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateObjectToWorld3x4`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateObjectToWorld4x3`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateWorldToObject3x4`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateWorldToObject4x3`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateTriangleBarycentrics`` | ``OpRayQueryGetIntersectionBarycentricsKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CandidateTriangleFrontFace`` | ``OpRayQueryGetIntersectionFrontFaceKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedStatus`` | ``OpRayQueryGetIntersectionTypeKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedInstanceIndex`` | ``OpRayQueryGetIntersectionInstanceIdKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedInstanceID`` | ``OpRayQueryGetIntersectionInstanceCustomIndexKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +| ``.CommittedInstanceContributionToHitGroupIndex`` | ``OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedGeometryIndex`` | ``OpRayQueryGetIntersectionGeometryIndexKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedPrimitiveIndex`` | ``OpRayQueryGetIntersectionPrimitiveIndexKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedRayT`` | ``OpRayQueryGetIntersectionTKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedObjectRayOrigin`` | ``OpRayQueryGetIntersectionObjectRayOriginKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedObjectRayDirection`` | ``OpRayQueryGetIntersectionObjectRayDirectionKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedObjectToWorld3x4`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedObjectToWorld4x3`` | ``OpRayQueryGetIntersectionObjectToWorldKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedWorldToObject3x4`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedWorldToObject4x3`` | ``OpRayQueryGetIntersectionWorldToObjectKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedTriangleBarycentrics`` | ``OpRayQueryGetIntersectionBarycentricsKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommittedTriangleFrontFace`` | ``OpRayQueryGetIntersectionFrontFaceKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommitNonOpaqueTriangleHit`` | ``OpRayQueryConfirmIntersectionKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.CommitProceduralPrimitiveHit`` | ``OpRayQueryGenerateIntersectionKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.Proceed`` | ``OpRayQueryProceedKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.RayFlags`` | ``OpRayQueryGetRayFlagsKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.RayTMin`` | ``OpRayQueryGetRayTMinKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.TraceRayInline`` | ``OpRayQueryInitializeKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.WorldRayDirection`` | ``OpRayQueryGetWorldRayDirectionKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ +|``.WorldRayOrigin` | ``OpRayQueryGetWorldRayOriginKHR`` | ++---------------------------------------------------+-------------------------------------------------------------------------+ Shader Model 6.0 Wave Intrinsics ================================ diff --git a/tools/clang/include/clang/SPIRV/FeatureManager.h b/tools/clang/include/clang/SPIRV/FeatureManager.h index 73288483b..c1a9955ff 100644 --- a/tools/clang/include/clang/SPIRV/FeatureManager.h +++ b/tools/clang/include/clang/SPIRV/FeatureManager.h @@ -17,9 +17,9 @@ #include "spirv-tools/libspirv.h" +#include "dxc/Support/SPIRVOptions.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" -#include "dxc/Support/SPIRVOptions.h" #include "llvm/ADT/SmallBitVector.h" #include "llvm/ADT/StringRef.h" @@ -48,6 +48,7 @@ enum class Extension { GOOGLE_user_type, NV_ray_tracing, NV_mesh_shader, + KHR_ray_query, Unknown, }; diff --git a/tools/clang/include/clang/SPIRV/SpirvBuilder.h b/tools/clang/include/clang/SPIRV/SpirvBuilder.h index 6f803234d..4c3034b5e 100644 --- a/tools/clang/include/clang/SPIRV/SpirvBuilder.h +++ b/tools/clang/include/clang/SPIRV/SpirvBuilder.h @@ -437,6 +437,12 @@ public: /// \brief Creates an OpDemoteToHelperInvocationEXT instruction. SpirvInstruction *createDemoteToHelperInvocationEXT(SourceLocation); + /// \brief Create SPIR-V instructions for KHR RayQuery ops + SpirvInstruction * + createRayQueryOpsKHR(spv::Op opcode, QualType resultType, + llvm::ArrayRef operands, + bool cullFlags, SourceLocation loc); + // === SPIR-V Module Structure === inline void setMemoryModel(spv::AddressingModel, spv::MemoryModel); diff --git a/tools/clang/include/clang/SPIRV/SpirvContext.h b/tools/clang/include/clang/SPIRV/SpirvContext.h index bb92800e7..c571d9be7 100644 --- a/tools/clang/include/clang/SPIRV/SpirvContext.h +++ b/tools/clang/include/clang/SPIRV/SpirvContext.h @@ -185,6 +185,10 @@ public: return accelerationStructureTypeNV; } + const RayQueryProvisionalTypeKHR *getRayQueryProvisionalTypeKHR() const { + return rayQueryProvisionalTypeKHR; + } + /// --- Hybrid type getter functions --- /// /// Concrete SpirvType objects represent a SPIR-V type completely. Hybrid @@ -276,6 +280,7 @@ private: llvm::DenseMap pointerTypes; llvm::DenseSet functionTypes; const AccelerationStructureTypeNV *accelerationStructureTypeNV; + const RayQueryProvisionalTypeKHR *rayQueryProvisionalTypeKHR; // Current ShaderModelKind for entry point. ShaderModelKind curShaderModelKind; diff --git a/tools/clang/include/clang/SPIRV/SpirvInstruction.h b/tools/clang/include/clang/SPIRV/SpirvInstruction.h index 9f8fc2645..646aa7dde 100644 --- a/tools/clang/include/clang/SPIRV/SpirvInstruction.h +++ b/tools/clang/include/clang/SPIRV/SpirvInstruction.h @@ -103,22 +103,22 @@ public: IK_GroupNonUniformElect, // OpGroupNonUniformElect IK_GroupNonUniformUnaryOp, // Group non-uniform unary operations - IK_ImageOp, // OpImage* - IK_ImageQuery, // OpImageQuery* - IK_ImageSparseTexelsResident, // OpImageSparseTexelsResident - IK_ImageTexelPointer, // OpImageTexelPointer - IK_Load, // OpLoad - IK_SampledImage, // OpSampledImage - IK_Select, // OpSelect - IK_SpecConstantBinaryOp, // SpecConstant binary operations - IK_SpecConstantUnaryOp, // SpecConstant unary operations - IK_Store, // OpStore - IK_UnaryOp, // Unary operations - IK_VectorShuffle, // OpVectorShuffle - IK_ArrayLength, // OpArrayLength - IK_RayTracingOpNV, // NV raytracing ops - + IK_ImageOp, // OpImage* + IK_ImageQuery, // OpImageQuery* + IK_ImageSparseTexelsResident, // OpImageSparseTexelsResident + IK_ImageTexelPointer, // OpImageTexelPointer + IK_Load, // OpLoad + IK_SampledImage, // OpSampledImage + IK_Select, // OpSelect + IK_SpecConstantBinaryOp, // SpecConstant binary operations + IK_SpecConstantUnaryOp, // SpecConstant unary operations + IK_Store, // OpStore + IK_UnaryOp, // Unary operations + IK_VectorShuffle, // OpVectorShuffle + IK_ArrayLength, // OpArrayLength + IK_RayTracingOpNV, // NV raytracing ops IK_DemoteToHelperInvocationEXT, // OpDemoteToHelperInvocationEXT + IK_RayQueryOpKHR, // KHR rayquery ops }; virtual ~SpirvInstruction() = default; @@ -1750,6 +1750,27 @@ public: private: llvm::SmallVector operands; }; +class SpirvRayQueryOpKHR : public SpirvInstruction { +public: + SpirvRayQueryOpKHR(QualType resultType, spv::Op opcode, + llvm::ArrayRef vecOperands, bool flags, + SourceLocation loc); + + // For LLVM-style RTTI + static bool classof(const SpirvInstruction *inst) { + return inst->getKind() == IK_RayQueryOpKHR; + } + + bool invokeVisitor(Visitor *v) override; + + llvm::ArrayRef getOperands() const { return operands; } + + bool hasCullFlags() const { return cullFlags; } + +private: + llvm::SmallVector operands; + bool cullFlags; +}; /// \brief OpDemoteToHelperInvocationEXT instruction. /// Demote fragment shader invocation to a helper invocation. Any stores to diff --git a/tools/clang/include/clang/SPIRV/SpirvType.h b/tools/clang/include/clang/SPIRV/SpirvType.h index 20981300c..bf058f12b 100644 --- a/tools/clang/include/clang/SPIRV/SpirvType.h +++ b/tools/clang/include/clang/SPIRV/SpirvType.h @@ -48,6 +48,7 @@ public: TK_Pointer, TK_Function, TK_AccelerationStructureNV, + TK_RayQueryProvisionalKHR, // Order matters: all the following are hybrid types TK_HybridStruct, TK_HybridPointer, @@ -399,6 +400,16 @@ public: } }; +class RayQueryProvisionalTypeKHR : public SpirvType { +public: + RayQueryProvisionalTypeKHR() + : SpirvType(TK_RayQueryProvisionalKHR, "rayQueryProvisionalKHR") {} + + static bool classof(const SpirvType *t) { + return t->getKind() == TK_RayQueryProvisionalKHR; + } +}; + class HybridType : public SpirvType { public: static bool classof(const SpirvType *t) { diff --git a/tools/clang/include/clang/SPIRV/SpirvVisitor.h b/tools/clang/include/clang/SPIRV/SpirvVisitor.h index d385514b8..19ad4f6c6 100644 --- a/tools/clang/include/clang/SPIRV/SpirvVisitor.h +++ b/tools/clang/include/clang/SPIRV/SpirvVisitor.h @@ -114,7 +114,7 @@ public: DEFINE_VISIT_METHOD(SpirvArrayLength) DEFINE_VISIT_METHOD(SpirvRayTracingOpNV) DEFINE_VISIT_METHOD(SpirvDemoteToHelperInvocationEXT) - + DEFINE_VISIT_METHOD(SpirvRayQueryOpKHR) #undef DEFINE_VISIT_METHOD protected: diff --git a/tools/clang/lib/SPIRV/AstTypeProbe.cpp b/tools/clang/lib/SPIRV/AstTypeProbe.cpp index fcc8d872b..a242e8851 100644 --- a/tools/clang/lib/SPIRV/AstTypeProbe.cpp +++ b/tools/clang/lib/SPIRV/AstTypeProbe.cpp @@ -908,6 +908,9 @@ bool isOpaqueType(QualType type) { if (name == "RaytracingAccelerationStructure") return true; + + if (name == "RayQuery") + return true; } return false; } @@ -1097,7 +1100,8 @@ bool isOrContainsNonFpColMajorMatrix(const ASTContext &astContext, if (isMxNMatrix(arrayType->getElementType(), &elemType) && !elemType->isFloatingType()) return isColMajorDecl(decl); - if (const auto *structType = arrayType->getElementType()->getAs()) { + if (const auto *structType = + arrayType->getElementType()->getAs()) { return isOrContainsNonFpColMajorMatrix(astContext, spirvOptions, arrayType->getElementType(), structType->getDecl()); diff --git a/tools/clang/lib/SPIRV/CapabilityVisitor.cpp b/tools/clang/lib/SPIRV/CapabilityVisitor.cpp index d12376207..2201a84de 100644 --- a/tools/clang/lib/SPIRV/CapabilityVisitor.cpp +++ b/tools/clang/lib/SPIRV/CapabilityVisitor.cpp @@ -195,6 +195,12 @@ void CapabilityVisitor::addCapabilityForType(const SpirvType *type, for (auto field : structType->getFields()) addCapabilityForType(field.type, loc, sc); } + // + else if (const auto *rayQueryType = + dyn_cast(type)) { + addCapability(spv::Capability::RayQueryProvisionalKHR); + addExtension(Extension::KHR_ray_query, "SPV_KHR_ray_query", {}); + } } bool CapabilityVisitor::visit(SpirvDecoration *decor) { @@ -475,6 +481,16 @@ bool CapabilityVisitor::visitInstruction(SpirvInstruction *instr) { } break; } + case spv::Op::OpRayQueryInitializeKHR: { + auto rayQueryInst = dyn_cast(instr); + if (rayQueryInst->hasCullFlags()) { + addCapability( + spv::Capability::RayTraversalPrimitiveCullingProvisionalKHR); + } + + break; + } + default: break; } diff --git a/tools/clang/lib/SPIRV/EmitVisitor.cpp b/tools/clang/lib/SPIRV/EmitVisitor.cpp index f486f3a1f..26421993c 100644 --- a/tools/clang/lib/SPIRV/EmitVisitor.cpp +++ b/tools/clang/lib/SPIRV/EmitVisitor.cpp @@ -1126,6 +1126,20 @@ bool EmitVisitor::visit(SpirvDemoteToHelperInvocationEXT *inst) { return true; } +bool EmitVisitor::visit(SpirvRayQueryOpKHR *inst) { + initInstruction(inst); + if (inst->hasResultType()) { + curInst.push_back(inst->getResultTypeId()); + curInst.push_back(getOrAssignResultId(inst)); + } + for (const auto operand : inst->getOperands()) + curInst.push_back(getOrAssignResultId(operand)); + finalizeInstruction(); + emitDebugNameForInstruction(getOrAssignResultId(inst), + inst->getDebugName()); + return true; +} + // EmitTypeHandler ------ void EmitTypeHandler::initTypeInstruction(spv::Op op) { @@ -1643,6 +1657,13 @@ uint32_t EmitTypeHandler::emitType(const SpirvType *type) { curTypeInst.push_back(id); finalizeTypeInstruction(); } + // RayQueryProvisionalType KHR type + else if (const auto *rayQueryType = + dyn_cast(type)) { + initTypeInstruction(spv::Op::OpTypeRayQueryProvisionalKHR); + curTypeInst.push_back(id); + finalizeTypeInstruction(); + } // Hybrid Types // Note: The type lowering pass should lower all types to SpirvTypes. // Therefore, if we find a hybrid type when going through the emitting pass, diff --git a/tools/clang/lib/SPIRV/EmitVisitor.h b/tools/clang/lib/SPIRV/EmitVisitor.h index 349409a0a..28b7b4340 100644 --- a/tools/clang/lib/SPIRV/EmitVisitor.h +++ b/tools/clang/lib/SPIRV/EmitVisitor.h @@ -259,6 +259,7 @@ public: bool visit(SpirvArrayLength *); bool visit(SpirvRayTracingOpNV *); bool visit(SpirvDemoteToHelperInvocationEXT *); + bool visit(SpirvRayQueryOpKHR *); // Returns the assembled binary built up in this visitor. std::vector takeBinary(); diff --git a/tools/clang/lib/SPIRV/FeatureManager.cpp b/tools/clang/lib/SPIRV/FeatureManager.cpp index 575bf6d01..6378ed514 100644 --- a/tools/clang/lib/SPIRV/FeatureManager.cpp +++ b/tools/clang/lib/SPIRV/FeatureManager.cpp @@ -129,6 +129,7 @@ Extension FeatureManager::getExtensionSymbol(llvm::StringRef name) { .Case("SPV_KHR_post_depth_coverage", Extension::KHR_post_depth_coverage) .Case("SPV_NV_ray_tracing", Extension::NV_ray_tracing) .Case("SPV_NV_mesh_shader", Extension::NV_mesh_shader) + .Case("SPV_KHR_ray_query", Extension::KHR_ray_query) .Default(Extension::Unknown); } @@ -174,6 +175,8 @@ const char *FeatureManager::getExtensionName(Extension symbol) { return "SPV_NV_ray_tracing"; case Extension::NV_mesh_shader: return "SPV_NV_mesh_shader"; + case Extension::KHR_ray_query: + return "SPV_KHR_ray_query"; default: break; } diff --git a/tools/clang/lib/SPIRV/LowerTypeVisitor.cpp b/tools/clang/lib/SPIRV/LowerTypeVisitor.cpp index 82bf10c66..0be79e44c 100644 --- a/tools/clang/lib/SPIRV/LowerTypeVisitor.cpp +++ b/tools/clang/lib/SPIRV/LowerTypeVisitor.cpp @@ -511,6 +511,9 @@ const SpirvType *LowerTypeVisitor::lowerResourceType(QualType type, return spvContext.getAccelerationStructureTypeNV(); } + if (name == "RayQuery") + return spvContext.getRayQueryProvisionalTypeKHR(); + if (name == "StructuredBuffer" || name == "RWStructuredBuffer" || name == "AppendStructuredBuffer" || name == "ConsumeStructuredBuffer") { // StructureBuffer will be translated into an OpTypeStruct with one diff --git a/tools/clang/lib/SPIRV/SpirvBuilder.cpp b/tools/clang/lib/SPIRV/SpirvBuilder.cpp index 8b75d9658..13e64c713 100644 --- a/tools/clang/lib/SPIRV/SpirvBuilder.cpp +++ b/tools/clang/lib/SPIRV/SpirvBuilder.cpp @@ -790,6 +790,17 @@ SpirvBuilder::createDemoteToHelperInvocationEXT(SourceLocation loc) { return inst; } +SpirvInstruction * +SpirvBuilder::createRayQueryOpsKHR(spv::Op opcode, QualType resultType, + ArrayRef operands, + bool cullFlags, SourceLocation loc) { + assert(insertPoint && "null insert point"); + auto *inst = new (context) + SpirvRayQueryOpKHR(resultType, opcode, operands, cullFlags, loc); + insertPoint->addInstruction(inst); + return inst; +} + void SpirvBuilder::addModuleProcessed(llvm::StringRef process) { mod->addModuleProcessed(new (context) SpirvModuleProcessed({}, process)); } diff --git a/tools/clang/lib/SPIRV/SpirvContext.cpp b/tools/clang/lib/SPIRV/SpirvContext.cpp index 960248e9c..da9fb9da5 100644 --- a/tools/clang/lib/SPIRV/SpirvContext.cpp +++ b/tools/clang/lib/SPIRV/SpirvContext.cpp @@ -24,6 +24,7 @@ SpirvContext::SpirvContext() boolType = new (this) BoolType; samplerType = new (this) SamplerType; accelerationStructureTypeNV = new (this) AccelerationStructureTypeNV; + rayQueryProvisionalTypeKHR = new (this) RayQueryProvisionalTypeKHR; } inline uint32_t log2ForBitwidth(uint32_t bitwidth) { diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index d3da98200..c4be9051c 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/StringExtras.h" #include "InitListHandler.h" +#include "dxc/DXIL/DxilConstants.h" #ifdef SUPPORT_QUERY_GIT_COMMIT_INFO #include "clang/Basic/Version.h" @@ -338,7 +339,8 @@ inline bool canActAsInParmVar(const ParmVarDecl *param) { /// Returns true if the given function parameter can act as shader stage /// output parameter. inline bool canActAsOutParmVar(const ParmVarDecl *param) { - return param->hasAttr() || param->hasAttr(); + return param->hasAttr() || param->hasAttr() || + hlsl::IsHLSLRayQueryType(param->getType()); } /// Returns true if the given expression is of builtin type and can be evaluated @@ -834,6 +836,8 @@ SpirvInstruction *SpirvEmitter::doExpr(const Expr *expr) { } else if (isa(expr)) { assert(curThis); result = curThis; + } else if (isa(expr)) { + result = curThis; } else { emitError("expression class '%0' unimplemented", expr->getExprLoc()) << expr->getStmtClassName() << expr->getSourceRange(); @@ -4098,6 +4102,48 @@ SpirvEmitter::processIntrinsicMemberCall(const CXXMemberCallExpr *expr, expr->getCallee()->getExprLoc()) << expr->getMethodDecl()->getName(); return nullptr; + case IntrinsicOp::MOP_TraceRayInline: + return processTraceRayInline(expr); + case IntrinsicOp::MOP_Abort: + case IntrinsicOp::MOP_CandidateGeometryIndex: + case IntrinsicOp::MOP_CandidateInstanceContributionToHitGroupIndex: + case IntrinsicOp::MOP_CandidateInstanceID: + case IntrinsicOp::MOP_CandidateInstanceIndex: + case IntrinsicOp::MOP_CandidateObjectRayDirection: + case IntrinsicOp::MOP_CandidateObjectRayOrigin: + case IntrinsicOp::MOP_CandidateObjectToWorld3x4: + case IntrinsicOp::MOP_CandidateObjectToWorld4x3: + case IntrinsicOp::MOP_CandidatePrimitiveIndex: + case IntrinsicOp::MOP_CandidateProceduralPrimitiveNonOpaque: + case IntrinsicOp::MOP_CandidateTriangleBarycentrics: + case IntrinsicOp::MOP_CandidateTriangleFrontFace: + case IntrinsicOp::MOP_CandidateTriangleRayT: + case IntrinsicOp::MOP_CandidateType: + case IntrinsicOp::MOP_CandidateWorldToObject3x4: + case IntrinsicOp::MOP_CandidateWorldToObject4x3: + case IntrinsicOp::MOP_CommitNonOpaqueTriangleHit: + case IntrinsicOp::MOP_CommitProceduralPrimitiveHit: + case IntrinsicOp::MOP_CommittedGeometryIndex: + case IntrinsicOp::MOP_CommittedInstanceContributionToHitGroupIndex: + case IntrinsicOp::MOP_CommittedInstanceID: + case IntrinsicOp::MOP_CommittedInstanceIndex: + case IntrinsicOp::MOP_CommittedObjectRayDirection: + case IntrinsicOp::MOP_CommittedObjectRayOrigin: + case IntrinsicOp::MOP_CommittedObjectToWorld3x4: + case IntrinsicOp::MOP_CommittedObjectToWorld4x3: + case IntrinsicOp::MOP_CommittedPrimitiveIndex: + case IntrinsicOp::MOP_CommittedRayT: + case IntrinsicOp::MOP_CommittedStatus: + case IntrinsicOp::MOP_CommittedTriangleBarycentrics: + case IntrinsicOp::MOP_CommittedTriangleFrontFace: + case IntrinsicOp::MOP_CommittedWorldToObject3x4: + case IntrinsicOp::MOP_CommittedWorldToObject4x3: + case IntrinsicOp::MOP_Proceed: + case IntrinsicOp::MOP_RayFlags: + case IntrinsicOp::MOP_RayTMin: + case IntrinsicOp::MOP_WorldRayDirection: + case IntrinsicOp::MOP_WorldRayOrigin: + return processRayQueryIntrinsics(expr, opcode); default: emitError("intrinsic '%0' method unimplemented", expr->getCallee()->getExprLoc()) @@ -5138,6 +5184,10 @@ void SpirvEmitter::storeValue(SpirvInstruction *lhsPtr, // let SPIRV-Tools opt to do the legalization work. // // Note: legalization specific code + if (hlsl::IsHLSLRayQueryType(lhsValType)) { + emitError("store value of type %0 is unsupported", {}) << lhsValType; + return; + } spvBuilder.createStore(lhsPtr, rhsVal, loc); needsLegalization = true; } else if (isAKindOfStructuredOrByteBuffer(lhsValType)) { @@ -11315,5 +11365,315 @@ void SpirvEmitter::addFunctionToWorkQueue(hlsl::DXIL::ShaderKind shaderKind, } } +SpirvInstruction * +SpirvEmitter::processTraceRayInline(const CXXMemberCallExpr *expr) { + emitWarning("SPV_KHR_ray_query is currently a provisional extension and might" + "change in ways that are not backwards compatible", + expr->getExprLoc()); + const auto object = expr->getImplicitObjectArgument(); + uint32_t templateFlags = hlsl::GetHLSLResourceTemplateUInt(object->getType()); + const auto constFlags = spvBuilder.getConstantInt( + astContext.UnsignedIntTy, llvm::APInt(32, templateFlags)); + + SpirvInstruction *rayqueryObj = loadIfAliasVarRef(object); + + const auto args = expr->getArgs(); + + if (expr->getNumArgs() != 4) { + emitError("invalid number of arguments to RayQueryInitialize", + expr->getExprLoc()); + } + + // HLSL Func + // void RayQuery::TraceRayInline( + // RaytracingAccelerationStructure AccelerationStructure, + // uint RayFlags, + // uint InstanceInclusionMask, + // RayDesc Ray); + + // void OpRayQueryInitializeKHR ( RayQuery, + // Acceleration Structure + // RayFlags + // CullMask + // RayOrigin + // RayTmin + // RayDirection + // Ray Tmax) + + const auto accelStructure = doExpr(args[0]); + SpirvInstruction *rayFlags = nullptr; + + if (rayFlags = tryToEvaluateAsConst(args[1])) { + rayFlags->setRValue(); + } else { + rayFlags = doExpr(args[1]); + } + + if (auto constFlags = dyn_cast(rayFlags)) { + auto interRayFlags = constFlags->getValue().getZExtValue(); + templateFlags |= interRayFlags; + } + + bool hasCullFlags = + templateFlags & (uint32_t(hlsl::DXIL::RayFlag::SkipTriangles) | + uint32_t(hlsl::DXIL::RayFlag::SkipProceduralPrimitives)); + + auto loc = args[1]->getLocStart(); + rayFlags = + spvBuilder.createBinaryOp(spv::Op::OpBitwiseOr, astContext.UnsignedIntTy, + constFlags, rayFlags, loc); + const auto cullMask = doExpr(args[2]); + + // Extract the ray description to match SPIR-V + const auto floatType = astContext.FloatTy; + const auto vecType = astContext.getExtVectorType(astContext.FloatTy, 3); + SpirvInstruction *rayDescArg = doExpr(args[3]); + loc = args[3]->getLocStart(); + const auto origin = + spvBuilder.createCompositeExtract(vecType, rayDescArg, {0}, loc); + const auto tMin = + spvBuilder.createCompositeExtract(floatType, rayDescArg, {1}, loc); + const auto direction = + spvBuilder.createCompositeExtract(vecType, rayDescArg, {2}, loc); + const auto tMax = + spvBuilder.createCompositeExtract(floatType, rayDescArg, {3}, loc); + + llvm::SmallVector traceArgs = { + rayqueryObj, accelStructure, rayFlags, cullMask, + origin, tMin, direction, tMax}; + + return spvBuilder.createRayQueryOpsKHR(spv::Op::OpRayQueryInitializeKHR, + QualType(), traceArgs, hasCullFlags, + expr->getExprLoc()); +} + +SpirvInstruction * +SpirvEmitter::processRayQueryIntrinsics(const CXXMemberCallExpr *expr, + hlsl::IntrinsicOp opcode) { + emitWarning("SPV_KHR_ray_query is currently a provisional extension and might" + "change in ways that are not backwards compatible", + expr->getExprLoc()); + const auto object = expr->getImplicitObjectArgument(); + SpirvInstruction *rayqueryObj = loadIfAliasVarRef(object); + + const auto args = expr->getArgs(); + + llvm::SmallVector traceArgs; + traceArgs.push_back(rayqueryObj); + + for (uint32_t i = 0; i < expr->getNumArgs(); ++i) { + traceArgs.push_back(doExpr(args[i])); + } + + spv::Op spvCode = spv::Op::Max; + QualType exprType = expr->getType(); + + exprType = exprType->isVoidType() ? QualType() : exprType; + + const auto candidateIntersection = + spvBuilder.getConstantInt(astContext.UnsignedIntTy, llvm::APInt(32, 0)); + const auto committedIntersection = + spvBuilder.getConstantInt(astContext.UnsignedIntTy, llvm::APInt(32, 1)); + + bool transposeMatrix = false; + bool logicalNot = false; + + using namespace hlsl; + switch (opcode) { + case IntrinsicOp::MOP_Proceed: + spvCode = spv::Op::OpRayQueryProceedKHR; + break; + case IntrinsicOp::MOP_Abort: + spvCode = spv::Op::OpRayQueryTerminateKHR; + exprType = QualType(); + break; + case IntrinsicOp::MOP_CandidateGeometryIndex: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR; + break; + case IntrinsicOp::MOP_CandidateInstanceContributionToHitGroupIndex: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op:: + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR; + break; + case IntrinsicOp::MOP_CandidateInstanceID: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR; + break; + case IntrinsicOp::MOP_CandidateInstanceIndex: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionInstanceIdKHR; + break; + case IntrinsicOp::MOP_CandidateObjectRayDirection: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR; + break; + case IntrinsicOp::MOP_CandidateObjectRayOrigin: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR; + break; + case IntrinsicOp::MOP_CandidateObjectToWorld3x4: + spvCode = spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR; + traceArgs.push_back(candidateIntersection); + transposeMatrix = true; + break; + case IntrinsicOp::MOP_CandidateObjectToWorld4x3: + spvCode = spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR; + traceArgs.push_back(candidateIntersection); + break; + case IntrinsicOp::MOP_CandidatePrimitiveIndex: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR; + break; + case IntrinsicOp::MOP_CandidateProceduralPrimitiveNonOpaque: + spvCode = spv::Op::OpRayQueryGetIntersectionCandidateAABBOpaqueKHR; + logicalNot = true; + break; + case IntrinsicOp::MOP_CandidateTriangleBarycentrics: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionBarycentricsKHR; + break; + case IntrinsicOp::MOP_CandidateTriangleFrontFace: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionFrontFaceKHR; + break; + case IntrinsicOp::MOP_CandidateTriangleRayT: + traceArgs.push_back(candidateIntersection); + spvCode = spv::Op::OpRayQueryGetIntersectionTKHR; + break; + case IntrinsicOp::MOP_CandidateType: + spvCode = spv::Op::OpRayQueryGetIntersectionTypeKHR; + traceArgs.push_back(candidateIntersection); + break; + case IntrinsicOp::MOP_CandidateWorldToObject4x3: + spvCode = spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR; + traceArgs.push_back(candidateIntersection); + break; + case IntrinsicOp::MOP_CandidateWorldToObject3x4: + spvCode = spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR; + traceArgs.push_back(candidateIntersection); + transposeMatrix = true; + break; + case IntrinsicOp::MOP_CommitNonOpaqueTriangleHit: + spvCode = spv::Op::OpRayQueryConfirmIntersectionKHR; + exprType = QualType(); + break; + case IntrinsicOp::MOP_CommitProceduralPrimitiveHit: + spvCode = spv::Op::OpRayQueryGenerateIntersectionKHR; + exprType = QualType(); + break; + case IntrinsicOp::MOP_CommittedGeometryIndex: + spvCode = spv::Op::OpRayQueryGetIntersectionGeometryIndexKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedInstanceContributionToHitGroupIndex: + spvCode = spv::Op:: + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedInstanceID: + spvCode = spv::Op::OpRayQueryGetIntersectionInstanceCustomIndexKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedInstanceIndex: + spvCode = spv::Op::OpRayQueryGetIntersectionInstanceIdKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedObjectRayDirection: + spvCode = spv::Op::OpRayQueryGetIntersectionObjectRayDirectionKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedObjectRayOrigin: + spvCode = spv::Op::OpRayQueryGetIntersectionObjectRayOriginKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedObjectToWorld3x4: + spvCode = spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR; + traceArgs.push_back(committedIntersection); + transposeMatrix = true; + break; + case IntrinsicOp::MOP_CommittedObjectToWorld4x3: + spvCode = spv::Op::OpRayQueryGetIntersectionObjectToWorldKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedPrimitiveIndex: + spvCode = spv::Op::OpRayQueryGetIntersectionPrimitiveIndexKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedRayT: + spvCode = spv::Op::OpRayQueryGetIntersectionTKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedStatus: + spvCode = spv::Op::OpRayQueryGetIntersectionTypeKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedTriangleBarycentrics: + spvCode = spv::Op::OpRayQueryGetIntersectionBarycentricsKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedTriangleFrontFace: + spvCode = spv::Op::OpRayQueryGetIntersectionFrontFaceKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_CommittedWorldToObject3x4: + spvCode = spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR; + traceArgs.push_back(committedIntersection); + transposeMatrix = true; + break; + case IntrinsicOp::MOP_CommittedWorldToObject4x3: + spvCode = spv::Op::OpRayQueryGetIntersectionWorldToObjectKHR; + traceArgs.push_back(committedIntersection); + break; + case IntrinsicOp::MOP_RayFlags: + spvCode = spv::Op::OpRayQueryGetRayFlagsKHR; + break; + case IntrinsicOp::MOP_RayTMin: + spvCode = spv::Op::OpRayQueryGetRayTMinKHR; + break; + case IntrinsicOp::MOP_WorldRayDirection: + spvCode = spv::Op::OpRayQueryGetWorldRayDirectionKHR; + break; + case IntrinsicOp::MOP_WorldRayOrigin: + spvCode = spv::Op::OpRayQueryGetWorldRayOriginKHR; + break; + default: + emitError("intrinsic '%0' method unimplemented", + expr->getCallee()->getExprLoc()) + << expr->getDirectCallee()->getName(); + return nullptr; + } + + if (transposeMatrix) { + assert(hlsl::IsHLSLMatType(exprType) && "intrinsic should be matrix"); + const clang::Type *type = exprType.getCanonicalType().getTypePtr(); + const RecordType *RT = cast(type); + const ClassTemplateSpecializationDecl *templateSpecDecl = + cast(RT->getDecl()); + ClassTemplateDecl *templateDecl = + templateSpecDecl->getSpecializedTemplate(); + const auto retType = exprType; + exprType = getHLSLMatrixType(astContext, theCompilerInstance.getSema(), + templateDecl, astContext.FloatTy, 4, 3); + } + + const auto loc = expr->getExprLoc(); + SpirvInstruction *retVal = + spvBuilder.createRayQueryOpsKHR(spvCode, exprType, traceArgs, false, loc); + + if (transposeMatrix) { + retVal = spvBuilder.createUnaryOp(spv::Op::OpTranspose, expr->getType(), + retVal, loc); + } + + if (logicalNot) { + retVal = spvBuilder.createUnaryOp(spv::Op::OpLogicalNot, expr->getType(), + retVal, loc); + } + + retVal->setRValue(); + return retVal; +} + } // end namespace spirv } // end namespace clang diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.h b/tools/clang/lib/SPIRV/SpirvEmitter.h index 17b31975d..af6f9369c 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.h +++ b/tools/clang/lib/SPIRV/SpirvEmitter.h @@ -553,6 +553,13 @@ private: /// Process mesh shader intrinsics. void processMeshOutputCounts(const CallExpr *callExpr); + /// Process ray query traceinline intrinsics. + SpirvInstruction *processTraceRayInline(const CXXMemberCallExpr *expr); + + /// Process ray query intrinsics + SpirvInstruction *processRayQueryIntrinsics(const CXXMemberCallExpr *expr, + hlsl::IntrinsicOp opcode); + private: /// Returns the for constant value 0 of the given type. SpirvConstant *getValueZero(QualType type); diff --git a/tools/clang/lib/SPIRV/SpirvInstruction.cpp b/tools/clang/lib/SPIRV/SpirvInstruction.cpp index df49c76b6..18874151f 100644 --- a/tools/clang/lib/SPIRV/SpirvInstruction.cpp +++ b/tools/clang/lib/SPIRV/SpirvInstruction.cpp @@ -82,6 +82,7 @@ DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvVectorShuffle) DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvArrayLength) DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvRayTracingOpNV) DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvDemoteToHelperInvocationEXT) +DEFINE_INVOKE_VISITOR_FOR_CLASS(SpirvRayQueryOpKHR) #undef DEFINE_INVOKE_VISITOR_FOR_CLASS @@ -766,5 +767,11 @@ SpirvDemoteToHelperInvocationEXT::SpirvDemoteToHelperInvocationEXT( spv::Op::OpDemoteToHelperInvocationEXT, /*QualType*/ {}, loc) {} +SpirvRayQueryOpKHR::SpirvRayQueryOpKHR( + QualType resultType, spv::Op opcode, + llvm::ArrayRef vecOperands, bool flags, + SourceLocation loc) + : SpirvInstruction(IK_RayQueryOpKHR, opcode, resultType, loc), + operands(vecOperands.begin(), vecOperands.end()), cullFlags(flags) {} } // namespace spirv } // namespace clang diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_assign.cs.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_assign.cs.hlsl new file mode 100644 index 000000000..045722689 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_assign.cs.hlsl @@ -0,0 +1,9 @@ +// Run: %dxc -T cs_6_5 -E CS +// CHECK: error: store value of type 'RayQuery' is unsupported + +[numThreads(1,1,1)] +void CS() +{ + RayQuery q; + RayQuery b = q; +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_ds.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_ds.hlsl new file mode 100644 index 000000000..0953023df --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_ds.hlsl @@ -0,0 +1,63 @@ +// RUN: %dxc -T ds_6_5 -E main +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_query" + +struct VSSceneIn { + float3 pos : POSITION; +}; + +struct PSSceneIn { + float4 pos : SV_Position; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// Simple forwarding Tessellation shaders + +struct HSPerVertexData { + // This is just the original vertex verbatim. In many real life cases this would be a + // control point instead + PSSceneIn v; +}; + +struct HSPerPatchData { + // We at least have to specify tess factors per patch + // As we're tesselating triangles, there will be 4 tess factors + // In real life case this might contain face normal, for example + float edges[3] : SV_TessFactor; + float inside : SV_InsideTessFactor; +}; + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +// domain shader that actually outputs the triangle vertices +[domain("tri")] PSSceneIn main(const float3 bary + : SV_DomainLocation, + const OutputPatch patch, + const HSPerPatchData perPatchData) { + PSSceneIn v; + v.pos = patch[0].v.pos * bary.x + patch[1].v.pos * bary.y + patch[2].v.pos * bary.z + perPatchData.edges[1]; + + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); + + return v; +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_gs.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_gs.hlsl new file mode 100644 index 000000000..2076f25cf --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_gs.hlsl @@ -0,0 +1,43 @@ +// RUN: %dxc -T gs_6_5 -E main +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_query + +struct Out +{ + float4 pos : SV_Position; +}; + +struct Empty{}; + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +[maxvertexcount(3)] +void main(line Empty e[4], inout PointStream OutputStream0) +{ + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); + + Out output = (Out)0; + + OutputStream0.Append(output); + OutputStream0.RestartStrip(); +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_hs.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_hs.hlsl new file mode 100644 index 000000000..a858d194a --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_hs.hlsl @@ -0,0 +1,75 @@ +// Run: %dxc -T hs_6_5 -E main +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpCapability RayTraversalPrimitiveCullingProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_query" + +#define MAX_POINTS 3 + +// Input control point +struct VS_CONTROL_POINT_OUTPUT +{ + float3 vPosition : WORLDPOS; +}; + +// Output control point +struct CONTROL_POINT +{ + float3 vPosition : BEZIERPOS; +}; + +// Output patch constant data. +struct HS_CONSTANT_DATA_OUTPUT +{ + float Edges[4] : SV_TessFactor; + float Inside[2] : SV_InsideTessFactor; +}; + +// Patch Constant Function +HS_CONSTANT_DATA_OUTPUT mainConstant(InputPatch ip) { + HS_CONSTANT_DATA_OUTPUT Output; + + // Must initialize Edges and Inside; otherwise HLSL validation will fail. + Output.Edges[0] = 1.0; + Output.Edges[1] = 2.0; + Output.Edges[2] = 3.0; + Output.Edges[3] = 4.0; + Output.Inside[0] = 5.0; + Output.Inside[1] = 6.0; + + return Output; +} + + + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +[outputcontrolpoints(MAX_POINTS)] +[patchconstantfunc("mainConstant")] +CONTROL_POINT main(InputPatch ip, uint cpid : SV_OutputControlPointID) { +// CHECK: %rayQueryProvisionalKHR = OpTypeRayQueryProvisionalKHR +// CHECK: %_ptr_Function_rayQueryProvisionalKHR = OpTypePointer Function %rayQueryProvisionalKHR +// CHECK: [[rayquery:%\d+]] = OpVariable %_ptr_Function_rayQueryProvisionalKHR Function + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_517 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_259 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); + CONTROL_POINT result; + return result; +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_ps.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_ps.hlsl new file mode 100644 index 000000000..c96cf4105 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_ps.hlsl @@ -0,0 +1,33 @@ +// RUN: %dxc -E main -T ps_6_5 + +// RUN: %dxc -T gs_6_5 -E main +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_query + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +uint4 main() : SV_Target +{ + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); + return float4(1.0, 0.0, 0.0, 1.0); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_rahit.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_rahit.hlsl new file mode 100644 index 000000000..11e207c03 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_rahit.hlsl @@ -0,0 +1,42 @@ +// Run: %dxc -T lib_6_3 +// CHECK: OpCapability RayTracingProvisionalKHR +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_tracing" +// CHECK: OpExtension "SPV_KHR_ray_query" + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +struct Payload +{ + float4 color; +}; +// CHECK: OpTypePointer HitAttributeNV %Attribute +struct Attribute +{ + float2 bary; +}; + +[shader("anyhit")] +void main(inout Payload MyPayload, in Attribute MyAttr) { + Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) }; + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_rcall.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_rcall.hlsl new file mode 100644 index 000000000..26dd9190f --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_rcall.hlsl @@ -0,0 +1,37 @@ +// Run: %dxc -T lib_6_3 +// CHECK: OpCapability RayTracingProvisionalKHR +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_tracing" +// CHECK: OpExtension "SPV_KHR_ray_query" + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +struct Payload +{ + float4 color; +}; + +[shader("miss")] +void main(inout Payload MyPayload) { + Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) }; + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_rchit.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_rchit.hlsl new file mode 100644 index 000000000..bbc2fbca2 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_rchit.hlsl @@ -0,0 +1,42 @@ +// Run: %dxc -T lib_6_3 +// CHECK: OpCapability RayTracingProvisionalKHR +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_tracing" +// CHECK: OpExtension "SPV_KHR_ray_query" + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +struct Payload +{ + float4 color; +}; +// CHECK: OpTypePointer HitAttributeNV %Attribute +struct Attribute +{ + float2 bary; +}; + +[shader("closesthit")] +void main(inout Payload MyPayload, in Attribute MyAttr) { + Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) }; + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_rgen.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_rgen.hlsl new file mode 100644 index 000000000..e1c0e5b5c --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_rgen.hlsl @@ -0,0 +1,42 @@ +// Run: %dxc -T lib_6_3 +// CHECK: OpCapability RayTracingProvisionalKHR +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_tracing" +// CHECK: OpExtension "SPV_KHR_ray_query" + +// CHECK-COUNT-1: [[rs:%\d+]] = OpTypeAccelerationStructureNV +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +struct Payload +{ + float4 color; +}; + + +[shader("raygeneration")] +void main() { + + Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) }; + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); +// CHECK: OpTraceNV {{%\d+}} %uint_0 %uint_255 %uint_0 %uint_1 %uint_0 {{%\d+}} {{%\d+}} {{%\d+}} {{%\d+}} %uint_0 + TraceRay(AccelerationStructure, 0x0, 0xff, 0, 1, 0, ray, myPayload); +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_rint.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_rint.hlsl new file mode 100644 index 000000000..4b4f3df9f --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_rint.hlsl @@ -0,0 +1,41 @@ +// Run: %dxc -T lib_6_3 +// CHECK: OpCapability RayTracingProvisionalKHR +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_tracing" +// CHECK: OpExtension "SPV_KHR_ray_query" + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +struct CallData +{ + float4 data; +}; + +[shader("callable")] +void main() { + + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); + + Attribute myHitAttribute = { float2(0.0f,0.0f) }; +// CHECK: OpReportIntersectionKHR %bool %float_0 %uint_0 + ReportHit(0.0f, 0U, myHitAttribute); +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_rmiss.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_rmiss.hlsl new file mode 100644 index 000000000..26dd9190f --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_rmiss.hlsl @@ -0,0 +1,37 @@ +// Run: %dxc -T lib_6_3 +// CHECK: OpCapability RayTracingProvisionalKHR +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_tracing" +// CHECK: OpExtension "SPV_KHR_ray_query" + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray); +} + +struct Payload +{ + float4 color; +}; + +[shader("miss")] +void main(inout Payload MyPayload) { + Payload myPayload = { float4(0.0f,0.0f,0.0f,0.0f) }; + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_1 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + q.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_OPAQUE, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_3 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); +} diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_init_vs.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_init_vs.hlsl new file mode 100644 index 000000000..c1209e42f --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_init_vs.hlsl @@ -0,0 +1,45 @@ +// Run: %dxc -T vs_6_5 -E main +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpCapability RayTraversalPrimitiveCullingProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_query" + + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RWByteAddressBuffer log : register(u0); + +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} + + +void DoSomething() +{ + log.Store(0,1); +} + +void doInitialize(RayQuery query, RayDesc ray) +{ + query.TraceRayInline(AccelerationStructure,RAY_FLAG_NONE,0xFF,ray); +} + + +void main() +{ +// CHECK: %rayQueryProvisionalKHR = OpTypeRayQueryProvisionalKHR +// CHECK: %_ptr_Function_rayQueryProvisionalKHR = OpTypePointer Function %rayQueryProvisionalKHR +// CHECK: [[rayquery:%\d+]] = OpVariable %_ptr_Function_rayQueryProvisionalKHR Function + RayQuery q; + RayDesc ray = MakeRayDesc(); +// CHECK: [[accel:%\d+]] = OpLoad %accelerationStructureNV %AccelerationStructure +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_517 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + + q.TraceRayInline(AccelerationStructure,RAY_FLAG_SKIP_PROCEDURAL_PRIMITIVES, 0xFF, ray); +// CHECK: OpRayQueryInitializeKHR [[rayquery]] [[accel]] %uint_5 %uint_255 {{%\d+}} %float_0 {{%\d+}} %float_9999 + doInitialize(q, ray); +} \ No newline at end of file diff --git a/tools/clang/test/CodeGenSPIRV/rayquery_tryAllOps.cs.hlsl b/tools/clang/test/CodeGenSPIRV/rayquery_tryAllOps.cs.hlsl new file mode 100644 index 000000000..a405b1616 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rayquery_tryAllOps.cs.hlsl @@ -0,0 +1,206 @@ +// Run: dxc -T cs_6_5 -E CS +// CHECK: OpCapability RayQueryProvisionalKHR +// CHECK: OpExtension "SPV_KHR_ray_query" + +RaytracingAccelerationStructure AccelerationStructure : register(t0); +RWByteAddressBuffer log : register(u0); + +RayDesc MakeRayDesc() +{ + RayDesc desc; + desc.Origin = float3(0,0,0); + desc.Direction = float3(1,0,0); + desc.TMin = 0.0f; + desc.TMax = 9999.0; + return desc; +} + +void DoSomething() +{ + log.Store(0,1); +} + +[numThreads(1,1,1)] +void CS() +{ + RayQuery q; + RayDesc ray = MakeRayDesc(); + q.TraceRayInline(AccelerationStructure,RAY_FLAG_NONE,0xFF,ray); + float4x3 mat4x3; + float3x4 mat3x4; +// CHECK: [[rayquery:%\d+]] = OpVariable %_ptr_Function_rayQueryProvisionalKHR Function +// CHECK: OpRayQueryProceedKHR %bool [[rayquery]] + while(q.Proceed()) + { +// CHECK: OpRayQueryGetIntersectionTypeKHR %uint [[rayquery]] %uint_0 + switch(q.CandidateType()) + { + case CANDIDATE_NON_OPAQUE_TRIANGLE: + q.Abort(); +// CHECK: OpRayQueryGetIntersectionObjectToWorldKHR %mat4v3float [[rayquery]] %uint_0 + mat3x4 = q.CandidateObjectToWorld3x4(); + mat4x3 = q.CandidateObjectToWorld4x3(); +// CHECK: OpRayQueryConfirmIntersectionKHR [[rayquery]] + q.CommitNonOpaqueTriangleHit(); +// CHECK: OpRayQueryGetIntersectionFrontFaceKHR %bool [[rayquery]] %uint_0 + if(q.CandidateTriangleFrontFace()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionBarycentricsKHR %v2float [[rayquery]] %uint_0 + if(q.CandidateTriangleBarycentrics().x == 0) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionGeometryIndexKHR %uint [[rayquery]] %uint_0 + if(q.CandidateGeometryIndex()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionInstanceCustomIndexKHR %uint [[rayquery]] %uint_0 + if(q.CandidateInstanceID()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionInstanceIdKHR %uint [[rayquery]] %uint_0 + if(q.CandidateInstanceIndex()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionObjectRayDirectionKHR %v3float [[rayquery]] %uint_0 + if(q.CandidateObjectRayDirection().x) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionObjectRayOriginKHR %v3float [[rayquery]] %uint_0 + if(q.CandidateObjectRayOrigin().y) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionPrimitiveIndexKHR %uint [[rayquery]] %uint_0 + if(q.CandidatePrimitiveIndex()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionTKHR %float [[rayquery]] %uint_0 + if(q.CandidateTriangleRayT()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %uint [[rayquery]] %uint_0 + if(q.CandidateInstanceContributionToHitGroupIndex()) + { + DoSomething(); + } + break; + case CANDIDATE_PROCEDURAL_PRIMITIVE: + { +// CHECK: OpRayQueryGetIntersectionWorldToObjectKHR %mat4v3float [[rayquery]] %uint_0 + mat3x4 = q.CandidateWorldToObject3x4(); + mat4x3 = q.CandidateWorldToObject4x3(); +// CHECK: OpRayQueryGetIntersectionCandidateAABBOpaqueKHR %bool + if(q.CandidateProceduralPrimitiveNonOpaque()) + { + DoSomething(); + } + float t = 0.5; +// CHECK: OpRayQueryGenerateIntersectionKHR [[rayquery]] %float_0_5 + q.CommitProceduralPrimitiveHit(t); + q.Abort(); + break; + } + } + } + if(mat3x4[0][0] == mat4x3[0][0]) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionTypeKHR %uint [[rayquery]] %uint_1 + switch(q.CommittedStatus()) + { + case COMMITTED_NOTHING: +// CHECK: OpRayQueryGetIntersectionObjectToWorldKHR %mat4v3float [[rayquery]] %uint_1 + mat3x4 = q.CommittedObjectToWorld3x4(); + mat4x3 = q.CommittedObjectToWorld4x3(); + break; + case COMMITTED_TRIANGLE_HIT: +// CHECK: OpRayQueryGetIntersectionWorldToObjectKHR %mat4v3float [[rayquery]] %uint_1 + mat3x4 = q.CommittedWorldToObject3x4(); + mat4x3 = q.CommittedWorldToObject4x3(); +// CHECK: OpRayQueryGetIntersectionFrontFaceKHR %bool [[rayquery]] %uint_1 + if(q.CommittedTriangleFrontFace()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionBarycentricsKHR %v2float [[rayquery]] %uint_1 + if(q.CommittedTriangleBarycentrics().y == 0) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR %uint [[rayquery]] %uint_1 + if(q.CommittedInstanceContributionToHitGroupIndex()) + { + DoSomething(); + } + break; + case COMMITTED_PROCEDURAL_PRIMITIVE_HIT: +// CHECK: OpRayQueryGetIntersectionGeometryIndexKHR %uint [[rayquery]] %uint_1 + if(q.CommittedGeometryIndex()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionInstanceCustomIndexKHR %uint [[rayquery]] %uint_1 + if(q.CommittedInstanceID()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionInstanceIdKHR %uint [[rayquery]] %uint_1 + if(q.CommittedInstanceIndex()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionObjectRayDirectionKHR %v3float [[rayquery]] %uint_1 + if(q.CommittedObjectRayDirection().z) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionObjectRayOriginKHR %v3float [[rayquery]] %uint_1 + if(q.CommittedObjectRayOrigin().x) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionPrimitiveIndexKHR %uint [[rayquery]] %uint_1 + if(q.CommittedPrimitiveIndex()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetIntersectionTKHR %float [[rayquery]] %uint_1 + if(q.CommittedRayT()) + { + DoSomething(); + } + break; + } + if(mat3x4[0][0] == mat4x3[0][0]) + { + DoSomething(); + } +// CHECK: OpRayQueryGetRayFlagsKHR %uint [[rayquery]] + if(q.RayFlags()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetRayTMinKHR %float [[rayquery]] + if(q.RayTMin()) + { + DoSomething(); + } +// CHECK: OpRayQueryGetWorldRayDirectionKHR %v3float [[rayquery]] + float3 o = q.WorldRayDirection(); +// CHECK: OpRayQueryGetWorldRayOriginKHR %v3float [[rayquery]] + float3 d = q.WorldRayOrigin(); + if(o.x == d.z) + { + DoSomething(); + } +} \ No newline at end of file