From 97fccf15f9ea03e1a8dafb1403ef825cb34ba1ee Mon Sep 17 00:00:00 2001 From: Andrew Savonichev Date: Sat, 30 May 2026 00:39:52 +0900 Subject: [PATCH] [mlir][dxsa] Add interface_call --- mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td | 29 ++++++++++++++++++ mlir/lib/Target/DXSA/BinaryParser.cpp | 24 +++++++++++++++ .../Target/DXSA/inputs/interface_call.bin | Bin 0 -> 24 bytes mlir/test/Target/DXSA/interface_call.mlir | 10 ++++++ .../Target/DXSA/interface_call_invalid.mlir | 12 ++++++++ 5 files changed, 75 insertions(+) create mode 100644 mlir/test/Target/DXSA/inputs/interface_call.bin create mode 100644 mlir/test/Target/DXSA/interface_call.mlir create mode 100644 mlir/test/Target/DXSA/interface_call_invalid.mlir diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index 33055b8991dc..39952328834a 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -1072,4 +1072,33 @@ def DXSA_DclStream : DXSA_Op<"dcl_stream"> { let assemblyFormat = [{ $index attr-dict }]; } +def DXSA_InterfaceCall : DXSA_Op<"interface_call"> { + let summary = "interface function call (fcall)"; + let description = [{ + Call the function body at the following location: + - Interface `operand` selects a function table from an interface. + - `call_site` is an immediate unsigned integer offset into the selected + function table, selecting a function body # to execute. + + If the interface is declared with `access = dynamic` attribute, the operand + can use relative indexing. + + Example: + ```mlir + module { + %0 = dxsa.index.imm {imm = 0 : i32} + %1 = dxsa.index.imm {imm = 0 : i32} + %2 = dxsa.operand %1 {num_components = 4 : i32, one = 0 : i32, type = 0 : i32} + %3 = dxsa.index.rel %2 + %4 = dxsa.operand %0, %3 {num_components = 0 : i32, type = 19 : i32} + dxsa.interface_call %4, + } + ``` + }]; + let arguments = (ins DXSA_OperandType:$operand, ConfinedAttr:$call_site); + let assemblyFormat = [{ $operand `,` `<` + `call_site` `=` $call_site `>` attr-dict + }]; +} + #endif // DXSA_OPS diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index 0e0e38c70fa1..9c515af8af22 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -733,6 +733,11 @@ class DXBuilder { optionalToAttr(space)); } + Instruction buildInterfaceCall(Operand operand, uint32_t callSite, + Location loc) { + return dxsa::InterfaceCall::create(builder, loc, operand, callSite); + } + private: MLIRContext *context; ModuleOp module; @@ -1476,6 +1481,22 @@ class Parser { return builder.buildDclSampler(id, lbound, ubound, space, *mode, loc); } + FailureOr parseInterfaceCall(uint32_t opcodeToken, + Location loc) { + if (DECODE_IS_D3D10_SB_OPCODE_EXTENDED(opcodeToken)) { + return emitError(getLocation(), + "extended interface calls are not supported"); + } + + auto callSite = parseToken(); + FAILURE_IF_FAILED(callSite); + + auto operand = parseOperand(); + FAILURE_IF_FAILED(operand); + + return builder.buildInterfaceCall(*operand, *callSite, loc); + } + OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc, Instruction &out) { FailureOr result; @@ -1567,6 +1588,9 @@ class Parser { case D3D10_SB_OPCODE_DCL_SAMPLER: result = parseDclSampler(opcodeToken, loc); break; + case D3D11_SB_OPCODE_INTERFACE_CALL: + result = parseInterfaceCall(opcodeToken, loc); + break; default: return std::nullopt; } diff --git a/mlir/test/Target/DXSA/inputs/interface_call.bin b/mlir/test/Target/DXSA/inputs/interface_call.bin new file mode 100644 index 0000000000000000000000000000000000000000..186f57a63b686b7d2b9d3483e7a97d800135082a GIT binary patch literal 24 Xcmb +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/interface_call_invalid.mlir b/mlir/test/Target/DXSA/interface_call_invalid.mlir new file mode 100644 index 000000000000..278778978a3a --- /dev/null +++ b/mlir/test/Target/DXSA/interface_call_invalid.mlir @@ -0,0 +1,12 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +module { + %0 = dxsa.index.imm {imm = 0 : i32} + %1 = dxsa.index.imm {imm = 0 : i32} + %2 = dxsa.operand %1 {num_components = 4 : i32, one = 0 : i32, type = 0 : i32} + %3 = dxsa.index.rel %2 + %4 = dxsa.operand %0, %3 {num_components = 0 : i32, type = 19 : i32} + + // expected-error@+1 {{attribute 'call_site' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative}} + dxsa.interface_call %4, +}