| // Copyright 2023 The Clspv Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "SamplerUtils.h" |
| #include "Builtins.h" |
| #include "BuiltinsEnum.h" |
| #include "Constants.h" |
| #include "Types.h" |
| |
| using namespace llvm; |
| |
| namespace clspv { |
| |
| Value *GetImageDimFP(Module &M, IRBuilder<> &B, Value *Img, Type *ImgTy) { |
| auto float4Ty = FixedVectorType::get(B.getFloatTy(), 4); |
| auto getImageSizesFct = M.getOrInsertFunction( |
| "_Z13get_image_dim11ocl_image3d", |
| FunctionType::get(FixedVectorType::get(B.getInt32Ty(), 4), {ImgTy}, |
| false)); |
| Value *ImgSizes = B.CreateCall(getImageSizesFct, {Img}); |
| return B.CreateSIToFP(ImgSizes, float4Ty); |
| } |
| |
| Value *NormalizedCoordinate(Module &M, IRBuilder<> &B, Value *Coord, |
| Value *ImgDimFP, bool FilteringNearest) { |
| if (FilteringNearest) { |
| auto float4Ty = FixedVectorType::get(B.getFloatTy(), 4); |
| auto getFloorFct = M.getOrInsertFunction( |
| "floor", FunctionType::get(float4Ty, {float4Ty}, false)); |
| Coord = B.CreateCall(getFloorFct, {Coord}); |
| Coord = B.CreateFAdd(Coord, ConstantFP::get(float4Ty, 0.5)); |
| } |
| |
| return B.CreateFDiv(Coord, ImgDimFP); |
| } |
| |
| bool isReadImage3DWithNonLiteralSampler(CallInst *call) { |
| auto FI = Builtins::Lookup(call->getCalledFunction()); |
| switch (FI.getType()) { |
| case Builtins::kReadImagef: |
| case Builtins::kReadImagei: |
| case Builtins::kReadImageui: { |
| if (FI.getParameter(1).isSampler()) { |
| Type *ImgTy = call->getOperand(0)->getType(); |
| auto sampler_call = dyn_cast<CallInst>(call->getOperand(1)); |
| bool literal_sampler = |
| sampler_call && |
| (sampler_call->getCalledFunction()->getName().contains( |
| TranslateSamplerInitializerFunction()) || |
| sampler_call->getCalledFunction()->getName().contains( |
| LiteralSamplerFunction())); |
| if (clspv::ImageDimensionality(ImgTy) == spv::Dim3D && !literal_sampler) { |
| return true; |
| } |
| } |
| } break; |
| default: |
| break; |
| } |
| return false; |
| } |
| |
| } // namespace clspv |