1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
//- DXIL.td - Describe DXIL operation -------------------------*- tablegen -*-//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This is a target description file for DXIL operations.
///
//===----------------------------------------------------------------------===//
include "llvm/IR/Intrinsics.td"
include "llvm/IR/Attributes.td"
// Abstract representation of the class a DXIL Operation belongs to.
class DXILOpClass<string name> {
string Name = name;
}
// Abstract representation of the category a DXIL Operation belongs to
class DXILOpCategory<string name> {
string Name = name;
}
def UnaryClass : DXILOpClass<"Unary">;
def BinaryClass : DXILOpClass<"Binary">;
def FlattenedThreadIdInGroupClass : DXILOpClass<"FlattenedThreadIdInGroup">;
def ThreadIdInGroupClass : DXILOpClass<"ThreadIdInGroup">;
def ThreadIdClass : DXILOpClass<"ThreadId">;
def GroupIdClass : DXILOpClass<"GroupId">;
def BinaryUintCategory : DXILOpCategory<"Binary uint">;
def UnaryFloatCategory : DXILOpCategory<"Unary float">;
def ComputeIDCategory : DXILOpCategory<"Compute/Mesh/Amplification shader">;
// Following are the scalar types supported by DXIL operations and are synonymous
// to llvm_*_ty defined for readability and ease of use in the context of this file.
def voidTy : LLVMType<isVoid>;
// Floating point types
def f16Ty : LLVMType<f16>;
def f32Ty : LLVMType<f32>;
def f64Ty : LLVMType<f64>;
// Integer types
def i1Ty : LLVMType<i1>;
def i8Ty : LLVMType<i8>;
def i16Ty : LLVMType<i16>;
def i32Ty : LLVMType<i32>;
def i64Ty : LLVMType<i64>;
// The parameter description for a DXIL operation
class DXILOpParameter<int pos, string type, string name, string doc,
bit isConstant = 0, string enumName = "",
int maxValue = 0> {
int Pos = pos; // Position in parameter list
string Type = type; // LLVM type name, $o for overload, $r for resource
// type, $cb for legacy cbuffer, $u4 for u4 struct
string Name = name; // Short, unique parameter name
string Doc = doc; // Description of this parameter
bit IsConstant = isConstant; // Whether this parameter requires a constant value in the IR
string EnumName = enumName; // Name of the enum type, if applicable
int MaxValue = maxValue; // Maximum value for this parameter, if applicable
}
// A representation for a DXIL operation
class DXILOperationDesc {
string OpName = ""; // Name of DXIL operation
int OpCode = 0; // Unique non-negative integer associated with the operation
DXILOpClass OpClass; // Class of the operation
DXILOpCategory OpCategory; // Category of the operation
string Doc = ""; // Description of the operation
list<DXILOpParameter> Params = []; // Parameter list of the operation
list<LLVMType> OverloadTypes = []; // Overload types, if applicable
EnumAttr Attribute; // Operation Attribute. Leverage attributes defined in Attributes.td
// ReadNone - operation does not access memory.
// ReadOnly - only reads from memory.
// "ReadMemory" - reads memory
bit IsDerivative = 0; // Whether this is some kind of derivative
bit IsGradient = 0; // Whether this requires a gradient calculation
bit IsFeedback = 0; // Whether this is a sampler feedback operation
bit IsWave = 0; // Whether this requires in-wave, cross-lane functionality
bit NeedsUniformInputs = 0; // Whether this operation requires that all
// of its inputs are uniform across the wave
// Group DXIL operation for stats - e.g., to accumulate the number of atomic/float/uint/int/...
// operations used in the program.
list<string> StatsGroup = [];
}
class DXILOperation<string name, int opCode, DXILOpClass opClass, DXILOpCategory opCategory, string doc,
list<LLVMType> oloadTypes, EnumAttr attrs, list<DXILOpParameter> params,
list<string> statsGroup = []> : DXILOperationDesc {
let OpName = name;
let OpCode = opCode;
let Doc = doc;
let Params = params;
let OpClass = opClass;
let OpCategory = opCategory;
let OverloadTypes = oloadTypes;
let Attribute = attrs;
let StatsGroup = statsGroup;
}
// LLVM intrinsic that DXIL operation maps to.
class LLVMIntrinsic<Intrinsic llvm_intrinsic_> { Intrinsic llvm_intrinsic = llvm_intrinsic_; }
def Sin : DXILOperation<"Sin", 13, UnaryClass, UnaryFloatCategory, "returns sine(theta) for theta in radians.",
[f16Ty,f32Ty], ReadNone,
[
DXILOpParameter<0, "$o", "", "operation result">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
DXILOpParameter<2, "$o", "value", "input value">
],
["floats"]>,
LLVMIntrinsic<int_sin>;
def UMax : DXILOperation< "UMax", 39, BinaryClass, BinaryUintCategory, "unsigned integer maximum. UMax(a,b) = a > b ? a : b",
[i16Ty,i32Ty,i64Ty], ReadNone,
[
DXILOpParameter<0, "$o", "", "operation result">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
DXILOpParameter<2, "$o", "a", "input value">,
DXILOpParameter<3, "$o", "b", "input value">
],
["uints"]>,
LLVMIntrinsic<int_umax>;
def ThreadId : DXILOperation< "ThreadId", 93, ThreadIdClass, ComputeIDCategory, "reads the thread ID", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "thread ID component">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
DXILOpParameter<2, "i32", "component", "component to read (x,y,z)">
]>,
LLVMIntrinsic<int_dx_thread_id>;
def GroupId : DXILOperation< "GroupId", 94, GroupIdClass, ComputeIDCategory, "reads the group ID (SV_GroupID)", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "group ID component">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
DXILOpParameter<2, "i32", "component", "component to read">
]>,
LLVMIntrinsic<int_dx_group_id>;
def ThreadIdInGroup : DXILOperation< "ThreadIdInGroup", 95, ThreadIdInGroupClass, ComputeIDCategory,
"reads the thread ID within the group (SV_GroupThreadID)", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "thread ID in group component">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">,
DXILOpParameter<2, "i32", "component", "component to read (x,y,z)">
]>,
LLVMIntrinsic<int_dx_thread_id_in_group>;
def FlattenedThreadIdInGroup : DXILOperation< "FlattenedThreadIdInGroup", 96, FlattenedThreadIdInGroupClass, ComputeIDCategory,
"provides a flattened index for a given thread within a given group (SV_GroupIndex)", [i32Ty], ReadNone,
[
DXILOpParameter<0, "i32", "", "result">,
DXILOpParameter<1, "i32", "opcode", "DXIL opcode">
]>,
LLVMIntrinsic<int_dx_flattened_thread_id_in_group>;
|