15
15
#define MLIR_DIALECT_SPIRV_IR_IMAGE_OPS
16
16
17
17
include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"
18
+ include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.td"
18
19
include "mlir/Interfaces/SideEffectInterfaces.td"
19
20
20
21
// -----
@@ -51,10 +52,15 @@ class SPIRV_NoneOrElementMatchImage<string operand, string image, string transfo
51
52
CPred<"::llvm::isa<NoneType>(cast<ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType()) ||"
52
53
"(getElementTypeOrSelf($" # operand # ")"
53
54
"=="
54
- "cast<ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType())"
55
+ "cast<::mlir::spirv:: ImageType>(" # !subst("$_self", "$" # image # ".getType()", transform) # ").getElementType())"
55
56
>
56
57
>;
57
58
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
+
58
64
def SPIRV_SampledImageTransform : StrFunc<"llvm::cast<spirv::SampledImageType>($_self).getImageType()">;
59
65
60
66
// -----
@@ -89,7 +95,7 @@ def SPIRV_ImageDrefGatherOp : SPIRV_Op<"ImageDrefGather",
89
95
90
96
```mlir
91
97
%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>
93
99
```
94
100
}];
95
101
@@ -115,7 +121,7 @@ def SPIRV_ImageDrefGatherOp : SPIRV_Op<"ImageDrefGather",
115
121
116
122
let assemblyFormat = [{
117
123
$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)^ `)` )?
119
125
`->` type($result)
120
126
}];
121
127
@@ -227,7 +233,7 @@ def SPIRV_ImageWriteOp : SPIRV_Op<"ImageWrite",
227
233
228
234
let assemblyFormat = [{
229
235
$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)^ `)`)?
231
237
}];
232
238
}
233
239
@@ -268,4 +274,208 @@ def SPIRV_ImageOp : SPIRV_Op<"Image",
268
274
let hasVerifier = 0;
269
275
}
270
276
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
0 commit comments