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");
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)) {
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());
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()) &&
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");