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());
230 llvm::cast<spirv::ImageType>(getImage().
getType());
231 Type resultType = getResult().getType();
233 spirv::Dim dim = imageType.
getDim();
237 case spirv::Dim::Dim1D:
238 case spirv::Dim::Dim2D:
239 case spirv::Dim::Dim3D:
240 case spirv::Dim::Cube:
241 if (samplingInfo != spirv::ImageSamplingInfo::MultiSampled &&
242 samplerInfo != spirv::ImageSamplerUseInfo::SamplerUnknown &&
243 samplerInfo != spirv::ImageSamplerUseInfo::NoSampler)
245 "if Dim is 1D, 2D, 3D, or Cube, "
246 "it must also have either an MS of 1 or a Sampled of 0 or 2");
248 case spirv::Dim::Buffer:
249 case spirv::Dim::Rect:
252 return emitError(
"the Dim operand of the image type must "
253 "be 1D, 2D, 3D, Buffer, Cube, or Rect");
256 unsigned componentNumber = 0;
258 case spirv::Dim::Dim1D:
259 case spirv::Dim::Buffer:
262 case spirv::Dim::Dim2D:
263 case spirv::Dim::Cube:
264 case spirv::Dim::Rect:
267 case spirv::Dim::Dim3D:
274 if (imageType.
getArrayedInfo() == spirv::ImageArrayedInfo::Arrayed)
275 componentNumber += 1;
277 unsigned resultComponentNumber = 1;
278 if (
auto resultVectorType = llvm::dyn_cast<VectorType>(resultType))
279 resultComponentNumber = resultVectorType.getNumElements();
281 if (componentNumber != resultComponentNumber)
282 return emitError(
"expected the result to have ")
283 << componentNumber <<
" component(s), but found "
284 << resultComponentNumber <<
" component(s)";
295 getOperandArguments());
307 getOperandArguments());
316 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,...