24 spirv::ImageOperandsAttr attr,
30 return imageOp->
emitError(
"the Image Operands should encode what operands "
31 "follow, as per Image Operands");
34 if (spirv::bitEnumContainsAll(attr.getValue(),
35 spirv::ImageOperands::Lod |
36 spirv::ImageOperands::Grad))
38 "it is invalid to set both the Lod and Grad bits");
45 if (spirv::bitEnumContainsAny(attr.getValue(), spirv::ImageOperands::Bias)) {
46 if (!isa<spirv::ImplicitLodOpInterface>(imageOp))
48 "Bias is only valid with implicit-lod instructions");
50 if (index + 1 > operands.size())
51 return imageOp->
emitError(
"Bias operand requires 1 argument");
53 if (!isa<FloatType>(operands[index].
getType()))
54 return imageOp->
emitError(
"Bias must be a floating-point type scalar");
56 auto samplingOp = cast<spirv::SamplingOpInterface>(imageOp);
57 auto sampledImageType =
58 cast<spirv::SampledImageType>(samplingOp.getSampledImage().getType());
59 auto imageType = cast<spirv::ImageType>(sampledImageType.getImageType());
61 if (!llvm::is_contained({spirv::Dim::Dim1D, spirv::Dim::Dim2D,
62 spirv::Dim::Dim3D, spirv::Dim::Cube},
65 "Bias must only be used with an image type that has "
66 "a dim operand of 1D, 2D, 3D, or Cube");
68 if (imageType.getSamplingInfo() != spirv::ImageSamplingInfo::SingleSampled)
69 return imageOp->
emitError(
"Bias must only be used with an image type "
70 "that has a MS operand of 0");
75 if (spirv::bitEnumContainsAny(attr.getValue(), spirv::ImageOperands::Lod)) {
76 if (!isa<spirv::ExplicitLodOpInterface>(imageOp) &&
77 !isa<spirv::FetchOpInterface>(imageOp))
79 "Lod is only valid with explicit-lod and fetch instructions");
81 if (index + 1 > operands.size())
82 return imageOp->
emitError(
"Lod operand requires 1 argument");
86 if (isa<spirv::SamplingOpInterface>(imageOp)) {
87 if (!isa<mlir::FloatType>(operands[index].
getType()))
88 return imageOp->
emitError(
"for sampling operations, Lod must be a "
89 "floating-point type scalar");
91 auto samplingOp = cast<spirv::SamplingOpInterface>(imageOp);
92 auto sampledImageType = llvm::cast<spirv::SampledImageType>(
93 samplingOp.getSampledImage().getType());
94 imageType = cast<spirv::ImageType>(sampledImageType.getImageType());
96 if (!isa<mlir::IntegerType>(operands[index].
getType()))
98 "for fetch operations, Lod must be an integer type scalar");
100 auto fetchOp = cast<spirv::FetchOpInterface>(imageOp);
101 imageType = cast<spirv::ImageType>(fetchOp.getImage().getType());
104 if (!llvm::is_contained({spirv::Dim::Dim1D, spirv::Dim::Dim2D,
105 spirv::Dim::Dim3D, spirv::Dim::Cube},
108 "Lod must only be used with an image type that has "
109 "a dim operand of 1D, 2D, 3D, or Cube");
111 if (imageType.
getSamplingInfo() != spirv::ImageSamplingInfo::SingleSampled)
112 return imageOp->
emitError(
"Lod must only be used with an image type that "
113 "has a MS operand of 0");
118 if (spirv::bitEnumContainsAny(attr.getValue(), spirv::ImageOperands::Grad)) {
119 if (!isa<spirv::ExplicitLodOpInterface>(imageOp))
121 "Grad is only valid with explicit-lod instructions");
123 if (index + 2 > operands.size())
125 "Grad operand requires 2 arguments (scalars or vectors)");
127 auto samplingOp = cast<spirv::SamplingOpInterface>(imageOp);
128 auto sampledImageType =
129 cast<spirv::SampledImageType>(samplingOp.getSampledImage().getType());
130 auto imageType = cast<spirv::ImageType>(sampledImageType.getImageType());
132 if (imageType.getSamplingInfo() != spirv::ImageSamplingInfo::SingleSampled)
133 return imageOp->
emitError(
"Grad must only be used with an image type "
134 "that has a MS operand of 0");
136 int64_t numberOfComponents = 0;
139 dyn_cast<mlir::VectorType>(samplingOp.getCoordinate().getType());
141 numberOfComponents = coordVector.getNumElements();
142 if (imageType.getArrayedInfo() == spirv::ImageArrayedInfo::Arrayed)
143 numberOfComponents -= 1;
145 numberOfComponents = 1;
148 assert(numberOfComponents > 0);
150 auto dXVector = dyn_cast<mlir::VectorType>(operands[index].
getType());
151 auto dYVector = dyn_cast<mlir::VectorType>(operands[index + 1].
getType());
152 if (dXVector && dYVector) {
153 if (dXVector.getNumElements() != dYVector.getNumElements() ||
154 dXVector.getNumElements() != numberOfComponents)
156 "number of components of each Grad argument must equal the number "
157 "of components in coordinate, minus the array layer component, if "
160 if (!isa<mlir::FloatType>(dXVector.getElementType()) ||
161 !isa<mlir::FloatType>(dYVector.getElementType()))
163 "Grad arguments must be a vector of floating-point type");
164 }
else if (isa<mlir::FloatType>(operands[index].
getType()) &&
165 isa<mlir::FloatType>(operands[index + 1].
getType())) {
166 if (numberOfComponents != 1)
168 "number of components of each Grad argument must equal the number "
169 "of components in coordinate, minus the array layer component, if "
173 "Grad arguments must be a scalar or vector of floating-point type");
180 spirv::ImageOperands noSupportOperands =
181 spirv::ImageOperands::ConstOffset | spirv::ImageOperands::Offset |
182 spirv::ImageOperands::ConstOffsets | spirv::ImageOperands::Sample |
183 spirv::ImageOperands::MinLod | spirv::ImageOperands::MakeTexelAvailable |
184 spirv::ImageOperands::MakeTexelVisible |
185 spirv::ImageOperands::SignExtend | spirv::ImageOperands::ZeroExtend;
187 assert(!spirv::bitEnumContainsAny(attr.getValue(), noSupportOperands) &&
188 "unimplemented operands of Image Operands");
189 (void)noSupportOperands;
191 if (index < operands.size())
193 "too many image operand arguments have been provided");
204 getOperandArguments());
221 getOperandArguments());
238 getOperandArguments());
247 llvm::cast<spirv::ImageType>(getImage().
getType());
248 Type resultType = getResult().getType();
250 spirv::Dim dim = imageType.
getDim();
254 case spirv::Dim::Dim1D:
255 case spirv::Dim::Dim2D:
256 case spirv::Dim::Dim3D:
257 case spirv::Dim::Cube:
258 if (samplingInfo != spirv::ImageSamplingInfo::MultiSampled &&
259 samplerInfo != spirv::ImageSamplerUseInfo::SamplerUnknown &&
260 samplerInfo != spirv::ImageSamplerUseInfo::NoSampler)
262 "if Dim is 1D, 2D, 3D, or Cube, "
263 "it must also have either an MS of 1 or a Sampled of 0 or 2");
265 case spirv::Dim::Buffer:
266 case spirv::Dim::Rect:
269 return emitError(
"the Dim operand of the image type must "
270 "be 1D, 2D, 3D, Buffer, Cube, or Rect");
273 unsigned componentNumber = 0;
275 case spirv::Dim::Dim1D:
276 case spirv::Dim::Buffer:
279 case spirv::Dim::Dim2D:
280 case spirv::Dim::Cube:
281 case spirv::Dim::Rect:
284 case spirv::Dim::Dim3D:
291 if (imageType.
getArrayedInfo() == spirv::ImageArrayedInfo::Arrayed)
292 componentNumber += 1;
294 unsigned resultComponentNumber = 1;
295 if (
auto resultVectorType = llvm::dyn_cast<VectorType>(resultType))
296 resultComponentNumber = resultVectorType.getNumElements();
298 if (componentNumber != resultComponentNumber)
299 return emitError(
"expected the result to have ")
300 << componentNumber <<
" component(s), but found "
301 << resultComponentNumber <<
" component(s)";
312 getOperandArguments());
324 getOperandArguments());
333 getOperandArguments());
342 getOperandArguments());
static LogicalResult verifyImageOperands(Operation *imageOp, spirv::ImageOperandsAttr attr, Operation::operand_range operands)
This class implements the operand iterators for the Operation class.
Operation is the basic unit of execution within MLIR.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error about fatal conditions with this operation, reporting up to any diagnostic handlers tha...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
ImageArrayedInfo getArrayedInfo() const
ImageSamplerUseInfo getSamplerUseInfo() const
ImageSamplingInfo getSamplingInfo() const
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...