DPC++ Runtime
Runtime libraries for oneAPI DPC++
bindless_images_descriptor.hpp
Go to the documentation of this file.
1 //==------ bindless_images_descriptor.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/detail/array.hpp> // for array
12 #include <sycl/exception.hpp> // for errc, exception
13 #include <sycl/image.hpp> // for image_channel_order, image_channel_type
14 #include <sycl/range.hpp> // for range
15 
16 #include <algorithm> // for max
17 #include <stddef.h> // for size_t
18 #include <system_error> // for error_code
19 
20 namespace sycl {
21 inline namespace _V1 {
22 namespace ext::oneapi::experimental {
23 
25 enum class image_type : unsigned int {
26  standard = 0,
27  mipmap = 1,
28  array = 2,
29  cubemap = 3,
30 };
31 
34  size_t width;
35  size_t height;
36  size_t depth;
40  unsigned int num_levels;
41  unsigned int array_size;
42 
43  image_descriptor() = default;
44 
48  unsigned int num_levels = 1, unsigned int array_size = 1)
49  : width(dims[0]), height(0), depth(0), channel_order(channel_order),
52  verify();
53  }
54 
58  unsigned int num_levels = 1, unsigned int array_size = 1)
59  : width(dims[0]), height(dims[1]), depth(0), channel_order(channel_order),
62  verify();
63  }
64 
68  unsigned int num_levels = 1, unsigned int array_size = 1)
69  : width(dims[0]), height(dims[1]), depth(dims[2]),
72  verify();
73  };
74 
77  // Check that this descriptor describes a mipmap - otherwise throw
78  if (this->type != image_type::mipmap)
79  throw sycl::exception(
80  sycl::errc::invalid,
81  "Invalid descriptor `image_type` passed to "
82  "`get_mip_level_desc`. A mipmap level descriptor can only be "
83  "requested by a descriptor with mipmap image type!");
84 
85  // Generate a new descriptor which represents the level accordingly
86  // Do not allow height/depth values to be clamped to 1 when naturally 0
87  size_t width = std::max<size_t>(this->width >> level, 1);
88  size_t height = this->height == 0
89  ? this->height
90  : std::max<size_t>(this->height >> level, 1);
91  size_t depth = this->depth == 0 ? this->depth
92  : std::max<size_t>(this->depth >> level, 1);
93 
94  // This will generate the new descriptor with image_type standard
95  // since individual mip levels are standard images
97  {width, height, depth}, this->channel_order, this->channel_type);
98 
99  levelDesc.verify();
100  return levelDesc;
101  }
102 
103  void verify() const {
104  switch (this->type) {
106  if (this->array_size > 1) {
107  // Not a standard image.
108  throw sycl::exception(
109  sycl::errc::invalid,
110  "Standard images cannot have array_size greater than 1! Use "
111  "image_type::array for image arrays.");
112  }
113  if (this->num_levels > 1) {
114  // Image arrays cannot be mipmaps.
115  throw sycl::exception(
116  sycl::errc::invalid,
117  "Standard images cannot have num_levels greater than 1! Use "
118  "image_type::mipmap for mipmap images.");
119  }
120  return;
121 
122  case image_type::array:
123  if (this->array_size <= 1) {
124  // Not an image array.
125  throw sycl::exception(sycl::errc::invalid,
126  "Image array must have array_size greater than "
127  "1! Use image_type::standard otherwise.");
128  }
129  if (this->depth != 0) {
130  // Image arrays must only be 1D or 2D.
131  throw sycl::exception(sycl::errc::invalid,
132  "Cannot have 3D image arrays! Either depth must "
133  "be 0 or array_size must be 1.");
134  }
135  if (this->num_levels != 1) {
136  // Image arrays cannot be mipmaps.
137  throw sycl::exception(sycl::errc::invalid,
138  "Cannot have mipmap image arrays! Either "
139  "num_levels or array_size must be 1.");
140  }
141  return;
142 
143  case image_type::mipmap:
144  if (this->array_size > 1) {
145  // Mipmap images cannot be arrays.
146  throw sycl::exception(
147  sycl::errc::invalid,
148  "Mipmap images cannot have array_size greater than 1! Use "
149  "image_type::array for image arrays.");
150  }
151  if (this->num_levels <= 1) {
152  // Mipmaps must have more than one level.
153  throw sycl::exception(sycl::errc::invalid,
154  "Mipmap images must have num_levels greater than "
155  "1! Use image_type::standard otherwise.");
156  }
157  return;
158 
159  case image_type::cubemap:
160  if (this->array_size != 6) {
161  // Cubemaps must have an array size of 6.
162  throw sycl::exception(sycl::errc::invalid,
163  "Cubemap images must have array_size of 6 only! "
164  "Use image_type::array instead.");
165  }
166  if (this->depth != 0 || this->height == 0 ||
167  this->width != this->height) {
168  // Cubemaps must be 2D
169  throw sycl::exception(
170  sycl::errc::invalid,
171  "Cubemap images must be square with valid and equivalent width and "
172  "height! Use image_type::array instead.");
173  }
174  if (this->num_levels != 1) {
175  // Cubemaps cannot be mipmaps.
176  throw sycl::exception(sycl::errc::invalid,
177  "Cannot have mipmap cubemaps! Either num_levels "
178  "or array_size must be 1.");
179  }
180  return;
181  }
182  }
183 };
184 
185 } // namespace ext::oneapi::experimental
186 } // namespace _V1
187 } // namespace sycl
image_channel_order
Definition: image.hpp:56
image_channel_type
Definition: image.hpp:74
Definition: access.hpp:18
A struct to describe the properties of an image.
image_descriptor(range< 1 > dims, image_channel_order channel_order, image_channel_type channel_type, image_type type=image_type::standard, unsigned int num_levels=1, unsigned int array_size=1)
image_descriptor(range< 2 > dims, image_channel_order channel_order, image_channel_type channel_type, image_type type=image_type::standard, unsigned int num_levels=1, unsigned int array_size=1)
image_descriptor get_mip_level_desc(unsigned int level) const
Get the descriptor for a mipmap level.
image_descriptor(range< 3 > dims, image_channel_order channel_order, image_channel_type channel_type, image_type type=image_type::standard, unsigned int num_levels=1, unsigned int array_size=1)