Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/dxc/DXIL/DxilConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,11 @@ const unsigned kMSStoreOutputColOpIdx = 3;
const unsigned kMSStoreOutputVIdxOpIdx = 4;
const unsigned kMSStoreOutputValOpIdx = 5;

// HitObject::TraceRay
const unsigned kHitObjectTraceRay_RayDescOpIdx = 7;
const unsigned kHitObjectTraceRay_PayloadOpIdx = 15;
const unsigned kHitObjectTraceRay_NumOp = 16;

// MatVec Ops
const unsigned kMatVecMulInputVectorIdx = 1;
const unsigned kMatVecMulIsInputUnsignedIdx = 2;
Expand Down
8 changes: 8 additions & 0 deletions include/dxc/HLSL/HLOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,14 @@ const unsigned kNodeHandleToResCastOpIdx = 1;
const unsigned kAnnotateNodeHandleNodePropIdx = 2;
const unsigned kAnnotateNodeRecordHandleNodeRecordPropIdx = 2;

// HitObject::MakeMiss
const unsigned kHitObjectMakeMiss_NumOp = 8;
const unsigned kHitObjectMakeMissRayDescOpIdx = 4;

// HitObject::TraceRay
const unsigned kHitObjectTraceRay_RayDescOpIdx = 8;
const unsigned kHitObjectTraceRay_NumOp = 10;

// Linear Algebra Operations

// MatVecMul
Expand Down
242 changes: 190 additions & 52 deletions lib/HLSL/HLOperationLower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
// //
///////////////////////////////////////////////////////////////////////////////

#include "dxc/DXIL/DxilConstants.h"
#define _USE_MATH_DEFINES
#include <array>
#include <cmath>
#include <functional>
#include <unordered_set>

#include "dxc/DXIL/DxilConstants.h"
#include "dxc/DXIL/DxilInstructions.h"
#include "dxc/DXIL/DxilModule.h"
#include "dxc/DXIL/DxilOperations.h"
#include "dxc/DXIL/DxilResourceProperties.h"
Expand Down Expand Up @@ -5717,58 +5720,61 @@ Value *TranslateCallShader(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
return Builder.CreateCall(F, {opArg, ShaderIndex, Parameter});
}

Value *TranslateTraceRay(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
HLOperationLowerHelper &helper,
HLObjectOperationLowerHelper *pObjHelper,
bool &Translated) {
hlsl::OP *hlslOP = &helper.hlslOP;

Value *rayDesc = CI->getArgOperand(HLOperandIndex::kTraceRayRayDescOpIdx);
Value *payLoad = CI->getArgOperand(HLOperandIndex::kTraceRayPayLoadOpIdx);

Value *opArg = hlslOP->GetU32Const(static_cast<unsigned>(opcode));

Value *Args[DXIL::OperandIndex::kTraceRayNumOp];
Args[0] = opArg;
for (unsigned i = 1; i < HLOperandIndex::kTraceRayRayDescOpIdx; i++) {
Args[i] = CI->getArgOperand(i);
}
IRBuilder<> Builder(CI);
static unsigned LoadRayDescElementsIntoArgs(Value **Args, hlsl::OP *OP,
IRBuilder<> &Builder,
Value *RayDescPtr, unsigned Index) {
// struct RayDesc
//{
// float3 Origin;
// float TMin;
// float3 Direction;
// float TMax;
//};
Value *zeroIdx = hlslOP->GetU32Const(0);
Value *origin = Builder.CreateGEP(rayDesc, {zeroIdx, zeroIdx});
origin = Builder.CreateLoad(origin);
unsigned index = DXIL::OperandIndex::kTraceRayRayDescOpIdx;
Args[index++] = Builder.CreateExtractElement(origin, (uint64_t)0);
Args[index++] = Builder.CreateExtractElement(origin, 1);
Args[index++] = Builder.CreateExtractElement(origin, 2);
Value *ZeroIdx = OP->GetU32Const(0);
Value *Origin = Builder.CreateGEP(RayDescPtr, {ZeroIdx, ZeroIdx});
Origin = Builder.CreateLoad(Origin);
Args[Index++] = Builder.CreateExtractElement(Origin, (uint64_t)0);
Args[Index++] = Builder.CreateExtractElement(Origin, 1);
Args[Index++] = Builder.CreateExtractElement(Origin, 2);

Value *tmin = Builder.CreateGEP(rayDesc, {zeroIdx, hlslOP->GetU32Const(1)});
tmin = Builder.CreateLoad(tmin);
Args[index++] = tmin;
Value *TMinPtr = Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(1)});
Args[Index++] = Builder.CreateLoad(TMinPtr);

Value *direction =
Builder.CreateGEP(rayDesc, {zeroIdx, hlslOP->GetU32Const(2)});
direction = Builder.CreateLoad(direction);
Value *DirectionPtr =
Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(2)});
Value *Direction = Builder.CreateLoad(DirectionPtr);

Args[index++] = Builder.CreateExtractElement(direction, (uint64_t)0);
Args[index++] = Builder.CreateExtractElement(direction, 1);
Args[index++] = Builder.CreateExtractElement(direction, 2);
Args[Index++] = Builder.CreateExtractElement(Direction, (uint64_t)0);
Args[Index++] = Builder.CreateExtractElement(Direction, 1);
Args[Index++] = Builder.CreateExtractElement(Direction, 2);

Value *TMaxPtr = Builder.CreateGEP(RayDescPtr, {ZeroIdx, OP->GetU32Const(3)});
Args[Index++] = Builder.CreateLoad(TMaxPtr);
return Index;
}

Value *TranslateTraceRay(CallInst *CI, IntrinsicOp IOP, OP::OpCode OpCode,
HLOperationLowerHelper &Helper,
HLObjectOperationLowerHelper *pObjHelper,
bool &Translated) {
hlsl::OP *OP = &Helper.hlslOP;

Value *RayDesc = CI->getArgOperand(HLOperandIndex::kTraceRayRayDescOpIdx);
Value *PayLoad = CI->getArgOperand(HLOperandIndex::kTraceRayPayLoadOpIdx);

Value *Args[DXIL::OperandIndex::kTraceRayNumOp];
Args[0] = OP->GetU32Const(static_cast<unsigned>(OpCode));
for (unsigned i = 1; i < HLOperandIndex::kTraceRayRayDescOpIdx; i++)
Args[i] = CI->getArgOperand(i);

Value *tmax = Builder.CreateGEP(rayDesc, {zeroIdx, hlslOP->GetU32Const(3)});
tmax = Builder.CreateLoad(tmax);
Args[index++] = tmax;
IRBuilder<> Builder(CI);
LoadRayDescElementsIntoArgs(Args, OP, Builder, RayDesc,
DXIL::OperandIndex::kTraceRayRayDescOpIdx);

Args[DXIL::OperandIndex::kTraceRayPayloadOpIdx] = payLoad;
Args[DXIL::OperandIndex::kTraceRayPayloadOpIdx] = PayLoad;

Type *Ty = payLoad->getType();
Function *F = hlslOP->GetOpFunc(opcode, Ty);
Type *Ty = PayLoad->getType();
Function *F = OP->GetOpFunc(OpCode, Ty);

return Builder.CreateCall(F, Args);
}
Expand Down Expand Up @@ -6183,19 +6189,114 @@ Value *TranslateUnpack(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,

// Shader Execution Reordering.
namespace {
Value *TranslateHitObjectMake(CallInst *CI, IntrinsicOp IOP, OP::OpCode opcode,
HLOperationLowerHelper &helper,
HLObjectOperationLowerHelper *pObjHelper,
Value *TranslateHitObjectMake(CallInst *CI, IntrinsicOp IOP, OP::OpCode Opcode,
HLOperationLowerHelper &Helper,
HLObjectOperationLowerHelper *ObjHelper,
bool &Translated) {
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
hlsl::OP *HlslOP = &Helper.hlslOP;
IRBuilder<> Builder(CI);
unsigned SrcIdx = 1;
Value *HitObjectPtr = CI->getArgOperand(SrcIdx++);
if (Opcode == OP::OpCode::HitObject_MakeNop) {
Value *HitObject = TrivialDxilOperation(
Opcode, {nullptr}, Type::getVoidTy(CI->getContext()), CI, HlslOP);
Builder.CreateStore(HitObject, HitObjectPtr);
DXASSERT(
CI->use_empty(),
"Default ctor return type is a Clang artifact. Value must not be used");
return nullptr;
}

DXASSERT_NOMSG(CI->getNumArgOperands() ==
HLOperandIndex::kHitObjectMakeMiss_NumOp);
Value *RayFlags = CI->getArgOperand(SrcIdx++);
Value *MissShaderIdx = CI->getArgOperand(SrcIdx++);
DXASSERT_NOMSG(SrcIdx == HLOperandIndex::kHitObjectMakeMissRayDescOpIdx);
Value *RayDescOrigin = CI->getArgOperand(SrcIdx++);
Value *RayDescOriginX =
Builder.CreateExtractElement(RayDescOrigin, (uint64_t)0);
Value *RayDescOriginY =
Builder.CreateExtractElement(RayDescOrigin, (uint64_t)1);
Value *RayDescOriginZ =
Builder.CreateExtractElement(RayDescOrigin, (uint64_t)2);

Value *RayDescTMin = CI->getArgOperand(SrcIdx++);
Value *RayDescDirection = CI->getArgOperand(SrcIdx++);
Value *RayDescDirectionX =
Builder.CreateExtractElement(RayDescDirection, (uint64_t)0);
Value *RayDescDirectionY =
Builder.CreateExtractElement(RayDescDirection, (uint64_t)1);
Value *RayDescDirectionZ =
Builder.CreateExtractElement(RayDescDirection, (uint64_t)2);

Value *RayDescTMax = CI->getArgOperand(SrcIdx++);
DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands());

Value *OutHitObject = TrivialDxilOperation(
Opcode,
{nullptr, RayFlags, MissShaderIdx, RayDescOriginX, RayDescOriginY,
RayDescOriginZ, RayDescTMin, RayDescDirectionX, RayDescDirectionY,
RayDescDirectionZ, RayDescTMax},
Helper.voidTy, CI, HlslOP);
Builder.CreateStore(OutHitObject, HitObjectPtr);
return nullptr;
}

Value *TranslateMaybeReorderThread(CallInst *CI, IntrinsicOp IOP,
OP::OpCode opcode,
HLOperationLowerHelper &helper,
OP::OpCode OpCode,
HLOperationLowerHelper &Helper,
HLObjectOperationLowerHelper *pObjHelper,
bool &Translated) {
return nullptr; // TODO: Merge SER DXIL patches
hlsl::OP *OP = &Helper.hlslOP;

// clang-format off
// Match MaybeReorderThread overload variants:
// void MaybeReorderThread(<Op>,
// HitObject Hit);
// void MaybeReorderThread(<Op>,
// uint CoherenceHint,
// uint NumCoherenceHintBitsFromLSB );
// void MaybeReorderThread(<Op>,
// HitObject Hit,
// uint CoherenceHint,
// uint NumCoherenceHintBitsFromLSB);
// clang-format on
const unsigned NumHLArgs = CI->getNumArgOperands();
DXASSERT_NOMSG(NumHLArgs >= 2);

// Use a NOP HitObject for MaybeReorderThread without HitObject.
Value *HitObject = nullptr;
unsigned HLIndex = 1;
if (3 == NumHLArgs) {
HitObject = TrivialDxilOperation(DXIL::OpCode::HitObject_MakeNop, {nullptr},
Type::getVoidTy(CI->getContext()), CI, OP);
} else {
Value *FirstParam = CI->getArgOperand(HLIndex);
DXASSERT_NOMSG(isa<PointerType>(FirstParam->getType()));
IRBuilder<> Builder(CI);
HitObject = Builder.CreateLoad(FirstParam);
HLIndex++;
}

// If there are trailing parameters, these have to be the two coherence bit
// parameters
Value *CoherenceHint = nullptr;
Value *NumCoherenceHintBits = nullptr;
if (2 != NumHLArgs) {
DXASSERT_NOMSG(HLIndex + 2 == NumHLArgs);
CoherenceHint = CI->getArgOperand(HLIndex++);
NumCoherenceHintBits = CI->getArgOperand(HLIndex++);
DXASSERT_NOMSG(Helper.i32Ty == CoherenceHint->getType());
DXASSERT_NOMSG(Helper.i32Ty == NumCoherenceHintBits->getType());
} else {
CoherenceHint = UndefValue::get(Helper.i32Ty);
NumCoherenceHintBits = OP->GetU32Const(0);
}

TrivialDxilOperation(
OpCode, {nullptr, HitObject, CoherenceHint, NumCoherenceHintBits},
Type::getVoidTy(CI->getContext()), CI, OP);
return nullptr;
}

Value *TranslateHitObjectFromRayQuery(CallInst *CI, IntrinsicOp IOP,
Expand All @@ -6211,15 +6312,54 @@ Value *TranslateHitObjectTraceRay(CallInst *CI, IntrinsicOp IOP,
HLOperationLowerHelper &Helper,
HLObjectOperationLowerHelper *pObjHelper,
bool &Translated) {
return UndefValue::get(CI->getType()); // TODO: Merge SER DXIL patches
hlsl::OP *OP = &Helper.hlslOP;
IRBuilder<> Builder(CI);

const unsigned DxilNumArgs = DxilInst_HitObject_TraceRay::arg_payload + 1;
DXASSERT_NOMSG(CI->getNumArgOperands() ==
HLOperandIndex::kHitObjectTraceRay_NumOp);
Value *Args[DxilNumArgs];
Value *OpArg = OP->GetU32Const(static_cast<unsigned>(OpCode));
Args[0] = OpArg;

unsigned DestIdx = 1, SrcIdx = 1;
Value *HitObjectPtr = CI->getArgOperand(SrcIdx++);
Args[DestIdx++] = CI->getArgOperand(SrcIdx++);
for (; SrcIdx < HLOperandIndex::kHitObjectTraceRay_RayDescOpIdx;
++SrcIdx, ++DestIdx) {
Args[DestIdx] = CI->getArgOperand(SrcIdx);
}

Value *RayDescPtr = CI->getArgOperand(SrcIdx++);
DestIdx = LoadRayDescElementsIntoArgs(Args, OP, Builder, RayDescPtr, DestIdx);
Value *Payload = CI->getArgOperand(SrcIdx++);
Args[DestIdx++] = Payload;

DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands());
DXASSERT_NOMSG(DestIdx == DxilNumArgs);

Function *F = OP->GetOpFunc(OpCode, Payload->getType());

Value *OutHitObject = Builder.CreateCall(F, Args);
Builder.CreateStore(OutHitObject, HitObjectPtr);
return nullptr;
}

Value *TranslateHitObjectInvoke(CallInst *CI, IntrinsicOp IOP,
OP::OpCode OpCode,
HLOperationLowerHelper &Helper,
HLObjectOperationLowerHelper *pObjHelper,
bool &Translated) {
return nullptr; // TODO: Merge SER DXIL patches
unsigned SrcIdx = 1;
Value *HitObjectPtr = CI->getArgOperand(SrcIdx++);
Value *Payload = CI->getArgOperand(SrcIdx++);
DXASSERT_NOMSG(SrcIdx == CI->getNumArgOperands());

IRBuilder<> Builder(CI);
Value *HitObject = Builder.CreateLoad(HitObjectPtr);
TrivialDxilOperation(OpCode, {nullptr, HitObject, Payload},
Payload->getType(), CI, &Helper.hlslOP);
return nullptr;
}

Value *TranslateHitObjectGetAttributes(CallInst *CI, IntrinsicOp IOP,
Expand Down Expand Up @@ -7162,11 +7302,9 @@ IntrinsicLower gLowerTable[] = {
{IntrinsicOp::MOP_InterlockedUMin, TranslateMopAtomicBinaryOperation,
DXIL::OpCode::NumOpCodes},
{IntrinsicOp::MOP_DxHitObject_MakeNop, TranslateHitObjectMake,
DXIL::OpCode::NumOpCodes_Dxil_1_8}, // FIXME: Just a placeholder Dxil
// opcode
DXIL::OpCode::HitObject_MakeNop},
{IntrinsicOp::IOP_DxMaybeReorderThread, TranslateMaybeReorderThread,
DXIL::OpCode::NumOpCodes_Dxil_1_8}, // FIXME: Just a placeholder Dxil
// opcode
DXIL::OpCode::MaybeReorderThread},
{IntrinsicOp::IOP_Vkstatic_pointer_cast, UnsupportedVulkanIntrinsic,
DXIL::OpCode::NumOpCodes},
{IntrinsicOp::IOP_Vkreinterpret_pointer_cast, UnsupportedVulkanIntrinsic,
Expand Down
10 changes: 10 additions & 0 deletions lib/Transforms/Scalar/ScalarReplAggregatesHLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,8 @@ void isSafeForScalarRepl(Instruction *I, uint64_t Offset, AllocaInfo &Info) {
// basing on IOP?
IntrinsicOp opcode = static_cast<IntrinsicOp>(GetHLOpcode(CI));
if (IntrinsicOp::IOP_TraceRay == opcode ||
IntrinsicOp::MOP_DxHitObject_TraceRay == opcode ||
IntrinsicOp::MOP_DxHitObject_Invoke == opcode ||
IntrinsicOp::IOP_ReportHit == opcode ||
IntrinsicOp::IOP_CallShader == opcode) {
return MarkUnsafe(Info, User);
Expand Down Expand Up @@ -2775,6 +2777,14 @@ void SROA_Helper::RewriteCall(CallInst *CI) {
RewriteCallArg(CI, HLOperandIndex::kCallShaderPayloadOpIdx,
/*bIn*/ true, /*bOut*/ true);
} break;
case IntrinsicOp::MOP_DxHitObject_MakeMiss: {
if (OldVal ==
CI->getArgOperand(HLOperandIndex::kHitObjectMakeMissRayDescOpIdx)) {
RewriteWithFlattenedHLIntrinsicCall(CI, OldVal, NewElts,
/*loadElts*/ true);
DeadInsts.push_back(CI);
}
} break;
case IntrinsicOp::MOP_TraceRayInline: {
if (OldVal ==
CI->getArgOperand(HLOperandIndex::kTraceRayInlineRayDescOpIdx)) {
Expand Down
11 changes: 10 additions & 1 deletion tools/clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1047,8 +1047,17 @@ bool CGDebugInfo::TryCollectHLSLRecordElements(const RecordType *Ty,
unsigned VecSize = hlsl::GetHLSLVecSize(QualTy);
unsigned ElemSizeInBits = CGM.getContext().getTypeSize(ElemQualTy);
unsigned CurrentAlignedOffset = 0;
SmallString<8> FieldNameBuf;
for (unsigned ElemIdx = 0; ElemIdx < VecSize; ++ElemIdx) {
StringRef FieldName = StringRef(&"xyzw"[ElemIdx], 1);
StringRef FieldName;
if (VecSize <= 4) {
FieldName = StringRef(&"xyzw"[ElemIdx], 1);
} else {
FieldNameBuf.clear();
llvm::raw_svector_ostream OS(FieldNameBuf);
OS << 'c' << ElemIdx;
FieldName = OS.str();
}
CurrentAlignedOffset =
llvm::RoundUpToAlignment(CurrentAlignedOffset, AlignBits);
llvm::DIType *FieldType =
Expand Down
3 changes: 2 additions & 1 deletion tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3522,7 +3522,8 @@ SpirvVariable *DeclResultIdMapper::createSpirvInterfaceVariable(
// Decorate with PerPrimitiveNV for per-primitive out variables.
spvBuilder.decoratePerPrimitiveNV(varInstr,
varInstr->getSourceLocation());
} else {
} else if (stageVar.getSemanticInfo().getKind() !=
hlsl::Semantic::Kind::DomainLocation) {
spvBuilder.decoratePatch(varInstr, varInstr->getSourceLocation());
}
}
Expand Down
Loading