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 000000000000..c44a9fa34acd Binary files /dev/null and b/mlir/test/Target/DXSA/inputs/dcl_input_control_point_count.bin differ 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 000000000000..66505edc7b86 Binary files /dev/null and b/mlir/test/Target/DXSA/inputs/dcl_output_control_point_count.bin differ