diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index 9d26894db8c5..0e53bd636d86 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -922,4 +922,32 @@ def DXSA_DclTgsmStructured : DXSA_Op<"dcl_tgsm_structured"> { let hasVerifier = 1; } +def DXSA_DclResourceRaw : DXSA_Op<"dcl_resource_raw"> { + let summary = "declares a raw buffer shader input resource bound to a register"; + let description = [{ + The `dxsa.dcl_resource_raw` operation declares a raw buffer shader + input resource bound to a register. + + Example: + + ```mlir + dxsa.dcl_resource_raw + dxsa.dcl_resource_raw + ``` + }]; + + let arguments = (ins + I32Attr:$id, + OptionalAttr:$lbound, + OptionalAttr:$ubound, + OptionalAttr:$space); + let assemblyFormat = [{ + ` ` `<` `id` `=` $id + (`,` `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..1666985c3620 100644 --- a/mlir/lib/Dialect/DXSA/IR/DXSA.cpp +++ b/mlir/lib/Dialect/DXSA/IR/DXSA.cpp @@ -84,6 +84,15 @@ LogicalResult DclTgsmStructured::verify() { return success(); } +LogicalResult DclResourceRaw::verify() { + 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..173f20090c95 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -692,6 +692,16 @@ class DXBuilder { builder.getI32IntegerAttr(structCount)); } + Instruction buildDclResourceRaw(uint32_t id, 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::DclResourceRaw::create(builder, loc, id, toAttr(lbound), + toAttr(ubound), toAttr(space)); + } + private: MLIRContext *context; ModuleOp module; @@ -1317,6 +1327,30 @@ class Parser { *structCount, loc); } + FailureOr parseDclResourceRaw(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, space; + if (indexDim == 3) { + lbound = indexArray[1]; + ubound = indexArray[2]; + auto spaceToken = parseToken(); + FAILURE_IF_FAILED(spaceToken); + space = *spaceToken; + } + + return builder.buildDclResourceRaw(id, lbound, ubound, space, loc); + } + OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc, Instruction &out) { FailureOr result; @@ -1393,6 +1427,9 @@ class Parser { case D3D11_SB_OPCODE_DCL_THREAD_GROUP_SHARED_MEMORY_STRUCTURED: result = parseDclTgsmStructured(loc); break; + case D3D11_SB_OPCODE_DCL_RESOURCE_RAW: + result = parseDclResourceRaw(loc); + break; default: return std::nullopt; } diff --git a/mlir/test/Target/DXSA/dcl_resource_raw.mlir b/mlir/test/Target/DXSA/dcl_resource_raw.mlir new file mode 100644 index 000000000000..2f995af6543d --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_resource_raw.mlir @@ -0,0 +1,6 @@ +// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_resource_raw.bin | FileCheck %s + +// CHECK: module { +// CHECK-NEXT: dxsa.dcl_resource_raw +// CHECK-NEXT: dxsa.dcl_resource_raw +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/dcl_resource_raw_invalid.mlir b/mlir/test/Target/DXSA/dcl_resource_raw_invalid.mlir new file mode 100644 index 000000000000..8a56749ed793 --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_resource_raw_invalid.mlir @@ -0,0 +1,4 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +// expected-error@+1 {{'dxsa.dcl_resource_raw' op expected lbound <= ubound, got lbound=5, ubound=3}} +dxsa.dcl_resource_raw diff --git a/mlir/test/Target/DXSA/inputs/dcl_resource_raw.bin b/mlir/test/Target/DXSA/inputs/dcl_resource_raw.bin new file mode 100644 index 000000000000..75b720860cbc Binary files /dev/null and b/mlir/test/Target/DXSA/inputs/dcl_resource_raw.bin differ