Skip to content

Commit f78359c

Browse files
authored
[mlir][spirv] Add definition for OpEmitVertex and OpEndPrimitive (#123759)
This is hopefully the first patch in the series of patches adding some missing SPIR-V ops to MLIR over the next weeks/months, starting with something simple: `OpEmitVertex` and `OpEndPrimitive`. Since the ops have no input and outputs, and the only condition is "This instruction must only be used when only one stream is present.", which I don't think can be validate at the instruction level in isolation, I set `hasVerifier` to 0. I hope I didn't miss anything, but I'm more than happy to address any comments.
1 parent 8e79ade commit f78359c

File tree

6 files changed

+148
-4
lines changed

6 files changed

+148
-4
lines changed

mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4438,6 +4438,8 @@ def SPIRV_OC_OpBitFieldSExtract : I32EnumAttrCase<"OpBitFieldSExtrac
44384438
def SPIRV_OC_OpBitFieldUExtract : I32EnumAttrCase<"OpBitFieldUExtract", 203>;
44394439
def SPIRV_OC_OpBitReverse : I32EnumAttrCase<"OpBitReverse", 204>;
44404440
def SPIRV_OC_OpBitCount : I32EnumAttrCase<"OpBitCount", 205>;
4441+
def SPIRV_OC_OpEmitVertex : I32EnumAttrCase<"OpEmitVertex", 218>;
4442+
def SPIRV_OC_OpEndPrimitive : I32EnumAttrCase<"OpEndPrimitive", 219>;
44414443
def SPIRV_OC_OpControlBarrier : I32EnumAttrCase<"OpControlBarrier", 224>;
44424444
def SPIRV_OC_OpMemoryBarrier : I32EnumAttrCase<"OpMemoryBarrier", 225>;
44434445
def SPIRV_OC_OpAtomicExchange : I32EnumAttrCase<"OpAtomicExchange", 229>;
@@ -4576,7 +4578,8 @@ def SPIRV_OpcodeAttr :
45764578
SPIRV_OC_OpBitwiseOr, SPIRV_OC_OpBitwiseXor, SPIRV_OC_OpBitwiseAnd,
45774579
SPIRV_OC_OpNot, SPIRV_OC_OpBitFieldInsert, SPIRV_OC_OpBitFieldSExtract,
45784580
SPIRV_OC_OpBitFieldUExtract, SPIRV_OC_OpBitReverse, SPIRV_OC_OpBitCount,
4579-
SPIRV_OC_OpControlBarrier, SPIRV_OC_OpMemoryBarrier, SPIRV_OC_OpAtomicExchange,
4581+
SPIRV_OC_OpEmitVertex, SPIRV_OC_OpEndPrimitive, SPIRV_OC_OpControlBarrier,
4582+
SPIRV_OC_OpMemoryBarrier, SPIRV_OC_OpAtomicExchange,
45804583
SPIRV_OC_OpAtomicCompareExchange, SPIRV_OC_OpAtomicCompareExchangeWeak,
45814584
SPIRV_OC_OpAtomicIIncrement, SPIRV_OC_OpAtomicIDecrement,
45824585
SPIRV_OC_OpAtomicIAdd, SPIRV_OC_OpAtomicISub, SPIRV_OC_OpAtomicSMin,
@@ -4609,9 +4612,8 @@ def SPIRV_OpcodeAttr :
46094612
SPIRV_OC_OpCooperativeMatrixLengthKHR, SPIRV_OC_OpSubgroupBlockReadINTEL,
46104613
SPIRV_OC_OpSubgroupBlockWriteINTEL, SPIRV_OC_OpAssumeTrueKHR,
46114614
SPIRV_OC_OpAtomicFAddEXT, SPIRV_OC_OpConvertFToBF16INTEL,
4612-
SPIRV_OC_OpConvertBF16ToFINTEL,
4613-
SPIRV_OC_OpControlBarrierArriveINTEL, SPIRV_OC_OpControlBarrierWaitINTEL,
4614-
SPIRV_OC_OpGroupIMulKHR,
4615+
SPIRV_OC_OpConvertBF16ToFINTEL, SPIRV_OC_OpControlBarrierArriveINTEL,
4616+
SPIRV_OC_OpControlBarrierWaitINTEL, SPIRV_OC_OpGroupIMulKHR,
46154617
SPIRV_OC_OpGroupFMulKHR
46164618
]>;
46174619

mlir/include/mlir/Dialect/SPIRV/IR/SPIRVOps.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ include "mlir/Dialect/SPIRV/IR/SPIRVMatrixOps.td"
4040
include "mlir/Dialect/SPIRV/IR/SPIRVMemoryOps.td"
4141
include "mlir/Dialect/SPIRV/IR/SPIRVMiscOps.td"
4242
include "mlir/Dialect/SPIRV/IR/SPIRVNonUniformOps.td"
43+
include "mlir/Dialect/SPIRV/IR/SPIRVPrimitiveOps.td"
4344
include "mlir/Dialect/SPIRV/IR/SPIRVCLOps.td"
4445
include "mlir/Dialect/SPIRV/IR/SPIRVStructureOps.td"
4546
include "mlir/Interfaces/SideEffectInterfaces.td"
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===-- SPIRVPrimitiveOps.td - MLIR SPIR-V Primitive Ops ------*- tablegen -*------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===------------------------------------------------------------------------------===//
8+
//
9+
// This file contains primitive ops for the SPIR-V dialect. It corresponds
10+
// to "3.52.19. Primitive Instructions" of the SPIR-V specification.
11+
//
12+
//===-----------------------------------------------------------------------------===//
13+
14+
#ifndef MLIR_DIALECT_SPIRV_PRIMITIVE_OPS
15+
#define MLIR_DIALECT_SPIRV_PRIMITIVE_OPS
16+
17+
include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"
18+
19+
// -----
20+
21+
def SPIRV_EmitVertexOp : SPIRV_Op<"EmitVertex", []> {
22+
let summary = [{
23+
Emits the current values of all output variables to the current output
24+
primitive. After execution, the values of all output variables are
25+
undefined.
26+
}];
27+
28+
let description = [{
29+
This instruction must only be used when only one stream is present.
30+
31+
#### Example:
32+
33+
```mlir
34+
spirv.EmitVertex
35+
```
36+
}];
37+
38+
let availability = [
39+
MinVersion<SPIRV_V_1_0>,
40+
MaxVersion<SPIRV_V_1_6>,
41+
Extension<[]>,
42+
Capability<[SPIRV_C_Geometry]>
43+
];
44+
45+
let arguments = (ins);
46+
let results = (outs);
47+
let hasVerifier = 0;
48+
let assemblyFormat = "attr-dict";
49+
}
50+
51+
// -----
52+
53+
def SPIRV_EndPrimitiveOp : SPIRV_Op<"EndPrimitive", []> {
54+
let summary = [{
55+
Finish the current primitive and start a new one. No vertex is emitted.
56+
}];
57+
58+
let description = [{
59+
This instruction must only be used when only one stream is present.
60+
61+
#### Example:
62+
63+
```mlir
64+
spirv.EndPrimitive
65+
```
66+
}];
67+
68+
let availability = [
69+
MinVersion<SPIRV_V_1_0>,
70+
MaxVersion<SPIRV_V_1_6>,
71+
Extension<[]>,
72+
Capability<[SPIRV_C_Geometry]>
73+
];
74+
75+
let arguments = (ins);
76+
let results = (outs);
77+
let hasVerifier = 0;
78+
let assemblyFormat = "attr-dict";
79+
}
80+
81+
#endif // MLIR_DIALECT_SPIRV_PRIMITIVE_OPS

mlir/test/Dialect/SPIRV/IR/availability.mlir

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,3 +233,25 @@ func.func @udot_acc_sat_vector_4xi16_i64(%a: vector<4xi16>, %acc: i64) -> i64 {
233233
%r = spirv.UDotAccSat %a, %a, %acc: vector<4xi16> -> i64
234234
return %r: i64
235235
}
236+
237+
//===----------------------------------------------------------------------===//
238+
// Primitive ops
239+
//===----------------------------------------------------------------------===//
240+
241+
// CHECK-LABEL: emit_vertex
242+
func.func @emit_vertex() -> () {
243+
// CHECK: min version: v1.0
244+
// CHECK: max version: v1.6
245+
// CHECK: capabilities: [ [Geometry] ]
246+
spirv.EmitVertex
247+
return
248+
}
249+
250+
// CHECK-LABEL: end_primitive
251+
func.func @end_primitive() -> () {
252+
// CHECK: min version: v1.0
253+
// CHECK: max version: v1.6
254+
// CHECK: capabilities: [ [Geometry] ]
255+
spirv.EndPrimitive
256+
return
257+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: mlir-opt %s | FileCheck %s
2+
3+
//===----------------------------------------------------------------------===//
4+
// spirv.EmitVertex
5+
//===----------------------------------------------------------------------===//
6+
7+
func.func @emit_vertex() {
8+
// CHECK: spirv.EmitVertex
9+
spirv.EmitVertex
10+
spirv.Return
11+
}
12+
13+
//===----------------------------------------------------------------------===//
14+
// spirv.EndPrimitive
15+
//===----------------------------------------------------------------------===//
16+
17+
func.func @end_primitive() {
18+
// CHECK: spirv.EndPrimitive
19+
spirv.EndPrimitive
20+
spirv.Return
21+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: mlir-translate --no-implicit-module --test-spirv-roundtrip %s | FileCheck %s
2+
3+
spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Geometry], []> {
4+
spirv.GlobalVariable @out : !spirv.ptr<!spirv.struct<(vector<4xf32>, f32, !spirv.array<1 x f32>)>, Output>
5+
spirv.func @primitive_ops() "None" {
6+
// CHECK: spirv.EmitVertex
7+
spirv.EmitVertex
8+
// CHECK: spirv.EndPrimitive
9+
spirv.EndPrimitive
10+
spirv.Return
11+
}
12+
spirv.EntryPoint "Geometry" @primitive_ops, @out
13+
spirv.ExecutionMode @primitive_ops "InputPoints"
14+
spirv.ExecutionMode @primitive_ops "Invocations", 1
15+
spirv.ExecutionMode @primitive_ops "OutputLineStrip"
16+
spirv.ExecutionMode @primitive_ops "OutputVertices", 2
17+
}

0 commit comments

Comments
 (0)