LCOV - code coverage report
Current view: top level - xenolith/core - XLCoreAttachment.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 189 229 82.5 %
Date: 2024-05-12 00:16:13 Functions: 48 53 90.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             : #include "XLCoreAttachment.h"
      24             : #include "XLCoreFrameQueue.h"
      25             : #include "XLCoreFrameHandle.h"
      26             : #include "XLCoreDevice.h"
      27             : 
      28             : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
      29             : 
      30         877 : uint32_t DependencyEvent::GetNextId() {
      31             :         static std::atomic<uint32_t> s_eventId = 1;
      32         877 :         return s_eventId.fetch_add(1);
      33             : }
      34             : 
      35        1754 : DependencyEvent::~DependencyEvent() { }
      36             : 
      37         877 : DependencyEvent::DependencyEvent(QueueSet &&q) : _queues(move(q)) { }
      38             : 
      39           0 : DependencyEvent::DependencyEvent(InitializerList<Rc<Queue>> &&il) : _queues(move(il)) { }
      40             : 
      41        3346 : bool DependencyEvent::signal(Queue *q, bool success) {
      42        3346 :         if (!success) {
      43           0 :                 _success = success;
      44             :         }
      45             : 
      46        3346 :         auto it = _queues.find(q);
      47        3346 :         if (it != _queues.end()) {
      48        1673 :                 _queues.erase(it);
      49             :         }
      50        6692 :         return _queues.empty();
      51             : }
      52             : 
      53        3508 : bool DependencyEvent::isSignaled() const {
      54        3508 :         return _queues.empty();
      55             : }
      56             : 
      57           0 : bool DependencyEvent::isSuccessful() const {
      58           0 :         return _success;
      59             : }
      60             : 
      61         796 : void DependencyEvent::addQueue(Rc<Queue> &&q) {
      62         796 :         _queues.emplace(move(q));
      63         796 : }
      64             : 
      65         624 : bool Attachment::init(AttachmentBuilder &builder) {
      66         624 :         _data = builder.getAttachmentData();
      67         624 :         return true;
      68             : }
      69             : 
      70          32 : void Attachment::clear() {
      71             : 
      72          32 : }
      73             : 
      74          48 : StringView Attachment::getName() const {
      75          48 :         return _data->key;
      76             : }
      77             : 
      78       21998 : uint64_t Attachment::getId() const {
      79       21998 :         return _data->id;
      80             : }
      81             : 
      82     2782308 : AttachmentUsage Attachment::getUsage() const {
      83     2782308 :         return _data->usage;
      84             : }
      85             : 
      86       21998 : bool Attachment::isTransient() const {
      87       21998 :         return _data->transient;
      88             : }
      89             : 
      90          16 : void Attachment::setInputCallback(Function<void(FrameQueue &, const Rc<AttachmentHandle> &, Function<void(bool)> &&)> &&input) {
      91          16 :         _inputCallback = move(input);
      92          16 : }
      93             : 
      94          48 : void Attachment::setValidateInputCallback(ValidateInputCallback &&cb) {
      95          48 :         _validateInputCallback = move(cb);
      96          48 : }
      97             : 
      98          48 : void Attachment::setFrameHandleCallback(FrameHandleCallback &&cb) {
      99          48 :         _frameHandleCallback = move(cb);
     100          48 : }
     101             : 
     102       29352 : void Attachment::acquireInput(FrameQueue &frame, const Rc<AttachmentHandle> &a, Function<void(bool)> &&cb) {
     103       29352 :         if (_inputCallback) {
     104           0 :                 _inputCallback(frame, a, move(cb));
     105             :         } else {
     106             :                 // wait for input on handle
     107       29352 :                 frame.getFrame()->waitForInput(frame, a, move(cb));
     108             :         }
     109       29352 : }
     110             : 
     111       54972 : bool Attachment::validateInput(const Rc<AttachmentInputData> &data) const {
     112       54972 :         if (_validateInputCallback) {
     113       38416 :                 return _validateInputCallback(*this, data);
     114             :         }
     115       16555 :         return true;
     116             : }
     117             : 
     118           0 : Rc<AttachmentHandle> Attachment::makeFrameHandle(const FrameQueue &queue) {
     119           0 :         if (_frameHandleCallback) {
     120           0 :                 return _frameHandleCallback(*this, queue);
     121             :         }
     122           0 :         return nullptr;
     123             : }
     124             : 
     125      395280 : Vector<const QueuePassData *> Attachment::getRenderPasses() const {
     126      395280 :         Vector<const PassData *> ret;
     127      908574 :         for (auto &it : _data->passes) {
     128      513294 :                 ret.emplace_back(it->pass);
     129             :         }
     130      395280 :         return ret;
     131           0 : }
     132             : 
     133      512177 : const QueuePassData *Attachment::getFirstRenderPass() const {
     134      512177 :         if (_data->passes.empty()) {
     135           0 :                 return nullptr;
     136             :         }
     137             : 
     138      512177 :         return _data->passes.front()->pass;
     139             : }
     140             : 
     141      540612 : const QueuePassData *Attachment::getLastRenderPass() const {
     142      540612 :         if (_data->passes.empty()) {
     143           0 :                 return nullptr;
     144             :         }
     145             : 
     146      540612 :         return _data->passes.back()->pass;
     147             : }
     148             : 
     149          48 : const QueuePassData *Attachment::getNextRenderPass(const PassData *pass) const {
     150          48 :         size_t idx = 0;
     151          96 :         for (auto &it : _data->passes) {
     152          96 :                 if (it->pass == pass) {
     153          48 :                         break;
     154             :                 }
     155          48 :                 ++idx;
     156             :         }
     157          48 :         if (idx + 1 >= _data->passes.size()) {
     158           0 :                 return nullptr;
     159             :         }
     160          48 :         return _data->passes.at(idx + 1)->pass;
     161             : }
     162             : 
     163          64 : const QueuePassData *Attachment::getPrevRenderPass(const PassData *pass) const {
     164          64 :         size_t idx = 0;
     165         112 :         for (auto &it : _data->passes) {
     166         112 :                 if (it->pass == pass) {
     167          64 :                         break;
     168             :                 }
     169          48 :                 ++ idx;
     170             :         }
     171          64 :         if (idx == 0) {
     172          16 :                 return nullptr;
     173             :         }
     174          48 :         return _data->passes.at(idx - 1)->pass;
     175             : }
     176             : 
     177         544 : void Attachment::setCompiled(Device &dev) {
     178             : 
     179         544 : }
     180             : 
     181         256 : bool BufferAttachment::init(AttachmentBuilder &builder, const BufferInfo &info) {
     182         256 :         _info = info;
     183         256 :         builder.setType(AttachmentType::Buffer);
     184         256 :         if (Attachment::init(builder)) {
     185         256 :                 _info.key = _data->key;
     186         256 :                 return true;
     187             :         }
     188           0 :         return false;
     189             : }
     190             : 
     191          16 : bool BufferAttachment::init(AttachmentBuilder &builder, const BufferData *data) {
     192          16 :         _info = *data;
     193          16 :         builder.setType(AttachmentType::Buffer);
     194          16 :         if (Attachment::init(builder)) {
     195          16 :                 _staticBuffers.emplace_back(data);
     196          16 :                 _info.key = _data->key;
     197          16 :                 return true;
     198             :         }
     199           0 :         return false;
     200             : }
     201             : 
     202         112 : bool BufferAttachment::init(AttachmentBuilder &builder, Vector<const BufferData *> &&buffers) {
     203         112 :         _info = *buffers.front();
     204         112 :         builder.setType(AttachmentType::Buffer);
     205         112 :         if (Attachment::init(builder)) {
     206         112 :                 _staticBuffers = move(buffers);
     207         112 :                 _info.key = _data->key;
     208         112 :                 return true;
     209             :         }
     210           0 :         return false;
     211             : }
     212             : 
     213          16 : void BufferAttachment::clear() {
     214          16 :         Attachment::clear();
     215          16 : }
     216             : 
     217      134400 : Vector<BufferObject *> BufferAttachment::getStaticBuffers() const {
     218      134400 :         Vector<BufferObject *> ret; ret.reserve(_staticBuffers.size());
     219      499200 :         for (auto &it : _staticBuffers) {
     220      364800 :                 if (it->buffer) {
     221      364800 :                         ret.emplace_back(it->buffer);
     222             :                 }
     223             :         }
     224      134400 :         return ret;
     225           0 : }
     226             : 
     227          80 : bool ImageAttachment::init(AttachmentBuilder &builder, const ImageInfo &info, AttachmentInfo &&a) {
     228          80 :         builder.setType(AttachmentType::Image);
     229          80 :         if (Attachment::init(builder)) {
     230          80 :                 _imageInfo = info;
     231          80 :                 _attachmentInfo = move(a);
     232          80 :                 _imageInfo.key = _data->key;
     233          80 :                 return true;
     234             :         }
     235           0 :         return false;
     236             : }
     237             : 
     238          32 : bool ImageAttachment::init(AttachmentBuilder &builder, const ImageData *data, AttachmentInfo &&a) {
     239          32 :         builder.setType(AttachmentType::Image);
     240          32 :         if (Attachment::init(builder)) {
     241          32 :                 _imageInfo = *data; // copy info
     242          32 :                 if ((_imageInfo.hints & ImageHints::Static) != ImageHints::Static) {
     243          32 :                         log::error("ImageAttachment", "Image ", data->key, " is not defined as ImageHint::Static to be used as static image attachment");
     244             :                 }
     245          32 :                 _staticImage = data;
     246          32 :                 _attachmentInfo = move(a);
     247          32 :                 _imageInfo.key = _data->key;
     248          32 :                 return true;
     249             :         }
     250           0 :         return false;
     251             : }
     252             : 
     253         112 : void ImageAttachment::addImageUsage(ImageUsage usage) {
     254         112 :         _imageInfo.usage |= usage;
     255         112 : }
     256             : 
     257          32 : bool ImageAttachment::isCompatible(const ImageInfo &image) const {
     258          32 :         return _imageInfo.isCompatible(image);
     259             : }
     260             : 
     261       57328 : ImageViewInfo ImageAttachment::getImageViewInfo(const ImageInfoData &info, const AttachmentPassData &passAttachment) const {
     262       57328 :         bool allowSwizzle = true;
     263       57328 :         AttachmentUsage usage = AttachmentUsage::None;
     264      124999 :         for (auto &subpassAttachment : passAttachment.subpasses) {
     265       67671 :                 usage |= subpassAttachment->usage;
     266             :         }
     267             : 
     268       57328 :         if ((usage & AttachmentUsage::Input) != AttachmentUsage::None
     269       39663 :                         || (usage & AttachmentUsage::Output) != AttachmentUsage::None
     270       32325 :                         || (usage & AttachmentUsage::Resolve) != AttachmentUsage::None
     271       96991 :                         || (usage & AttachmentUsage::DepthStencil) != AttachmentUsage::None) {
     272       42668 :                 allowSwizzle = false;
     273             :         }
     274             : 
     275       57328 :         ImageViewInfo passInfo(info);
     276       57328 :         passInfo.setup(passAttachment.colorMode, allowSwizzle);
     277      114656 :         return passInfo;
     278             : }
     279             : 
     280       21998 : Vector<ImageViewInfo> ImageAttachment::getImageViews(const ImageInfoData &info) const {
     281       21998 :         Vector<ImageViewInfo> ret;
     282             : 
     283       51302 :         auto addView = [&] (const ImageViewInfo &info) {
     284       51302 :                 auto it = std::find(ret.begin(), ret.end(), info);
     285       51302 :                 if (it == ret.end()) {
     286       29320 :                         ret.emplace_back(info);
     287             :                 }
     288       51302 :         };
     289             : 
     290       51318 :         for (auto &passAttachment : _data->passes) {
     291       29320 :                 addView(getImageViewInfo(info, *passAttachment));
     292             : 
     293       51302 :                 for (auto &desc : passAttachment->descriptors) {
     294       21982 :                         bool allowSwizzle = (desc->type == DescriptorType::SampledImage);
     295             : 
     296       21982 :                         ImageViewInfo passInfo(info);
     297       21982 :                         passInfo.setup(passAttachment->colorMode, allowSwizzle);
     298       21982 :                         addView(passInfo);
     299             :                 }
     300             :         }
     301             : 
     302       43996 :         return ret;
     303           0 : }
     304             : 
     305          80 : void ImageAttachment::setCompiled(Device &dev) {
     306          80 :         Attachment::setCompiled(dev);
     307             : 
     308          80 :         if (!isStatic()) {
     309          80 :                 return;
     310             :         }
     311             : 
     312           0 :         auto views = getImageViews(getImageInfo());
     313             : 
     314           0 :         _staticImageStorage = Rc<ImageStorage>::create(getStaticImage());
     315             : 
     316           0 :         for (auto &info : views) {
     317           0 :                 auto v = _staticImageStorage->getView(info);
     318           0 :                 if (!v) {
     319           0 :                         auto v = dev.makeImageView(_staticImageStorage->getImage(), info);
     320           0 :                         _staticImageStorage->addView(info, move(v));
     321           0 :                 }
     322           0 :         }
     323           0 : }
     324             : 
     325         128 : bool GenericAttachment::init(AttachmentBuilder &builder) {
     326         128 :         builder.setType(AttachmentType::Generic);
     327         128 :         return Attachment::init(builder);
     328             : }
     329             : 
     330      394355 : bool AttachmentHandle::init(const Rc<Attachment> &attachment, const FrameQueue &frame) {
     331      394355 :         _attachment = attachment;
     332      394355 :         return true;
     333             : }
     334             : 
     335       38416 : bool AttachmentHandle::init(Attachment &attachment, const FrameQueue &frame) {
     336       38416 :         return init(&attachment, frame);
     337             : }
     338             : 
     339      394355 : void AttachmentHandle::setQueueData(FrameAttachmentData &data) {
     340      394355 :         _queueData = &data;
     341      394355 : }
     342             : 
     343       38416 : void AttachmentHandle::setInputCallback(InputCallback &&cb) {
     344       38416 :         _inputCallback = move(cb);
     345       38416 : }
     346             : 
     347             : // returns true for immediate setup, false if seyup job was scheduled
     348      385136 : bool AttachmentHandle::setup(FrameQueue &, Function<void(bool)> &&) {
     349      385136 :         return true;
     350             : }
     351             : 
     352      394355 : void AttachmentHandle::finalize(FrameQueue &, bool successful) {
     353             : 
     354      394355 : }
     355             : 
     356       38416 : void AttachmentHandle::submitInput(FrameQueue &q, Rc<AttachmentInputData> &&data, Function<void(bool)> &&cb) {
     357       38416 :         _input = move(data);
     358             : 
     359       38416 :         if (_input->waitDependencies.empty()) {
     360       38416 :                 auto ret = true;
     361       38416 :                 if (_inputCallback) {
     362       38416 :                         _inputCallback(*this, q, _input, move(cb));
     363             :                 } else {
     364           0 :                         cb(ret);
     365             :                 }
     366             :         } else {
     367           0 :                 q.getFrame()->waitForDependencies(_input->waitDependencies, [this, cb = move(cb), q = Rc<FrameQueue>(&q)] (FrameHandle &, bool success) mutable {
     368           0 :                         if (!success) {
     369           0 :                                 cb(success);
     370           0 :                         } else if (_inputCallback) {
     371           0 :                                 _inputCallback(*this, *q, _input, move(cb));
     372             :                         } else {
     373           0 :                                 cb(success);
     374             :                         }
     375           0 :                 });
     376             :         }
     377       38416 : }
     378             : 
     379      394355 : bool AttachmentHandle::isInput() const {
     380      394355 :         return (_attachment->getUsage() & AttachmentUsage::Input) != AttachmentUsage::None;
     381             : }
     382             : 
     383     2387953 : bool AttachmentHandle::isOutput() const {
     384     2387953 :         return (_attachment->getUsage() & AttachmentUsage::Output) != AttachmentUsage::None;
     385             : }
     386             : 
     387      245725 : uint32_t AttachmentHandle::getDescriptorArraySize(const PassHandle &, const PipelineDescriptor &d, bool isExternal) const {
     388      245725 :         return d.count;
     389             : }
     390             : 
     391           0 : bool AttachmentHandle::isDescriptorDirty(const PassHandle &, const PipelineDescriptor &d, uint32_t, bool isExternal) const {
     392           0 :         return false;
     393             : }
     394             : 
     395             : }

Generated by: LCOV version 1.14