DPC++ Runtime
Runtime libraries for oneAPI DPC++
image_accessor_util.cpp
Go to the documentation of this file.
1 //==----------- image_accessor_util.cpp ------------------------------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <sycl/accessor.hpp>
10 #include <sycl/accessor_image.hpp>
11 #include <sycl/builtins.hpp>
12 #include <sycl/image.hpp>
13 
14 namespace sycl {
15 inline namespace _V1 {
16 namespace detail {
17 
18 // For Nearest Filtering mode, process float4 Coordinates and
19 // return the appropriate Pixel Coordinates based on Addressing Mode.
20 int4 getPixelCoordNearestFiltMode(float4 Coorduvw,
21  const addressing_mode SmplAddrMode,
22  const range<3> ImgRange) {
23  int4 Coordijk(0);
24  int4 Rangewhd(ImgRange[0], ImgRange[1], ImgRange[2], 0);
25  switch (SmplAddrMode) {
27  float4 Tempuvw(0);
28  Tempuvw = 2.0f * sycl::rint(0.5f * Coorduvw);
29  Tempuvw = sycl::fabs(Coorduvw - Tempuvw);
30  Tempuvw = Tempuvw * (Rangewhd.convert<cl_float>());
31  Tempuvw = (sycl::floor(Tempuvw));
32  Coordijk = Tempuvw.convert<cl_int>();
33  Coordijk = sycl::min(Coordijk, (Rangewhd - 1));
34  // Eg:
35  // u,v,w = {2.3,1.7,0.5} // normalized coordinates.
36  // w,h,d = {9,9,9}
37  // u1=2*rint(1.15)=2
38  // v1=2*rint(0.85)=2
39  // w1=2*rint(0.5)=0
40  // u1=fabs(2.3-2)=.3
41  // v1=fabs(1.7-2)=.3
42  // w1=fabs(0.5-0)=.5
43  // u1=0.3*9=2.7
44  // v1=0.3*9=2.7
45  // w1=0.5*9=4.5
46  // i,j,k = {2,2,4}
47 
48  } break;
50 
51  float4 Tempuvw(0);
52  Tempuvw = (Coorduvw - sycl::floor(Coorduvw)) * Rangewhd.convert<cl_float>();
53  Coordijk = (sycl::floor(Tempuvw)).convert<cl_int>();
54  int4 GreaterThanEqual = (Coordijk >= Rangewhd);
55  Coordijk = sycl::select(Coordijk, (Coordijk - Rangewhd), GreaterThanEqual);
56  // Eg:
57  // u = 2.3; v = 1.5; w = 0.5; // normalized coordinates.
58  // w,h,d = {9,9,9};
59  // u1= 0.3*w;
60  // v1= 0.5*d;
61  // w1= 0.5*h;
62  // i = floor(2.7);
63  // j = floor(4.5);
64  // k = floor(4.5);
65  // if (i/j/k > w/h/d-1)
66  // // Condition is not satisfied.
67  // (This condition I think will only be satisfied if the floating point
68  // arithmetic of multiplication
69  // gave a value in u1/v1/w1 as > w/h/d)
70  // i = 2; j = 4; k = 4;
71  } break;
73  Coordijk = (sycl::floor(Coorduvw)).convert<cl_int>();
74  Coordijk = sycl::clamp(Coordijk, int4(0), (Rangewhd - 1));
75  break;
77  Coordijk = (sycl::floor(Coorduvw)).convert<cl_int>();
78  Coordijk = sycl::clamp(Coordijk, int4(-1), Rangewhd);
79  break;
81  Coordijk = (sycl::floor(Coorduvw)).convert<cl_int>();
82  break;
83  }
84  return Coordijk;
85 }
86 
87 // For Linear Filtering mode, process Coordinates-Coord_uvw and return
88 // coordinate indexes based on Addressing Mode.
89 // The value returned contains (i0,j0,k0,0,i1,j1,k1,0).
90 // Retabc contains the values of (a,b,c,0)
91 // The caller of this function should use these values to create the 8 pixel
92 // coordinates and multiplication coefficients.
93 int8 getPixelCoordLinearFiltMode(float4 Coorduvw,
94  const addressing_mode SmplAddrMode,
95  const range<3> ImgRange, float4 &Retabc) {
96  int4 Rangewhd(ImgRange[0], ImgRange[1], ImgRange[2], 0);
97  int4 Ci0j0k0(0);
98  int4 Ci1j1k1(0);
99  int4 Int_uvwsubhalf = sycl::floor(Coorduvw - 0.5f).convert<cl_int>();
100 
101  switch (SmplAddrMode) {
103  float4 Temp;
104  Temp = (sycl::rint(Coorduvw * 0.5f)) * 2.0f;
105  Temp = sycl::fabs(Coorduvw - Temp);
106  Coorduvw = Temp * Rangewhd.convert<cl_float>();
107  Int_uvwsubhalf = sycl::floor(Coorduvw - 0.5f).convert<cl_int>();
108 
109  Ci0j0k0 = Int_uvwsubhalf;
110  Ci1j1k1 = Ci0j0k0 + 1;
111 
112  Ci0j0k0 = sycl::max(Ci0j0k0, 0);
113  Ci1j1k1 = sycl::min(Ci1j1k1, (Rangewhd - 1));
114  } break;
116 
117  Coorduvw =
118  (Coorduvw - sycl::floor(Coorduvw)) * Rangewhd.convert<cl_float>();
119  Int_uvwsubhalf = sycl::floor(Coorduvw - 0.5f).convert<cl_int>();
120 
121  Ci0j0k0 = Int_uvwsubhalf;
122  Ci1j1k1 = Ci0j0k0 + 1;
123 
124  Ci0j0k0 = sycl::select(Ci0j0k0, (Ci0j0k0 + Rangewhd), Ci0j0k0 < int4(0));
125  Ci1j1k1 = sycl::select(Ci1j1k1, (Ci1j1k1 - Rangewhd), Ci1j1k1 >= Rangewhd);
126 
127  } break;
129  Ci0j0k0 = sycl::clamp(Int_uvwsubhalf, int4(0), (Rangewhd - 1));
130  Ci1j1k1 = sycl::clamp((Int_uvwsubhalf + 1), int4(0), (Rangewhd - 1));
131  break;
132  }
133  case addressing_mode::clamp: {
134  Ci0j0k0 = sycl::clamp(Int_uvwsubhalf, int4(-1), Rangewhd);
135  Ci1j1k1 = sycl::clamp((Int_uvwsubhalf + 1), int4(-1), Rangewhd);
136  break;
137  }
138  case addressing_mode::none: {
139  Ci0j0k0 = Int_uvwsubhalf;
140  Ci1j1k1 = Ci0j0k0 + 1;
141  break;
142  }
143  }
144  Retabc = (Coorduvw - 0.5f) - (Int_uvwsubhalf.convert<cl_float>());
145  Retabc.w() = 0.0f;
146  return int8(Ci0j0k0, Ci1j1k1);
147 }
148 
149 // Function returns true when PixelCoord is out of image's range.
150 // It is only valid for addressing_mode::clamp/none.
151 // Note: For addressing_mode::none , spec says outofrange access is not defined.
152 // This function handles this addressing_mode to avoid accessing out of bound
153 // memories on host.
154 bool isOutOfRange(const int4 PixelCoord, const addressing_mode SmplAddrMode,
155  const range<3> ImgRange) {
156 
157  if (SmplAddrMode != addressing_mode::clamp &&
158  SmplAddrMode != addressing_mode::none)
159  return false;
160 
161  auto CheckOutOfRange = [](cl_int Coord, cl_int Range) {
162  return ((Coord < 0) || (Coord >= Range));
163  };
164 
165  bool CheckWidth = CheckOutOfRange(PixelCoord.x(), ImgRange[0]);
166  bool CheckHeight = CheckOutOfRange(PixelCoord.y(), ImgRange[1]);
167  bool CheckDepth = CheckOutOfRange(PixelCoord.z(), ImgRange[2]);
168 
169  return (CheckWidth || CheckHeight || CheckDepth);
170 }
171 
172 float4 getBorderColor(const image_channel_order ImgChannelOrder) {
173 
174  float4 BorderColor(0.0f);
175  switch (ImgChannelOrder) {
180  BorderColor.w() = 1.0f;
181  break;
182  default:
183  break;
184  }
185  return BorderColor;
186 }
187 
188 } // namespace detail
189 } // namespace _V1
190 } // namespace sycl
The file contains implementations of accessor class.
float4 getBorderColor(const image_channel_order ImgChannelOrder)
int4 getPixelCoordNearestFiltMode(float4, const addressing_mode, const range< 3 >)
bool isOutOfRange(const int4 PixelCoord, const addressing_mode SmplAddrMode, const range< 3 > ImgRange)
int8 getPixelCoordLinearFiltMode(float4, const addressing_mode, const range< 3 >, float4 &)
std::enable_if_t< detail::is_bf16_storage_type< T >::value, T > fabs(T x)
std::int32_t cl_int
Definition: aliases.hpp:134
addressing_mode
Definition: sampler.hpp:23
image_channel_order
Definition: image.hpp:56
float floor(float)
float rint(float)
Definition: access.hpp:18