DPC++ Runtime
Runtime libraries for oneAPI DPC++
image_ocl_types.hpp
Go to the documentation of this file.
1 //===-- Image_ocl_types.hpp - Image OpenCL types --------- ------*- C++ -*-===//
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 // This file is to define some utility functions and declare the structs with
9 // type as appropriate opencl image types based on Dims, AccessMode and
10 // AccessTarget. The macros essentially expand to -
11 //
12 // template <> struct
13 // opencl_image_type<1, access::mode::read, access::target::image> {
14 // using type = __ocl_image1d_ro_t;
15 // };
16 //
17 // template <>
18 // struct opencl_image_type<1, access::mode::write, access::target::image> {
19 // using type = __ocl_image1d_array_wo_t;
20 // };
21 //
22 // As an example, this can be
23 // used as below:
24 // detail::opencl_image_type<2, access::mode::read, access::target::image>::type
25 // MyImage;
26 //
27 #pragma once
28 
29 #ifdef __SYCL_DEVICE_ONLY__
30 
31 #include <sycl/access/access.hpp>
33 
34 #include <CL/__spirv/spirv_ops.hpp>
35 
36 namespace sycl {
37 inline namespace _V1 {
38 namespace detail {
39 
40 // Type trait to get the associated sampled image type for a given image type.
41 template <typename ImageType> struct sampled_opencl_image_type;
42 
43 } // namespace detail
44 } // namespace _V1
45 } // namespace sycl
46 
47 #define __SYCL_INVOKE_SPIRV_CALL_ARG1(call) \
48  template <typename R, typename T1> inline R __invoke_##call(T1 ParT1) { \
49  using Ret = sycl::detail::ConvertToOpenCLType_t<R>; \
50  return sycl::detail::convertFromOpenCLTypeFor<R>( \
51  __spirv_##call<Ret, T1>(ParT1)); \
52  }
53 
54 // The macro defines the function __invoke_ImageXXXX,
55 // The functions contains the spirv call to __spirv_ImageXXXX.
56 __SYCL_INVOKE_SPIRV_CALL_ARG1(ImageQuerySize)
57 __SYCL_INVOKE_SPIRV_CALL_ARG1(ImageQueryFormat)
58 __SYCL_INVOKE_SPIRV_CALL_ARG1(ImageQueryOrder)
59 
60 template <typename ImageT, typename CoordT, typename ValT>
61 static void __invoke__ImageWrite(ImageT Img, CoordT Coords, ValT Val) {
62 
63  // Convert from sycl types to builtin types to get correct function mangling.
64  auto TmpCoords = sycl::detail::convertToOpenCLType(Coords);
65  auto TmpVal = sycl::detail::convertToOpenCLType(Val);
66 
67  __spirv_ImageWrite<ImageT, decltype(TmpCoords), decltype(TmpVal)>(
68  Img, TmpCoords, TmpVal);
69 }
70 
71 template <typename RetType, typename ImageT, typename CoordT>
72 static RetType __invoke__ImageRead(ImageT Img, CoordT Coords) {
73 
74  // Convert from sycl types to builtin types to get correct function mangling.
75  using TempRetT = sycl::detail::ConvertToOpenCLType_t<RetType>;
76  auto TmpCoords = sycl::detail::convertToOpenCLType(Coords);
77 
78  return sycl::detail::convertFromOpenCLTypeFor<RetType>(
79  __spirv_ImageRead<TempRetT, ImageT, decltype(TmpCoords)>(Img, TmpCoords));
80 }
81 
82 template <typename RetType, typename ImageT, typename CoordT>
83 static RetType __invoke__ImageArrayFetch(ImageT Img, CoordT Coords,
84  int ArrayLayer) {
85 
86  // Convert from sycl types to builtin types to get correct function mangling.
87  using TempRetT = sycl::detail::ConvertToOpenCLType_t<RetType>;
88  auto TmpCoords = sycl::detail::convertToOpenCLType(Coords);
89 
90  return sycl::detail::convertFromOpenCLTypeFor<RetType>(
91  __spirv_ImageArrayFetch<TempRetT, ImageT, decltype(TmpCoords)>(
92  Img, TmpCoords, ArrayLayer));
93 }
94 
95 template <typename ImageT, typename CoordT, typename ValT>
96 static void __invoke__ImageArrayWrite(ImageT Img, CoordT Coords, int ArrayLayer,
97  ValT Val) {
98 
99  // Convert from sycl types to builtin types to get correct function mangling.
100  auto TmpCoords = sycl::detail::convertToOpenCLType(Coords);
101  auto TmpVal = sycl::detail::convertToOpenCLType(Val);
102 
103  __spirv_ImageArrayWrite<ImageT, decltype(TmpCoords), decltype(TmpVal)>(
104  Img, TmpCoords, ArrayLayer, TmpVal);
105 }
106 
107 template <typename RetType, typename SmpImageT, typename DirVecT>
108 static RetType __invoke__ImageReadCubemap(SmpImageT SmpImg, DirVecT DirVec) {
109 
110  // Convert from sycl types to builtin types to get correct function mangling.
111  using TempRetT = sycl::detail::ConvertToOpenCLType_t<RetType>;
112  auto TmpDirVec = sycl::detail::convertToOpenCLType(DirVec);
113 
114  return sycl::detail::convertFromOpenCLTypeFor<RetType>(
115  __spirv_ImageSampleCubemap<SmpImageT, TempRetT, decltype(TmpDirVec)>(
116  SmpImg, TmpDirVec));
117 }
118 
119 template <typename RetType, typename SmpImageT, typename CoordT>
120 static RetType __invoke__ImageReadLod(SmpImageT SmpImg, CoordT Coords,
121  float Level) {
122 
123  // Convert from sycl types to builtin types to get correct function mangling.
124  using TempRetT = sycl::detail::ConvertToOpenCLType_t<RetType>;
125  auto TmpCoords = sycl::detail::convertToOpenCLType(Coords);
126 
127  enum ImageOperands { Lod = 0x2 };
128 
129  // OpImageSampleExplicitLod
130  // Its components must be the same as Sampled Type of the underlying
131  // OpTypeImage
132  // Sampled Image must be an object whose type is OpTypeSampledImage
133  // Image Operands encodes what operands follow. Either Lod
134  // or Grad image operands must be present
135  return sycl::detail::convertFromOpenCLTypeFor<RetType>(
136  __spirv_ImageSampleExplicitLod<SmpImageT, TempRetT, decltype(TmpCoords)>(
137  SmpImg, TmpCoords, ImageOperands::Lod, Level));
138 }
139 
140 template <typename RetType, typename SmpImageT, typename CoordT>
141 static RetType __invoke__ImageReadGrad(SmpImageT SmpImg, CoordT Coords,
142  CoordT Dx, CoordT Dy) {
143 
144  // Convert from sycl types to builtin types to get correct function mangling.
145  using TempRetT = sycl::detail::ConvertToOpenCLType_t<RetType>;
146  auto TmpCoords = sycl::detail::convertToOpenCLType(Coords);
147  auto TmpGraddX = sycl::detail::convertToOpenCLType(Dx);
148  auto TmpGraddY = sycl::detail::convertToOpenCLType(Dy);
149 
150  enum ImageOperands { Grad = 0x4 };
151 
152  // OpImageSampleExplicitLod
153  // Its components must be the same as Sampled Type of the underlying
154  // OpTypeImage
155  // Sampled Image must be an object whose type is OpTypeSampledImage
156  // Image Operands encodes what operands follow. Either Lod
157  // or Grad image operands must be present
158  return sycl::detail::convertFromOpenCLTypeFor<RetType>(
159  __spirv_ImageSampleExplicitLod<SmpImageT, TempRetT, decltype(TmpCoords)>(
160  SmpImg, TmpCoords, ImageOperands::Grad, TmpGraddX, TmpGraddY));
161 }
162 
163 template <typename RetType, typename ImageT, typename CoordT>
164 static RetType __invoke__ImageReadSampler(ImageT Img, CoordT Coords,
165  const __ocl_sampler_t &Smpl) {
166 
167  // Convert from sycl types to builtin types to get correct function mangling.
168  using TempRetT = sycl::detail::ConvertToOpenCLType_t<RetType>;
169  using SampledT =
170  typename sycl::detail::sampled_opencl_image_type<ImageT>::type;
171 
172  auto TmpCoords = sycl::detail::convertToOpenCLType(Coords);
173  // According to validation rules(SPIR-V specification, section 2.16.1) result
174  // of __spirv_SampledImage is allowed to be an operand of image lookup
175  // and query instructions explicitly specified to take an operand whose
176  // type is OpTypeSampledImage.
177  //
178  // According to SPIR-V specification section 3.32.10 at least one operand
179  // setting the level of detail must be present. The last two arguments of
180  // __spirv_ImageSampleExplicitLod represent image operand type and value.
181  // From the SPIR-V specification section 3.14:
182  enum ImageOperands { Lod = 0x2 };
183 
184  // Lod value is zero as mipmap is not supported.
185  return sycl::detail::convertFromOpenCLTypeFor<RetType>(
186  __spirv_ImageSampleExplicitLod<SampledT, TempRetT, decltype(TmpCoords)>(
187  __spirv_SampledImage<ImageT, SampledT>(Img, Smpl), TmpCoords,
188  ImageOperands::Lod, 0.0f));
189 }
190 
191 namespace sycl {
192 inline namespace _V1 {
193 namespace detail {
194 
195 // Function to return the number of channels for Image Channel Order returned by
196 // SPIR-V call to OpImageQueryOrder.
197 // The returned int value represents an enum from Image Channel Order. The enums
198 // for Image Channel Order are mapped differently in sycl and SPIR-V spec.
199 inline int getSPIRVNumChannels(int ImageChannelOrder) {
200  switch (ImageChannelOrder) {
201  case 0: // R
202  case 1: // A
203  case 10: // Rx
204  case 8: // Intensity
205  case 9: // Luminance
206  return 1;
207  case 2: // RG
208  case 3: // RA
209  case 11: // RGx
210  return 2;
211  case 4: // RGB
212  return 3;
213  case 5: // RGBA
214  case 6: // BGRA
215  case 7: // ARGB
216  case 12: // RGBx
217  case 19: // ABGR
218  case 17: // sRGBA
219  return 4;
220  case 13: // Depth
221  case 14: // DepthStencil
222  case 18: // sBGRA
223  // TODO: Enable the below assert after assert is supported for device
224  // compiler. assert(!"Unhandled image channel order in sycl.");
225  default:
226  return 0;
227  }
228 }
229 
230 // Function to compute the Element Size for a given Image Channel Type and Image
231 // Channel Order, returned by SPIR-V calls to OpImageQueryFormat and
232 // OpImageQueryOrder respectively.
233 // The returned int value from OpImageQueryFormat represents an enum from Image
234 // Channel Data Type. The enums for Image Channel Data Type are mapped
235 // differently in sycl and SPIR-V spec.
236 inline int getSPIRVElementSize(int ImageChannelType, int ImageChannelOrder) {
237  int NumChannels = getSPIRVNumChannels(ImageChannelOrder);
238  switch (ImageChannelType) {
239  case 0: // SnormInt8
240  case 2: // UnormInt8
241  case 7: // SignedInt8
242  case 10: // UnsignedInt8
243  return NumChannels;
244  case 1: // SnormInt16
245  case 3: // UnormInt16
246  case 8: // SignedInt16
247  case 11: // UnsignedInt16
248  case 13: // HalfFloat
249  return 2 * NumChannels;
250  case 4: // UnormShort565
251  case 5: // UnormShort555
252  return 2;
253  case 6: // UnormInt101010
254  return 4;
255  case 9: // SignedInt32
256  case 12: // UnsignedInt32
257  case 14: // Float
258  return 4 * NumChannels;
259  case 15: // UnormInt24
260  case 16: // UnormInt101010_2
261  default:
262  // TODO: Enable the below assert after assert is supported for device
263  // compiler. assert(!"Unhandled image channel type in sycl.");
264  return 0;
265  }
266 }
267 
268 template <int Dimensions, access::mode AccessMode, access::target AccessTarget>
269 struct opencl_image_type;
270 
271 // Creation of dummy ocl types for host_image targets.
272 // These dummy ocl types are needed by the compiler parser for the compilation
273 // of host application code with __SYCL_DEVICE_ONLY__ macro set.
274 template <int Dimensions, access::mode AccessMode>
275 struct opencl_image_type<Dimensions, AccessMode, access::target::host_image> {
276  using type =
277  opencl_image_type<Dimensions, AccessMode, access::target::host_image> *;
278 };
279 template <typename T> struct sampled_opencl_image_type<T *> {
280  using type = void *;
281 };
282 
283 #define __SYCL_IMAGETY_DEFINE(Dim, AccessMode, AMSuffix, Target, Ifarray_) \
284  template <> \
285  struct opencl_image_type<Dim, access::mode::AccessMode, \
286  access::target::Target> { \
287  using type = __ocl_image##Dim##d_##Ifarray_##AMSuffix##_t; \
288  };
289 #define __SYCL_SAMPLED_AND_IMAGETY_DEFINE(Dim, AccessMode, AMSuffix, Target, \
290  Ifarray_) \
291  __SYCL_IMAGETY_DEFINE(Dim, AccessMode, AMSuffix, Target, Ifarray_) \
292  template <> \
293  struct sampled_opencl_image_type<typename opencl_image_type< \
294  Dim, access::mode::AccessMode, access::target::Target>::type> { \
295  using type = __ocl_sampled_image##Dim##d_##Ifarray_##AMSuffix##_t; \
296  };
297 
298 #define __SYCL_IMAGETY_READ_3_DIM_IMAGE \
299  __SYCL_SAMPLED_AND_IMAGETY_DEFINE(1, read, ro, image, ) \
300  __SYCL_SAMPLED_AND_IMAGETY_DEFINE(2, read, ro, image, ) \
301  __SYCL_SAMPLED_AND_IMAGETY_DEFINE(3, read, ro, image, )
302 
303 #define __SYCL_IMAGETY_WRITE_3_DIM_IMAGE \
304  __SYCL_IMAGETY_DEFINE(1, write, wo, image, ) \
305  __SYCL_IMAGETY_DEFINE(2, write, wo, image, ) \
306  __SYCL_IMAGETY_DEFINE(3, write, wo, image, )
307 
308 #define __SYCL_IMAGETY_DISCARD_WRITE_3_DIM_IMAGE \
309  __SYCL_IMAGETY_DEFINE(1, discard_write, wo, image, ) \
310  __SYCL_IMAGETY_DEFINE(2, discard_write, wo, image, ) \
311  __SYCL_IMAGETY_DEFINE(3, discard_write, wo, image, )
312 
313 #define __SYCL_IMAGETY_READ_2_DIM_IARRAY \
314  __SYCL_SAMPLED_AND_IMAGETY_DEFINE(1, read, ro, image_array, array_) \
315  __SYCL_SAMPLED_AND_IMAGETY_DEFINE(2, read, ro, image_array, array_)
316 
317 #define __SYCL_IMAGETY_WRITE_2_DIM_IARRAY \
318  __SYCL_IMAGETY_DEFINE(1, write, wo, image_array, array_) \
319  __SYCL_IMAGETY_DEFINE(2, write, wo, image_array, array_)
320 
321 #define __SYCL_IMAGETY_DISCARD_WRITE_2_DIM_IARRAY \
322  __SYCL_IMAGETY_DEFINE(1, discard_write, wo, image_array, array_) \
323  __SYCL_IMAGETY_DEFINE(2, discard_write, wo, image_array, array_)
324 
325 __SYCL_IMAGETY_READ_3_DIM_IMAGE
326 __SYCL_IMAGETY_WRITE_3_DIM_IMAGE
327 __SYCL_IMAGETY_DISCARD_WRITE_3_DIM_IMAGE
328 
329 __SYCL_IMAGETY_READ_2_DIM_IARRAY
330 __SYCL_IMAGETY_WRITE_2_DIM_IARRAY
331 __SYCL_IMAGETY_DISCARD_WRITE_2_DIM_IARRAY
332 
333 } // namespace detail
334 } // namespace _V1
335 } // namespace sycl
336 
337 #undef __SYCL_SAMPLED_AND_IMAGETY_DEFINE
338 #undef __SYCL_INVOKE_SPIRV_CALL_ARG1
339 #undef __SYCL_IMAGETY_DEFINE
340 #undef __SYCL_IMAGETY_DISCARD_WRITE_3_DIM_IMAGE
341 #undef __SYCL_IMAGETY_READ_3_DIM_IMAGE
342 #undef __SYCL_IMAGETY_WRITE_3_DIM_IMAGE
343 #undef __SYCL_IMAGETY_DISCARD_WRITE_2_DIM_IARRAY
344 #undef __SYCL_IMAGETY_READ_2_DIM_IARRAY
345 #undef __SYCL_IMAGETY_WRITE_2_DIM_IARRAY
346 #endif // #ifdef __SYCL_DEVICE_ONLY__
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS Dimensions
Definition: accessor.hpp:3233
class __SYCL_EBO __SYCL_SPECIAL_CLASS __SYCL_TYPE(local_accessor) local_accessor class __SYCL_EBO __SYCL_SPECIAL_CLASS AccessMode
Definition: accessor.hpp:3233
Definition: access.hpp:18
void * __ocl_sampler_t