Skip to content

Commit 3bf1e1f

Browse files
authored
[mlir][spirv] Add definition of OpImageRead (#144038)
1 parent 36c710c commit 3bf1e1f

File tree

5 files changed

+114
-3
lines changed

5 files changed

+114
-3
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4370,6 +4370,7 @@ def SPIRV_OC_OpImageSampleImplicitLod : I32EnumAttrCase<"OpImageSampleIm
43704370
def SPIRV_OC_OpImageSampleExplicitLod : I32EnumAttrCase<"OpImageSampleExplicitLod", 88>;
43714371
def SPIRV_OC_OpImageSampleProjDrefImplicitLod : I32EnumAttrCase<"OpImageSampleProjDrefImplicitLod", 93>;
43724372
def SPIRV_OC_OpImageDrefGather : I32EnumAttrCase<"OpImageDrefGather", 97>;
4373+
def SPIRV_OC_OpImageRead : I32EnumAttrCase<"OpImageRead", 98>;
43734374
def SPIRV_OC_OpImageWrite : I32EnumAttrCase<"OpImageWrite", 99>;
43744375
def SPIRV_OC_OpImage : I32EnumAttrCase<"OpImage", 100>;
43754376
def SPIRV_OC_OpImageQuerySize : I32EnumAttrCase<"OpImageQuerySize", 104>;
@@ -4577,7 +4578,8 @@ def SPIRV_OpcodeAttr :
45774578
SPIRV_OC_OpCompositeInsert, SPIRV_OC_OpTranspose,
45784579
SPIRV_OC_OpImageSampleImplicitLod, SPIRV_OC_OpImageSampleExplicitLod,
45794580
SPIRV_OC_OpImageSampleProjDrefImplicitLod, SPIRV_OC_OpImageDrefGather,
4580-
SPIRV_OC_OpImageWrite, SPIRV_OC_OpImage, SPIRV_OC_OpImageQuerySize,
4581+
SPIRV_OC_OpImageRead, SPIRV_OC_OpImageWrite, SPIRV_OC_OpImage,
4582+
SPIRV_OC_OpImageQuerySize,
45814583
SPIRV_OC_OpConvertFToU, SPIRV_OC_OpConvertFToS, SPIRV_OC_OpConvertSToF,
45824584
SPIRV_OC_OpConvertUToF, SPIRV_OC_OpUConvert, SPIRV_OC_OpSConvert,
45834585
SPIRV_OC_OpFConvert, SPIRV_OC_OpConvertPtrToU, SPIRV_OC_OpConvertUToPtr,

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

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,63 @@ def SPIRV_ImageQuerySizeOp : SPIRV_Op<"ImageQuerySize", [Pure]> {
186186

187187
// -----
188188

189+
def SPIRV_ImageReadOp : SPIRV_Op<"ImageRead",
190+
[SPIRV_SampledOperandIs<"image", ["SamplerUnknown", "NoSampler"]>,
191+
SPIRV_NoneOrElementMatchImage<"result", "image">]> {
192+
let summary = "Read a texel from an image without a sampler.";
193+
194+
let description = [{
195+
Result Type must be a scalar or vector of floating-point type or integer
196+
type. It must be a scalar or vector with component type the same as Sampled
197+
Type of the OpTypeImage (unless that Sampled Type is OpTypeVoid).
198+
199+
Image must be an object whose type is OpTypeImage with a Sampled operand of
200+
0 or 2. If the Arrayed operand is 1, then additional capabilities may be
201+
required; e.g., ImageCubeArray, or ImageMSArray.
202+
203+
Coordinate must be a scalar or vector of floating-point type or integer
204+
type. It contains non-normalized texel coordinates (u[, v] ... [, array
205+
layer]) as needed by the definition of Image. See the client API
206+
specification for handling of coordinates outside the image.
207+
208+
If the Image Dim operand is SubpassData, Coordinate is relative to the
209+
current fragment location. See the client API specification for more detail
210+
on how these coordinates are applied.
211+
212+
If the Image Dim operand is not SubpassData, the Image Format must not be
213+
Unknown, unless the StorageImageReadWithoutFormat Capability was declared.
214+
215+
Image Operands encodes what operands follow, as per Image Operands.
216+
217+
<!-- End of AutoGen section -->
218+
219+
#### Example:
220+
221+
```mlir
222+
%0 = spirv.ImageRead %1, %2 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, R32f>, vector<2xsi32> -> vector<4xf32>
223+
```
224+
}];
225+
226+
let arguments = (ins
227+
SPIRV_AnyImage:$image,
228+
AnyTypeOf<[SPIRV_ScalarOrVectorOf<SPIRV_Float>, SPIRV_ScalarOrVectorOf<SPIRV_Integer>]>:$coordinate,
229+
OptionalAttr<SPIRV_ImageOperandsAttr>:$image_operands,
230+
Variadic<SPIRV_Type>:$operand_arguments
231+
);
232+
233+
let results = (outs
234+
AnyTypeOf<[SPIRV_ScalarOrVectorOf<SPIRV_Float>, SPIRV_ScalarOrVectorOf<SPIRV_Integer>]>:$result
235+
);
236+
237+
let assemblyFormat = [{
238+
$image `,` $coordinate custom<ImageOperands>($image_operands) ( `,` $operand_arguments^ )? attr-dict
239+
`:` type($image) `,` type($coordinate) ( `,` type($operand_arguments)^ )?
240+
`->` type($result)
241+
}];
242+
}
243+
244+
// -----
245+
189246
def SPIRV_ImageWriteOp : SPIRV_Op<"ImageWrite",
190247
[SPIRV_SampledOperandIs<"image", ["SamplerUnknown", "NoSampler"]>,
191248
SPIRV_DimIsNot<"image", ["SubpassData"]>,

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

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,23 @@ LogicalResult spirv::ImageDrefGatherOp::verify() {
204204
getOperandArguments());
205205
}
206206

207+
//===----------------------------------------------------------------------===//
208+
// spirv.ImageReadOp
209+
//===----------------------------------------------------------------------===//
210+
211+
LogicalResult spirv::ImageReadOp::verify() {
212+
// TODO: Do we need check for: "If the Arrayed operand is 1, then additional
213+
// capabilities may be required; e.g., ImageCubeArray, or ImageMSArray."?
214+
215+
// TODO: Ideally it should be somewhere verified that "If the Image Dim
216+
// operand is not SubpassData, the Image Format must not be Unknown, unless
217+
// the StorageImageReadWithoutFormat Capability was declared." This function
218+
// however may not be the suitable place for such verification.
219+
220+
return verifyImageOperands(getOperation(), getImageOperandsAttr(),
221+
getOperandArguments());
222+
}
223+
207224
//===----------------------------------------------------------------------===//
208225
// spirv.ImageWriteOp
209226
//===----------------------------------------------------------------------===//

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,34 @@ func.func @image_query_size_error_result2(%arg0 : !spirv.image<f32, Buffer, NoDe
116116

117117
// -----
118118

119+
//===----------------------------------------------------------------------===//
120+
// spirv.ImageRead
121+
//===----------------------------------------------------------------------===//
122+
123+
func.func @image_read(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
124+
// CHECK: {{%.*}} = spirv.ImageRead {{%.*}}, {{%.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32> -> vector<4xf32>
125+
%0 = spirv.ImageRead %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32> -> vector<4xf32>
126+
spirv.Return
127+
}
128+
129+
// -----
130+
131+
func.func @image_read_type_mismatch(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
132+
// expected-error @+1 {{op failed to verify that the result component type must match the image sampled type}}
133+
%0 = spirv.ImageRead %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32> -> vector<4xf16>
134+
spirv.Return
135+
}
136+
137+
// -----
138+
139+
func.func @image_read_need_sampler(%arg0: !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, %arg1: vector<2xsi32>) -> () {
140+
// expected-error @+1 {{op failed to verify that the sampled operand of the underlying image must be SamplerUnknown or NoSampler}}
141+
%0 = spirv.ImageRead %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NeedSampler, Rgba8>, vector<2xsi32> -> vector<4xf16>
142+
spirv.Return
143+
}
144+
145+
// -----
146+
119147
//===----------------------------------------------------------------------===//
120148
// spirv.ImageWrite
121149
//===----------------------------------------------------------------------===//

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader, ImageQuery, Link
1313
%0 = spirv.ImageQuerySize %arg0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown> -> vector<2xi32>
1414
spirv.Return
1515
}
16+
spirv.func @image_read(%arg0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, %arg1 : vector<2xsi32>) "None" {
17+
// CHECK: {{.*}} = spirv.ImageRead {{%.*}}, {{%.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32> -> vector<4xf32>
18+
%0 = spirv.ImageRead %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32> -> vector<4xf32>
19+
spirv.Return
20+
}
1621
spirv.func @image_write(%arg0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, %arg1 : vector<2xsi32>, %arg2 : vector<4xf32>) "None" {
1722
// CHECK: spirv.ImageWrite {{%.*}}, {{%.*}}, {{%.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32>, vector<4xf32>
1823
spirv.ImageWrite %arg0, %arg1, %arg2 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Rgba8>, vector<2xsi32>, vector<4xf32>
@@ -38,9 +43,11 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader, ImageQuery, Link
3843
// -----
3944

4045
spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader, StorageImageWriteWithoutFormat, Linkage], []> {
41-
spirv.func @image_write(%arg0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>, %arg1 : vector<2xsi32>, %arg2 : vector<4xf32>) "None" {
46+
spirv.func @image_read_write(%arg0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>, %arg1 : vector<2xsi32>) "None" {
47+
// CHECK: spirv.ImageRead {{%.*}}, {{%.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>, vector<2xsi32> -> vector<4xf32>
48+
%0 = spirv.ImageRead %arg0, %arg1 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>, vector<2xsi32> -> vector<4xf32>
4249
// CHECK: spirv.ImageWrite {{%.*}}, {{%.*}}, {{%.*}} : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>, vector<2xsi32>, vector<4xf32>
43-
spirv.ImageWrite %arg0, %arg1, %arg2 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>, vector<2xsi32>, vector<4xf32>
50+
spirv.ImageWrite %arg0, %arg1, %0 : !spirv.image<f32, Dim2D, NoDepth, NonArrayed, SingleSampled, NoSampler, Unknown>, vector<2xsi32>, vector<4xf32>
4451
spirv.Return
4552
}
4653
}

0 commit comments

Comments
 (0)