From 9613125a481baeac540e876f295a2189c3e0510b Mon Sep 17 00:00:00 2001 From: Vladimir Shiryaev Date: Wed, 27 May 2026 19:00:23 -0700 Subject: [PATCH] [mlir][dxsa] Add dcl_resource_structured instruction Example: dxsa.dcl_resource_structured dxsa.dcl_resource_structured Signed-off-by: Vladimir Shiryaev --- mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td | 30 +++++++++++ mlir/lib/Dialect/DXSA/IR/DXSA.cpp | 13 +++++ mlir/lib/Target/DXSA/BinaryParser.cpp | 48 ++++++++++++++++++ .../Target/DXSA/dcl_resource_structured.mlir | 6 +++ .../DXSA/dcl_resource_structured_invalid.mlir | 14 +++++ .../DXSA/inputs/dcl_resource_structured.bin | Bin 0 -> 44 bytes 6 files changed, 111 insertions(+) create mode 100644 mlir/test/Target/DXSA/dcl_resource_structured.mlir create mode 100644 mlir/test/Target/DXSA/dcl_resource_structured_invalid.mlir create mode 100644 mlir/test/Target/DXSA/inputs/dcl_resource_structured.bin diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index 9d26894db8c5..88123b69a1b3 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -922,4 +922,34 @@ def DXSA_DclTgsmStructured : DXSA_Op<"dcl_tgsm_structured"> { let hasVerifier = 1; } +def DXSA_DclResourceStructured : DXSA_Op<"dcl_resource_structured"> { + let summary = "declares a structured buffer shader input resource bound to a register"; + let description = [{ + The `dxsa.dcl_resource_structured` operation declares a structured + buffer shader input resource bound to a register. + + Example: + + ```mlir + dxsa.dcl_resource_structured + dxsa.dcl_resource_structured + + ``` + }]; + + let arguments = (ins + I32Attr:$id, + ConfinedAttr:$struct_byte_stride, + OptionalAttr:$lbound, + OptionalAttr:$ubound, + OptionalAttr:$space); + let assemblyFormat = [{ + ` ` `<` `id` `=` $id `,` `struct_byte_stride` `=` $struct_byte_stride + (`,` `lbound` `=` $lbound^ `,` `ubound` `=` $ubound + `,` `space` `=` $space)? `>` + attr-dict + }]; + let hasVerifier = 1; +} + #endif // DXSA_OPS diff --git a/mlir/lib/Dialect/DXSA/IR/DXSA.cpp b/mlir/lib/Dialect/DXSA/IR/DXSA.cpp index f703a32e48ea..0fccf76abeea 100644 --- a/mlir/lib/Dialect/DXSA/IR/DXSA.cpp +++ b/mlir/lib/Dialect/DXSA/IR/DXSA.cpp @@ -84,6 +84,19 @@ LogicalResult DclTgsmStructured::verify() { return success(); } +LogicalResult DclResourceStructured::verify() { + auto stride = getStructByteStride(); + if (stride % 4 != 0) + return emitOpError("struct byte stride must be a multiple of 4, got ") + << stride; + auto lbound = getLbound(); + auto ubound = getUbound(); + if (lbound && ubound && *lbound > *ubound) + return emitOpError("expected lbound <= ubound, got lbound=") + << *lbound << ", ubound=" << *ubound; + return success(); +} + //===----------------------------------------------------------------------===// // TableGen'd attribute method definitions //===----------------------------------------------------------------------===// diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index 1ac5161fbb96..2971218b5acd 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -692,6 +692,19 @@ class DXBuilder { builder.getI32IntegerAttr(structCount)); } + Instruction buildDclResourceStructured(uint32_t id, uint32_t structByteStride, + std::optional lbound, + std::optional ubound, + std::optional space, + Location loc) { + auto toAttr = [&](std::optional v) -> IntegerAttr { + return v ? builder.getI32IntegerAttr(*v) : IntegerAttr(); + }; + return dxsa::DclResourceStructured::create(builder, loc, id, + structByteStride, toAttr(lbound), + toAttr(ubound), toAttr(space)); + } + private: MLIRContext *context; ModuleOp module; @@ -1317,6 +1330,38 @@ class Parser { *structCount, loc); } + FailureOr parseDclResourceStructured(Location loc) { + auto operand = parseInlineOperand(); + FAILURE_IF_FAILED(operand); + if (operand->getType() != dxsa::InlineOperandType::resource) + return emitError(loc, "operand must be a resource register, got ") + << dxsa::stringifyInlineOperandType(operand->getType()); + auto indexArray = operand->getIndex(); + auto indexDim = indexArray ? indexArray.size() : 0; + if (indexDim != 1 && indexDim != 3) + return emitError(loc, "operand must have a 1D or 3D index, got ") + << indexDim; + auto id = indexArray[0]; + std::optional lbound, ubound; + if (indexDim == 3) { + lbound = indexArray[1]; + ubound = indexArray[2]; + } + + auto strideToken = parseToken(); + FAILURE_IF_FAILED(strideToken); + + std::optional space; + if (indexDim == 3) { + auto spaceToken = parseToken(); + FAILURE_IF_FAILED(spaceToken); + space = *spaceToken; + } + + return builder.buildDclResourceStructured(id, *strideToken, lbound, ubound, + space, loc); + } + OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc, Instruction &out) { FailureOr result; @@ -1393,6 +1438,9 @@ class Parser { case D3D11_SB_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: result = parseDclTgsmStructured(loc); break; + case D3D11_SB_OPCODE_DCL_RESOURCE_STRUCTURED: + result = parseDclResourceStructured(loc); + break; default: return std::nullopt; } diff --git a/mlir/test/Target/DXSA/dcl_resource_structured.mlir b/mlir/test/Target/DXSA/dcl_resource_structured.mlir new file mode 100644 index 000000000000..de0258bc8f12 --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_resource_structured.mlir @@ -0,0 +1,6 @@ +// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_resource_structured.bin | FileCheck %s + +// CHECK: module { +// CHECK-NEXT: dxsa.dcl_resource_structured +// CHECK-NEXT: dxsa.dcl_resource_structured +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/dcl_resource_structured_invalid.mlir b/mlir/test/Target/DXSA/dcl_resource_structured_invalid.mlir new file mode 100644 index 000000000000..f5e5e56c729b --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_resource_structured_invalid.mlir @@ -0,0 +1,14 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +// expected-error@+1 {{'dxsa.dcl_resource_structured' op struct byte stride must be a multiple of 4, got 6}} +dxsa.dcl_resource_structured + +// ----- + +// expected-error@+1 {{attribute 'struct_byte_stride' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive}} +dxsa.dcl_resource_structured + +// ----- + +// expected-error@+1 {{'dxsa.dcl_resource_structured' op expected lbound <= ubound, got lbound=5, ubound=3}} +dxsa.dcl_resource_structured diff --git a/mlir/test/Target/DXSA/inputs/dcl_resource_structured.bin b/mlir/test/Target/DXSA/inputs/dcl_resource_structured.bin new file mode 100644 index 0000000000000000000000000000000000000000..c01d68c2b717de2702748537a634b919e4f64960 GIT binary patch literal 44 ncmZ3)z`(*#Ai%)Pz`!5?#ETdh*cl28fGh|Ai7NmxBM<`sR6_!% literal 0 HcmV?d00001