Line data Source code
1 : /**
2 : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
3 :
4 : Permission is hereby granted, free of charge, to any person obtaining a copy
5 : of this software and associated documentation files (the "Software"), to deal
6 : in the Software without restriction, including without limitation the rights
7 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 : copies of the Software, and to permit persons to whom the Software is
9 : furnished to do so, subject to the following conditions:
10 :
11 : The above copyright notice and this permission notice shall be included in
12 : all copies or substantial portions of the Software.
13 :
14 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 : THE SOFTWARE.
21 : **/
22 :
23 : #ifndef XENOLITH_CORE_XLCOREINFO_H_
24 : #define XENOLITH_CORE_XLCOREINFO_H_
25 :
26 : #include "XLCorePipelineInfo.h"
27 : #include "XLCorePlatform.h"
28 :
29 : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
30 :
31 : class BufferObject;
32 : class ImageObject;
33 : class DataAtlas;
34 : class Resource;
35 :
36 : using MipLevels = ValueWrapper<uint32_t, class MipLevelFlag>;
37 : using ArrayLayers = ValueWrapper<uint32_t, class ArrayLayersFlag>;
38 : using Extent1 = ValueWrapper<uint32_t, class Extent1Flag>;
39 : using BaseArrayLayer = ValueWrapper<uint32_t, class BaseArrayLayerFlag>;
40 :
41 : struct SamplerInfo {
42 : Filter magFilter = Filter::Nearest;
43 : Filter minFilter = Filter::Nearest;
44 : SamplerMipmapMode mipmapMode = SamplerMipmapMode::Nearest;
45 : SamplerAddressMode addressModeU = SamplerAddressMode::Repeat;
46 : SamplerAddressMode addressModeV = SamplerAddressMode::Repeat;
47 : SamplerAddressMode addressModeW = SamplerAddressMode::Repeat;
48 : float mipLodBias = 0.0f;
49 : bool anisotropyEnable = false;
50 : float maxAnisotropy = 0.0f;
51 : bool compareEnable = false;
52 : CompareOp compareOp = CompareOp::Never;
53 : float minLod = 0.0;
54 : float maxLod = 0.0;
55 :
56 : SP_THREE_WAY_COMPARISON_TYPE(SamplerInfo)
57 : };
58 :
59 : using ForceBufferFlags = ValueWrapper<BufferFlags, class ForceBufferFlagsFlag>;
60 : using ForceBufferUsage = ValueWrapper<BufferUsage, class ForceBufferUsageFlag>;
61 : using BufferPersistent = ValueWrapper<bool, class BufferPersistentFlag>;
62 :
63 : struct BufferInfo : NamedMem {
64 : BufferFlags flags = BufferFlags::None;
65 : BufferUsage usage = BufferUsage::TransferDst;
66 :
67 : // on which type of RenderPass this buffer will be used (there is no universal usage, so, think carefully)
68 : PassType type = PassType::Graphics;
69 : uint64_t size = 0;
70 : bool persistent = true;
71 :
72 573496 : BufferInfo() = default;
73 :
74 : template<typename ... Args>
75 651925 : BufferInfo(Args && ... args) {
76 651925 : define(std::forward<Args>(args)...);
77 651925 : }
78 :
79 25814 : void setup(const BufferInfo &value) { *this = value; }
80 : void setup(BufferFlags value) { flags |= value; }
81 : void setup(ForceBufferFlags value) { flags = value.get(); }
82 490589 : void setup(BufferUsage value) { usage |= value; }
83 29696 : void setup(ForceBufferUsage value) { usage = value.get(); }
84 532765 : void setup(uint64_t value) { size = value; }
85 0 : void setup(BufferPersistent value) { persistent = value.get(); }
86 479409 : void setup(PassType value) { type = value; }
87 :
88 : template <typename T>
89 1545142 : void define(T && t) {
90 1545142 : setup(std::forward<T>(t));
91 1545139 : }
92 :
93 : template <typename T, typename ... Args>
94 1131208 : void define(T && t, Args && ... args) {
95 1131208 : define(std::forward<T>(t));
96 1131208 : define(std::forward<Args>(args)...);
97 1131208 : }
98 :
99 : String description() const;
100 : };
101 :
102 : struct BufferData : BufferInfo {
103 : using DataCallback = memory::callback<void(BytesView)>;
104 :
105 : BytesView data;
106 : memory::function<void(uint8_t *, uint64_t, const DataCallback &)> memCallback = nullptr;
107 : std::function<void(uint8_t *, uint64_t, const DataCallback &)> stdCallback = nullptr;
108 : Rc<BufferObject> buffer; // GL implementation-dependent object
109 : Rc<DataAtlas> atlas;
110 : const Resource *resource = nullptr; // owning resource;
111 : core::AccessType targetAccess = core::AccessType::ShaderRead;
112 :
113 : size_t writeData(uint8_t *mem, size_t expected) const;
114 : };
115 :
116 :
117 : using ForceImageFlags = ValueWrapper<ImageFlags, class ForceImageFlagsFlag>;
118 : using ForceImageUsage = ValueWrapper<ImageUsage, class ForceImageUsageFlag>;
119 :
120 : struct ImageViewInfo;
121 :
122 : struct ImageInfoData {
123 146856 : ImageFormat format = ImageFormat::Undefined;
124 87992 : ImageFlags flags = ImageFlags::None;
125 87992 : ImageType imageType = ImageType::Image2D;
126 87992 : Extent3 extent = Extent3(1, 1, 1);
127 394355 : MipLevels mipLevels = MipLevels(1);
128 394355 : ArrayLayers arrayLayers = ArrayLayers(1);
129 87992 : SampleCount samples = SampleCount::X1;
130 87992 : ImageTiling tiling = ImageTiling::Optimal;
131 87992 : ImageUsage usage = ImageUsage::TransferDst;
132 :
133 : // on which type of RenderPass this image will be used (there is no universal usage, so, think carefully)
134 87992 : PassType type = PassType::Graphics;
135 87992 : ImageHints hints = ImageHints::None;
136 :
137 : ImageViewInfo getViewInfo(const ImageViewInfo &info) const;
138 :
139 : #if SP_HAVE_THREE_WAY_COMPARISON
140 146856 : SP_THREE_WAY_COMPARISON_TYPE(ImageInfoData)
141 : #else
142 : constexpr bool operator==(const ImageInfoData &other) const {
143 : return format == other.format
144 : && flags == other.flags
145 : && imageType == other.imageType
146 : && extent == other.extent
147 : && mipLevels == other.mipLevels
148 : && arrayLayers == other.arrayLayers
149 : && samples == other.samples
150 : && tiling == other.tiling
151 : && usage == other.usage
152 : && type == other.type
153 : && hints == other.hints
154 : ;
155 : }
156 : constexpr bool operator!=(const ImageInfoData &other) const {
157 : return format != other.format
158 : || flags != other.flags
159 : || imageType != other.imageType
160 : || extent != other.extent
161 : || mipLevels != other.mipLevels
162 : || arrayLayers != other.arrayLayers
163 : || samples != other.samples
164 : || tiling != other.tiling
165 : || usage != other.usage
166 : || type != other.type
167 : || hints != other.hints
168 : ;
169 : }
170 : constexpr bool operator<(const ImageInfoData &other) const {
171 : if (format < other.format) { return true; } else if (format > other.format) { return false; }
172 : if (flags < other.flags) { return true; } else if (flags > other.flags) { return false; }
173 : if (imageType < other.imageType) { return true; } else if (imageType > other.imageType) { return false; }
174 : if (extent < other.extent) { return true; } else if (extent > other.extent) { return false; }
175 : if (mipLevels < other.mipLevels) { return true; } else if (mipLevels > other.mipLevels) { return false; }
176 : if (arrayLayers < other.arrayLayers) { return true; } else if (arrayLayers > other.arrayLayers) { return false; }
177 : if (samples < other.samples) { return true; } else if (samples > other.samples) { return false; }
178 : if (tiling < other.tiling) { return true; } else if (tiling > other.tiling) { return false; }
179 : if (usage < other.usage) { return true; } else if (usage > other.usage) { return false; }
180 : if (type < other.type) { return true; } else if (type > other.type) { return false; }
181 : if (hints < other.hints) { return true; } else if (hints > other.hints) { return false; }
182 : return false;
183 : }
184 : #endif
185 : };
186 :
187 : struct ImageInfo : NamedMem, ImageInfoData {
188 8630 : ImageInfo() = default;
189 :
190 : template<typename ... Args>
191 340 : ImageInfo(Args && ... args) {
192 340 : define(std::forward<Args>(args)...);
193 340 : }
194 :
195 : void setup(Extent1 value) {
196 : extent = Extent3(value.get(), 1, 1);
197 : }
198 176 : void setup(Extent2 value) {
199 176 : extent = Extent3(value.width, value.height, 1);
200 176 : }
201 0 : void setup(Extent3 value) {
202 0 : extent = value;
203 0 : if (extent.depth > 1 && imageType != ImageType::Image3D) {
204 0 : imageType = ImageType::Image3D;
205 : }
206 0 : }
207 : void setup(ImageFlags value) { flags |= value; }
208 : void setup(ForceImageFlags value) { flags = value.get(); }
209 0 : void setup(ImageType value) { imageType = value; }
210 : void setup(MipLevels value) { mipLevels = value; }
211 : void setup(ArrayLayers value) { arrayLayers = value; }
212 : void setup(SampleCount value) { samples = value; }
213 16 : void setup(ImageTiling value) { tiling = value; }
214 432 : void setup(ImageUsage value) { usage |= value; }
215 40 : void setup(ForceImageUsage value) { usage = value.get(); }
216 224 : void setup(ImageFormat value) { format = value; }
217 63 : void setup(PassType value) { type = value; }
218 10 : void setup(ImageHints value) { hints |= value; }
219 84 : void setup(StringView value) { key = value; }
220 :
221 : template <typename T>
222 1021 : void define(T && t) {
223 1021 : setup(std::forward<T>(t));
224 1021 : }
225 :
226 : template <typename T, typename ... Args>
227 518 : void define(T && t, Args && ... args) {
228 518 : define(std::forward<T>(t));
229 518 : define(std::forward<Args>(args)...);
230 518 : }
231 :
232 : bool isCompatible(const ImageInfo &) const;
233 :
234 : String description() const;
235 : };
236 :
237 : struct ImageData : ImageInfo {
238 : using DataCallback = memory::callback<void(BytesView)>;
239 :
240 : BytesView data;
241 : memory::function<void(uint8_t *, uint64_t, const DataCallback &)> memCallback = nullptr;
242 : std::function<void(uint8_t *, uint64_t, const DataCallback &)> stdCallback = nullptr;
243 : Rc<ImageObject> image; // GL implementation-dependent object
244 : Rc<DataAtlas> atlas;
245 : const Resource *resource = nullptr; // owning resource;
246 : core::AccessType targetAccess = core::AccessType::ShaderRead;
247 : core::AttachmentLayout targetLayout = core::AttachmentLayout::ShaderReadOnlyOptimal;
248 :
249 : size_t writeData(uint8_t *mem, size_t expected) const;
250 : };
251 :
252 :
253 : using ComponentMappingR = ValueWrapper<ComponentMapping, class ComponentMappingRFlag>;
254 : using ComponentMappingG = ValueWrapper<ComponentMapping, class ComponentMappingGFlag>;
255 : using ComponentMappingB = ValueWrapper<ComponentMapping, class ComponentMappingBFlag>;
256 : using ComponentMappingA = ValueWrapper<ComponentMapping, class ComponentMappingAFlag>;
257 :
258 : struct ImageViewInfo {
259 118206 : ImageFormat format = ImageFormat::Undefined; // inherited from Image if undefined
260 118192 : ImageViewType type = ImageViewType::ImageView2D;
261 118262 : ComponentMapping r = ComponentMapping::Identity;
262 99686 : ComponentMapping g = ComponentMapping::Identity;
263 99681 : ComponentMapping b = ComponentMapping::Identity;
264 99688 : ComponentMapping a = ComponentMapping::Identity;
265 208522 : BaseArrayLayer baseArrayLayer = BaseArrayLayer(0);
266 99692 : ArrayLayers layerCount = ArrayLayers::max();
267 :
268 848 : ImageViewInfo() = default;
269 : ImageViewInfo(const ImageViewInfo &) = default;
270 : ImageViewInfo(ImageViewInfo &&) = default;
271 : ImageViewInfo &operator=(const ImageViewInfo &) = default;
272 : ImageViewInfo &operator=(ImageViewInfo &&) = default;
273 :
274 : template<typename ... Args>
275 107985 : ImageViewInfo(Args && ... args) {
276 107980 : define(std::forward<Args>(args)...);
277 107980 : }
278 :
279 : void setup(const ImageViewInfo &);
280 : void setup(const ImageInfoData &);
281 : void setup(ImageViewType value) { type = value; }
282 132 : void setup(ImageFormat value) { format = value; }
283 : void setup(ArrayLayers value) { layerCount = value; }
284 : void setup(BaseArrayLayer value) { baseArrayLayer = value; }
285 : void setup(ComponentMappingR value) { r = value.get(); }
286 : void setup(ComponentMappingG value) { g = value.get(); }
287 : void setup(ComponentMappingB value) { b = value.get(); }
288 : void setup(ComponentMappingA value) { a = value.get(); }
289 : void setup(ColorMode value, bool allowSwizzle = true);
290 : void setup(ImageType, ArrayLayers);
291 :
292 : ColorMode getColorMode() const;
293 :
294 : template <typename T>
295 108115 : void define(T && t) {
296 108115 : setup(std::forward<T>(t));
297 108111 : }
298 :
299 : template <typename T, typename ... Args>
300 132 : void define(T && t, Args && ... args) {
301 132 : define(std::forward<T>(t));
302 132 : define(std::forward<Args>(args)...);
303 132 : }
304 :
305 : bool isCompatible(const ImageInfo &) const;
306 : String description() const;
307 :
308 : #if SP_HAVE_THREE_WAY_COMPARISON
309 118206 : SP_THREE_WAY_COMPARISON_TYPE(ImageViewInfo)
310 : #else
311 : constexpr bool operator==(const ImageViewInfo &other) const {
312 : return format == other.format && type == other.type && r == other.r && g == other.g && b == other.b && a == other.a
313 : && baseArrayLayer == other.baseArrayLayer && layerCount == other.layerCount;
314 : }
315 : constexpr bool operator!=(const ImageViewInfo &other) const {
316 : return format != other.format || type != other.type || r != other.r || g != other.g || b != other.b || a != other.a
317 : || baseArrayLayer != other.baseArrayLayer || layerCount != other.layerCount;
318 : }
319 : constexpr bool operator<(const ImageViewInfo &other) const {
320 : if (format < other.format) { return true; } else if (format > other.format) { return false; }
321 : if (type < other.type) { return true; } else if (type > other.type) { return false; }
322 : if (r < other.r) { return true; } else if (r > other.r) { return false; }
323 : if (g < other.g) { return true; } else if (g > other.g) { return false; }
324 : if (b < other.b) { return true; } else if (b > other.b) { return false; }
325 : if (a < other.a) { return true; } else if (a > other.a) { return false; }
326 : if (baseArrayLayer < other.baseArrayLayer) { return true; } else if (baseArrayLayer > other.baseArrayLayer) { return false; }
327 : if (layerCount < other.layerCount) { return true; } else if (layerCount > other.layerCount) { return false; }
328 : return false;
329 : }
330 : #endif
331 : };
332 :
333 : struct FrameContraints {
334 9916 : Extent3 extent;
335 9895 : Padding contentPadding;
336 9895 : SurfaceTransformFlags transform = SurfaceTransformFlags::Identity;
337 9559 : float density = 1.0f;
338 :
339 38259 : Size2 getScreenSize() const {
340 38259 : if ((transform & core::SurfaceTransformFlags::PreRotated) != core::SurfaceTransformFlags::None) {
341 147 : switch (core::getPureTransform(transform)) {
342 84 : case SurfaceTransformFlags::Rotate90:
343 : case SurfaceTransformFlags::Rotate270:
344 : case SurfaceTransformFlags::MirrorRotate90:
345 : case SurfaceTransformFlags::MirrorRotate270:
346 84 : return Size2(extent.height, extent.width);
347 : break;
348 63 : default:
349 63 : break;
350 : }
351 : }
352 38172 : return Size2(extent.width, extent.height);
353 : }
354 :
355 : Padding getRotatedPadding() const {
356 : Padding out = contentPadding;
357 : switch (transform) {
358 : case SurfaceTransformFlags::Rotate90:
359 : out.left = contentPadding.top;
360 : out.top = contentPadding.right;
361 : out.right = contentPadding.bottom;
362 : out.bottom = contentPadding.left;
363 : break;
364 : case SurfaceTransformFlags::Rotate180:
365 : out.left = contentPadding.right;
366 : out.top = contentPadding.bottom;
367 : out.right = contentPadding.left;
368 : out.bottom = contentPadding.top;
369 : break;
370 : case SurfaceTransformFlags::Rotate270:
371 : out.left = contentPadding.bottom;
372 : out.top = contentPadding.left;
373 : out.right = contentPadding.top;
374 : out.bottom = contentPadding.right;
375 : break;
376 : case SurfaceTransformFlags::Mirror:
377 : out.left = contentPadding.right;
378 : out.right = contentPadding.left;
379 : break;
380 : case SurfaceTransformFlags::MirrorRotate90:
381 : break;
382 : case SurfaceTransformFlags::MirrorRotate180:
383 : out.top = contentPadding.bottom;
384 : out.bottom = contentPadding.top;
385 : break;
386 : case SurfaceTransformFlags::MirrorRotate270:
387 : break;
388 : default: break;
389 : }
390 : return out;
391 : }
392 :
393 9916 : constexpr bool operator==(const FrameContraints &) const = default;
394 9916 : constexpr bool operator!=(const FrameContraints &) const = default;
395 : };
396 :
397 : struct SwapchainConfig {
398 : PresentMode presentMode = PresentMode::Mailbox;
399 : PresentMode presentModeFast = PresentMode::Unsupported;
400 : ImageFormat imageFormat = ImageFormat::R8G8B8A8_UNORM;
401 : ColorSpace colorSpace = ColorSpace::SRGB_NONLINEAR_KHR;
402 : CompositeAlphaFlags alpha = CompositeAlphaFlags::Opaque;
403 : SurfaceTransformFlags transform = SurfaceTransformFlags::Identity;
404 : uint32_t imageCount = 3;
405 : Extent2 extent;
406 : bool clipped = false;
407 : bool transfer = true;
408 :
409 : String description() const;
410 :
411 : constexpr bool operator==(const SwapchainConfig &) const = default;
412 : constexpr bool operator!=(const SwapchainConfig &) const = default;
413 : };
414 :
415 : struct SurfaceInfo {
416 : uint32_t minImageCount;
417 : uint32_t maxImageCount;
418 : Extent2 currentExtent;
419 : Extent2 minImageExtent;
420 : Extent2 maxImageExtent;
421 : uint32_t maxImageArrayLayers;
422 : CompositeAlphaFlags supportedCompositeAlpha;
423 : SurfaceTransformFlags supportedTransforms;
424 : SurfaceTransformFlags currentTransform;
425 : ImageUsage supportedUsageFlags;
426 : Vector<Pair<ImageFormat, ColorSpace>> formats;
427 : Vector<PresentMode> presentModes;
428 : float surfaceDensity = 1.0f;
429 :
430 : bool isSupported(const SwapchainConfig &) const;
431 :
432 : String description() const;
433 : };
434 :
435 : String getBufferFlagsDescription(BufferFlags fmt);
436 : String getBufferUsageDescription(BufferUsage fmt);
437 : String getImageFlagsDescription(ImageFlags fmt);
438 : String getSampleCountDescription(SampleCount fmt);
439 : StringView getImageTypeName(ImageType type);
440 : StringView getImageViewTypeName(ImageViewType type);
441 : StringView getImageFormatName(ImageFormat fmt);
442 : StringView getImageTilingName(ImageTiling type);
443 : StringView getComponentMappingName(ComponentMapping);
444 : StringView getPresentModeName(PresentMode);
445 : StringView getColorSpaceName(ColorSpace);
446 : String getCompositeAlphaFlagsDescription(CompositeAlphaFlags);
447 : String getSurfaceTransformFlagsDescription(SurfaceTransformFlags);
448 : String getImageUsageDescription(ImageUsage fmt);
449 : size_t getFormatBlockSize(ImageFormat format);
450 : PixelFormat getImagePixelFormat(ImageFormat format);
451 : bool isStencilFormat(ImageFormat format);
452 : bool isDepthFormat(ImageFormat format);
453 :
454 : bool hasReadAccess(AccessType);
455 : bool hasWriteAccess(AccessType);
456 :
457 : std::ostream & operator<<(std::ostream &stream, const ImageInfoData &value);
458 :
459 : }
460 :
461 : #endif /* XENOLITH_CORE_XLCOREINFO_H_ */
|