diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index 02047bbc544b..46059c1f748e 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -255,6 +255,23 @@ def DXSA_SystemValueNameAttr : let assemblyFormat = "$value"; } +def DXSA_InterfaceAccess_Immediate : I32EnumAttrCase<"immediate", 0>; +def DXSA_InterfaceAccess_Dynamic : I32EnumAttrCase<"dynamic", 1>; + +def DXSA_InterfaceAccess : I32EnumAttr< + "InterfaceAccess", "DXBC access kind for an interface", [ + DXSA_InterfaceAccess_Immediate, + DXSA_InterfaceAccess_Dynamic + ]> { + let cppNamespace = "::mlir::dxsa"; + let genSpecializedAttr = 0; +} + +def DXSA_InterfaceAccessAttr : + EnumAttr { + let assemblyFormat = "$value"; +} + //===----------------------------------------------------------------------===// // DXSA ComponentMask bit-enum (mask field of operand, normalized to bits 0..3) //===----------------------------------------------------------------------===// @@ -756,4 +773,28 @@ def DXSA_DclFunctionTable : DXSA_Op<"dcl_function_table"> { let hasVerifier = 1; } +def DXSA_DclInterface : DXSA_Op<"dcl_interface"> { + let summary = "declares function table pointers (interfaces)"; + let description = [{ + Declare an `array_length` of function table pointers (interfaces). Each + table can be bound at runtime, and it should contain `num_call_sites` + function bodies. + + Example: + ```mlir + dxsa.dcl_function_body 0 + dxsa.dcl_function_body 1 + dxsa.dcl_function_table 0, + dxsa.dcl_interface 1, + ``` + }]; + let arguments = (ins I32Attr:$index, DXSA_InterfaceAccessAttr:$access, I32Attr:$array_length, I32Attr:$num_call_sites, DenseI32ArrayAttr:$tables); + let assemblyFormat = [{ $index `,` `<` + `access` `=` $access `,` + `array_length` `=` $array_length `,` + `num_call_sites` `=` $num_call_sites `,` + `tables` `=` $tables `>` attr-dict + }]; +} + #endif // DXSA_OPS diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index 9ccd9413a93f..304e624395ed 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -646,6 +646,15 @@ class DXBuilder { builder, loc, index, DenseI32ArrayAttr::get(ctx, functions)); } + Instruction buildDclInterface(uint32_t index, dxsa::InterfaceAccess access, + uint32_t arrayLength, uint32_t numCallSites, + ArrayRef tables, Location loc) { + auto *ctx = builder.getContext(); + return dxsa::DclInterface::create(builder, loc, index, access, arrayLength, + numCallSites, + DenseI32ArrayAttr::get(ctx, tables)); + } + private: MLIRContext *context; ModuleOp module; @@ -1209,6 +1218,40 @@ class Parser { return builder.buildDclFunctionTable(*index, functions, loc); } + FailureOr parseDclInterface(uint32_t opcodeToken, Location loc) { + bool isDynamic = DECODE_D3D11_SB_INTERFACE_INDEXED_BIT(opcodeToken); + auto access = isDynamic ? dxsa::InterfaceAccess::dynamic + : dxsa::InterfaceAccess::immediate; + + // Index of the interface (start index for an array). + auto index = parseToken(); + FAILURE_IF_FAILED(index); + + // Number of call sites (number of bodies in each table). + auto numCallSites = parseToken(); + FAILURE_IF_FAILED(numCallSites); + + auto packedLenghts = parseToken(); + FAILURE_IF_FAILED(packedLenghts); + + // Number of tables (variants). + auto tableLength = DECODE_D3D11_SB_INTERFACE_TABLE_LENGTH(*packedLenghts); + + // Number of slots to be defined at runtime. + auto arrayLength = DECODE_D3D11_SB_INTERFACE_ARRAY_LENGTH(*packedLenghts); + + SmallVector tables; + tables.resize(tableLength); + for (uint32_t i = 0; i < tableLength; ++i) { + auto tableIndex = parseToken(); + FAILURE_IF_FAILED(tableIndex); + tables[i] = *tableIndex; + } + + return builder.buildDclInterface(*index, access, arrayLength, *numCallSites, + tables, loc); + } + OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc, Instruction &out) { FailureOr result; @@ -1261,6 +1304,9 @@ class Parser { case D3D11_SB_OPCODE_DCL_FUNCTION_TABLE: result = parseDclFunctionTable(loc); break; + case D3D11_SB_OPCODE_DCL_INTERFACE: + result = parseDclInterface(opcodeToken, loc); + break; default: return std::nullopt; } diff --git a/mlir/test/Target/DXSA/dcl_interface.mlir b/mlir/test/Target/DXSA/dcl_interface.mlir new file mode 100644 index 000000000000..868adef5d71c --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_interface.mlir @@ -0,0 +1,6 @@ +// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_interface.bin | FileCheck %s + +// CHECK-LABEL: module + +// CHECK-NEXT: dxsa.dcl_interface 0, +// CHECK-NEXT: dxsa.dcl_interface 0, diff --git a/mlir/test/Target/DXSA/inputs/dcl_interface.bin b/mlir/test/Target/DXSA/inputs/dcl_interface.bin new file mode 100644 index 000000000000..74141aed86e2 Binary files /dev/null and b/mlir/test/Target/DXSA/inputs/dcl_interface.bin differ