Skip to content

Commit 45258c4

Browse files
committed
[mlir][dxsa] Add dcl_interface and dcl_interface_dynamicindexed
dcl_interface binds multiple dcl_function_table declarations, so they can be accessed either statically or dynamically. Each table is bound at runtime, but the compiler must know every variant to generate a specialized version of the shader.
1 parent 543afcc commit 45258c4

4 files changed

Lines changed: 98 additions & 0 deletions

File tree

mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,23 @@ def DXSA_SystemValueNameAttr :
255255
let assemblyFormat = "$value";
256256
}
257257

258+
def DXSA_InterfaceAccess_Immediate : I32EnumAttrCase<"immediate", 0>;
259+
def DXSA_InterfaceAccess_Dynamic : I32EnumAttrCase<"dynamic", 1>;
260+
261+
def DXSA_InterfaceAccess : I32EnumAttr<
262+
"InterfaceAccess", "DXBC access kind for an interface", [
263+
DXSA_InterfaceAccess_Immediate,
264+
DXSA_InterfaceAccess_Dynamic
265+
]> {
266+
let cppNamespace = "::mlir::dxsa";
267+
let genSpecializedAttr = 0;
268+
}
269+
270+
def DXSA_InterfaceAccessAttr :
271+
EnumAttr<DXSADialect, DXSA_InterfaceAccess, "interface_access"> {
272+
let assemblyFormat = "$value";
273+
}
274+
258275
//===----------------------------------------------------------------------===//
259276
// DXSA ComponentMask bit-enum (mask field of operand, normalized to bits 0..3)
260277
//===----------------------------------------------------------------------===//
@@ -758,4 +775,28 @@ def DXSA_DclFunctionTable : DXSA_Op<"dcl_function_table"> {
758775
let assemblyFormat = "$index `,` $functions attr-dict";
759776
}
760777

778+
def DXSA_DclInterface : DXSA_Op<"dcl_interface"> {
779+
let summary = "declares function table pointers (interfaces)";
780+
let description = [{
781+
782+
Declare an `array_length` of function table pointers
783+
(interfaces). Each table can be bound at runtime, and it should
784+
contain `table_length` function bodies.
785+
786+
Example:
787+
```mlir
788+
dxsa.dcl_function_body 0
789+
dxsa.dcl_function_body 1
790+
dxsa.dcl_function_table 0, [0, 1]
791+
dxsa.dcl_interface 1, <access = dynamic, array_length = 1, table_length = 2> [0]
792+
```
793+
}];
794+
let arguments = (ins I32Attr:$index, DXSA_InterfaceAccessAttr:$access, I32Attr:$array_length, I32Attr:$table_length, DenseI32ArrayAttr:$tables);
795+
let assemblyFormat = [{ $index `,` `<`
796+
`access` `=` $access `,`
797+
`array_length` `=` $array_length `,`
798+
`table_length` `=` $table_length `>` `,` $tables attr-dict
799+
}];
800+
}
801+
761802
#endif // DXSA_OPS

mlir/lib/Target/DXSA/BinaryParser.cpp

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,16 @@ class DXBuilder {
646646
builder, loc, index, DenseI32ArrayAttr::get(ctx, functions));
647647
}
648648

649+
Instruction buildDclInterface(uint32_t index,
650+
dxsa::InterfaceAccess access,
651+
uint32_t arrayLength,
652+
uint32_t tableLength,
653+
ArrayRef<int32_t> tables, Location loc) {
654+
auto *ctx = builder.getContext();
655+
return dxsa::DclInterface::create(builder, loc, index, access, arrayLength, tableLength,
656+
DenseI32ArrayAttr::get(ctx, tables));
657+
}
658+
649659
private:
650660
MLIRContext *context;
651661
ModuleOp module;
@@ -1209,6 +1219,41 @@ class Parser {
12091219
return builder.buildDclFunctionTable(*index, functions, loc);
12101220
}
12111221

1222+
FailureOr<Instruction> parseDclInterface(uint32_t opcodeToken, Location loc) {
1223+
bool isDynamic = DECODE_D3D11_SB_INTERFACE_INDEXED_BIT(opcodeToken);
1224+
auto access = dxsa::symbolizeInterfaceAccess(isDynamic);
1225+
assert(access && "unhandled interface access kind"); // access kind is 1 bit
1226+
1227+
// Index of the interface (start index for an array).
1228+
Token index = parseToken();
1229+
FAILURE_IF_FAILED(index);
1230+
1231+
// Expected function table length.
1232+
Token tableLength = parseToken();
1233+
FAILURE_IF_FAILED(tableLength);
1234+
1235+
Token interfaceArrayLength = parseToken();
1236+
FAILURE_IF_FAILED(interfaceArrayLength);
1237+
1238+
// Number of call sites.
1239+
uint32_t interfaceLength =
1240+
DECODE_D3D11_SB_INTERFACE_TABLE_LENGTH(*interfaceArrayLength);
1241+
1242+
// Number of interfaces.
1243+
uint32_t arrayLength =
1244+
DECODE_D3D11_SB_INTERFACE_ARRAY_LENGTH(*interfaceArrayLength);
1245+
1246+
SmallVector<int32_t, 16> tables;
1247+
tables.resize(interfaceLength);
1248+
for (uint32_t i = 0; i < interfaceLength; ++i) {
1249+
Token tableIndex = parseToken();
1250+
FAILURE_IF_FAILED(tableIndex);
1251+
tables[i] = *tableIndex;
1252+
}
1253+
1254+
return builder.buildDclInterface(*index, *access, arrayLength, *tableLength, tables, loc);
1255+
}
1256+
12121257
OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc,
12131258
Instruction &out) {
12141259
FailureOr<Instruction> result;
@@ -1261,6 +1306,9 @@ class Parser {
12611306
case D3D11_SB_OPCODE_DCL_FUNCTION_TABLE:
12621307
result = parseDclFunctionTable(loc);
12631308
break;
1309+
case D3D11_SB_OPCODE_DCL_INTERFACE:
1310+
result = parseDclInterface(opcodeToken, loc);
1311+
break;
12641312
default:
12651313
return std::nullopt;
12661314
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_interface.bin | FileCheck %s
2+
3+
// CHECK-LABEL: module
4+
5+
// dcl_interface fp0[253][1] = {ft0, ft1}
6+
// CHECK-NEXT: dxsa.dcl_interface 0, <access = dynamic, array_length = 253, table_length = 1>, [0, 1]
7+
8+
// dcl_interface_dynamicindexed fp0[253][1] = {ft0, ft1}
9+
// CHECK-NEXT: dxsa.dcl_interface 0, <access = immediate, array_length = 253, table_length = 1>, [0, 1]
48 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)