1515#define MLIR_DIALECT_SPIRV_IR_IMAGE_OPS
1616
1717include "mlir/Dialect/SPIRV/IR/SPIRVBase.td"
18+ include "mlir/Dialect/SPIRV/Interfaces/SPIRVImageInterfaces.td"
1819include "mlir/Interfaces/SideEffectInterfaces.td"
1920
2021// -----
@@ -48,14 +49,19 @@ class SPIRV_DimIsNot<string operand, list<string> values, string transform="$_se
4849
4950class 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
@@ -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
0 commit comments