diff --git a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td index 7f88dbb3c8b3..fdd44072735d 100644 --- a/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td +++ b/mlir/include/mlir/Dialect/DXSA/IR/DXSAOps.td @@ -73,6 +73,26 @@ def DXSA_TessellatorOutputPrimitiveTypeAttr : let assemblyFormat = "$value"; } +def DXSA_OutputPrimitiveTopology_PointList : I32EnumAttrCase<"pointlist", 1>; +def DXSA_OutputPrimitiveTopology_LineStrip : I32EnumAttrCase<"linestrip", 3>; +def DXSA_OutputPrimitiveTopology_TriangleStrip : I32EnumAttrCase<"trianglestrip", 5>; + +def DXSA_OutputPrimitiveTopology : I32EnumAttr< + "OutputPrimitiveTopology", "shader output primitive topology", [ + DXSA_OutputPrimitiveTopology_PointList, + DXSA_OutputPrimitiveTopology_LineStrip, + DXSA_OutputPrimitiveTopology_TriangleStrip + ]> { + let cppNamespace = "::mlir::dxsa"; + let genSpecializedAttr = 0; +} + +def DXSA_OutputPrimitiveTopologyAttr : + EnumAttr { + let assemblyFormat = "$value"; +} + //===----------------------------------------------------------------------===// // DXSA op definitions //===----------------------------------------------------------------------===// @@ -235,4 +255,20 @@ def DXSA_DclTessellatorOutputPrimitive let assemblyFormat = "$type attr-dict"; } +def DXSA_DclOutputTopology : DXSA_Op<"dcl_output_topology"> { + let summary = "declare what primitive topology the shader generates as output"; + let description = [{ + The `dxsa.dcl_output_topology` operation declares the primitive topology + that the shader generates as output. + + Example: + + ```mlir + dxsa.dcl_output_topology trianglestrip + ``` + }]; + let arguments = (ins DXSA_OutputPrimitiveTopologyAttr:$topology); + let assemblyFormat = "$topology attr-dict"; +} + #endif // DXSA_OPS diff --git a/mlir/lib/Target/DXSA/BinaryParser.cpp b/mlir/lib/Target/DXSA/BinaryParser.cpp index bc3f437d3f6d..f5a2dbf3623f 100644 --- a/mlir/lib/Target/DXSA/BinaryParser.cpp +++ b/mlir/lib/Target/DXSA/BinaryParser.cpp @@ -538,6 +538,14 @@ class DXBuilder { outputPrimitiveTypeAttr); } + Instruction + buildDclOutputTopology(dxsa::OutputPrimitiveTopology outputTopology, + Location loc) { + auto outputTopologyAttr = dxsa::OutputPrimitiveTopologyAttr::get( + builder.getContext(), outputTopology); + return dxsa::DclOutputTopology::create(builder, loc, outputTopologyAttr); + } + private: MLIRContext *context; ModuleOp module; @@ -913,6 +921,18 @@ class Parser { loc); } + FailureOr parseDclOutputTopology(uint32_t opcodeToken, + Location loc) { + auto rawOutputTopology = + DECODE_D3D10_SB_GS_OUTPUT_PRIMITIVE_TOPOLOGY(opcodeToken); + auto outputTopology = + dxsa::symbolizeOutputPrimitiveTopology(rawOutputTopology); + if (!outputTopology) + return emitError(loc, "unknown output primitive topology: ") + << rawOutputTopology; + return builder.buildDclOutputTopology(*outputTopology, loc); + } + OptionalParseResult parseDclInstruction(uint32_t opcodeToken, Location loc, Instruction &out) { FailureOr result; @@ -932,6 +952,9 @@ class Parser { case D3D11_SB_OPCODE_DCL_TESS_OUTPUT_PRIMITIVE: result = parseDclTessellatorOutputPrimitive(opcodeToken, loc); break; + case D3D10_SB_OPCODE_DCL_GS_OUTPUT_PRIMITIVE_TOPOLOGY: + result = parseDclOutputTopology(opcodeToken, loc); + break; default: return std::nullopt; } diff --git a/mlir/test/Target/DXSA/dcl_output_topology.mlir b/mlir/test/Target/DXSA/dcl_output_topology.mlir new file mode 100644 index 000000000000..62ff373d0974 --- /dev/null +++ b/mlir/test/Target/DXSA/dcl_output_topology.mlir @@ -0,0 +1,7 @@ +// RUN: mlir-translate --import-dxsa-bin %S/inputs/dcl_output_topology.bin | FileCheck %s + +// CHECK: module { +// CHECK-NEXT: dxsa.dcl_output_topology pointlist +// CHECK-NEXT: dxsa.dcl_output_topology linestrip +// CHECK-NEXT: dxsa.dcl_output_topology trianglestrip +// CHECK-NEXT: } diff --git a/mlir/test/Target/DXSA/inputs/dcl_output_topology.bin b/mlir/test/Target/DXSA/inputs/dcl_output_topology.bin new file mode 100644 index 000000000000..4cf2a4c69e85 Binary files /dev/null and b/mlir/test/Target/DXSA/inputs/dcl_output_topology.bin differ