Implement SPV_KHR_ray_query generation (#2834)
* Implement SPV_KHR_ray_query generation from dxr 1.1 rayquery hlsl * Fix CodeGenSPIRV folder test failures * Address reviewing issues and clang-format files * Undo all spacing changes to HlslTypes.cpp * Fix formatting issues in the doc file. Co-authored-by: Ehsan Nasiri <ehsannas@gmail.com>
This commit is contained in:
Родитель
00a8233c30
Коммит
fc54789458
178
docs/SPIR-V.rst
178
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 <array-size>`` |
|
||||
+-----------------+-------------------------------------------------------------------------+
|
||||
|
@ -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<RAY_FLAG_NONE> 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<RAY_FLAG_CULL_NON_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> 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<RAY_FLAGS>
|
||||
|
||||
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
|
||||
================================
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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<SpirvInstruction *> operands,
|
||||
bool cullFlags, SourceLocation loc);
|
||||
|
||||
// === SPIR-V Module Structure ===
|
||||
inline void setMemoryModel(spv::AddressingModel, spv::MemoryModel);
|
||||
|
||||
|
|
|
@ -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<const SpirvType *, SCToPtrTyMap> pointerTypes;
|
||||
llvm::DenseSet<FunctionType *, FunctionTypeMapInfo> functionTypes;
|
||||
const AccelerationStructureTypeNV *accelerationStructureTypeNV;
|
||||
const RayQueryProvisionalTypeKHR *rayQueryProvisionalTypeKHR;
|
||||
|
||||
// Current ShaderModelKind for entry point.
|
||||
ShaderModelKind curShaderModelKind;
|
||||
|
|
|
@ -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<SpirvInstruction *, 4> operands;
|
||||
};
|
||||
class SpirvRayQueryOpKHR : public SpirvInstruction {
|
||||
public:
|
||||
SpirvRayQueryOpKHR(QualType resultType, spv::Op opcode,
|
||||
llvm::ArrayRef<SpirvInstruction *> 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<SpirvInstruction *> getOperands() const { return operands; }
|
||||
|
||||
bool hasCullFlags() const { return cullFlags; }
|
||||
|
||||
private:
|
||||
llvm::SmallVector<SpirvInstruction *, 4> operands;
|
||||
bool cullFlags;
|
||||
};
|
||||
|
||||
/// \brief OpDemoteToHelperInvocationEXT instruction.
|
||||
/// Demote fragment shader invocation to a helper invocation. Any stores to
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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<RecordType>()) {
|
||||
if (const auto *structType =
|
||||
arrayType->getElementType()->getAs<RecordType>()) {
|
||||
return isOrContainsNonFpColMajorMatrix(astContext, spirvOptions,
|
||||
arrayType->getElementType(),
|
||||
structType->getDecl());
|
||||
|
|
|
@ -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<RayQueryProvisionalTypeKHR>(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<SpirvRayQueryOpKHR>(instr);
|
||||
if (rayQueryInst->hasCullFlags()) {
|
||||
addCapability(
|
||||
spv::Capability::RayTraversalPrimitiveCullingProvisionalKHR);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -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<SpirvInstruction>(inst));
|
||||
}
|
||||
for (const auto operand : inst->getOperands())
|
||||
curInst.push_back(getOrAssignResultId<SpirvInstruction>(operand));
|
||||
finalizeInstruction();
|
||||
emitDebugNameForInstruction(getOrAssignResultId<SpirvInstruction>(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<RayQueryProvisionalTypeKHR>(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,
|
||||
|
|
|
@ -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<uint32_t> takeBinary();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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<S> will be translated into an OpTypeStruct with one
|
||||
|
|
|
@ -790,6 +790,17 @@ SpirvBuilder::createDemoteToHelperInvocationEXT(SourceLocation loc) {
|
|||
return inst;
|
||||
}
|
||||
|
||||
SpirvInstruction *
|
||||
SpirvBuilder::createRayQueryOpsKHR(spv::Op opcode, QualType resultType,
|
||||
ArrayRef<SpirvInstruction *> 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));
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<HLSLOutAttr>() || param->hasAttr<HLSLInOutAttr>();
|
||||
return param->hasAttr<HLSLOutAttr>() || param->hasAttr<HLSLInOutAttr>() ||
|
||||
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<CXXThisExpr>(expr)) {
|
||||
assert(curThis);
|
||||
result = curThis;
|
||||
} else if (isa<CXXConstructExpr>(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 ( <id> RayQuery,
|
||||
// <id> Acceleration Structure
|
||||
// <id> RayFlags
|
||||
// <id> CullMask
|
||||
// <id> RayOrigin
|
||||
// <id> RayTmin
|
||||
// <id> RayDirection
|
||||
// <id> 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<SpirvConstantInteger>(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<SpirvInstruction *, 8> 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<SpirvInstruction *, 8> 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<RecordType>(type);
|
||||
const ClassTemplateSpecializationDecl *templateSpecDecl =
|
||||
cast<ClassTemplateSpecializationDecl>(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
|
||||
|
|
|
@ -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 <result-id> for constant value 0 of the given type.
|
||||
SpirvConstant *getValueZero(QualType type);
|
||||
|
|
|
@ -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<SpirvInstruction *> vecOperands, bool flags,
|
||||
SourceLocation loc)
|
||||
: SpirvInstruction(IK_RayQueryOpKHR, opcode, resultType, loc),
|
||||
operands(vecOperands.begin(), vecOperands.end()), cullFlags(flags) {}
|
||||
} // namespace spirv
|
||||
} // namespace clang
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
// Run: %dxc -T cs_6_5 -E CS
|
||||
// CHECK: error: store value of type 'RayQuery<RAY_FLAG_FORCE_OPAQUE | RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH>' is unsupported
|
||||
|
||||
[numThreads(1,1,1)]
|
||||
void CS()
|
||||
{
|
||||
RayQuery<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> q;
|
||||
RayQuery<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> b = q;
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> 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<HSPerVertexData, 3> 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<RAY_FLAG_FORCE_OPAQUE> 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;
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> query, RayDesc ray)
|
||||
{
|
||||
query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray);
|
||||
}
|
||||
|
||||
[maxvertexcount(3)]
|
||||
void main(line Empty e[4], inout PointStream<Out> OutputStream0)
|
||||
{
|
||||
RayQuery<RAY_FLAG_FORCE_OPAQUE> 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();
|
||||
}
|
|
@ -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<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> 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<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_SKIP_TRIANGLES> query, RayDesc ray)
|
||||
{
|
||||
query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray);
|
||||
}
|
||||
|
||||
[outputcontrolpoints(MAX_POINTS)]
|
||||
[patchconstantfunc("mainConstant")]
|
||||
CONTROL_POINT main(InputPatch<VS_CONTROL_POINT_OUTPUT, MAX_POINTS> ip, uint cpid : SV_OutputControlPointID) {
|
||||
// CHECK: %rayQueryProvisionalKHR = OpTypeRayQueryProvisionalKHR
|
||||
// CHECK: %_ptr_Function_rayQueryProvisionalKHR = OpTypePointer Function %rayQueryProvisionalKHR
|
||||
// CHECK: [[rayquery:%\d+]] = OpVariable %_ptr_Function_rayQueryProvisionalKHR Function
|
||||
RayQuery<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_SKIP_TRIANGLES> 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;
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> query, RayDesc ray)
|
||||
{
|
||||
query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray);
|
||||
}
|
||||
|
||||
uint4 main() : SV_Target
|
||||
{
|
||||
RayQuery<RAY_FLAG_FORCE_OPAQUE> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> 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<RAY_FLAG_FORCE_OPAQUE> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> 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<RAY_FLAG_FORCE_OPAQUE> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> 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<RAY_FLAG_FORCE_OPAQUE> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> 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<RAY_FLAG_FORCE_OPAQUE> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> query, RayDesc ray)
|
||||
{
|
||||
query.TraceRayInline(AccelerationStructure,RAY_FLAG_FORCE_NON_OPAQUE,0xFF,ray);
|
||||
}
|
||||
|
||||
struct CallData
|
||||
{
|
||||
float4 data;
|
||||
};
|
||||
|
||||
[shader("callable")]
|
||||
void main() {
|
||||
|
||||
RayQuery<RAY_FLAG_FORCE_OPAQUE> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE> 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<RAY_FLAG_FORCE_OPAQUE> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> 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<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> 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);
|
||||
}
|
|
@ -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<RAY_FLAG_FORCE_OPAQUE|RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH> 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();
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче