-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[DXIL] Define and generate DXILAttribute
and DXILProperty
#117072
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b715825
b27564e
fde0d22
fd5dbce
66c0750
4205861
eb10290
4a1561d
5c4c605
147395e
3b795f5
d3c1224
007fc09
66989ec
206667d
e988056
de938df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -266,18 +266,29 @@ def miss : DXILShaderStage; | |
def all_stages : DXILShaderStage; | ||
// Denote support for DXIL Op to have been removed | ||
def removed : DXILShaderStage; | ||
|
||
// DXIL Op attributes | ||
|
||
// A function attribute denotes that there is a corresponding LLVM function | ||
// attribute that will be set when building the DXIL op. The mapping is defined | ||
// by setDXILAttributes in DXILOpBuilder.cpp | ||
class DXILAttribute; | ||
|
||
def ReadOnly : DXILAttribute; | ||
def ReadNone : DXILAttribute; | ||
def IsDerivative : DXILAttribute; | ||
def IsGradient : DXILAttribute; | ||
def IsFeedback : DXILAttribute; | ||
def IsWave : DXILAttribute; | ||
def NeedsUniformInputs : DXILAttribute; | ||
def IsBarrier : DXILAttribute; | ||
def ReadOnly : DXILAttribute; | ||
def NoDuplicate : DXILAttribute; | ||
def NoReturn : DXILAttribute; | ||
|
||
// A property is simply used to mark that a DXIL op belongs to a sub-group of | ||
// DXIL ops, and it is used to query if a particular op holds this property. | ||
// This is used for the static analysis of DXIL ops. | ||
class DXILProperty; | ||
|
||
def IsBarrier : DXILProperty; | ||
def IsGradient : DXILProperty; | ||
def IsFeedback : DXILProperty; | ||
def IsWave : DXILProperty; | ||
def RequiresUniformInputs : DXILProperty; | ||
|
||
class Overloads<Version ver, list<DXILOpParamType> ols> { | ||
Version dxil_version = ver; | ||
|
@@ -291,7 +302,7 @@ class Stages<Version ver, list<DXILShaderStage> st> { | |
|
||
class Attributes<Version ver = DXIL1_0, list<DXILAttribute> attrs> { | ||
Version dxil_version = ver; | ||
list<DXILAttribute> op_attrs = attrs; | ||
list<DXILAttribute> fn_attrs = attrs; | ||
} | ||
|
||
defvar BarrierMode_DeviceMemoryBarrier = 2; | ||
|
@@ -376,6 +387,9 @@ class DXILOp<int opcode, DXILOpClass opclass> { | |
|
||
// Versioned attributes of operation | ||
list<Attributes> attributes = []; | ||
|
||
// List of properties. Default to no properties. | ||
list<DXILProperty> properties = []; | ||
} | ||
|
||
// Concrete definitions of DXIL Operations | ||
|
@@ -783,6 +797,10 @@ def CreateHandle : DXILOp<57, createHandle> { | |
let arguments = [Int8Ty, Int32Ty, Int32Ty, Int1Ty]; | ||
let result = HandleTy; | ||
let stages = [Stages<DXIL1_0, [all_stages]>, Stages<DXIL1_6, [removed]>]; | ||
// NOTE: The ReadOnly attribute was set for consistency with DXC. However, it | ||
// seems like ReadNone may more appropiately describe it. So noted to | ||
// consider a change in the future | ||
let attributes = [Attributes<DXIL1_0, [ReadOnly]>]; | ||
} | ||
|
||
def BufferLoad : DXILOp<68, bufferLoad> { | ||
|
@@ -794,6 +812,7 @@ def BufferLoad : DXILOp<68, bufferLoad> { | |
[Overloads<DXIL1_0, | ||
[ResRetHalfTy, ResRetFloatTy, ResRetInt16Ty, ResRetInt32Ty]>]; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadOnly]>]; | ||
} | ||
|
||
def BufferStore : DXILOp<69, bufferStore> { | ||
|
@@ -822,6 +841,7 @@ def CheckAccessFullyMapped : DXILOp<71, checkAccessFullyMapped> { | |
let result = Int1Ty; | ||
let overloads = [Overloads<DXIL1_0, [Int32Ty]>]; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadOnly]>]; | ||
} | ||
|
||
def Discard : DXILOp<82, discard> { | ||
|
@@ -896,8 +916,8 @@ def Dot4AddI8Packed : DXILOp<163, dot4AddPacked> { | |
let intrinsics = [ IntrinSelect<int_dx_dot4add_i8packed> ]; | ||
let arguments = [Int32Ty, Int32Ty, Int32Ty]; | ||
let result = Int32Ty; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
} | ||
|
||
def Dot4AddU8Packed : DXILOp<164, dot4AddPacked> { | ||
|
@@ -906,22 +926,24 @@ def Dot4AddU8Packed : DXILOp<164, dot4AddPacked> { | |
let intrinsics = [ IntrinSelect<int_dx_dot4add_u8packed> ]; | ||
let arguments = [Int32Ty, Int32Ty, Int32Ty]; | ||
let result = Int32Ty; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
} | ||
|
||
def AnnotateHandle : DXILOp<216, annotateHandle> { | ||
let Doc = "annotate handle with resource properties"; | ||
let arguments = [HandleTy, ResPropsTy]; | ||
let result = HandleTy; | ||
let stages = [Stages<DXIL1_6, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
} | ||
|
||
def CreateHandleFromBinding : DXILOp<217, createHandleFromBinding> { | ||
let Doc = "create resource handle from binding"; | ||
let arguments = [ResBindTy, Int32Ty, Int1Ty]; | ||
let result = HandleTy; | ||
let stages = [Stages<DXIL1_6, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
} | ||
|
||
def WaveActiveAllTrue : DXILOp<114, waveAllTrue> { | ||
|
@@ -930,6 +952,7 @@ def WaveActiveAllTrue : DXILOp<114, waveAllTrue> { | |
let arguments = [Int1Ty]; | ||
let result = Int1Ty; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let properties = [IsWave]; | ||
} | ||
|
||
def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> { | ||
|
@@ -938,6 +961,7 @@ def WaveActiveAnyTrue : DXILOp<113, waveAnyTrue> { | |
let arguments = [Int1Ty]; | ||
let result = Int1Ty; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let properties = [IsWave]; | ||
} | ||
|
||
def WaveIsFirstLane : DXILOp<110, waveIsFirstLane> { | ||
|
@@ -946,7 +970,7 @@ def WaveIsFirstLane : DXILOp<110, waveIsFirstLane> { | |
let arguments = []; | ||
let result = Int1Ty; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
let properties = [IsWave]; | ||
} | ||
|
||
def WaveReadLaneAt: DXILOp<117, waveReadLaneAt> { | ||
|
@@ -956,7 +980,7 @@ def WaveReadLaneAt: DXILOp<117, waveReadLaneAt> { | |
let result = OverloadTy; | ||
let overloads = [Overloads<DXIL1_0, [HalfTy, FloatTy, DoubleTy, Int1Ty, Int16Ty, Int32Ty, Int64Ty]>]; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
let properties = [IsWave]; | ||
} | ||
|
||
def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> { | ||
|
@@ -965,7 +989,8 @@ def WaveGetLaneIndex : DXILOp<111, waveGetLaneIndex> { | |
let arguments = []; | ||
let result = Int32Ty; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadOnly]>]; | ||
let properties = [IsWave]; | ||
} | ||
|
||
def WaveAllBitCount : DXILOp<135, waveAllOp> { | ||
|
@@ -974,7 +999,7 @@ def WaveAllBitCount : DXILOp<135, waveAllOp> { | |
let arguments = [Int1Ty]; | ||
let result = Int32Ty; | ||
let stages = [Stages<DXIL1_0, [all_stages]>]; | ||
let attributes = [Attributes<DXIL1_0, [ReadNone]>]; | ||
let properties = [IsWave]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think all these wave ops could be readonly at the least, maybe we want to investigate that later though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I agree that we could further investigate the correctness of the attributes. The goal of this PR was to get consistent behaviour with DXC, so I will file an issue to look into that. |
||
} | ||
|
||
def Barrier : DXILOp<80, barrier> { | ||
|
@@ -989,4 +1014,5 @@ def Barrier : DXILOp<80, barrier> { | |
let result = VoidTy; | ||
let stages = [Stages<DXIL1_0, [compute, library]>]; | ||
let attributes = [Attributes<DXIL1_0, []>]; | ||
let properties = [IsBarrier]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is consistent with hctdb.py, but I'm not certain it's right. I can't really rationalize why this is RO while both
CreateHandleFromBinding
and evenCreateHandleFromHeap
are RN. I'm not suggesting changing it. At worst, if you're unsure, a comment here might give future generations a chance to revisit this when we might be better suited to answerThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a comment to note this and will mention it in the new issue.