From a963016d7ee47153e864235adaa131c47c10a9b0 Mon Sep 17 00:00:00 2001 From: Vladimir Shiryaev Date: Thu, 30 Apr 2026 21:41:49 -0700 Subject: [PATCH] [mlir][dxsa] Add dcl_input_control_point_count and dcl_output_control_point_count instructions Example: dxsa.dcl_input_control_point_count 3 dxsa.dcl_output_control_point_count 4 Signed-off-by: Vladimir Shiryaev --- mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td | 40 +++++++++++++++ mlir/lib/Target/DXSA/BinaryParser.cpp | 46 +++++++++++++++++- .../DXSA/dcl_input_control_point_count.mlir | 8 +++ ...dcl_input_control_point_count_invalid.mlir | 14 ++++++ .../DXSA/dcl_output_control_point_count.mlir | 8 +++ ...cl_output_control_point_count_invalid.mlir | 9 ++++ .../inputs/dcl_input_control_point_count.bin | Bin 0 -> 16 bytes .../inputs/dcl_output_control_point_count.bin | Bin 0 -> 16 bytes 8 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 mlir/test/Target/DXSA/dcl_input_control_point_count.mlir create mode 100644 mlir/test/Target/DXSA/dcl_input_control_point_count_invalid.mlir create mode 100644 mlir/test/Target/DXSA/dcl_output_control_point_count.mlir create mode 100644 mlir/test/Target/DXSA/dcl_output_control_point_count_invalid.mlir create mode 100644 mlir/test/Target/DXSA/inputs/dcl_input_control_point_count.bin create mode 100644 mlir/test/Target/DXSA/inputs/dcl_output_control_point_count.bin diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index 5039217ee07b..35b7642bc4c3 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -158,4 +158,44 @@ def DXSA_DclTemps : DXSA_Op<"dcl_temps"> { let assemblyFormat = [{ $count attr-dict }]; } +def DXSA_DclInputControlPointCount : + DXSA_Op<"dcl_input_control_point_count"> { + let summary = "declares the hull shader input control point count"; + let description = [{ + The `dxsa.dcl_input_control_point_count` operation declares the number of + input control points for the hull shader. + + The count must be in [1, 32]. + + Example: + + ```mlir + dxsa.dcl_input_control_point_count 3 + ``` + }]; + let arguments = (ins ConfinedAttr]>:$count); + let assemblyFormat = [{ $count attr-dict }]; +} + +def DXSA_DclOutputControlPointCount : + DXSA_Op<"dcl_output_control_point_count"> { + let summary = "declares the hull shader output control point count"; + let description = [{ + The `dxsa.dcl_output_control_point_count` operation declares the number + of output control points for the hull shader. + + The count must be in [0, 32]. + + Example: + + ```mlir + dxsa.dcl_output_control_point_count 4 + ``` + }]; + let arguments = (ins ConfinedAttr]>:$count); + let assemblyFormat = [{ $count attr-dict }]; +} + #endif // DXSA_OPS diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index 2ac6629e6d75..2cb602c4327e 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -19,7 +19,11 @@ #include -#include "d3d12TokenizedProgramFormat.hpp" +// d3d12TokenizedProgramFormat.hpp references the `UINT` type in some DECODE_* +// macros. Mirror the Windows SDK alias (`typedef unsigned int UINT`) to use the +// header without modification. +using UINT = unsigned int; +#include "d3d12TokenizedProgramFormat.hpp" // NOLINT #define DEBUG_TYPE "import-dxsa-bin" @@ -516,6 +520,16 @@ class DXBuilder { builder.getI32IntegerAttr(count)); } + Instruction buildDclInputControlPointCount(uint32_t count, Location loc) { + return dxsa::DclInputControlPointCount::create( + builder, loc, builder.getI32IntegerAttr(count)); + } + + Instruction buildDclOutputControlPointCount(uint32_t count, Location loc) { + return dxsa::DclOutputControlPointCount::create( + builder, loc, builder.getI32IntegerAttr(count)); + } + private: MLIRContext *context; ModuleOp module; @@ -831,6 +845,30 @@ class Parser { return builder.buildDclTemps(count, loc); } + FailureOr parseDclInputControlPointCount(uint32_t opcodeToken, + Location loc) { + auto count = DECODE_D3D11_SB_INPUT_CONTROL_POINT_COUNT(opcodeToken); + if (count == 0) { + emitError(loc, "input control point count cannot be zero"); + return failure(); + } + if (count > 32) { + emitError(loc, "input control point count must be <= 32, got ") << count; + return failure(); + } + return builder.buildDclInputControlPointCount(count, loc); + } + + FailureOr parseDclOutputControlPointCount(uint32_t opcodeToken, + Location loc) { + auto count = DECODE_D3D11_SB_OUTPUT_CONTROL_POINT_COUNT(opcodeToken); + if (count > 32) { + emitError(loc, "output control point count must be <= 32, got ") << count; + return failure(); + } + return builder.buildDclOutputControlPointCount(count, loc); + } + OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc, Instruction &out) { FailureOr result; @@ -841,6 +879,12 @@ class Parser { case D3D10_SB_OPCODE_DCL_TEMPS: result = parseDclTemps(loc); break; + case D3D11_SB_OPCODE_DCL_INPUT_CONTROL_POINT_COUNT: + result = parseDclInputControlPointCount(opcodeToken, loc); + break; + case D3D11_SB_OPCODE_DCL_OUTPUT_CONTROL_POINT_COUNT: + result = parseDclOutputControlPointCount(opcodeToken, loc); + break; default: return std::nullopt; } diff --git a/mlir/test/Target/DXSA/dcl_input_control_point_count.mlir b/mlir/test/Target/DXSA/dcl_input_control_point_count.mlir new file mode 100644 index 000000000000..0021300a7110 --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_input_control_point_count.mlir @@ -0,0 +1,8 @@ +// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_input_control_point_count.bin | FileCheck %s + +// CHECK: module { +// CHECK-NEXT: dxsa.dcl_input_control_point_count 1 +// CHECK-NEXT: dxsa.dcl_input_control_point_count 3 +// CHECK-NEXT: dxsa.dcl_input_control_point_count 16 +// CHECK-NEXT: dxsa.dcl_input_control_point_count 32 +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/dcl_input_control_point_count_invalid.mlir b/mlir/test/Target/DXSA/dcl_input_control_point_count_invalid.mlir new file mode 100644 index 000000000000..60d429c04b11 --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_input_control_point_count_invalid.mlir @@ -0,0 +1,14 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +// expected-error@+1 {{attribute 'count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 32}} +dxsa.dcl_input_control_point_count -1 + +// ----- + +// expected-error@+1 {{attribute 'count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 32}} +dxsa.dcl_input_control_point_count 0 + +// ----- + +// expected-error@+1 {{attribute 'count' failed to satisfy constraint: 32-bit signless integer attribute whose value is positive whose maximum value is 32}} +dxsa.dcl_input_control_point_count 33 diff --git a/mlir/test/Target/DXSA/dcl_output_control_point_count.mlir b/mlir/test/Target/DXSA/dcl_output_control_point_count.mlir new file mode 100644 index 000000000000..039b866dd75c --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_output_control_point_count.mlir @@ -0,0 +1,8 @@ +// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_output_control_point_count.bin | FileCheck %s + +// CHECK: module { +// CHECK-NEXT: dxsa.dcl_output_control_point_count 0 +// CHECK-NEXT: dxsa.dcl_output_control_point_count 1 +// CHECK-NEXT: dxsa.dcl_output_control_point_count 4 +// CHECK-NEXT: dxsa.dcl_output_control_point_count 32 +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/dcl_output_control_point_count_invalid.mlir b/mlir/test/Target/DXSA/dcl_output_control_point_count_invalid.mlir new file mode 100644 index 000000000000..1770126d227c --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_output_control_point_count_invalid.mlir @@ -0,0 +1,9 @@ +// RUN: mlir-opt %s -split-input-file -verify-diagnostics + +// expected-error@+1 {{attribute 'count' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 32}} +dxsa.dcl_output_control_point_count -1 + +// ----- + +// expected-error@+1 {{attribute 'count' failed to satisfy constraint: 32-bit signless integer attribute whose value is non-negative whose maximum value is 32}} +dxsa.dcl_output_control_point_count 33 diff --git a/mlir/test/Target/DXSA/inputs/dcl_input_control_point_count.bin b/mlir/test/Target/DXSA/inputs/dcl_input_control_point_count.bin new file mode 100644 index 0000000000000000000000000000000000000000..c44a9fa34acdeb5c703dde3afaad3870eccb81b4 GIT binary patch literal 16 UcmbQt!N53K0*D)cn1PWI030R)@&Et; literal 0 HcmV?d00001 diff --git a/mlir/test/Target/DXSA/inputs/dcl_output_control_point_count.bin b/mlir/test/Target/DXSA/inputs/dcl_output_control_point_count.bin new file mode 100644 index 0000000000000000000000000000000000000000..66505edc7b862bd763f5396436797b70149bc668 GIT binary patch literal 16 UcmbQjz`!_#1BexXn1PWI02qb>egFUf literal 0 HcmV?d00001