DPC++ Runtime
Runtime libraries for oneAPI DPC++
bindless_images.hpp
Go to the documentation of this file.
1 //==----------- bindless_images.hpp --- SYCL bindless images ---------------==//
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 #pragma once
10 
11 #include <sycl/context.hpp> // for context
12 #include <sycl/detail/export.hpp> // for __SYCL_EXPORT
13 #include <sycl/device.hpp> // for device
14 #include <sycl/ext/oneapi/bindless_images_descriptor.hpp> // for image_desc...
15 #include <sycl/ext/oneapi/bindless_images_interop.hpp> // for interop_me...
16 #include <sycl/ext/oneapi/bindless_images_memory.hpp> // for image_mem_...
17 #include <sycl/ext/oneapi/bindless_images_sampler.hpp> // for bindless_i...
18 #include <sycl/image.hpp> // for image_chan...
19 #include <sycl/queue.hpp> // for queue
20 #include <sycl/range.hpp> // for range
21 
22 #include <assert.h> // for assert
23 #include <stddef.h> // for size_t
24 #include <type_traits> // for is_scalar
25 
26 #ifdef __SYCL_DEVICE_ONLY__
27 #include <sycl/detail/image_ocl_types.hpp> // for __invoke__*
28 #endif
29 
30 namespace sycl {
31 inline namespace _V1 {
32 namespace ext::oneapi::experimental {
33 
36  using raw_image_handle_type = uint64_t;
37 
39 
41  : raw_handle(raw_image_handle) {}
42 
44 };
45 
48  using raw_image_handle_type = uint64_t;
49 
51 
53 
55 };
56 
65 __SYCL_EXPORT image_mem_handle
66 alloc_image_mem(const image_descriptor &desc, const sycl::device &syclDevice,
67  const sycl::context &syclContext);
68 
76 __SYCL_EXPORT image_mem_handle alloc_image_mem(const image_descriptor &desc,
77  const sycl::queue &syclQueue);
78 
87 __SYCL_EXPORT void free_image_mem(image_mem_handle handle, image_type imageType,
88  const sycl::device &syclDevice,
89  const sycl::context &syclContext);
90 
98 __SYCL_EXPORT void free_image_mem(image_mem_handle handle, image_type imageType,
99  const sycl::queue &syclQueue);
100 
111  const image_mem_handle mipMem, unsigned int level,
112  const sycl::device &syclDevice, const sycl::context &syclContext);
113 
122 __SYCL_EXPORT image_mem_handle
123 get_mip_level_mem_handle(const image_mem_handle mipMem, unsigned int level,
124  const sycl::queue &syclQueue);
125 
138 template <typename ExternalMemHandleType>
141  const sycl::device &syclDevice, const sycl::context &syclContext);
142 
154 template <typename ExternalMemHandleType>
157  const sycl::queue &syclQueue);
158 
169 __SYCL_EXPORT
171  const image_descriptor &desc,
172  const sycl::device &syclDevice,
173  const sycl::context &syclContext);
174 
184 __SYCL_EXPORT
186  const image_descriptor &desc,
187  const sycl::queue &syclQueue);
188 
202 template <typename ExternalSemaphoreHandleType>
205  externalSemaphoreDesc,
206  const sycl::device &syclDevice, const sycl::context &syclContext);
207 
219 template <typename ExternalSemaphoreHandleType>
222  externalSemaphoreDesc,
223  const sycl::queue &syclQueue);
224 
234 __SYCL_EXPORT void
236  const sycl::device &syclDevice,
237  const sycl::context &syclContext);
238 
246 __SYCL_EXPORT void
248  const sycl::queue &syclQueue);
249 
259 __SYCL_EXPORT void release_external_memory(interop_mem_handle interopHandle,
260  const sycl::device &syclDevice,
261  const sycl::context &syclContext);
262 
270 __SYCL_EXPORT void release_external_memory(interop_mem_handle interopHandle,
271  const sycl::queue &syclQueue);
272 
282 __SYCL_EXPORT unsampled_image_handle
283 create_image(image_mem &memHandle, const image_descriptor &desc,
284  const sycl::device &syclDevice, const sycl::context &syclContext);
285 
294 __SYCL_EXPORT unsampled_image_handle create_image(image_mem &memHandle,
295  const image_descriptor &desc,
296  const sycl::queue &syclQueue);
297 
307 __SYCL_EXPORT unsampled_image_handle
308 create_image(image_mem_handle memHandle, const image_descriptor &desc,
309  const sycl::device &syclDevice, const sycl::context &syclContext);
310 
320  const image_descriptor &desc,
321  const sycl::queue &syclQueue);
322 
334 __SYCL_EXPORT sampled_image_handle
335 create_image(void *imgMem, size_t pitch, const bindless_image_sampler &sampler,
336  const image_descriptor &desc, const sycl::device &syclDevice,
337  const sycl::context &syclContext);
338 
349 __SYCL_EXPORT sampled_image_handle
350 create_image(void *imgMem, size_t pitch, const bindless_image_sampler &sampler,
351  const image_descriptor &desc, const sycl::queue &syclQueue);
352 
363 __SYCL_EXPORT sampled_image_handle
364 create_image(image_mem &memHandle, const bindless_image_sampler &sampler,
365  const image_descriptor &desc, const sycl::device &syclDevice,
366  const sycl::context &syclContext);
367 
377 __SYCL_EXPORT sampled_image_handle
378 create_image(image_mem &memHandle, const bindless_image_sampler &sampler,
379  const image_descriptor &desc, const sycl::queue &syclQueue);
380 
391 __SYCL_EXPORT sampled_image_handle
392 create_image(image_mem_handle memHandle, const bindless_image_sampler &sampler,
393  const image_descriptor &desc, const sycl::device &syclDevice,
394  const sycl::context &syclContext);
395 
405 __SYCL_EXPORT sampled_image_handle
406 create_image(image_mem_handle memHandle, const bindless_image_sampler &sampler,
407  const image_descriptor &desc, const sycl::queue &syclQueue);
408 
417 __SYCL_EXPORT void destroy_image_handle(unsampled_image_handle &imageHandle,
418  const sycl::device &syclDevice,
419  const sycl::context &syclContext);
420 
428 __SYCL_EXPORT void destroy_image_handle(unsampled_image_handle &imageHandle,
429  const sycl::queue &syclQueue);
430 
439 __SYCL_EXPORT void destroy_image_handle(sampled_image_handle &imageHandle,
440  const sycl::device &syclDevice,
441  const sycl::context &syclContext);
442 
450 __SYCL_EXPORT void destroy_image_handle(sampled_image_handle &imageHandle,
451  const sycl::queue &syclQueue);
452 
463 __SYCL_EXPORT void *pitched_alloc_device(size_t *resultPitch,
464  size_t widthInBytes, size_t height,
465  unsigned int elementSizeBytes,
466  const sycl::queue &syclQueue);
467 
479 __SYCL_EXPORT void *pitched_alloc_device(size_t *resultPitch,
480  size_t widthInBytes, size_t height,
481  unsigned int elementSizeBytes,
482  const sycl::device &syclDevice,
483  const sycl::context &syclContext);
484 
493 __SYCL_EXPORT void *pitched_alloc_device(size_t *resultPitch,
494  const image_descriptor &desc,
495  const sycl::queue &syclQueue);
496 
506 __SYCL_EXPORT void *pitched_alloc_device(size_t *resultPitch,
507  const image_descriptor &desc,
508  const sycl::device &syclDevice,
509  const sycl::context &syclContext);
510 
519 __SYCL_EXPORT sycl::range<3> get_image_range(const image_mem_handle memHandle,
520  const sycl::device &syclDevice,
521  const sycl::context &syclContext);
522 
530 __SYCL_EXPORT sycl::range<3> get_image_range(const image_mem_handle memHandle,
531  const sycl::queue &syclQueue);
532 
541 __SYCL_EXPORT sycl::image_channel_type
543  const sycl::device &syclDevice,
544  const sycl::context &syclContext);
545 
553 __SYCL_EXPORT sycl::image_channel_type
555  const sycl::queue &syclQueue);
556 
565 __SYCL_EXPORT unsigned int
567  const sycl::device &syclDevice,
568  const sycl::context &syclContext);
569 
577 __SYCL_EXPORT unsigned int
579  const sycl::queue &syclQueue);
580 
581 namespace detail {
582 
583 // is sycl::vec
584 template <typename T> struct is_vec {
585  static constexpr bool value = false;
586 };
587 template <typename T, int N> struct is_vec<sycl::vec<T, N>> {
588  static constexpr bool value = true;
589 };
590 template <typename T> inline constexpr bool is_vec_v = is_vec<T>::value;
591 
592 // Get the number of coordinates
593 template <typename CoordT> constexpr size_t coord_size() {
594  if constexpr (std::is_scalar_v<CoordT>) {
595  return 1;
596  } else {
597  return CoordT::size();
598  }
599 }
600 
601 // bit_cast Color to a type the backend is known to accept
602 template <typename DataT> constexpr auto convert_color(DataT Color) {
603  constexpr size_t dataSize = sizeof(DataT);
604  static_assert(
605  dataSize == 1 || dataSize == 2 || dataSize == 4 || dataSize == 8 ||
606  dataSize == 16,
607  "Expected input data type to be of size 1, 2, 4, 8, or 16 bytes.");
608 
609  if constexpr (dataSize == 1) {
610  return sycl::bit_cast<uint8_t>(Color);
611  } else if constexpr (dataSize == 2) {
612  return sycl::bit_cast<uint16_t>(Color);
613  } else if constexpr (dataSize == 4) {
614  return sycl::bit_cast<uint32_t>(Color);
615  } else if constexpr (dataSize == 8) {
616  return sycl::bit_cast<sycl::vec<uint32_t, 2>>(Color);
617  } else { // dataSize == 16
618  return sycl::bit_cast<sycl::vec<uint32_t, 4>>(Color);
619  }
620 }
621 
622 // assert coords or elements of coords is of an integer type
623 template <typename CoordT> constexpr void assert_unsampled_coords() {
624  if constexpr (std::is_scalar_v<CoordT>) {
625  static_assert(std::is_same_v<CoordT, int>,
626  "Expected integer coordinate data type");
627  } else {
628  static_assert(is_vec_v<CoordT>, "Expected sycl::vec coordinates");
629  static_assert(std::is_same_v<typename CoordT::element_type, int>,
630  "Expected integer coordinates data type");
631  }
632 }
633 
634 template <typename CoordT> constexpr bool are_floating_coords() {
635  if constexpr (is_vec_v<CoordT>) {
636  return std::is_same_v<typename CoordT::element_type, float>;
637  } else {
638  return std::is_same_v<CoordT, float>;
639  }
640 }
641 
642 template <typename CoordT> constexpr bool are_integer_coords() {
643  if constexpr (is_vec_v<CoordT>) {
644  return std::is_same_v<typename CoordT::element_type, int>;
645  } else {
646  return std::is_same_v<CoordT, int>;
647  }
648 }
649 
650 template <typename CoordT> constexpr void assert_coords_type() {
651  static_assert(are_floating_coords<CoordT>() || are_integer_coords<CoordT>(),
652  "Expected coordinates to be of `float` or `int` type, or "
653  "vectors of these types.");
654 }
655 
656 // assert coords or elements of coords is of a float type
657 template <typename CoordT> constexpr void assert_sample_coords() {
658  if constexpr (std::is_scalar_v<CoordT>) {
659  static_assert(std::is_same_v<CoordT, float>,
660  "Expected float coordinate data type");
661  } else {
662  static_assert(is_vec_v<CoordT>, "Expected sycl::vec coordinates");
663  static_assert(std::is_same_v<typename CoordT::element_type, float>,
664  "Expected float coordinates data type");
665  }
666 }
667 
668 // assert coords or elements of coords is of a int type
669 template <typename CoordT> constexpr void assert_fetch_coords() {
670  if constexpr (std::is_scalar_v<CoordT>) {
671  static_assert(std::is_same_v<CoordT, int>,
672  "Expected int coordinate data type");
673  } else {
674  static_assert(is_vec_v<CoordT>, "Expected sycl::vec coordinates");
675  static_assert(std::is_same_v<typename CoordT::element_type, int>,
676  "Expected int coordinates data type");
677  }
678 }
679 
680 template <typename DataT> constexpr bool is_data_size_valid() {
681  return (sizeof(DataT) == 1) || (sizeof(DataT) == 2) || (sizeof(DataT) == 4) ||
682  (sizeof(DataT) == 8) || (sizeof(DataT) == 16);
683 }
684 
685 template <typename DataT> constexpr bool is_recognized_standard_type() {
686  return is_data_size_valid<DataT>() &&
687  (is_vec_v<DataT> || std::is_scalar_v<DataT> ||
688  std::is_floating_point_v<DataT> || std::is_same_v<DataT, sycl::half>);
689 }
690 
691 #ifdef __SYCL_DEVICE_ONLY__
692 
693 // Image types used for generating SPIR-V
694 template <int NDims>
695 using OCLImageTyRead =
696  typename sycl::detail::opencl_image_type<NDims, sycl::access::mode::read,
697  sycl::access::target::image>::type;
698 
699 template <int NDims>
700 using OCLImageTyWrite =
701  typename sycl::detail::opencl_image_type<NDims, sycl::access::mode::write,
702  sycl::access::target::image>::type;
703 
704 template <int NDims>
705 using OCLImageArrayTyRead = typename sycl::detail::opencl_image_type<
706  NDims, sycl::access::mode::read, sycl::access::target::image_array>::type;
707 
708 template <int NDims>
709 using OCLImageArrayTyWrite = typename sycl::detail::opencl_image_type<
710  NDims, sycl::access::mode::write, sycl::access::target::image_array>::type;
711 
712 template <int NDims>
713 using OCLSampledImageArrayTyRead =
714  typename sycl::detail::sampled_opencl_image_type<
715  detail::OCLImageArrayTyRead<NDims>>::type;
716 
717 // Macros are required because it is not legal for a function to return
718 // a variable of type 'opencl_image_type'.
719 #if defined(__SPIR__)
720 #define CONVERT_HANDLE_TO_IMAGE(raw_handle, ImageType) \
721  __spirv_ConvertHandleToImageINTEL<ImageType>(raw_handle)
722 
723 #define CONVERT_HANDLE_TO_SAMPLED_IMAGE(raw_handle, NDims) \
724  __spirv_ConvertHandleToSampledImageINTEL< \
725  typename sycl::detail::sampled_opencl_image_type< \
726  detail::OCLImageTyRead<NDims>>::type>(raw_handle)
727 
728 #define CONVERT_HANDLE_TO_SAMPLED_IMAGE_ARRAY(raw_handle, NDims) \
729  __spirv_ConvertHandleToSampledImageINTEL< \
730  typename sycl::detail::sampled_opencl_image_type< \
731  detail::OCLImageArrayTyRead<NDims>>::type>(raw_handle)
732 
733 #define FETCH_UNSAMPLED_IMAGE(DataT, raw_handle, coords) \
734  __invoke__ImageRead<DataT>(raw_handle, coords)
735 
736 #define FETCH_SAMPLED_IMAGE(DataT, raw_handle, coords) \
737  __invoke__ImageReadLod<DataT>(raw_handle, coords, 0.f)
738 
739 #define SAMPLE_IMAGE_READ(DataT, raw_handle, coords) \
740  __invoke__ImageReadLod<DataT>(raw_handle, coords, 0.f)
741 
742 #define FETCH_IMAGE_ARRAY(DataT, raw_handle, coords, arrayLayer, coordsLayer) \
743  __invoke__ImageRead<DataT>(raw_handle, coordsLayer)
744 
745 #define WRITE_IMAGE_ARRAY(raw_handle, coords, arrayLayer, coordsLayer, color) \
746  __invoke__ImageWrite(raw_handle, coordsLayer, color)
747 
748 #define FETCH_SAMPLED_IMAGE_ARRAY(DataT, raw_handle, coords, arrayLayer, \
749  coordsLayer) \
750  __invoke__ImageReadLod<DataT>(raw_handle, coordsLayer, 0.f)
751 
752 #define READ_SAMPLED_IMAGE_ARRAY(DataT, raw_handle, coords, arrayLayer, \
753  coordsLayer) \
754  __invoke__ImageReadLod<DataT>(raw_handle, coordsLayer, 0.f)
755 
756 #else
757 #define CONVERT_HANDLE_TO_IMAGE(raw_handle, ImageType) raw_handle
758 
759 #define CONVERT_HANDLE_TO_SAMPLED_IMAGE(raw_handle, NDims) raw_handle
760 
761 #define CONVERT_HANDLE_TO_SAMPLED_IMAGE_ARRAY(raw_handle, NDims) raw_handle
762 
763 #define FETCH_UNSAMPLED_IMAGE(DataT, raw_handle, coords) \
764  __invoke__ImageFetch<DataT>(raw_handle, coords)
765 
766 #define FETCH_SAMPLED_IMAGE(DataT, raw_handle, coords) \
767  __invoke__SampledImageFetch<DataT>(raw_handle, coords)
768 
769 #define SAMPLE_IMAGE_READ(DataT, raw_handle, coords) \
770  __invoke__ImageRead<DataT>(raw_handle, coords)
771 
772 #define FETCH_IMAGE_ARRAY(DataT, raw_handle, coords, arrayLayer, coordsLayer) \
773  __invoke__ImageArrayFetch<DataT>(raw_handle, coords, arrayLayer)
774 
775 #define WRITE_IMAGE_ARRAY(raw_handle, coords, arrayLayer, coordsLayer, color) \
776  __invoke__ImageArrayWrite(raw_handle, coords, arrayLayer, color)
777 
778 #define FETCH_SAMPLED_IMAGE_ARRAY(DataT, raw_handle, coords, arrayLayer, \
779  coordsLayer) \
780  __invoke__SampledImageArrayFetch<DataT>(raw_handle, coords, arrayLayer)
781 
782 #define READ_SAMPLED_IMAGE_ARRAY(DataT, raw_handle, coords, arrayLayer, \
783  coordsLayer) \
784  __invoke__ImageArrayRead<DataT>(raw_handle, coords, arrayLayer)
785 
786 #endif
787 
788 #endif // __SYCL_DEVICE_ONLY__
789 
790 } // namespace detail
791 
813 template <typename DataT, typename HintT = DataT, typename CoordT>
814 DataT fetch_image(const unsampled_image_handle &imageHandle [[maybe_unused]],
815  const CoordT &coords [[maybe_unused]]) {
816  detail::assert_fetch_coords<CoordT>();
817  constexpr size_t coordSize = detail::coord_size<CoordT>();
818  static_assert(coordSize == 1 || coordSize == 2 || coordSize == 3,
819  "Expected input coordinate to be have 1, 2, or 3 components "
820  "for 1D, 2D and 3D images, respectively.");
821 
822 #ifdef __SYCL_DEVICE_ONLY__
823  if constexpr (detail::is_recognized_standard_type<DataT>()) {
824  return FETCH_UNSAMPLED_IMAGE(
825  DataT,
826  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
827  detail::OCLImageTyRead<coordSize>),
828  coords);
829 
830  } else {
831  static_assert(sizeof(HintT) == sizeof(DataT),
832  "When trying to read a user-defined type, HintT must be of "
833  "the same size as the user-defined DataT.");
834  static_assert(detail::is_recognized_standard_type<HintT>(),
835  "HintT must always be a recognized standard type");
836  return sycl::bit_cast<DataT>(FETCH_UNSAMPLED_IMAGE(
837  HintT,
838  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
839  detail::OCLImageTyRead<coordSize>),
840  coords));
841  }
842 #else
843  assert(false); // Bindless images not yet implemented on host
844 #endif
845 }
846 
868 template <typename DataT, typename HintT = DataT, typename CoordT>
869 DataT fetch_image(const sampled_image_handle &imageHandle [[maybe_unused]],
870  const CoordT &coords [[maybe_unused]]) {
871  detail::assert_fetch_coords<CoordT>();
872  constexpr size_t coordSize = detail::coord_size<CoordT>();
873  static_assert(coordSize == 1 || coordSize == 2 || coordSize == 3,
874  "Expected input coordinate to be have 1, 2, or 3 components "
875  "for 1D, 2D and 3D images, respectively.");
876  static_assert(sizeof(HintT) == sizeof(DataT),
877  "When trying to read a user-defined type, HintT must be of "
878  "the same size as the user-defined DataT.");
879  static_assert(detail::is_recognized_standard_type<HintT>(),
880  "HintT must always be a recognized standard type");
881 
882 #ifdef __SYCL_DEVICE_ONLY__
883  if constexpr (detail::is_recognized_standard_type<DataT>()) {
884  return FETCH_SAMPLED_IMAGE(
885  DataT,
886  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
887  coords);
888  } else {
889  return sycl::bit_cast<DataT>(FETCH_SAMPLED_IMAGE(
890  HintT,
891  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
892  coords));
893  }
894 #else
895  assert(false); // Bindless images not yet implemented on host.
896 #endif
897 }
898 
920 template <typename DataT, typename HintT = DataT, typename CoordT>
921 DataT sample_image(const sampled_image_handle &imageHandle [[maybe_unused]],
922  const CoordT &coords [[maybe_unused]]) {
923  detail::assert_sample_coords<CoordT>();
924  constexpr size_t coordSize = detail::coord_size<CoordT>();
925  static_assert(coordSize == 1 || coordSize == 2 || coordSize == 3,
926  "Expected input coordinate to be have 1, 2, or 3 components "
927  "for 1D, 2D and 3D images, respectively.");
928  static_assert(sizeof(HintT) == sizeof(DataT),
929  "When trying to read a user-defined type, HintT must be of "
930  "the same size as the user-defined DataT.");
931  static_assert(detail::is_recognized_standard_type<HintT>(),
932  "HintT must always be a recognized standard type");
933 
934 #ifdef __SYCL_DEVICE_ONLY__
935  if constexpr (detail::is_recognized_standard_type<DataT>()) {
936  return SAMPLE_IMAGE_READ(
937  DataT,
938  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
939  coords);
940  } else {
941  return sycl::bit_cast<DataT>(SAMPLE_IMAGE_READ(
942  HintT,
943  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
944  coords));
945  }
946 #else
947  assert(false); // Bindless images not yet implemented on host.
948 #endif
949 }
950 
966 template <typename DataT, typename HintT = DataT, typename CoordT>
967 DataT sample_mipmap(const sampled_image_handle &imageHandle [[maybe_unused]],
968  const CoordT &coords [[maybe_unused]],
969  const float level [[maybe_unused]]) {
970  detail::assert_sample_coords<CoordT>();
971  constexpr size_t coordSize = detail::coord_size<CoordT>();
972  static_assert(coordSize == 1 || coordSize == 2 || coordSize == 3,
973  "Expected input coordinate to be have 1, 2, or 3 components "
974  "for 1D, 2D and 3D images, respectively.");
975 
976 #ifdef __SYCL_DEVICE_ONLY__
977  if constexpr (detail::is_recognized_standard_type<DataT>()) {
978  return __invoke__ImageReadLod<DataT>(
979  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
980  coords, level);
981  } else {
982  static_assert(sizeof(HintT) == sizeof(DataT),
983  "When trying to read a user-defined type, HintT must be of "
984  "the same size as the user-defined DataT.");
985  static_assert(detail::is_recognized_standard_type<HintT>(),
986  "HintT must always be a recognized standard type");
987  return sycl::bit_cast<DataT>(__invoke__ImageReadLod<HintT>(
988  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
989  coords, level));
990  }
991 #else
992  assert(false); // Bindless images not yet implemented on host
993 #endif
994 }
995 
1012 template <typename DataT, typename HintT = DataT, typename CoordT>
1013 DataT sample_mipmap(const sampled_image_handle &imageHandle [[maybe_unused]],
1014  const CoordT &coords [[maybe_unused]],
1015  const CoordT &dX [[maybe_unused]],
1016  const CoordT &dY [[maybe_unused]]) {
1017  detail::assert_sample_coords<CoordT>();
1018  constexpr size_t coordSize = detail::coord_size<CoordT>();
1019  static_assert(coordSize == 1 || coordSize == 2 || coordSize == 3,
1020  "Expected input coordinates and gradients to have 1, 2, or 3 "
1021  "components for 1D, 2D, and 3D images, respectively.");
1022 
1023 #ifdef __SYCL_DEVICE_ONLY__
1024  if constexpr (detail::is_recognized_standard_type<DataT>()) {
1025  return __invoke__ImageReadGrad<DataT>(
1026  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
1027  coords, dX, dY);
1028  } else {
1029  static_assert(sizeof(HintT) == sizeof(DataT),
1030  "When trying to read a user-defined type, HintT must be of "
1031  "the same size as the user-defined DataT.");
1032  static_assert(detail::is_recognized_standard_type<HintT>(),
1033  "HintT must always be a recognized standard type");
1034  return sycl::bit_cast<DataT>(__invoke__ImageReadGrad<HintT>(
1035  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, coordSize),
1036  coords, dX, dY));
1037  }
1038 #else
1039  assert(false); // Bindless images not yet implemented on host
1040 #endif
1041 }
1042 
1058 template <typename DataT, typename HintT = DataT, typename CoordT>
1060  [[maybe_unused]],
1061  const CoordT &coords [[maybe_unused]],
1062  unsigned int arrayLayer [[maybe_unused]]) {
1063  detail::assert_unsampled_coords<CoordT>();
1064  constexpr size_t coordSize = detail::coord_size<CoordT>();
1065  static_assert(coordSize == 1 || coordSize == 2,
1066  "Expected input coordinate to be have 1 or 2 components for 1D "
1067  "and 2D images respectively.");
1068 
1069 #ifdef __SYCL_DEVICE_ONLY__
1070  sycl::vec<int, coordSize + 1> coordsLayer{coords, arrayLayer};
1071  if constexpr (detail::is_recognized_standard_type<DataT>()) {
1072  return FETCH_IMAGE_ARRAY(
1073  DataT,
1074  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
1075  detail::OCLImageArrayTyRead<coordSize>),
1076  coords, arrayLayer, coordsLayer);
1077  } else {
1078  static_assert(sizeof(HintT) == sizeof(DataT),
1079  "When trying to fetch a user-defined type, HintT must be of "
1080  "the same size as the user-defined DataT.");
1081  static_assert(detail::is_recognized_standard_type<HintT>(),
1082  "HintT must always be a recognized standard type");
1083  return sycl::bit_cast<DataT>(FETCH_IMAGE_ARRAY(
1084  HintT,
1085  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
1086  detail::OCLImageArrayTyRead<coordSize>),
1087  coords, arrayLayer, coordsLayer));
1088  }
1089 #else
1090  assert(false); // Bindless images not yet implemented on host.
1091 #endif
1092 }
1093 
1108 template <typename DataT, typename HintT = DataT>
1109 DataT fetch_cubemap(const unsampled_image_handle &imageHandle,
1110  const int2 &coords, unsigned int face) {
1111  return fetch_image_array<DataT, HintT>(imageHandle, coords, face);
1112 }
1113 
1128 template <typename DataT, typename HintT = DataT>
1129 DataT sample_cubemap(const sampled_image_handle &imageHandle [[maybe_unused]],
1130  const sycl::float3 &dirVec [[maybe_unused]]) {
1131  [[maybe_unused]] constexpr size_t NDims = 2;
1132 
1133 #ifdef __SYCL_DEVICE_ONLY__
1134  if constexpr (detail::is_recognized_standard_type<DataT>()) {
1135  return __invoke__ImageReadCubemap<DataT, uint64_t>(
1136  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, NDims), dirVec);
1137  } else {
1138  static_assert(sizeof(HintT) == sizeof(DataT),
1139  "When trying to read a user-defined type, HintT must be of "
1140  "the same size as the user-defined DataT.");
1141  static_assert(detail::is_recognized_standard_type<HintT>(),
1142  "HintT must always be a recognized standard type");
1143  return sycl::bit_cast<DataT>(__invoke__ImageReadCubemap<HintT, uint64_t>(
1144  CONVERT_HANDLE_TO_SAMPLED_IMAGE(imageHandle.raw_handle, NDims),
1145  dirVec));
1146  }
1147 #else
1148  assert(false); // Bindless images not yet implemented on host
1149 #endif
1150 }
1151 
1167 template <typename DataT, typename HintT = DataT, typename CoordT>
1168 DataT fetch_image_array(const sampled_image_handle &imageHandle
1169  [[maybe_unused]],
1170  const CoordT &coords [[maybe_unused]],
1171  unsigned int arrayLayer [[maybe_unused]]) {
1172  detail::assert_unsampled_coords<CoordT>();
1173  constexpr size_t coordSize = detail::coord_size<CoordT>();
1174  static_assert(coordSize == 1 || coordSize == 2,
1175  "Expected input coordinate to be have 1 or 2 components for 1D "
1176  "and 2D images respectively.");
1177 
1178 #ifdef __SYCL_DEVICE_ONLY__
1179  sycl::vec<int, coordSize + 1> coordsLayer{coords, arrayLayer};
1180  if constexpr (detail::is_recognized_standard_type<DataT>()) {
1181  return FETCH_SAMPLED_IMAGE_ARRAY(DataT,
1182  CONVERT_HANDLE_TO_SAMPLED_IMAGE_ARRAY(
1183  imageHandle.raw_handle, coordSize),
1184  coords, arrayLayer, coordsLayer);
1185  } else {
1186  static_assert(sizeof(HintT) == sizeof(DataT),
1187  "When trying to fetch a user-defined type, HintT must be of "
1188  "the same size as the user-defined DataT.");
1189  static_assert(detail::is_recognized_standard_type<HintT>(),
1190  "HintT must always be a recognized standard type");
1191  return sycl::bit_cast<DataT>(
1192  FETCH_SAMPLED_IMAGE_ARRAY(HintT,
1193  CONVERT_HANDLE_TO_SAMPLED_IMAGE_ARRAY(
1194  imageHandle.raw_handle, coordSize),
1195  coords, arrayLayer, coordsLayer));
1196  }
1197 #else
1198  assert(false); // Bindless images not yet implemented on host.
1199 #endif
1200 }
1201 
1217 template <typename DataT, typename HintT = DataT, typename CoordT>
1219  [[maybe_unused]],
1220  const CoordT &coords [[maybe_unused]],
1221  unsigned int arrayLayer [[maybe_unused]]) {
1222  detail::assert_sample_coords<CoordT>();
1223  constexpr size_t coordSize = detail::coord_size<CoordT>();
1224  static_assert(coordSize == 1 || coordSize == 2,
1225  "Expected input coordinate to be have 1 or 2 components for 1D "
1226  "and 2D images respectively.");
1227 
1228 #ifdef __SYCL_DEVICE_ONLY__
1229  sycl::vec<float, coordSize + 1> coordsLayer{coords, arrayLayer};
1230  if constexpr (detail::is_recognized_standard_type<DataT>()) {
1231  return READ_SAMPLED_IMAGE_ARRAY(DataT,
1232  CONVERT_HANDLE_TO_SAMPLED_IMAGE_ARRAY(
1233  imageHandle.raw_handle, coordSize),
1234  coords, arrayLayer, coordsLayer);
1235  } else {
1236  static_assert(sizeof(HintT) == sizeof(DataT),
1237  "When trying to fetch a user-defined type, HintT must be of "
1238  "the same size as the user-defined DataT.");
1239  static_assert(detail::is_recognized_standard_type<HintT>(),
1240  "HintT must always be a recognized standard type");
1241  return sycl::bit_cast<DataT>(
1242  READ_SAMPLED_IMAGE_ARRAY(HintT,
1243  CONVERT_HANDLE_TO_SAMPLED_IMAGE_ARRAY(
1244  imageHandle.raw_handle, coordSize),
1245  coords, arrayLayer, coordsLayer));
1246  }
1247 #else
1248  assert(false); // Bindless images not yet implemented on host.
1249 #endif
1250 }
1251 
1262 template <typename DataT, typename CoordT>
1263 void write_image(unsampled_image_handle imageHandle [[maybe_unused]],
1264  const CoordT &coords [[maybe_unused]],
1265  const DataT &color [[maybe_unused]]) {
1266  detail::assert_unsampled_coords<CoordT>();
1267  constexpr size_t coordSize = detail::coord_size<CoordT>();
1268  static_assert(coordSize == 1 || coordSize == 2 || coordSize == 3,
1269  "Expected input coordinate to be have 1, 2, or 3 components "
1270  "for 1D, 2D and 3D images, respectively.");
1271 
1272 #ifdef __SYCL_DEVICE_ONLY__
1273  if constexpr (detail::is_recognized_standard_type<DataT>()) {
1274  __invoke__ImageWrite(
1275  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
1276  detail::OCLImageTyWrite<coordSize>),
1277  coords, color);
1278  } else {
1279  // Convert DataT to a supported backend write type when user-defined type is
1280  // passed
1281  __invoke__ImageWrite(
1282  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
1283  detail::OCLImageTyWrite<coordSize>),
1284  coords, detail::convert_color(color));
1285  }
1286 #else
1287  assert(false); // Bindless images not yet implemented on host
1288 #endif
1289 }
1290 
1302 template <typename DataT, typename CoordT>
1303 void write_image_array(unsampled_image_handle imageHandle [[maybe_unused]],
1304  const CoordT &coords [[maybe_unused]],
1305  unsigned int arrayLayer [[maybe_unused]],
1306  const DataT &color [[maybe_unused]]) {
1307  detail::assert_unsampled_coords<CoordT>();
1308  constexpr size_t coordSize = detail::coord_size<CoordT>();
1309  static_assert(coordSize == 1 || coordSize == 2,
1310  "Expected input coordinate to be have 1 or 2 components for 1D "
1311  "and 2D images respectively.");
1312 
1313 #ifdef __SYCL_DEVICE_ONLY__
1314  sycl::vec<int, coordSize + 1> coordsLayer{coords, arrayLayer};
1315  if constexpr (detail::is_recognized_standard_type<DataT>()) {
1316  WRITE_IMAGE_ARRAY(
1317  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
1318  detail::OCLImageArrayTyWrite<coordSize>),
1319  coords, arrayLayer, coordsLayer, color);
1320  } else {
1321  // Convert DataT to a supported backend write type when user-defined type is
1322  // passed
1323  WRITE_IMAGE_ARRAY(
1324  CONVERT_HANDLE_TO_IMAGE(imageHandle.raw_handle,
1325  detail::OCLImageArrayTyWrite<coordSize>),
1326  coords, arrayLayer, coordsLayer, detail::convert_color(color));
1327  }
1328 #else
1329  assert(false); // Bindless images not yet implemented on host.
1330 #endif
1331 }
1332 
1343 template <typename DataT>
1344 void write_cubemap(unsampled_image_handle imageHandle, const sycl::int2 &coords,
1345  int face, const DataT &color) {
1346  return write_image_array(imageHandle, coords, face, color);
1347 }
1348 
1349 } // namespace ext::oneapi::experimental
1350 
1352  const void *Src, ext::oneapi::experimental::image_mem_handle Dest,
1354  const detail::code_location &CodeLoc) {
1355  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1356  return submit(
1357  [&](handler &CGH) { CGH.ext_oneapi_copy(Src, Dest, DestImgDesc); },
1358  CodeLoc);
1359 }
1360 
1362  const void *Src, sycl::range<3> SrcOffset, sycl::range<3> SrcExtent,
1365  sycl::range<3> CopyExtent, const detail::code_location &CodeLoc) {
1366  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1367  return submit(
1368  [&](handler &CGH) {
1369  CGH.ext_oneapi_copy(Src, SrcOffset, SrcExtent, Dest, DestOffset,
1370  DestImgDesc, CopyExtent);
1371  },
1372  CodeLoc);
1373 }
1374 
1376  const void *Src, ext::oneapi::experimental::image_mem_handle Dest,
1378  event DepEvent, const detail::code_location &CodeLoc) {
1379  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1380  return submit(
1381  [&](handler &CGH) {
1382  CGH.depends_on(DepEvent);
1383  CGH.ext_oneapi_copy(Src, Dest, DestImgDesc);
1384  },
1385  CodeLoc);
1386 }
1387 
1389  const void *Src, sycl::range<3> SrcOffset, sycl::range<3> SrcExtent,
1392  sycl::range<3> CopyExtent, event DepEvent,
1393  const detail::code_location &CodeLoc) {
1394  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1395  return submit(
1396  [&](handler &CGH) {
1397  CGH.depends_on(DepEvent);
1398  CGH.ext_oneapi_copy(Src, SrcOffset, SrcExtent, Dest, DestOffset,
1399  DestImgDesc, CopyExtent);
1400  },
1401  CodeLoc);
1402 }
1403 
1405  const void *Src, ext::oneapi::experimental::image_mem_handle Dest,
1407  const std::vector<event> &DepEvents, const detail::code_location &CodeLoc) {
1408  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1409  return submit(
1410  [&](handler &CGH) {
1411  CGH.depends_on(DepEvents);
1412  CGH.ext_oneapi_copy(Src, Dest, DestImgDesc);
1413  },
1414  CodeLoc);
1415 }
1416 
1418  const void *Src, sycl::range<3> SrcOffset, sycl::range<3> SrcExtent,
1421  sycl::range<3> CopyExtent, const std::vector<event> &DepEvents,
1422  const detail::code_location &CodeLoc) {
1423  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1424  return submit(
1425  [&](handler &CGH) {
1426  CGH.depends_on(DepEvents);
1427  CGH.ext_oneapi_copy(Src, SrcOffset, SrcExtent, Dest, DestOffset,
1428  DestImgDesc, CopyExtent);
1429  },
1430  CodeLoc);
1431 }
1432 
1434  const ext::oneapi::experimental::image_mem_handle Src, void *Dest,
1436  const detail::code_location &CodeLoc) {
1437  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1438  return submit(
1439  [&](handler &CGH) { CGH.ext_oneapi_copy(Src, Dest, SrcImgDesc); },
1440  CodeLoc);
1441 }
1442 
1445  sycl::range<3> SrcOffset,
1446  const ext::oneapi::experimental::image_descriptor &SrcImgDesc, void *Dest,
1447  sycl::range<3> DestOffset, sycl::range<3> DestExtent,
1448  sycl::range<3> CopyExtent, const detail::code_location &CodeLoc) {
1449  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1450  return submit(
1451  [&](handler &CGH) {
1452  CGH.ext_oneapi_copy(Src, SrcOffset, SrcImgDesc, Dest, DestOffset,
1453  DestExtent, CopyExtent);
1454  },
1455  CodeLoc);
1456 }
1457 
1459  const ext::oneapi::experimental::image_mem_handle Src, void *Dest,
1461  event DepEvent, const detail::code_location &CodeLoc) {
1462  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1463  return submit(
1464  [&](handler &CGH) {
1465  CGH.depends_on(DepEvent);
1466  CGH.ext_oneapi_copy(Src, Dest, SrcImgDesc);
1467  },
1468  CodeLoc);
1469 }
1470 
1473  sycl::range<3> SrcOffset,
1474  const ext::oneapi::experimental::image_descriptor &SrcImgDesc, void *Dest,
1475  sycl::range<3> DestOffset, sycl::range<3> DestExtent,
1476  sycl::range<3> CopyExtent, event DepEvent,
1477  const detail::code_location &CodeLoc) {
1478  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1479  return submit(
1480  [&](handler &CGH) {
1481  CGH.depends_on(DepEvent);
1482  CGH.ext_oneapi_copy(Src, SrcOffset, SrcImgDesc, Dest, DestOffset,
1483  DestExtent, CopyExtent);
1484  },
1485  CodeLoc);
1486 }
1487 
1489  const ext::oneapi::experimental::image_mem_handle Src, void *Dest,
1491  const std::vector<event> &DepEvents, const detail::code_location &CodeLoc) {
1492  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1493  return submit(
1494  [&](handler &CGH) {
1495  CGH.depends_on(DepEvents);
1496  CGH.ext_oneapi_copy(Src, Dest, SrcImgDesc);
1497  },
1498  CodeLoc);
1499 }
1500 
1503  sycl::range<3> SrcOffset,
1504  const ext::oneapi::experimental::image_descriptor &SrcImgDesc, void *Dest,
1505  sycl::range<3> DestOffset, sycl::range<3> DestExtent,
1506  sycl::range<3> CopyExtent, const std::vector<event> &DepEvents,
1507  const detail::code_location &CodeLoc) {
1508  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1509  return submit(
1510  [&](handler &CGH) {
1511  CGH.depends_on(DepEvents);
1512  CGH.ext_oneapi_copy(Src, SrcOffset, SrcImgDesc, Dest, DestOffset,
1513  DestExtent, CopyExtent);
1514  },
1515  CodeLoc);
1516 }
1517 
1519  const void *Src, void *Dest,
1520  const ext::oneapi::experimental::image_descriptor &DeviceImgDesc,
1521  size_t DeviceRowPitch, const detail::code_location &CodeLoc) {
1522  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1523  return submit(
1524  [&](handler &CGH) {
1525  CGH.ext_oneapi_copy(Src, Dest, DeviceImgDesc, DeviceRowPitch);
1526  },
1527  CodeLoc);
1528 }
1529 
1531  const void *Src, sycl::range<3> SrcOffset, void *Dest,
1532  sycl::range<3> DestOffset,
1533  const ext::oneapi::experimental::image_descriptor &DeviceImgDesc,
1534  size_t DeviceRowPitch, sycl::range<3> HostExtent, sycl::range<3> CopyExtent,
1535  const detail::code_location &CodeLoc) {
1536  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1537  return submit(
1538  [&](handler &CGH) {
1539  CGH.ext_oneapi_copy(Src, SrcOffset, Dest, DestOffset, DeviceImgDesc,
1540  DeviceRowPitch, HostExtent, CopyExtent);
1541  },
1542  CodeLoc);
1543 }
1544 
1546  const void *Src, void *Dest,
1547  const ext::oneapi::experimental::image_descriptor &DeviceImgDesc,
1548  size_t DeviceRowPitch, event DepEvent,
1549  const detail::code_location &CodeLoc) {
1550  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1551  return submit(
1552  [&](handler &CGH) {
1553  CGH.depends_on(DepEvent);
1554  CGH.ext_oneapi_copy(Src, Dest, DeviceImgDesc, DeviceRowPitch);
1555  },
1556  CodeLoc);
1557 }
1558 
1563  event DepEvent, const detail::code_location &CodeLoc) {
1564  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1565  return submit(
1566  [&](handler &CGH) {
1567  CGH.depends_on(DepEvent);
1568  CGH.ext_oneapi_copy(Src, Dest, ImageDesc);
1569  },
1570  CodeLoc);
1571 }
1572 
1577  const std::vector<event> &DepEvents, const detail::code_location &CodeLoc) {
1578  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1579  return submit(
1580  [&](handler &CGH) {
1581  CGH.depends_on(DepEvents);
1582  CGH.ext_oneapi_copy(Src, Dest, ImageDesc);
1583  },
1584  CodeLoc);
1585 }
1586 
1591  const detail::code_location &CodeLoc) {
1592  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1593  return submit(
1594  [&](handler &CGH) { CGH.ext_oneapi_copy(Src, Dest, ImageDesc); },
1595  CodeLoc);
1596 }
1597 
1599  const void *Src, sycl::range<3> SrcOffset, void *Dest,
1600  sycl::range<3> DestOffset,
1601  const ext::oneapi::experimental::image_descriptor &DeviceImgDesc,
1602  size_t DeviceRowPitch, sycl::range<3> HostExtent, sycl::range<3> CopyExtent,
1603  event DepEvent, const detail::code_location &CodeLoc) {
1604  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1605  return submit(
1606  [&](handler &CGH) {
1607  CGH.depends_on(DepEvent);
1608  CGH.ext_oneapi_copy(Src, SrcOffset, Dest, DestOffset, DeviceImgDesc,
1609  DeviceRowPitch, HostExtent, CopyExtent);
1610  },
1611  CodeLoc);
1612 }
1613 
1615  const void *Src, void *Dest,
1616  const ext::oneapi::experimental::image_descriptor &DeviceImgDesc,
1617  size_t DeviceRowPitch, const std::vector<event> &DepEvents,
1618  const detail::code_location &CodeLoc) {
1619  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1620  return submit(
1621  [&](handler &CGH) {
1622  CGH.depends_on(DepEvents);
1623  CGH.ext_oneapi_copy(Src, Dest, DeviceImgDesc, DeviceRowPitch);
1624  },
1625  CodeLoc);
1626 }
1627 
1629  const void *Src, sycl::range<3> SrcOffset, void *Dest,
1630  sycl::range<3> DestOffset,
1631  const ext::oneapi::experimental::image_descriptor &DeviceImgDesc,
1632  size_t DeviceRowPitch, sycl::range<3> HostExtent, sycl::range<3> CopyExtent,
1633  const std::vector<event> &DepEvents, const detail::code_location &CodeLoc) {
1634  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1635  return submit(
1636  [&](handler &CGH) {
1637  CGH.depends_on(DepEvents);
1638  CGH.ext_oneapi_copy(Src, SrcOffset, Dest, DestOffset, DeviceImgDesc,
1639  DeviceRowPitch, HostExtent, CopyExtent);
1640  },
1641  CodeLoc);
1642 }
1643 
1646  event DepEvent, const detail::code_location &CodeLoc) {
1647  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1648  return submit(
1649  [&](handler &CGH) {
1650  CGH.depends_on(DepEvent);
1651  CGH.ext_oneapi_wait_external_semaphore(SemaphoreHandle);
1652  },
1653  CodeLoc);
1654 }
1655 
1658  const std::vector<event> &DepEvents, const detail::code_location &CodeLoc) {
1659  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1660  return submit(
1661  [&](handler &CGH) {
1662  CGH.depends_on(DepEvents);
1663  CGH.ext_oneapi_wait_external_semaphore(SemaphoreHandle);
1664  },
1665  CodeLoc);
1666 }
1667 
1670  uint64_t WaitValue, const detail::code_location &CodeLoc) {
1671  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1672  return submit(
1673  [&](handler &CGH) {
1674  CGH.ext_oneapi_wait_external_semaphore(SemaphoreHandle, WaitValue);
1675  },
1676  CodeLoc);
1677 }
1678 
1681  uint64_t WaitValue, event DepEvent, const detail::code_location &CodeLoc) {
1682  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1683  return submit(
1684  [&](handler &CGH) {
1685  CGH.depends_on(DepEvent);
1686  CGH.ext_oneapi_wait_external_semaphore(SemaphoreHandle, WaitValue);
1687  },
1688  CodeLoc);
1689 }
1690 
1693  uint64_t WaitValue, const std::vector<event> &DepEvents,
1694  const detail::code_location &CodeLoc) {
1695  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1696  return submit(
1697  [&](handler &CGH) {
1698  CGH.depends_on(DepEvents);
1699  CGH.ext_oneapi_wait_external_semaphore(SemaphoreHandle, WaitValue);
1700  },
1701  CodeLoc);
1702 }
1703 
1706  const detail::code_location &CodeLoc) {
1707  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1708  return submit(
1709  [&](handler &CGH) {
1710  CGH.ext_oneapi_signal_external_semaphore(SemaphoreHandle);
1711  },
1712  CodeLoc);
1713 }
1714 
1717  event DepEvent, const detail::code_location &CodeLoc) {
1718  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1719  return submit(
1720  [&](handler &CGH) {
1721  CGH.depends_on(DepEvent);
1722  CGH.ext_oneapi_signal_external_semaphore(SemaphoreHandle);
1723  },
1724  CodeLoc);
1725 }
1726 
1729  const std::vector<event> &DepEvents, const detail::code_location &CodeLoc) {
1730  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1731  return submit(
1732  [&](handler &CGH) {
1733  CGH.depends_on(DepEvents);
1734  CGH.ext_oneapi_signal_external_semaphore(SemaphoreHandle);
1735  },
1736  CodeLoc);
1737 }
1738 
1741  uint64_t SignalValue, const detail::code_location &CodeLoc) {
1742  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1743  return submit(
1744  [&](handler &CGH) {
1745  CGH.ext_oneapi_signal_external_semaphore(SemaphoreHandle, SignalValue);
1746  },
1747  CodeLoc);
1748 }
1749 
1752  uint64_t SignalValue, event DepEvent,
1753  const detail::code_location &CodeLoc) {
1754  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1755  return submit(
1756  [&](handler &CGH) {
1757  CGH.depends_on(DepEvent);
1758  CGH.ext_oneapi_signal_external_semaphore(SemaphoreHandle, SignalValue);
1759  },
1760  CodeLoc);
1761 }
1762 
1765  uint64_t SignalValue, const std::vector<event> &DepEvents,
1766  const detail::code_location &CodeLoc) {
1767  detail::tls_code_loc_t TlsCodeLocCapture(CodeLoc);
1768  return submit(
1769  [&](handler &CGH) {
1770  CGH.depends_on(DepEvents);
1771  CGH.ext_oneapi_signal_external_semaphore(SemaphoreHandle, SignalValue);
1772  },
1773  CodeLoc);
1774 }
1775 
1776 } // namespace _V1
1777 } // namespace sycl
The context class represents a SYCL context on which kernel functions may be executed.
Definition: context.hpp:50
Data type that manages the code_location information in TLS.
Definition: common.hpp:131
The SYCL device class encapsulates a single SYCL device on which kernels may be executed.
Definition: device.hpp:64
An event object can be used to synchronize memory transfers, enqueues of kernels and signaling barrie...
Definition: event.hpp:44
Command group handler class.
Definition: handler.hpp:467
void depends_on(event Event)
Registers event dependencies on this command group.
Definition: handler.cpp:1529
void ext_oneapi_signal_external_semaphore(ext::oneapi::experimental::interop_semaphore_handle SemaphoreHandle)
Instruct the queue to signal the external semaphore once all previous commands submitted to the queue...
Definition: handler.cpp:1461
void ext_oneapi_wait_external_semaphore(ext::oneapi::experimental::interop_semaphore_handle SemaphoreHandle)
Submit a non-blocking device-side wait on an external.
Definition: handler.cpp:1419
void ext_oneapi_copy(const void *Src, ext::oneapi::experimental::image_mem_handle Dest, const ext::oneapi::experimental::image_descriptor &DestImgDesc)
Copies data from one memory region to another, where Src is a USM pointer and Dest is an opaque image...
Definition: handler.cpp:1012
Encapsulates a single SYCL queue which schedules kernels on a SYCL device.
Definition: queue.hpp:110
event ext_oneapi_wait_external_semaphore(sycl::ext::oneapi::experimental::interop_semaphore_handle SemaphoreHandle, const detail::code_location &CodeLoc=detail::code_location::current())
Instruct the queue with a non-blocking wait on an external semaphore.
Definition: queue.hpp:1848
event ext_oneapi_signal_external_semaphore(sycl::ext::oneapi::experimental::interop_semaphore_handle SemaphoreHandle, const detail::code_location &CodeLoc=detail::code_location::current())
Instruct the queue to signal the external semaphore once all previous commands have completed executi...
event ext_oneapi_copy(const void *Src, ext::oneapi::experimental::image_mem_handle Dest, const ext::oneapi::experimental::image_descriptor &DestImgDesc, const detail::code_location &CodeLoc=detail::code_location::current())
Copies data from one memory region to another, where Src is a USM pointer and Dest is an opaque image...
std::enable_if_t< std::is_invocable_r_v< void, T, handler & >, event > submit(T CGF, const detail::code_location &CodeLoc=detail::code_location::current())
Submits a command group function object to the queue, in order to be scheduled for execution on the d...
Definition: queue.hpp:340
Defines the iteration domain of either a single work-group in a parallel dispatch,...
Definition: range.hpp:26
void write(GlobalBufAccessorT &GlobalFlushBuf, size_t FlushBufferSize, unsigned WIOffset, const char *Str, unsigned Len, unsigned Padding=0)
Definition: stream.hpp:131
void release_external_semaphore(interop_semaphore_handle semaphoreHandle, const sycl::device &syclDevice, const sycl::context &syclContext)
Release the external semaphore.
image_mem_handle map_external_image_memory(interop_mem_handle memHandle, const image_descriptor &desc, const sycl::device &syclDevice, const sycl::context &syclContext)
Maps an interop memory handle to an image memory handle (which may have a device optimized memory lay...
sycl::range< 3 > get_image_range(const image_mem_handle memHandle, const sycl::device &syclDevice, const sycl::context &syclContext)
Get the range that describes the image's dimensions.
unsigned int get_image_num_channels(const image_mem_handle memHandle, const sycl::device &syclDevice, const sycl::context &syclContext)
Get the number of channels that describes the image memory.
interop_mem_handle import_external_memory(external_mem_descriptor< ExternalMemHandleType > externalMem, const sycl::device &syclDevice, const sycl::context &syclContext)
Import external memory taking an external memory handle (the type of which is dependent on the OS & e...
DataT sample_image(const sampled_image_handle &imageHandle[[maybe_unused]], const CoordT &coords[[maybe_unused]])
Sample data from a sampled image using its handle.
DataT sample_cubemap(const sampled_image_handle &imageHandle[[maybe_unused]], const sycl::float3 &dirVec[[maybe_unused]])
Sample a cubemap image using its handle.
unsampled_image_handle create_image(image_mem &memHandle, const image_descriptor &desc, const sycl::device &syclDevice, const sycl::context &syclContext)
Create an image and return the device image handle.
DataT fetch_image_array(const unsampled_image_handle &imageHandle[[maybe_unused]], const CoordT &coords[[maybe_unused]], unsigned int arrayLayer[[maybe_unused]])
Fetch data from an unsampled image array using its handle.
void free_image_mem(image_mem_handle handle, image_type imageType, const sycl::device &syclDevice, const sycl::context &syclContext)
Free image memory.
image_mem_handle get_mip_level_mem_handle(const image_mem_handle mipMem, unsigned int level, const sycl::device &syclDevice, const sycl::context &syclContext)
Retrieve the memory handle to an individual mipmap image.
void write_cubemap(unsampled_image_handle imageHandle, const sycl::int2 &coords, int face, const DataT &color)
Write to an unsampled cubemap using its handle.
void * pitched_alloc_device(size_t *resultPitch, size_t widthInBytes, size_t height, unsigned int elementSizeBytes, const sycl::queue &syclQueue)
Allocate pitched USM image memory.
void write_image_array(unsampled_image_handle imageHandle[[maybe_unused]], const CoordT &coords[[maybe_unused]], unsigned int arrayLayer[[maybe_unused]], const DataT &color[[maybe_unused]])
Write to an unsampled image array using its handle.
DataT fetch_image(const unsampled_image_handle &imageHandle[[maybe_unused]], const CoordT &coords[[maybe_unused]])
Fetch data from an unsampled image using its handle.
DataT sample_mipmap(const sampled_image_handle &imageHandle[[maybe_unused]], const CoordT &coords[[maybe_unused]], const float level[[maybe_unused]])
Sample a mipmap image using its handle with LOD filtering.
image_mem_handle alloc_image_mem(const image_descriptor &desc, const sycl::device &syclDevice, const sycl::context &syclContext)
Allocate image memory based on image_descriptor.
void release_external_memory(interop_mem_handle interopHandle, const sycl::device &syclDevice, const sycl::context &syclContext)
Release external memory.
DataT sample_image_array(const sampled_image_handle &imageHandle[[maybe_unused]], const CoordT &coords[[maybe_unused]], unsigned int arrayLayer[[maybe_unused]])
Sample data from a sampled image array using its handle.
interop_semaphore_handle import_external_semaphore(external_semaphore_descriptor< ExternalSemaphoreHandleType > externalSemaphoreDesc, const sycl::device &syclDevice, const sycl::context &syclContext)
Import external semaphore taking an external semaphore handle (the type of which is dependent on the ...
void destroy_image_handle(unsampled_image_handle &imageHandle, const sycl::device &syclDevice, const sycl::context &syclContext)
Destroy an unsampled image handle.
DataT fetch_cubemap(const unsampled_image_handle &imageHandle, const int2 &coords, unsigned int face)
Fetch data from an unsampled cubemap image using its handle.
void write_image(unsampled_image_handle imageHandle[[maybe_unused]], const CoordT &coords[[maybe_unused]], const DataT &color[[maybe_unused]])
Write to an unsampled image using its handle.
sycl::image_channel_type get_image_channel_type(const image_mem_handle memHandle, const sycl::device &syclDevice, const sycl::context &syclContext)
Get the channel type that describes the image memory.
image_channel_type
Definition: image.hpp:74
Definition: access.hpp:18
A struct to describe the properties of an image.
unsampled_image_handle(raw_image_handle_type raw_image_handle)