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:
JiaoluAMD 2020-05-12 01:28:00 +08:00 коммит произвёл GitHub
Родитель 00a8233c30
Коммит fc54789458
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
31 изменённых файлов: 1388 добавлений и 21 удалений

Просмотреть файл

@ -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();
}
}