LCOV - code coverage report
Current view: top level - xenolith/core - XLCoreInfo.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 84 91 92.3 %
Date: 2024-05-12 00:16:13 Functions: 106 146 72.6 %

          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_ */

Generated by: LCOV version 1.14