Skip to content

Commit 13ffdd1

Browse files
committed
[mlir][spirv]: Add OpImageFetch
At the missing `spirv::ImageFetchOp` operation to the SPIR-V MLIR dialect ODS with appropriate testing including negative testing of the verifiers. Signed-off-by: Jack Frankland <[email protected]>
1 parent d144eb1 commit 13ffdd1

File tree

5 files changed

+113
-1
lines changed

5 files changed

+113
-1
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4369,6 +4369,7 @@ def SPIRV_OC_OpTranspose : I32EnumAttrCase<"OpTranspose", 8
43694369
def SPIRV_OC_OpImageSampleImplicitLod : I32EnumAttrCase<"OpImageSampleImplicitLod", 87>;
43704370
def SPIRV_OC_OpImageSampleExplicitLod : I32EnumAttrCase<"OpImageSampleExplicitLod", 88>;
43714371
def SPIRV_OC_OpImageSampleProjDrefImplicitLod : I32EnumAttrCase<"OpImageSampleProjDrefImplicitLod", 93>;
4372+
def SPIRV_OC_OpImageFetch : I32EnumAttrCase<"OpImageFetch", 95>;
43724373
def SPIRV_OC_OpImageDrefGather : I32EnumAttrCase<"OpImageDrefGather", 97>;
43734374
def SPIRV_OC_OpImageRead : I32EnumAttrCase<"OpImageRead", 98>;
43744375
def SPIRV_OC_OpImageWrite : I32EnumAttrCase<"OpImageWrite", 99>;
@@ -4577,7 +4578,8 @@ def SPIRV_OpcodeAttr :
45774578
SPIRV_OC_OpCompositeConstruct, SPIRV_OC_OpCompositeExtract,
45784579
SPIRV_OC_OpCompositeInsert, SPIRV_OC_OpTranspose,
45794580
SPIRV_OC_OpImageSampleImplicitLod, SPIRV_OC_OpImageSampleExplicitLod,
4580-
SPIRV_OC_OpImageSampleProjDrefImplicitLod, SPIRV_OC_OpImageDrefGather,
4581+
SPIRV_OC_OpImageSampleProjDrefImplicitLod, SPIRV_OC_OpImageFetch,
4582+
SPIRV_OC_OpImageDrefGather,
45814583
SPIRV_OC_OpImageRead, SPIRV_OC_OpImageWrite, SPIRV_OC_OpImage,
45824584
SPIRV_OC_OpImageQuerySize,
45834585
SPIRV_OC_OpConvertFToU, SPIRV_OC_OpConvertFToS, SPIRV_OC_OpConvertSToF,

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

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,4 +541,50 @@ def SPIRV_ImageSampleProjDrefImplicitLodOp : SPIRV_Op<"ImageSampleProjDrefImplic
541541

542542
// -----
543543

544+
def SPIRV_ImageFetchOp : SPIRV_Op<"ImageFetch",
545+
[SPIRV_DimIsNot<"image", ["Cube"]>,
546+
SPIRV_SampledOperandIs<"image", ["NeedSampler"]>,
547+
SPIRV_NoneOrElementMatchImage<"result", "image">]> {
548+
let summary = "Fetch a single texel from an image whose Sampled operand is 1. ";
549+
550+
let description = [{
551+
Result Type must be a vector of four components of floating-point type or
552+
integer type. Its components must be the same as Sampled Type of the underlying
553+
OpTypeImage (unless that underlying Sampled Type is OpTypeVoid).
554+
555+
Image must be an object whose type is OpTypeImage. Its Dim operand must not be
556+
Cube, and its Sampled operand must be 1.
557+
558+
Coordinate must be a scalar or vector of integer type. It contains (u[, v] … [,
559+
array layer]) as needed by the definition of Sampled Image.
560+
561+
Image Operands encodes what operands follow, as per Image Operands.
562+
563+
<!-- End of AutoGen section -->
564+
565+
#### Example:
566+
567+
```mlir
568+
%0 = spirv.ImageFetch %1, %2 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, R32f>, vector<2xsi32> -> vector<4xf32>
569+
```
570+
}];
571+
572+
let arguments = (ins
573+
SPIRV_AnyImage:$image,
574+
SPIRV_ScalarOrVectorOf<SPIRV_Integer>:$coordinate,
575+
OptionalAttr<SPIRV_ImageOperandsAttr>:$image_operands,
576+
Variadic<SPIRV_Type>:$operand_arguments
577+
);
578+
579+
let results = (outs
580+
AnyTypeOf<[SPIRV_Vec4<SPIRV_Float>, SPIRV_Vec4<SPIRV_Integer>]>:$result
581+
);
582+
583+
let assemblyFormat = [{
584+
$image `,` $coordinate custom<ImageOperands>($image_operands) ( `,` $operand_arguments^ )? attr-dict
585+
`:` type($image) `,` type($coordinate) ( `,` type($operand_arguments)^ )?
586+
`->` type($result)
587+
}];
588+
}
589+
544590
#endif // MLIR_DIALECT_SPIRV_IR_IMAGE_OPS

mlir/lib/Dialect/SPIRV/IR/ImageOps.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,3 +332,12 @@ LogicalResult spirv::ImageSampleProjDrefImplicitLodOp::verify() {
332332
return verifyImageOperands(getOperation(), getImageOperandsAttr(),
333333
getOperandArguments());
334334
}
335+
336+
//===----------------------------------------------------------------------===//
337+
// spirv.ImageFetchOp
338+
//===----------------------------------------------------------------------===//
339+
340+
LogicalResult spirv::ImageFetchOp::verify() {
341+
return verifyImageOperands(getOperation(), getImageOperandsAttr(),
342+
getOperandArguments());
343+
}

mlir/test/Dialect/SPIRV/IR/image-ops.mlir

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,56 @@ func.func @sample_implicit_proj_dref(%arg0 : !spirv.sampled_image<!spirv.image<f
304304

305305
// -----
306306

307+
//===----------------------------------------------------------------------===//
308+
// spirv.ImageFetch
309+
//===----------------------------------------------------------------------===//
310+
311+
func.func @image_fetch(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
312+
// CHECK: {{%.*}} = spirv.ImageFetch {{%.*}}, {{%.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, vector<2xsi32> -> vector<4xf32>
313+
%0 = spirv.ImageFetch %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, vector<2xsi32> -> vector<4xf32>
314+
spirv.Return
315+
}
316+
317+
// -----
318+
319+
func.func @image_fetch_dim_cube(%arg0: !spirv.image<f32, Cube, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
320+
// expected-error @+1 {{op failed to verify that the Dim operand of the underlying image must not be Cube}}
321+
%0 = spirv.ImageFetch %arg0, %arg1 : !spirv.image<f32, Cube, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, vector<2xsi32> -> vector<4xf32>
322+
spirv.Return
323+
}
324+
325+
// -----
326+
327+
func.func @image_fetch_no_sampler(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
328+
// expected-error @+1 {{op failed to verify that the sampled operand of the underlying image must be NeedSampler}}
329+
%0 = spirv.ImageFetch %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32> -> vector<4xf16>
330+
spirv.Return
331+
}
332+
333+
// -----
334+
335+
func.func @image_fetch_type_mismatch(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
336+
// expected-error @+1 {{op failed to verify that the result component type must match the image sampled type}}
337+
%0 = spirv.ImageFetch %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, vector<2xsi32> -> vector<4xf16>
338+
spirv.Return
339+
}
340+
341+
// -----
342+
343+
func.func @image_fetch_2d_result(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
344+
// expected-error @+1 {{op result #0 must be vector of 16/32/64-bit float values of length 4 or vector of 8/16/32/64-bit integer values of length 4, but got 'vector<2xf32>'}}
345+
%0 = spirv.ImageFetch %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, vector<2xsi32> -> vector<2xf32>
346+
spirv.Return
347+
}
348+
349+
// -----
350+
351+
func.func @image_fetch_float_coords(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, %arg1: vector<2xf32>) -> () {
352+
// expected-error @+1 {{op operand #1 must be 8/16/32/64-bit integer or vector of 8/16/32/64-bit integer values of length 2/3/4/8/16, but got 'vector<2xf32>'}}
353+
%0 = spirv.ImageFetch %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, vector<2xf32> -> vector<2xf32>
354+
spirv.Return
355+
}
356+
307357
//===----------------------------------------------------------------------===//
308358
// spirv.ImageOperands: Bias
309359
//===----------------------------------------------------------------------===//

mlir/test/Target/SPIRV/image-ops.mlir

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader, ImageQuery, Link
3838
%0 = spirv.ImageSampleProjDrefImplicitLod %arg0, %arg1, %arg2 : !spirv.sampled_image<!spirv.image<f32, Dim2D, IsDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>>, vector<4xf32>, f32 -> f32
3939
spirv.Return
4040
}
41+
spirv.func @image_fetch(%arg0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Unknown>, %arg1 : vector<2xsi32>) "None" {
42+
// CHECK: spirv.ImageFetch {{%.*}}, {{%.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Unknown>, vector<2xsi32> -> vector<4xf32>
43+
%0 = spirv.ImageFetch %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Unknown>, vector<2xsi32> -> vector<4xf32>
44+
spirv.Return
45+
}
4146
}
4247

4348
// -----

0 commit comments

Comments
 (0)