Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
112 changes: 57 additions & 55 deletions include/dxc/DXIL/DxilConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -487,60 +487,61 @@ inline bool IsFeedbackTexture(DXIL::ResourceKind ResourceKind) {
// Enumeration for operations specified by DXIL
enum class OpCode : unsigned {
//
Reserved0 = 226, // Reserved
Reserved1 = 227, // Reserved
Reserved10 = 236, // Reserved
Reserved11 = 237, // Reserved
Reserved2 = 228, // Reserved
Reserved3 = 229, // Reserved
Reserved4 = 230, // Reserved
Reserved5 = 231, // Reserved
Reserved6 = 232, // Reserved
Reserved7 = 233, // Reserved
Reserved8 = 234, // Reserved
Reserved9 = 235, // Reserved
ReservedA0 = 259, // reserved
ReservedA1 = 260, // reserved
ReservedA2 = 261, // reserved
ReservedB0 = 262, // reserved
ReservedB1 = 263, // reserved
ReservedB10 = 272, // reserved
ReservedB11 = 273, // reserved
ReservedB12 = 274, // reserved
ReservedB13 = 275, // reserved
ReservedB14 = 276, // reserved
ReservedB15 = 277, // reserved
ReservedB16 = 278, // reserved
ReservedB17 = 279, // reserved
ReservedB18 = 280, // reserved
ReservedB19 = 281, // reserved
ReservedB2 = 264, // reserved
ReservedB20 = 282, // reserved
ReservedB21 = 283, // reserved
ReservedB22 = 284, // reserved
ReservedB23 = 285, // reserved
ReservedB24 = 286, // reserved
ReservedB25 = 287, // reserved
ReservedB26 = 288, // reserved
ReservedB27 = 289, // reserved
ReservedB28 = 290, // reserved
ReservedB29 = 291, // reserved
ReservedB30 = 292, // reserved
ReservedB5 = 267, // reserved
ReservedB6 = 268, // reserved
ReservedB7 = 269, // reserved
ReservedB8 = 270, // reserved
ReservedB9 = 271, // reserved
ReservedC0 = 293, // reserved
ReservedC1 = 294, // reserved
ReservedC2 = 295, // reserved
ReservedC3 = 296, // reserved
ReservedC4 = 297, // reserved
ReservedC5 = 298, // reserved
ReservedC6 = 299, // reserved
ReservedC7 = 300, // reserved
ReservedC8 = 301, // reserved
ReservedC9 = 302, // reserved
MaybeReorderThread = 268, // Reorders the current thread. Optionally accepts a
// HitObject arg, or undef
Reserved0 = 226, // Reserved
Reserved1 = 227, // Reserved
Reserved10 = 236, // Reserved
Reserved11 = 237, // Reserved
Reserved2 = 228, // Reserved
Reserved3 = 229, // Reserved
Reserved4 = 230, // Reserved
Reserved5 = 231, // Reserved
Reserved6 = 232, // Reserved
Reserved7 = 233, // Reserved
Reserved8 = 234, // Reserved
Reserved9 = 235, // Reserved
ReservedA0 = 259, // reserved
ReservedA1 = 260, // reserved
ReservedA2 = 261, // reserved
ReservedB0 = 262, // reserved
ReservedB1 = 263, // reserved
ReservedB10 = 272, // reserved
ReservedB11 = 273, // reserved
ReservedB12 = 274, // reserved
ReservedB13 = 275, // reserved
ReservedB14 = 276, // reserved
ReservedB15 = 277, // reserved
ReservedB16 = 278, // reserved
ReservedB17 = 279, // reserved
ReservedB18 = 280, // reserved
ReservedB19 = 281, // reserved
ReservedB2 = 264, // reserved
ReservedB20 = 282, // reserved
ReservedB21 = 283, // reserved
ReservedB22 = 284, // reserved
ReservedB23 = 285, // reserved
ReservedB24 = 286, // reserved
ReservedB25 = 287, // reserved
ReservedB26 = 288, // reserved
ReservedB27 = 289, // reserved
ReservedB28 = 290, // reserved
ReservedB29 = 291, // reserved
ReservedB30 = 292, // reserved
ReservedB5 = 267, // reserved
ReservedB7 = 269, // reserved
ReservedB8 = 270, // reserved
ReservedB9 = 271, // reserved
ReservedC0 = 293, // reserved
ReservedC1 = 294, // reserved
ReservedC2 = 295, // reserved
ReservedC3 = 296, // reserved
ReservedC4 = 297, // reserved
ReservedC5 = 298, // reserved
ReservedC6 = 299, // reserved
ReservedC7 = 300, // reserved
ReservedC8 = 301, // reserved
ReservedC9 = 302, // reserved

// Amplification shader instructions
DispatchMesh = 173, // Amplification shader intrinsic DispatchMesh
Expand Down Expand Up @@ -1059,6 +1060,7 @@ enum class OpCode : unsigned {
// Groups for DXIL operations with equivalent function templates
enum class OpCodeClass : unsigned {
//
MaybeReorderThread,
Reserved,

// Amplification shader instructions
Expand Down Expand Up @@ -1361,7 +1363,7 @@ enum class OpCodeClass : unsigned {
NumOpClasses_Dxil_1_7 = 153,
NumOpClasses_Dxil_1_8 = 174,

NumOpClasses = 179 // exclusive last value of enumeration
NumOpClasses = 180 // exclusive last value of enumeration
};
// OPCODECLASS-ENUM:END

Expand Down
38 changes: 38 additions & 0 deletions include/dxc/DXIL/DxilInstructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -8924,6 +8924,44 @@ struct DxilInst_HitObject_MakeNop {
bool requiresUniformInputs() const { return false; }
};

/// This instruction Reorders the current thread. Optionally accepts a HitObject
/// arg, or undef
struct DxilInst_MaybeReorderThread {
llvm::Instruction *Instr;
// Construction and identification
DxilInst_MaybeReorderThread(llvm::Instruction *pInstr) : Instr(pInstr) {}
operator bool() const {
return hlsl::OP::IsDxilOpFuncCallInst(Instr,
hlsl::OP::OpCode::MaybeReorderThread);
}
// Validation support
bool isAllowed() const { return true; }
bool isArgumentListValid() const {
if (4 != llvm::dyn_cast<llvm::CallInst>(Instr)->getNumArgOperands())
return false;
return true;
}
// Metadata
bool requiresUniformInputs() const { return false; }
// Operand indexes
enum OperandIdx {
arg_hitObject = 1,
arg_coherenceHint = 2,
arg_numCoherenceHintBitsFromLSB = 3,
};
// Accessors
llvm::Value *get_hitObject() const { return Instr->getOperand(1); }
void set_hitObject(llvm::Value *val) { Instr->setOperand(1, val); }
llvm::Value *get_coherenceHint() const { return Instr->getOperand(2); }
void set_coherenceHint(llvm::Value *val) { Instr->setOperand(2, val); }
llvm::Value *get_numCoherenceHintBitsFromLSB() const {
return Instr->getOperand(3);
}
void set_numCoherenceHintBitsFromLSB(llvm::Value *val) {
Instr->setOperand(3, val);
}
};

/// This instruction reads from a raw buffer and structured buffer
struct DxilInst_RawBufferVectorLoad {
llvm::Instruction *Instr;
Expand Down
20 changes: 14 additions & 6 deletions lib/DXIL/DxilOperations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2353,10 +2353,10 @@ const OP::OpCodeProperty OP::m_OpCodeProps[(unsigned)OP::OpCode::NumOpCodes] = {
0,
{},
{}}, // Overloads: v
{OC::ReservedB6,
"ReservedB6",
OCC::Reserved,
"reserved",
{OC::MaybeReorderThread,
"MaybeReorderThread",
OCC::MaybeReorderThread,
"maybeReorderThread",
Attribute::None,
0,
{},
Expand Down Expand Up @@ -3145,6 +3145,11 @@ void OP::GetMinShaderModelAndMask(OpCode C, bool bWithTranslation,
SFLAG(Amplification) | SFLAG(Mesh) | SFLAG(Node);
return;
}
// Instructions: MaybeReorderThread=268
if (op == 268) {
mask = SFLAG(Library) | SFLAG(RayGeneration);
return;
}
// Instructions: RenderTargetGetSamplePosition=76,
// RenderTargetGetSampleCount=77, Discard=82, EvalSnapped=87,
// EvalSampleIndex=88, EvalCentroid=89, SampleIndex=90, Coverage=91,
Expand Down Expand Up @@ -5618,9 +5623,12 @@ Function *OP::GetOpFunc(OpCode opCode, Type *pOverloadType) {
A(pV);
A(pI32);
break;
case OpCode::ReservedB6:
case OpCode::MaybeReorderThread:
A(pV);
A(pI32);
A(pHit);
A(pI32);
A(pI32);
break;
case OpCode::ReservedB7:
A(pV);
Expand Down Expand Up @@ -6047,7 +6055,7 @@ llvm::Type *OP::GetOverloadType(OpCode opCode, llvm::Function *F) {
case OpCode::HitObject_MakeMiss:
case OpCode::HitObject_MakeNop:
case OpCode::ReservedB5:
case OpCode::ReservedB6:
case OpCode::MaybeReorderThread:
case OpCode::ReservedB7:
case OpCode::ReservedB8:
case OpCode::ReservedB9:
Expand Down
24 changes: 24 additions & 0 deletions lib/DxilValidation/DxilValidation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1871,6 +1871,30 @@ static void ValidateDxilOperationCallInProfile(CallInst *CI,
{"CreateHandleForLib", "Library"});
}
break;

// Shader Execution Reordering
case DXIL::OpCode::MaybeReorderThread: {
Value *HitObject = CI->getArgOperand(1);
Value *CoherenceHintBits = CI->getArgOperand(2);
Value *NumCoherenceHintBits = CI->getArgOperand(3);

if (isa<UndefValue>(HitObject))
ValCtx.EmitInstrError(CI, ValidationRule::InstrUndefHitObject);

if (isa<UndefValue>(NumCoherenceHintBits))
ValCtx.EmitInstrError(
CI, ValidationRule::InstrMayReorderThreadUndefCoherenceHintParam);

ConstantInt *NumCoherenceHintBitsConst =
dyn_cast<ConstantInt>(NumCoherenceHintBits);
const bool HasCoherenceHint =
NumCoherenceHintBitsConst &&
NumCoherenceHintBitsConst->getLimitedValue() != 0;
if (HasCoherenceHint && isa<UndefValue>(CoherenceHintBits))
ValCtx.EmitInstrError(
CI, ValidationRule::InstrMayReorderThreadUndefCoherenceHintParam);
} break;

case DXIL::OpCode::AtomicBinOp:
case DXIL::OpCode::AtomicCompareExchange: {
Type *pOverloadType = OP::GetOverloadType(Opcode, CI->getCalledFunction());
Expand Down
60 changes: 60 additions & 0 deletions tools/clang/test/LitDXILValidation/ser_maybereorder_failing.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
; REQUIRES: dxil-1-9
; RUN: not %dxv %s 2>&1 | FileCheck %s

target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"

%dx.types.HitObject = type { i8* }

; CHECK: Function: ?main@@YAXXZ: error: Use of undef coherence hint or num coherence hint bits in MaybeReorderThread.
; CHECK-NEXT: note: at 'call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject %nop, i32 1, i32 undef)'

; CHECK: Function: ?main@@YAXXZ: error: Use of undef coherence hint or num coherence hint bits in MaybeReorderThread.
; CHECK-NEXT: note: at 'call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject %nop, i32 undef, i32 1)'

; CHECK: Function: ?main@@YAXXZ: error: HitObject is undef.
; CHECK-NEXT: note: at 'call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject undef, i32 11, i32 0)'

; CHECK: Validation failed.

; Function Attrs: nounwind
define void @"\01?main@@YAXXZ"() #0 {
%nop = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()

; Validate that hit object is not undef.
call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject undef, i32 11, i32 0) ; MaybeReorderThread(hitObject,coherenceHint,numCoherenceHintBitsFromLSB)

; Validate that coherence hint is not undef while numCoherenceHintBitsFromLSB is not 0.
call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject %nop, i32 undef, i32 1) ; MaybeReorderThread(hitObject,coherenceHint,numCoherenceHintBitsFromLSB)

; Validate that num coherence hint bits from LSB is not undef.
call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject %nop, i32 1, i32 undef) ; MaybeReorderThread(hitObject,coherenceHint,numCoherenceHintBitsFromLSB)
ret void
}

; Function Attrs: nounwind readnone
declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1

; Function Attrs: nounwind
declare void @dx.op.maybeReorderThread(i32, %dx.types.HitObject, i32, i32) #0

attributes #0 = { nounwind }
attributes #1 = { nounwind readnone }

!dx.version = !{!0}
!dx.valver = !{!0}
!dx.shaderModel = !{!1}
!dx.typeAnnotations = !{!2}
!dx.entryPoints = !{!6, !8}

!0 = !{i32 1, i32 9}
!1 = !{!"lib", i32 6, i32 9}
!2 = !{i32 1, void ()* @"\01?main@@YAXXZ", !3}
!3 = !{!4}
!4 = !{i32 1, !5, !5}
!5 = !{}
!6 = !{null, !"", null, null, !7}
!7 = !{i32 0, i64 0}
!8 = !{void ()* @"\01?main@@YAXXZ", !"\01?main@@YAXXZ", null, null, !9}
!9 = !{i32 8, i32 7, i32 5, !10}
!10 = !{i32 0}
46 changes: 46 additions & 0 deletions tools/clang/test/LitDXILValidation/ser_maybereorder_passing.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
; REQUIRES: dxil-1-9
; RUN: %dxv %s | FileCheck %s

; CHECK: Validation succeeded.

target datalayout = "e-m:e-p:32:32-i1:32-i8:32-i16:32-i32:32-i64:64-f16:32-f32:32-f64:64-n8:16:32:64"
target triple = "dxil-ms-dx"

%dx.types.HitObject = type { i8* }

; Function Attrs: nounwind
define void @"\01?main@@YAXXZ"() #0 {
%nop = call %dx.types.HitObject @dx.op.hitObject_MakeNop(i32 266) ; HitObject_MakeNop()
call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject %nop, i32 241, i32 3) ; MaybeReorderThread(hitObject,coherenceHint,numCoherenceHintBitsFromLSB)

; Coherence hint disabled, accept 'undef' coherence hint bits.
call void @dx.op.maybeReorderThread(i32 268, %dx.types.HitObject %nop, i32 undef, i32 0) ; MaybeReorderThread(hitObject,coherenceHint,numCoherenceHintBitsFromLSB)
ret void
}

; Function Attrs: nounwind readnone
declare %dx.types.HitObject @dx.op.hitObject_MakeNop(i32) #1

; Function Attrs: nounwind
declare void @dx.op.maybeReorderThread(i32, %dx.types.HitObject, i32, i32) #0

attributes #0 = { nounwind }
attributes #1 = { nounwind readnone }

!dx.version = !{!0}
!dx.valver = !{!0}
!dx.shaderModel = !{!1}
!dx.typeAnnotations = !{!2}
!dx.entryPoints = !{!6, !8}

!0 = !{i32 1, i32 9}
!1 = !{!"lib", i32 6, i32 9}
!2 = !{i32 1, void ()* @"\01?main@@YAXXZ", !3}
!3 = !{!4}
!4 = !{i32 1, !5, !5}
!5 = !{}
!6 = !{null, !"", null, null, !7}
!7 = !{i32 0, i64 0}
!8 = !{void ()* @"\01?main@@YAXXZ", !"\01?main@@YAXXZ", null, null, !9}
!9 = !{i32 8, i32 7, i32 5, !10}
!10 = !{i32 0}
Loading