Skip to content

Commit 3aa20c2

Browse files
authored
[mlir][spirv] Add definition for selected sample operations (#129558)
This commit adds following three operations: ImageSampleImplicitLodOp, ImageSampleExplicitLodOp and ImageSampleProjDrefImplicitLodOp
1 parent 9694844 commit 3aa20c2

File tree

14 files changed

+981
-244
lines changed

14 files changed

+981
-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: 221 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
// -----
@@ -48,14 +49,19 @@ class SPIRV_DimIsNot<string operand, list<string> values, string transform="$_se
4849

4950
class SPIRV_NoneOrElementMatchImage<string operand, string image, string transform="$_self"> : PredOpTrait<
5051
"the " # operand # " component type must match the image sampled type",
51-
CPred<"::llvm::isa<NoneType>(cast<ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType()) ||"
52+
CPred<"::llvm::isa<NoneType>(cast<::mlir::spirv::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

58-
def SPIRV_SampledImageTransform : StrFunc<"llvm::cast<spirv::SampledImageType>($_self).getImageType()">;
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+
64+
def SPIRV_SampledImageTransform : StrFunc<"llvm::cast<::mlir::spirv::SampledImageType>($_self).getImageType()">;
5965

6066
// -----
6167

@@ -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

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

mlir/lib/Dialect/SPIRV/IR/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_mlir_dialect_library(MLIRSPIRVDialect
3535
MLIRSPIRVCanonicalizationIncGen
3636
MLIRSPIRVEnumAvailabilityIncGen
3737
MLIRSPIRVEnumsIncGen
38+
MLIRSPIRVImageInterfacesIncGen
3839
MLIRSPIRVOpsIncGen
3940

4041
LINK_LIBS PUBLIC
@@ -43,6 +44,7 @@ add_mlir_dialect_library(MLIRSPIRVDialect
4344
MLIRIR
4445
MLIRParser
4546
MLIRSideEffectInterfaces
47+
MLIRSPIRVImageInterfaces
4648
MLIRSupport
4749
MLIRTransforms
4850
MLIRUBDialect

0 commit comments

Comments
 (0)