Skip to content

Commit b443fc4

Browse files
committed
[mlir][spirv] Add definition for selected sample operations
This commit adds following three operations: ImageSampleImplicitLodOp, ImageSampleExplicitLodOp and ImageSampleProjDrefImplicitLodOp
1 parent 8bea511 commit b443fc4

File tree

14 files changed

+982
-244
lines changed

14 files changed

+982
-244
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
add_subdirectory(IR)
2+
add_subdirectory(Interfaces)
23
add_subdirectory(Transforms)

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

Lines changed: 242 additions & 237 deletions
Large diffs are not rendered by default.

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

Lines changed: 215 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define MLIR_DIALECT_SPIRV_IR_IMAGE_OPS
1616

1717
include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"
18+
include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.td"
1819
include "mlir/Interfaces/SideEffectInterfaces.td"
1920

2021
// -----
@@ -51,10 +52,15 @@ class SPIRV_NoneOrElementMatchImage<string operand, string image, string transfo
5152
CPred<"::llvm::isa<NoneType>(cast<ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType()) ||"
5253
"(getElementTypeOrSelf($" # operand # ")"
5354
"=="
54-
"cast<ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType())"
55+
"cast<::mlir::spirv::ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType())"
5556
>
5657
>;
5758

59+
class SPIRV_ImageOperandIsPresent<string operand, list<string> values> : PredOpTrait<
60+
"either " # !interleave(values, " or ") # " image operands must be present",
61+
CPred<"::mlir::spirv::bitEnumContainsAny($" # operand # ", " # "::mlir::spirv::ImageOperands::" # !interleave(values, " | ::mlir::spirv::ImageOperands::") # ")">
62+
>;
63+
5864
def SPIRV_SampledImageTransform : StrFunc<"llvm::cast<spirv::SampledImageType>($_self).getImageType()">;
5965

6066
// -----
@@ -89,7 +95,7 @@ def SPIRV_ImageDrefGatherOp : SPIRV_Op<"ImageDrefGather",
8995

9096
```mlir
9197
%0 = spirv.ImageDrefGather %1, %2, %3 : !spirv.sampled_image<!spirv.image<i32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>>, vector<4xf32>, f32 -> vector<4xi32>
92-
%0 = spirv.ImageDrefGather %1, %2, %3 : !spirv.sampled_image<!spirv.image<i32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>>, vector<4xf32>, f32 ["NonPrivateTexel"] -> vector<4xi32>
98+
%0 = spirv.ImageDrefGather %1, %2, %3 ["NonPrivateTexel"] : !spirv.sampled_image<!spirv.image<i32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>>, vector<4xf32>, f32 -> vector<4xi32>
9399
```
94100
}];
95101

@@ -115,7 +121,7 @@ def SPIRV_ImageDrefGatherOp : SPIRV_Op<"ImageDrefGather",
115121

116122
let assemblyFormat = [{
117123
$sampled_image `,` $coordinate `,` $dref custom<ImageOperands>($image_operands) ( `(` $operand_arguments^ `)` )? attr-dict
118-
`:` type($sampled_image) `,` type($coordinate) `,` type($dref) ( `(` type($operand_arguments)^ `)` )?
124+
`:` type($sampled_image) `,` type($coordinate) `,` type($dref) ` ` ( `(` type($operand_arguments)^ `)` )?
119125
`->` type($result)
120126
}];
121127

@@ -227,7 +233,7 @@ def SPIRV_ImageWriteOp : SPIRV_Op<"ImageWrite",
227233

228234
let assemblyFormat = [{
229235
$image `,` $coordinate `,` $texel custom<ImageOperands>($image_operands) ( `(` $operand_arguments^ `)`)? attr-dict
230-
`:` type($image) `,` type($coordinate) `,` type($texel) ( `(` type($operand_arguments)^ `)`)?
236+
`:` type($image) `,` type($coordinate) `,` type($texel) ` ` ( `(` type($operand_arguments)^ `)`)?
231237
}];
232238
}
233239

@@ -268,4 +274,208 @@ def SPIRV_ImageOp : SPIRV_Op<"Image",
268274
let hasVerifier = 0;
269275
}
270276

271-
#endif // MLIR_DIALECT_SPIRV_IR_GL_OPS
277+
// -----
278+
279+
def SPIRV_ImageSampleExplicitLodOp : SPIRV_Op<"ImageSampleExplicitLod",
280+
[SPIRV_DimIsNot<"sampled_image", ["Buffer"], SPIRV_SampledImageTransform.result>,
281+
SPIRV_MSOperandIs<"sampled_image", ["SingleSampled"], SPIRV_SampledImageTransform.result>,
282+
SPIRV_NoneOrElementMatchImage<"result", "sampled_image", SPIRV_SampledImageTransform.result>,
283+
SPIRV_ImageOperandIsPresent<"image_operands", ["Lod", "Grad"]>,
284+
DeclareOpInterfaceMethods<SPIRV_ExplicitLodOpInterface>]> {
285+
let summary = "Sample an image using an explicit level of detail.";
286+
287+
let description = [{
288+
Result Type must be a vector of four components of floating-point type
289+
or integer type. Its components must be the same as Sampled Type of the
290+
underlying OpTypeImage (unless that underlying Sampled Type is
291+
OpTypeVoid).
292+
293+
Sampled Image must be an object whose type is OpTypeSampledImage. Its
294+
OpTypeImage must not have a Dim of Buffer. The MS operand of the
295+
underlying OpTypeImage must be 0.
296+
297+
Coordinate must be a scalar or vector of floating-point type or integer
298+
type. It contains (u[, v] ... [, array layer]) as needed by the
299+
definition of Sampled Image. Unless the Kernel capability is declared,
300+
it must be floating point. It may be a vector larger than needed, but
301+
all unused components appear after all used components.
302+
303+
Image Operands encodes what operands follow, as per Image Operands.
304+
Either Lod or Grad image operands must be present.
305+
306+
<!-- End of AutoGen section -->
307+
308+
#### Example:
309+
310+
```mlir
311+
%result = spirv.ImageSampleExplicitLod %image, %coord ["Lod"](%lod) : !spirv.sampled_image<!spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Unknown>>, vector<2xf32> (f32) -> vector<4xf32>
312+
```
313+
}];
314+
315+
let arguments = (ins
316+
SPIRV_AnySampledImage:$sampled_image,
317+
AnyTypeOf<[SPIRV_ScalarOrVectorOf<SPIRV_Float>, SPIRV_ScalarOrVectorOf<SPIRV_Integer>]>:$coordinate,
318+
SPIRV_ImageOperandsAttr:$image_operands,
319+
Variadic<SPIRV_Type>:$operand_arguments
320+
);
321+
322+
let results = (outs
323+
AnyTypeOf<[SPIRV_Vec4<SPIRV_Integer>, SPIRV_Vec4<SPIRV_Float>]>:$result
324+
);
325+
326+
let assemblyFormat = [{
327+
$sampled_image `,` $coordinate custom<ImageOperands>($image_operands) ( `(` $operand_arguments^ `)` )? attr-dict
328+
`:` type($sampled_image) `,` type($coordinate) ` ` ( `(` type($operand_arguments)^ `)` )?
329+
`->` type($result)
330+
}];
331+
}
332+
333+
// -----
334+
335+
def SPIRV_ImageSampleImplicitLodOp : SPIRV_Op<"ImageSampleImplicitLod",
336+
[SPIRV_DimIsNot<"sampled_image", ["Buffer"], SPIRV_SampledImageTransform.result>,
337+
SPIRV_MSOperandIs<"sampled_image", ["SingleSampled"], SPIRV_SampledImageTransform.result>,
338+
SPIRV_NoneOrElementMatchImage<"result", "sampled_image", SPIRV_SampledImageTransform.result>,
339+
DeclareOpInterfaceMethods<SPIRV_ImplicitLodOpInterface>]> {
340+
let summary = "Sample an image with an implicit level of detail.";
341+
342+
let description = [{
343+
An invocation will not execute a dynamic instance of this instruction
344+
(X') until all invocations in its derivative group have executed all
345+
dynamic instances that are program-ordered before X'.
346+
347+
Result Type must be a vector of four components of floating-point type
348+
or integer type. Its components must be the same as Sampled Type of the
349+
underlying OpTypeImage (unless that underlying Sampled Type is
350+
OpTypeVoid).
351+
352+
Sampled Image must be an object whose type is OpTypeSampledImage. Its
353+
OpTypeImage must not have a Dim of Buffer. The MS operand of the
354+
underlying OpTypeImage must be 0.
355+
356+
Coordinate must be a scalar or vector of floating-point type. It
357+
contains (u[, v] ... [, array layer]) as needed by the definition of
358+
Sampled Image. It may be a vector larger than needed, but all unused
359+
components appear after all used components.
360+
361+
Image Operands encodes what operands follow, as per Image Operands.
362+
363+
This instruction is only valid in the Fragment Execution Model. In
364+
addition, it consumes an implicit derivative that can be affected by
365+
code motion.
366+
367+
<!-- End of AutoGen section -->
368+
369+
#### Example:
370+
371+
```mlir
372+
%result = spirv.ImageSampleImplicitLod %image, %coord : !spirv.sampled_image<!spirv.image<f32, Cube, NoDepth, NonArrayed, SingleSampled, NeedSampler, Unknown>>, vector<3xf32> -> vector<4xf32>
373+
```
374+
}];
375+
376+
let availability = [
377+
MinVersion<SPIRV_V_1_0>,
378+
MaxVersion<SPIRV_V_1_6>,
379+
Extension<[]>,
380+
Capability<[SPIRV_C_Shader]>
381+
];
382+
383+
let arguments = (ins
384+
SPIRV_AnySampledImage:$sampled_image,
385+
SPIRV_ScalarOrVectorOf<SPIRV_Float>:$coordinate,
386+
OptionalAttr<SPIRV_ImageOperandsAttr>:$image_operands,
387+
Variadic<SPIRV_Type>:$operand_arguments
388+
);
389+
390+
let results = (outs
391+
AnyTypeOf<[SPIRV_Vec4<SPIRV_Integer>, SPIRV_Vec4<SPIRV_Float>]>:$result
392+
);
393+
394+
let assemblyFormat = [{
395+
$sampled_image `,` $coordinate custom<ImageOperands>($image_operands) ( `(` $operand_arguments^ `)` )? attr-dict
396+
`:` type($sampled_image) `,` type($coordinate) ` ` ( `(` type($operand_arguments)^ `)` )?
397+
`->` type($result)
398+
}];
399+
}
400+
401+
// -----
402+
403+
def SPIRV_ImageSampleProjDrefImplicitLodOp : SPIRV_Op<"ImageSampleProjDrefImplicitLod",
404+
[SPIRV_DimIsNot<"sampled_image", ["Buffer"], SPIRV_SampledImageTransform.result>,
405+
SPIRV_MSOperandIs<"sampled_image", ["SingleSampled"], SPIRV_SampledImageTransform.result>,
406+
TypesMatchWith<"type of 'result' matches image type of 'sampled_image'",
407+
"sampled_image", "result",
408+
"::llvm::cast<::mlir::spirv::ImageType>(::llvm::cast<spirv::SampledImageType>($_self).getImageType()).getElementType()">,
409+
DeclareOpInterfaceMethods<SPIRV_ImplicitLodOpInterface>]> {
410+
411+
let summary = [{
412+
Sample an image with a project coordinate, doing depth-comparison, with
413+
an implicit level of detail.
414+
}];
415+
416+
let description = [{
417+
An invocation will not execute a dynamic instance of this instruction
418+
(X') until all invocations in its derivative group have executed all
419+
dynamic instances that are program-ordered before X'.
420+
421+
Result Type must be a scalar of integer type or floating-point type. It
422+
must be the same as Sampled Type of the underlying OpTypeImage.
423+
424+
Sampled Image must be an object whose type is OpTypeSampledImage. The
425+
Dim operand of the underlying OpTypeImage must be 1D, 2D, 3D, or Rect,
426+
and the Arrayed and MS operands must be 0.
427+
428+
Coordinate must be a vector of floating-point type. It contains (u[,
429+
v] [, w], q), as needed by the definition of Sampled Image, with the q
430+
component consumed for the projective division. That is, the actual
431+
sample coordinate is (u/q [, v/q] [, w/q]), as needed by the definition
432+
of Sampled Image. It may be a vector larger than needed, but all unused
433+
components appear after all used components.
434+
435+
Dref/q is the depth-comparison reference value. Dref must be a 32-bit
436+
floating-point type scalar.
437+
438+
Image Operands encodes what operands follow, as per Image Operands.
439+
440+
This instruction is only valid in the Fragment Execution Model. In
441+
addition, it consumes an implicit derivative that can be affected by
442+
code motion.
443+
444+
<!-- End of AutoGen section -->
445+
446+
#### Example:
447+
448+
```mlir
449+
%result = spirv.ImageSampleProjDrefImplicitLod %image, %coord, %dref : !spirv.sampled_image<!spirv.image<f32, Dim2D, IsDepth, NonArrayed, SingleSampled, NeedSampler, Unknown>>, vector<4xf16>, f32 -> f32
450+
```
451+
}];
452+
453+
let availability = [
454+
MinVersion<SPIRV_V_1_0>,
455+
MaxVersion<SPIRV_V_1_6>,
456+
Extension<[]>,
457+
Capability<[SPIRV_C_Shader]>
458+
];
459+
460+
let arguments = (ins
461+
SPIRV_AnySampledImage:$sampled_image,
462+
AnyTypeOf<[SPIRV_ScalarOrVectorOf<SPIRV_Float>, SPIRV_ScalarOrVectorOf<SPIRV_Integer>]>:$coordinate,
463+
SPIRV_Float32:$dref,
464+
OptionalAttr<SPIRV_ImageOperandsAttr>:$image_operands,
465+
Variadic<SPIRV_Type>:$operand_arguments
466+
);
467+
468+
let results = (outs
469+
AnyTypeOf<[SPIRV_Integer, SPIRV_Float]>:$result
470+
);
471+
472+
let assemblyFormat = [{
473+
$sampled_image `,` $coordinate `,` $dref custom<ImageOperands>($image_operands) ( `(` $operand_arguments^ `)` )? attr-dict
474+
`:` type($sampled_image) `,` type($coordinate) `,` type($dref) ` ` ( `(` type($operand_arguments)^ `)` )?
475+
`->` type($result)
476+
}];
477+
}
478+
479+
// -----
480+
481+
#endif // MLIR_DIALECT_SPIRV_IR_IMAGE_OPS

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "mlir/Dialect/SPIRV/IR/SPIRVAttributes.h"
1818
#include "mlir/Dialect/SPIRV/IR/SPIRVOpTraits.h"
1919
#include "mlir/Dialect/SPIRV/IR/SPIRVTypes.h"
20+
#include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.h"
2021
#include "mlir/IR/BuiltinOps.h"
2122
#include "mlir/IR/OpImplementation.h"
2223
#include "mlir/Interfaces/CallInterfaces.h"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_mlir_interface(SPIRVImageInterfaces)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//===- SPIRVImageInterfaces.h -----------------------------------*- C++ -*-===//
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+
#ifndef MLIR_DIALECT_SPIRV_IMAGE_INTERFACES_H_
10+
#define MLIR_DIALECT_SPIRV_IMAGE_INTERFACES_H_
11+
12+
#include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.h.inc"
13+
14+
#endif // MLIR_DIALECT_SPIRV_IMAGE_INTERFACES_H_
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
//===-- SPIRVImageInterfaces.td - MLIR SPIR-V Image Interfaces ------*- 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 interfaces used by image operations.
10+
//
11+
//===------------------------------------------------------------------------------------===//
12+
13+
#ifndef MLIR_DIALECT_SPIRV_IMAGE_INTERFACES
14+
#define MLIR_DIALECT_SPIRV_IMAGE_INTERFACES
15+
16+
include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"
17+
18+
// -----
19+
20+
def SPIRV_SampleOpInterface : OpInterface<"SamplingOpInterface"> {
21+
let description = [{
22+
The `SampleOpInterface` defines sampling image operations (OpImage.*Sample.*)
23+
and provides interface methods to query operands common across all sampling
24+
instructions.
25+
26+
Currently only getters for sampled image and coordinate are provided. The
27+
default implementation will work as long as the instruction the interface is
28+
attached to uses standard names for the operands: $sampled_image and $coordinate.
29+
}];
30+
let cppNamespace = "::mlir::spirv";
31+
let methods = [
32+
InterfaceMethod<
33+
"Get SampledImage of the operation.",
34+
"::mlir::TypedValue<::mlir::Type>", "getSampledImage", (ins), [{
35+
return $_op.getSampledImage();
36+
}]>,
37+
InterfaceMethod<
38+
"Get Coordinate of the operation.",
39+
"::mlir::TypedValue<::mlir::Type>", "getCoordinate", (ins), [{
40+
return $_op.getCoordinate();
41+
}]>
42+
];
43+
}
44+
45+
// -----
46+
47+
def SPIRV_ExplicitLodOpInterface : OpInterface<"ExplicitLodOpInterface", [SPIRV_SampleOpInterface]> {
48+
let description = [{
49+
The `ExplicitLodOpInterface` defines explicit sampling lod operations (.*ExplicitLod). Currently
50+
the interface is only used to check whether the instruction is an explicit lod.
51+
}];
52+
let cppNamespace = "::mlir::spirv";
53+
}
54+
55+
// -----
56+
57+
def SPIRV_ImplicitLodOpInterface : OpInterface<"ImplicitLodOpInterface", [SPIRV_SampleOpInterface]> {
58+
let description = [{
59+
The `ImplicitLodOpInterface` defines implicit sampling lod operations (.*ImplicitLod). Currently
60+
the interface is only used to check whether the instruction is an implicit lod.
61+
}];
62+
let cppNamespace = "::mlir::spirv";
63+
}
64+
65+
// -----
66+
67+
def SPIRV_FetchOpInterface : OpInterface<"FetchOpInterface"> {
68+
let description = [{
69+
The `FetchOpInterface` defines fetch image operations (OpImageFetch and
70+
OpImageSpareFetch) and provides interface methods to query operands common
71+
across all fetch instructions.
72+
73+
Currently only a getter for image is provided. The default implementation
74+
will work as long as the instruction the interface is attached to uses
75+
standard names for the operands: $image.
76+
}];
77+
let cppNamespace = "::mlir::spirv";
78+
let methods = [
79+
InterfaceMethod<
80+
"Get Image of the operation.",
81+
"::mlir::TypedValue<::mlir::Type>", "getImage", (ins), [{
82+
return $_op.getImage();
83+
}]>
84+
];
85+
}
86+
87+
// -----
88+
89+
#endif // MLIR_DIALECT_SPIRV_IMAGE_INTERFACES

mlir/lib/Dialect/SPIRV/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
add_subdirectory(IR)
2+
add_subdirectory(Interfaces)
23
add_subdirectory(Linking)
34
add_subdirectory(Transforms)
45
add_subdirectory(Utils)

0 commit comments

Comments
 (0)