Skip to content

Commit 3d63662

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 d03dc8a commit 3d63662

4 files changed

Lines changed: 95 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
//===----------------------------------------------------------------------===//
@@ -754,4 +771,28 @@ def DXSA_DclFunctionTable : DXSA_Op<"dcl_function_table"> {
754771
let assemblyFormat = "$index `,` `<` `functions` `=` $functions `>` attr-dict";
755772
}
756773

774+
def DXSA_DclInterface : DXSA_Op<"dcl_interface"> {
775+
let summary = "declares function table pointers (interfaces)";
776+
let description = [{
777+
Declare an `array_length` of function table pointers (interfaces). Each
778+
table can be bound at runtime, and it should contain `table_length` function
779+
bodies.
780+
781+
Example:
782+
```mlir
783+
dxsa.dcl_function_body 0
784+
dxsa.dcl_function_body 1
785+
dxsa.dcl_function_table 0, <functions = [0, 1]>
786+
dxsa.dcl_interface 1, <access = dynamic, array_length = 1, table_length = 2, tables = [0]>
787+
```
788+
}];
789+
let arguments = (ins I32Attr:$index, DXSA_InterfaceAccessAttr:$access, I32Attr:$array_length, I32Attr:$table_length, DenseI32ArrayAttr:$tables);
790+
let assemblyFormat = [{ $index `,` `<`
791+
`access` `=` $access `,`
792+
`array_length` `=` $array_length `,`
793+
`table_length` `=` $table_length `,`
794+
`tables` `=` $tables `>` attr-dict
795+
}];
796+
}
797+
757798
#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,15 @@ class DXBuilder {
646646
builder, loc, index, DenseI32ArrayAttr::get(ctx, functions));
647647
}
648648

649+
Instruction buildDclInterface(uint32_t index, dxsa::InterfaceAccess access,
650+
uint32_t arrayLength, uint32_t tableLength,
651+
ArrayRef<int32_t> tables, Location loc) {
652+
auto *ctx = builder.getContext();
653+
return dxsa::DclInterface::create(builder, loc, index, access, arrayLength,
654+
tableLength,
655+
DenseI32ArrayAttr::get(ctx, tables));
656+
}
657+
649658
private:
650659
MLIRContext *context;
651660
ModuleOp module;
@@ -1209,6 +1218,42 @@ class Parser {
12091218
return builder.buildDclFunctionTable(*index, functions, loc);
12101219
}
12111220

1221+
FailureOr<Instruction> parseDclInterface(uint32_t opcodeToken, Location loc) {
1222+
bool isDynamic = DECODE_D3D11_SB_INTERFACE_INDEXED_BIT(opcodeToken);
1223+
auto access = dxsa::symbolizeInterfaceAccess(isDynamic);
1224+
assert(access && "unhandled interface access kind"); // access kind is 1 bit
1225+
1226+
// Index of the interface (start index for an array).
1227+
auto index = parseToken();
1228+
FAILURE_IF_FAILED(index);
1229+
1230+
// Number of call sites (number of bodies in each table).
1231+
auto tableLength = parseToken();
1232+
FAILURE_IF_FAILED(tableLength);
1233+
1234+
auto interfaceArrayLength = parseToken();
1235+
FAILURE_IF_FAILED(interfaceArrayLength);
1236+
1237+
// Number of tables (variants).
1238+
uint32_t interfaceLength =
1239+
DECODE_D3D11_SB_INTERFACE_TABLE_LENGTH(*interfaceArrayLength);
1240+
1241+
// Number of slots to be defined at runtime.
1242+
uint32_t arrayLength =
1243+
DECODE_D3D11_SB_INTERFACE_ARRAY_LENGTH(*interfaceArrayLength);
1244+
1245+
SmallVector<int32_t, 16> tables;
1246+
tables.resize(interfaceLength);
1247+
for (uint32_t i = 0; i < interfaceLength; ++i) {
1248+
auto tableIndex = parseToken();
1249+
FAILURE_IF_FAILED(tableIndex);
1250+
tables[i] = *tableIndex;
1251+
}
1252+
1253+
return builder.buildDclInterface(*index, *access, arrayLength, *tableLength,
1254+
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: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_interface.bin | FileCheck %s
2+
3+
// CHECK-LABEL: module
4+
5+
// CHECK-NEXT: dxsa.dcl_interface 0, <access = dynamic, array_length = 253, table_length = 1, tables = [0, 1]>
6+
// CHECK-NEXT: dxsa.dcl_interface 0, <access = immediate, array_length = 253, table_length = 1, tables = [0, 1]>
48 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)