LCOV - code coverage report
Current view: top level - xenolith/core - XLCoreQueue.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 23 25 92.0 %
Date: 2024-05-12 00:16:13 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2021-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef XENOLITH_CORE_XLCOREQUEUE_H_
      25             : #define XENOLITH_CORE_XLCOREQUEUE_H_
      26             : 
      27             : #include "XLCoreQueueData.h"
      28             : #include "XLCoreInfo.h"
      29             : 
      30             : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
      31             : 
      32             : /* RenderQueue/RenderGraph implementation notes:
      33             :  *
      34             :  *      - RenderQueue
      35             :  *              - Attachment - global/per-queue data
      36             :  *                      - AttachmentDescriptor - per-pass attachment data
      37             :  *                              - AttachmentRef - per-subpass attachment data
      38             :  *                      - AttachmentHandle - per-frame attachment data
      39             :  *              - RenderPass
      40             :  *                      - AttachmentDescriptor - pass attachments
      41             :  *                      - RenderSubpass
      42             :  *                              - AttachmentRef - subpass attachments
      43             :  *                      - RenderSubpassDependency - dependency between subpasses
      44             :  *                      - RenderPassHandle - per-frame pass data
      45             :  */
      46             : 
      47             : class Queue : public NamedRef {
      48             : public:
      49             :         using FrameRequest = core::FrameRequest;
      50             :         using FrameQueue = core::FrameQueue;
      51             :         using AttachmentHandle = core::AttachmentHandle;
      52             :         using FrameHandle = core::FrameHandle;
      53             :         using AttachmentData = core::AttachmentData;
      54             :         using AttachmentBuilder = core::AttachmentBuilder;
      55             : 
      56             :         class Builder;
      57             : 
      58             :         Queue();
      59             :         virtual ~Queue();
      60             : 
      61             :         virtual bool init(Builder &&);
      62             : 
      63             :         bool isCompiled() const;
      64             : 
      65             :         // mark queue as compiled for device with specific finalization
      66             :         void setCompiled(Device &, Function<void()> &&);
      67             : 
      68             :         bool isCompatible(const ImageInfo &) const;
      69             : 
      70             :         virtual StringView getName() const override;
      71             : 
      72             :         FrameRenderPassState getDefaultSyncPassState() const;
      73             : 
      74             :         const HashTable<ProgramData *> &getPrograms() const;
      75             :         const HashTable<QueuePassData *> &getPasses() const;
      76             :         const HashTable<GraphicPipelineData *> &getGraphicPipelines() const;
      77             :         const HashTable<ComputePipelineData *> &getComputePipelines() const;
      78             :         const HashTable<AttachmentData *> &getAttachments() const;
      79             :         const HashTable<Rc<Resource>> &getLinkedResources() const;
      80             :         Rc<Resource> getInternalResource() const;
      81             : 
      82             :         const memory::vector<AttachmentData *> &getInputAttachments() const;
      83             :         const memory::vector<AttachmentData *> &getOutputAttachments() const;
      84             : 
      85             :         template <typename T>
      86             :         auto getInputAttachment() const -> const T *;
      87             : 
      88             :         template <typename T>
      89             :         auto getOutputAttachment() const -> const T *;
      90             : 
      91             :         const Attachment *getInputAttachment(std::type_index name) const;
      92             :         const Attachment *getOutputAttachment(std::type_index name) const;
      93             : 
      94             :         const QueuePassData *getPass(StringView) const;
      95             :         const ProgramData *getProgram(StringView) const;
      96             :         const GraphicPipelineData *getGraphicPipeline(StringView) const;
      97             :         const ComputePipelineData *getComputePipeline(StringView) const;
      98             :         const AttachmentData *getAttachment(StringView) const;
      99             : 
     100             :         Vector<AttachmentData *> getOutput() const;
     101             :         Vector<AttachmentData *> getOutput(AttachmentType) const;
     102             :         AttachmentData *getPresentImageOutput() const;
     103             :         AttachmentData *getTransferImageOutput() const;
     104             : 
     105             :         // get next frame order dumber for this queue
     106             :         uint64_t incrementOrder();
     107             : 
     108             :         // Prepare queue to be used on target device
     109             :         bool prepare(Device &);
     110             : 
     111             :         void beginFrame(FrameRequest &);
     112             :         void endFrame(FrameRequest &);
     113             : 
     114             :         void attachFrame(FrameHandle *);
     115             :         void detachFrame(FrameHandle *);
     116             : 
     117             : protected:
     118             :         QueueData *_data = nullptr;
     119             : };
     120             : 
     121             : class AttachmentBuilder final {
     122             : public:
     123             :         void setType(AttachmentType type);
     124             : 
     125         258 :         void defineAsInput(AttachmentOps ops = AttachmentOps::WritesColor | AttachmentOps::WritesStencil);
     126         206 :         void defineAsOutput(AttachmentOps ops = AttachmentOps::ReadColor | AttachmentOps::ReadStencil,
     127             :                         FrameRenderPassState pass = FrameRenderPassState::Submitted);
     128             :         void defineAsOutput(FrameRenderPassState pass);
     129             : 
     130         624 :         const AttachmentData *getAttachmentData() const { return _data; }
     131             : 
     132             : protected:
     133             :         friend class Queue::Builder;
     134             : 
     135             :         AttachmentBuilder(AttachmentData *);
     136             : 
     137             :         AttachmentData *_data = nullptr;
     138             : };
     139             : 
     140             : class AttachmentPassBuilder final {
     141             : public:
     142             :         void setAttachmentOps(AttachmentOps);
     143             :         void setInitialLayout(AttachmentLayout);
     144             :         void setFinalLayout(AttachmentLayout);
     145             : 
     146             :         void setLoadOp(AttachmentLoadOp);
     147             :         void setStoreOp(AttachmentStoreOp);
     148             :         void setStencilLoadOp(AttachmentLoadOp);
     149             :         void setStencilStoreOp(AttachmentStoreOp);
     150             : 
     151             :         void setColorMode(const ColorMode &);
     152             :         void setDependency(const AttachmentDependencyInfo &);
     153             : 
     154             : protected:
     155             :         friend class QueuePassBuilder;
     156             : 
     157             :         AttachmentPassBuilder(AttachmentPassData *);
     158             : 
     159             :         AttachmentPassData *_data = nullptr;
     160             : };
     161             : 
     162             : class DescriptorSetBuilder final {
     163             : public:
     164             :         // add single descriptor
     165             :         // compiler CAN inspect shaders to modify descriptors count, if descriptor is actually an array
     166             :         // if descriptor array size defined by spec constant - use addDescriptorArray instead
     167             :         bool addDescriptor(const AttachmentPassData *, DescriptorType = DescriptorType::Unknown, AttachmentLayout = AttachmentLayout::Ignored);
     168             : 
     169             :         // add descriptor array with predefined descriptors count
     170             :         // compiler can not modify size of this array
     171             :         bool addDescriptorArray(const AttachmentPassData *, uint32_t count, DescriptorType = DescriptorType::Unknown, AttachmentLayout = AttachmentLayout::Ignored);
     172             : 
     173             : protected:
     174             :         friend class PipelineLayoutBuilder;
     175             : 
     176             :         DescriptorSetBuilder(DescriptorSetData *);
     177             : 
     178             :         DescriptorSetData *_data = nullptr;
     179             : };
     180             : 
     181             : class PipelineLayoutBuilder final {
     182             : public:
     183             :         bool addSet(const Callback<void(DescriptorSetBuilder &)> &);
     184             :         void setUsesTextureSet(bool);
     185             : 
     186             : protected:
     187             :         friend class QueuePassBuilder;
     188             : 
     189             :         PipelineLayoutBuilder(PipelineLayoutData *);
     190             : 
     191             :         PipelineLayoutData *_data = nullptr;
     192             : };
     193             : 
     194             : class SubpassBuilder final {
     195             : public:
     196             :         bool addColor(const AttachmentPassData *, AttachmentDependencyInfo, AttachmentLayout = AttachmentLayout::Ignored,
     197             :                         AttachmentOps = AttachmentOps::Undefined, BlendInfo = BlendInfo());
     198             :         bool addColor(const AttachmentPassData *, AttachmentDependencyInfo, BlendInfo);
     199             :         bool addInput(const AttachmentPassData *, AttachmentDependencyInfo, AttachmentLayout = AttachmentLayout::Ignored,
     200             :                         AttachmentOps = AttachmentOps::Undefined);
     201             : 
     202             :         bool addResolve(const AttachmentPassData *color, const AttachmentPassData *resolve,
     203             :                         AttachmentDependencyInfo colorDep, AttachmentDependencyInfo resolveDep);
     204             : 
     205             :         bool setDepthStencil(const AttachmentPassData *, AttachmentDependencyInfo, AttachmentLayout = AttachmentLayout::Ignored,
     206             :                         AttachmentOps = AttachmentOps::Undefined);
     207             : 
     208             :         template <typename ... Args>
     209          60 :         const GraphicPipelineData * addGraphicPipeline(StringView key, const PipelineLayoutData *layout, Args && ...args) {
     210          60 :                 if (auto p = emplacePipeline(key, layout)) {
     211          60 :                         if (setPipelineOptions(*p, std::forward<Args>(args)...)) {
     212          50 :                                 finalizePipeline(p);
     213          50 :                                 return p;
     214             :                         }
     215          10 :                         erasePipeline(p);
     216             :                 }
     217          10 :                 return nullptr;
     218             :         }
     219             : 
     220             :         const ComputePipelineData *addComputePipeline(StringView key, const PipelineLayoutData *layout, SpecializationInfo &&);
     221             : 
     222             :         void setPrepareCallback(memory::function<void(const SubpassData &, FrameQueue &)> &&);
     223             :         void setCommandsCallback(memory::function<void(const SubpassData &, FrameQueue &, CommandBuffer &)> &&);
     224             : 
     225             : protected:
     226             :         friend class QueuePassBuilder;
     227             : 
     228             :         GraphicPipelineData *emplacePipeline(StringView key, const PipelineLayoutData *);
     229             :         void finalizePipeline(GraphicPipelineData *);
     230             :         void erasePipeline(GraphicPipelineData *);
     231             : 
     232             :         bool setPipelineOption(GraphicPipelineData &f, DynamicState);
     233             :         bool setPipelineOption(GraphicPipelineData &f, const Vector<SpecializationInfo> &);
     234             :         bool setPipelineOption(GraphicPipelineData &f, const PipelineMaterialInfo &);
     235             : 
     236             :         template <typename T>
     237          50 :         bool setPipelineOptions(GraphicPipelineData &f, T && t) {
     238          50 :                 return setPipelineOption(f, std::forward<T>(t));
     239             :         }
     240             : 
     241             :         template <typename T, typename ... Args>
     242          70 :         bool setPipelineOptions(GraphicPipelineData &f, T && t, Args && ... args) {
     243          70 :                 if (!setPipelineOption(f, std::forward<T>(t))) {
     244          10 :                         return false;
     245             :                 }
     246          60 :                 return setPipelineOptions(f, std::forward<Args>(args)...);
     247             :         }
     248             : 
     249             :         SubpassBuilder(SubpassData *);
     250             : 
     251             :         SubpassData *_data;
     252             : };
     253             : 
     254             : class QueuePassBuilder final {
     255             : public:
     256             :         const PipelineLayoutData * addDescriptorLayout(const Callback<void(PipelineLayoutBuilder &)> &);
     257             : 
     258             :         const SubpassData * addSubpass(const Callback<void(SubpassBuilder &)> &);
     259             : 
     260             :         bool addSubpassDependency(const SubpassData *src, PipelineStage srcStage, AccessType srcAccess,
     261             :                         const SubpassData *dst, PipelineStage dstStage, AccessType dstAccess, bool byRegion = true);
     262             : 
     263             :         const AttachmentPassData *addAttachment(const AttachmentData *);
     264             :         const AttachmentPassData *addAttachment(const AttachmentData *, const AttachmentDependencyInfo &);
     265             :         const AttachmentPassData *addAttachment(const AttachmentData *, const Callback<void(AttachmentPassBuilder &)> &);
     266             : 
     267             :         StringView getName() const;
     268             : 
     269             :         void addSubmittedCallback(memory::function<void(const QueuePassData &, FrameQueue &, bool success)> &&);
     270             :         void addCompleteCallback(memory::function<void(const QueuePassData &, FrameQueue &, bool success)> &&);
     271             : 
     272             : protected:
     273             :         friend class Queue::Builder;
     274             :         friend class QueuePass;
     275             : 
     276         320 :         QueuePassData *getData() const { return _data; }
     277             : 
     278             :         QueuePassBuilder(QueuePassData *);
     279             : 
     280             :         QueuePassData *_data = nullptr;
     281             : };
     282             : 
     283             : class Queue::Builder final {
     284             : public:
     285             :         Builder(StringView);
     286             :         ~Builder();
     287             : 
     288             :         void setDefaultSyncPassState(FrameRenderPassState);
     289             : 
     290             :         const AttachmentData *addAttachemnt(StringView name, const Callback<Rc<Attachment>(AttachmentBuilder &)> &);
     291             : 
     292             :         const QueuePassData * addPass(StringView name, PassType, RenderOrdering, const Callback<Rc<QueuePass>(QueuePassBuilder &)> &);
     293             : 
     294             :         // add program, copy all data
     295             :         const ProgramData * addProgram(StringView key, SpanView<uint32_t>, const ProgramInfo * = nullptr);
     296             : 
     297             :         // add program, take shader data by ref, data should exists for all resource lifetime
     298             :         const ProgramData * addProgramByRef(StringView key, SpanView<uint32_t>, const ProgramInfo * = nullptr);
     299             : 
     300             :         // add program, data will be acquired with callback when needed
     301             :         const ProgramData * addProgram(StringView key, const memory::function<void(const ProgramData::DataCallback &)> &,
     302             :                         const ProgramInfo * = nullptr);
     303             : 
     304             :         // external resources, that should be compiled when added
     305             :         void addLinkedResource(const Rc<Resource> &);
     306             : 
     307             :         void setBeginCallback(Function<void(FrameRequest &)> &&);
     308             :         void setEndCallback(Function<void(FrameRequest &)> &&);
     309             : 
     310             :         void setAttachCallback(Function<void(const FrameHandle *)> &&);
     311             :         void setDetachCallback(Function<void(const FrameHandle *)> &&);
     312             : 
     313             :         const BufferData * addBufferByRef(StringView key, BufferInfo &&, BytesView data,
     314             :                         Rc<DataAtlas> &&atlas = Rc<DataAtlas>(), AccessType = AccessType::ShaderRead);
     315             :         const BufferData * addBuffer(StringView key, BufferInfo &&, FilePath data,
     316             :                         Rc<DataAtlas> &&atlas = Rc<DataAtlas>(), AccessType = AccessType::ShaderRead);
     317             :         const BufferData * addBuffer(StringView key, BufferInfo &&, BytesView data,
     318             :                         Rc<DataAtlas> &&atlas = Rc<DataAtlas>(), AccessType = AccessType::ShaderRead);
     319             :         const BufferData * addBuffer(StringView key, BufferInfo &&,
     320             :                         const memory::function<void(uint8_t *, uint64_t, const BufferData::DataCallback &)> &cb,
     321             :                         Rc<DataAtlas> &&atlas = Rc<DataAtlas>(), AccessType = AccessType::ShaderRead);
     322             : 
     323             :         const ImageData * addImageByRef(StringView key, ImageInfo &&, BytesView data,
     324             :                         AttachmentLayout = AttachmentLayout::ShaderReadOnlyOptimal, AccessType = AccessType::ShaderRead);
     325             :         const ImageData * addImage(StringView key, ImageInfo &&img, FilePath data,
     326             :                         AttachmentLayout = AttachmentLayout::ShaderReadOnlyOptimal, AccessType = AccessType::ShaderRead);
     327             :         const ImageData * addImage(StringView key, ImageInfo &&img, BytesView data,
     328             :                         AttachmentLayout = AttachmentLayout::ShaderReadOnlyOptimal, AccessType = AccessType::ShaderRead);
     329             :         const ImageData * addImage(StringView key, ImageInfo &&img,
     330             :                         const memory::function<void(uint8_t *, uint64_t, const ImageData::DataCallback &)> &cb,
     331             :                         AttachmentLayout = AttachmentLayout::ShaderReadOnlyOptimal, AccessType = AccessType::ShaderRead);
     332             : 
     333             : protected:
     334             :         friend class Queue;
     335             : 
     336             :         QueueData *_data = nullptr;
     337             :         Resource::Builder _internalResource;
     338             : };
     339             : 
     340             : 
     341             : template <typename T>
     342          10 : inline auto Queue::getInputAttachment() const -> const T * {
     343          10 :         if (auto c = getInputAttachment(std::type_index(typeid(T)))) {
     344           0 :                 return static_cast<const T *>(c);
     345             :         }
     346             : 
     347          10 :         return nullptr;
     348             : }
     349             : 
     350             : template <typename T>
     351          10 : inline auto Queue::getOutputAttachment() const -> const T * {
     352          10 :         if (auto c = getOutputAttachment(std::type_index(typeid(T)))) {
     353           0 :                 return static_cast<const T *>(c);
     354             :         }
     355             : 
     356          10 :         return nullptr;
     357             : }
     358             : 
     359             : }
     360             : 
     361             : #endif /* XENOLITH_GL_RENDERQUEUE_XLRENDERQUEUEQUEUE_H_ */

Generated by: LCOV version 1.14