LCOV - code coverage report
Current view: top level - xenolith/core - XLCoreObject.cc (source / functions) Hit Total Coverage
Test: coverage.info Lines: 169 218 77.5 %
Date: 2024-05-12 00:16:13 Functions: 32 42 76.2 %

          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 "XLCoreObject.h"
      24             : #include "XLCoreInfo.h"
      25             : #include "XLCoreDevice.h"
      26             : #include "SPIRV-Reflect/spirv_reflect.h"
      27             : 
      28             : namespace STAPPLER_VERSIONIZED stappler::xenolith::core {
      29             : 
      30     1174410 : Object::~Object() {
      31     1174410 :         invalidate();
      32     1174410 : }
      33             : 
      34     1174305 : bool Object::init(Device &dev, ClearCallback cb, ObjectType type, ObjectHandle handle, void *extra) {
      35     1174305 :         _object.device = &dev;
      36     1174305 :         _object.callback = cb;
      37     1174305 :         _object.type = type;
      38     1174305 :         _object.handle = handle;
      39     1174305 :         _object.ptr = extra;
      40     1174305 :         if (_object.handle.get()) {
      41      643697 :                 _object.device->addObject(this);
      42             :         }
      43     1174357 :         return true;
      44             : }
      45             : 
      46     1705007 : void Object::invalidate() {
      47     1705007 :         if (_object.callback) {
      48     1174378 :                 if (_object.handle.get()) {
      49      643701 :                         _object.device->removeObject(this);
      50             :                 }
      51     1174378 :                 if (_object.callback) {
      52     1174378 :                         _object.callback(_object.device, _object.type, _object.handle, _object.ptr);
      53             :                 }
      54     1174378 :                 _object.callback = nullptr;
      55     1174378 :                 _object.device = nullptr;
      56     1174378 :                 _object.handle = ObjectHandle::zero();
      57             :         }
      58     1705007 : }
      59             : 
      60             : static std::atomic<uint64_t> s_RenderPassImplCurrentIndex = 1;
      61             : 
      62         272 : bool RenderPass::init(Device &dev, ClearCallback cb, ObjectType type, ObjectHandle ptr, void *p) {
      63         272 :         if (Object::init(dev, cb, type, ptr, p)) {
      64         272 :                 _index = s_RenderPassImplCurrentIndex.fetch_add(1);
      65         272 :                 return true;
      66             :         }
      67           0 :         return false;
      68             : }
      69             : 
      70           0 : uint64_t Framebuffer::getViewHash(SpanView<Rc<ImageView>> views) {
      71           0 :         Vector<uint64_t> ids; ids.reserve(views.size());
      72           0 :         for (auto &it : views) {
      73           0 :                 ids.emplace_back(it->getIndex());
      74             :         }
      75           0 :         return getViewHash(ids);
      76           0 : }
      77             : 
      78           0 : uint64_t Framebuffer::getViewHash(SpanView<uint64_t> ids) {
      79           0 :         return hash::hash64((const char *)ids.data(), ids.size() * sizeof(uint64_t));
      80             : }
      81             : 
      82           0 : uint64_t Framebuffer::getHash() const {
      83           0 :         return hash::hash64((const char *)_viewIds.data(), _viewIds.size() * sizeof(uint64_t));
      84             : }
      85             : 
      86             : static std::atomic<uint64_t> s_ImageViewCurrentIndex = 1;
      87             : 
      88         844 : bool DataAtlas::init(Type t, uint32_t count, uint32_t objectSize, Extent2 imageSize) {
      89         844 :         _type = t;
      90         844 :         _objectSize = objectSize;
      91         844 :         _imageExtent = imageSize;
      92         844 :         _data.reserve(count * objectSize);
      93         844 :         return true;
      94             : }
      95             : 
      96         828 : void DataAtlas::compile() {
      97         828 :         makeHashIndex();
      98         828 : }
      99             : 
     100      517636 : inline uint32_t hash(uint32_t k, uint32_t capacity) {
     101      517636 :         k ^= k >> 16;
     102      517636 :         k *= 0x85ebca6b;
     103      517636 :         k ^= k >> 13;
     104      517636 :         k *= 0xc2b2ae35;
     105      517636 :         k ^= k >> 16;
     106      517636 :         return k & (capacity - 1);
     107             : }
     108             : 
     109             : struct HashTableKeyValue {
     110             :         uint32_t key;
     111             :         uint32_t value;
     112             : };
     113             : 
     114          64 : const uint8_t *DataAtlas::getObjectByName(uint32_t id) const {
     115          64 :         if (!_dataIndex.empty()) {
     116          32 :                 auto size = _dataIndex.size() / sizeof(HashTableKeyValue);
     117          32 :                 uint32_t slot = hash(id, size);
     118          32 :                 auto data = (HashTableKeyValue *)_dataIndex.data();
     119             : 
     120             :                 while (true) {
     121          48 :                         uint32_t prev = data[slot].key;
     122          48 :                         if (prev == id) {
     123          32 :                                 return _data.data() + _objectSize * data[slot].value;
     124          16 :                         } else if (prev == 0xffffffffU) {
     125           0 :                                 break;
     126             :                         }
     127          16 :                         slot = (slot + 1) & (size - 1);
     128          16 :                 }
     129             :         }
     130             : 
     131          32 :         auto it = _intNames.find(id);
     132          32 :         if (it != _intNames.end()) {
     133          32 :                 if (it->second < _data.size() / _objectSize) {
     134          32 :                         return _data.data() + _objectSize * it->second;
     135             :                 }
     136             :         }
     137           0 :         return nullptr;
     138             : }
     139             : 
     140          16 : const uint8_t *DataAtlas::getObjectByName(StringView str) const {
     141          16 :         auto it = _stringNames.find(str.str<Interface>());
     142          16 :         if (it != _stringNames.end()) {
     143          16 :                 if (it->second < _data.size() / _objectSize) {
     144          16 :                         return _data.data() + _objectSize * it->second;
     145             :                 }
     146             :         }
     147           0 :         return nullptr;
     148             : }
     149             : 
     150          32 : const uint8_t *DataAtlas::getObjectByOrder(uint32_t order) const {
     151          32 :         if (order < _data.size() / _objectSize) {
     152          16 :                 return _data.data() + _objectSize * order;
     153             :         }
     154          16 :         return nullptr;
     155             : }
     156             : 
     157      517604 : void DataAtlas::addObject(uint32_t id, void *data) {
     158      517604 :         auto off = _data.size();
     159      517604 :         _data.resize(off + _objectSize);
     160      517604 :         memcpy(_data.data() + off, data,  _objectSize);
     161             : 
     162      517604 :         _intNames.emplace(id, off / _objectSize);
     163      517604 : }
     164             : 
     165          32 : void DataAtlas::addObject(StringView name, void *data) {
     166          32 :         auto off = _data.size();
     167          32 :         _data.resize(off + _objectSize);
     168          32 :         memcpy(_data.data() + off, data,  _objectSize);
     169             : 
     170          32 :         _stringNames.emplace(name.str<Interface>(), off / _objectSize);
     171          32 : }
     172             : 
     173         812 : void DataAtlas::setIndexBuffer(Rc<BufferObject> &&index) {
     174         812 :         _indexBuffer = move(index);
     175         812 : }
     176             : 
     177         812 : void DataAtlas::setDataBuffer(Rc<BufferObject> &&data) {
     178         812 :         _dataBuffer = move(data);
     179         812 : }
     180             : 
     181         828 : void DataAtlas::makeHashIndex() {
     182         828 :         auto size = math::npot(_intNames.size());
     183         828 :         Bytes dataStorage; dataStorage.resize(size * sizeof(HashTableKeyValue), uint8_t(0xFFU));
     184         828 :         auto data = (HashTableKeyValue *)dataStorage.data();
     185             : 
     186      518432 :         for (auto &it : _intNames) {
     187      517604 :                 uint32_t slot = hash(it.first, size);
     188             : 
     189             :                 while (true) {
     190     1510073 :                         uint32_t prev = data[slot].key;
     191     1510073 :                         if (prev == 0xffffffffU || prev == it.first) {
     192      517604 :                                 data[slot].key = it.first;
     193      517604 :                                 data[slot].value = it.second;
     194      517604 :                                 break;
     195             :                         }
     196      992469 :                         slot = (slot + 1) & (size - 1);
     197      992469 :                 }
     198             :         }
     199             : 
     200         828 :         _dataIndex = move(dataStorage);
     201         828 : }
     202             : 
     203        1116 : ImageObject::~ImageObject() { }
     204             : 
     205         304 : bool ImageObject::init(Device &dev, ClearCallback cb, ObjectType type, ObjectHandle ptr, void *p) {
     206         304 :         if (Object::init(dev, cb, type, ptr, p)) {
     207         304 :                 _index = s_ImageViewCurrentIndex.fetch_add(1);
     208         304 :                 return true;
     209             :         }
     210           0 :         return false;
     211             : }
     212         812 : bool ImageObject::init(Device &dev, ClearCallback cb, ObjectType type, ObjectHandle ptr, void *p, uint64_t idx) {
     213         812 :         if (Object::init(dev, cb, type, ptr, p)) {
     214         812 :                 _index = idx;
     215         812 :                 return true;
     216             :         }
     217           0 :         return false;
     218             : }
     219             : 
     220           0 : ImageViewInfo ImageObject::getViewInfo(const ImageViewInfo &info) const {
     221           0 :         return _info.getViewInfo(info);
     222             : }
     223             : 
     224        1180 : ImageView::~ImageView() {
     225        1180 :         if (_releaseCallback) {
     226           0 :                 _releaseCallback();
     227           0 :                 _releaseCallback = nullptr;
     228             :         }
     229        1180 : }
     230             : 
     231        1180 : bool ImageView::init(Device &dev, ClearCallback cb, ObjectType type, ObjectHandle ptr, void *p) {
     232        1180 :         if (Object::init(dev, cb, type, ptr, p)) {
     233        1180 :                 _index = s_ImageViewCurrentIndex.fetch_add(1);
     234        1180 :                 return true;
     235             :         }
     236           0 :         return false;
     237             : }
     238             : 
     239         176 : void ImageView::setReleaseCallback(Function<void()> &&cb) {
     240         176 :         _releaseCallback = move(cb);
     241         176 : }
     242             : 
     243         176 : void ImageView::runReleaseCallback() {
     244         176 :         if (_releaseCallback) {
     245         176 :                 auto cb = move(_releaseCallback);
     246         176 :                 _releaseCallback = nullptr;
     247         176 :                 cb();
     248         176 :         }
     249         176 : }
     250             : 
     251           0 : Extent3 ImageView::getExtent() const {
     252           0 :         return _image->getInfo().extent;
     253             : }
     254             : 
     255       36970 : uint32_t ImageView::getLayerCount() const {
     256       36970 :         return _info.layerCount.get();
     257             : }
     258             : 
     259       36970 : Extent3 ImageView::getFramebufferExtent() const {
     260       36970 :         return Extent3(_image->getInfo().extent.width, _image->getInfo().extent.height, getLayerCount());
     261             : }
     262             : 
     263       31944 : void CommandBuffer::bindImage(ImageObject *image) {
     264       31944 :         _images.emplace(image);
     265       31944 : }
     266             : 
     267     1770331 : void CommandBuffer::bindBuffer(BufferObject *buffer) {
     268     1770331 :         _buffers.emplace(buffer);
     269     1770331 : }
     270             : 
     271        7322 : void CommandBuffer::bindFramebuffer(Framebuffer *fb) {
     272        7322 :         _framebuffers.emplace(fb);
     273        7322 : }
     274             : 
     275           0 : void TextureSet::write(const MaterialLayout &set) {
     276           0 :         _layoutIndexes.clear();
     277           0 :         for (uint32_t i = 0; i < set.usedImageSlots; ++ i) {
     278           0 :                 if (set.imageSlots[i].image) {
     279           0 :                         _layoutIndexes.emplace_back(set.imageSlots[i].image->getIndex());
     280             :                 } else {
     281           0 :                         _layoutIndexes.emplace_back(0);
     282             :                 }
     283             :         }
     284             : 
     285           0 :         _layoutIndexes.resize(_count, 0);
     286           0 : }
     287             : 
     288          16 : String Shader::inspectShader(SpanView<uint32_t> data) {
     289             :         SpvReflectShaderModule shader;
     290             : 
     291          16 :         spvReflectCreateShaderModule(data.size() * sizeof(uint32_t), data.data(), &shader);
     292             : 
     293          16 :         ProgramStage stage = ProgramStage::None;
     294          16 :         switch (shader.spirv_execution_model) {
     295           0 :         case SpvExecutionModelVertex: stage = ProgramStage::Vertex; break;
     296           0 :         case SpvExecutionModelTessellationControl: stage = ProgramStage::TesselationControl; break;
     297           0 :         case SpvExecutionModelTessellationEvaluation: stage = ProgramStage::TesselationEvaluation; break;
     298           0 :         case SpvExecutionModelGeometry: stage = ProgramStage::Geometry; break;
     299           0 :         case SpvExecutionModelFragment: stage = ProgramStage::Fragment; break;
     300          16 :         case SpvExecutionModelGLCompute: stage = ProgramStage::Compute; break;
     301           0 :         case SpvExecutionModelKernel: stage = ProgramStage::Compute; break;
     302           0 :         case SpvExecutionModelTaskNV: stage = ProgramStage::Task; break;
     303           0 :         case SpvExecutionModelMeshNV: stage = ProgramStage::Mesh; break;
     304           0 :         case SpvExecutionModelRayGenerationKHR: stage = ProgramStage::RayGen; break;
     305           0 :         case SpvExecutionModelIntersectionKHR: stage = ProgramStage::Intersection; break;
     306           0 :         case SpvExecutionModelAnyHitKHR: stage = ProgramStage::AnyHit; break;
     307           0 :         case SpvExecutionModelClosestHitKHR: stage = ProgramStage::ClosestHit; break;
     308           0 :         case SpvExecutionModelMissKHR: stage = ProgramStage::MissHit; break;
     309           0 :         case SpvExecutionModelCallableKHR: stage = ProgramStage::Callable; break;
     310           0 :         default: break;
     311             :         }
     312             : 
     313          32 :         StringStream out;
     314             : 
     315          16 :         out << "[" << getProgramStageDescription(stage) << "]\n";
     316             : 
     317          80 :         for (auto &it : makeSpanView(shader.descriptor_bindings, shader.descriptor_binding_count)) {
     318          64 :                 out << "\tBinging: [" << it.set << ":" << it.binding << "] "
     319          64 :                                 << getDescriptorTypeName(DescriptorType(it.descriptor_type)) << "\n";
     320             :         }
     321             : 
     322          16 :         for (auto &it : makeSpanView(shader.push_constant_blocks, shader.push_constant_block_count)) {
     323           0 :                 out << "\tPushConstant: [" << it.absolute_offset << " - " << it.padded_size << "]\n";
     324             :         }
     325             : 
     326          16 :         spvReflectDestroyShaderModule(&shader);
     327             : 
     328          32 :         return out.str();
     329             : }
     330             : 
     331           0 : String Shader::inspect(SpanView<uint32_t> data) {
     332           0 :         return inspectShader(data);
     333             : }
     334             : 
     335      132658 : void Semaphore::setSignaled(bool value) {
     336      132658 :         _signaled = value;
     337      132658 : }
     338             : 
     339      132498 : void Semaphore::setWaited(bool value) {
     340      132498 :         _waited = value;
     341      132498 : }
     342             : 
     343      250576 : void Semaphore::setInUse(bool value, uint64_t timeline) {
     344      250576 :         if (timeline == _timeline) {
     345      250576 :                 _inUse = value;
     346             :         }
     347      250576 : }
     348             : 
     349       30254 : bool Semaphore::reset() {
     350       30254 :         if (_signaled == _waited) {
     351       30222 :                 _signaled = false;
     352       30222 :                 _waited = false;
     353       30222 :                 _inUse = false;
     354       30222 :                 ++ _timeline;
     355       30222 :                 return true;
     356             :         }
     357          32 :         return false;
     358             : }
     359             : 
     360             : }

Generated by: LCOV version 1.14