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 "XL2dVkMaterial.h" 24 : 25 : namespace STAPPLER_VERSIONIZED stappler::xenolith::basic2d::vk { 26 : 27 20 : MaterialAttachment::~MaterialAttachment() { } 28 : 29 10 : bool MaterialAttachment::init(AttachmentBuilder &builder, const BufferInfo &info) { 30 20 : return core::MaterialAttachment::init(builder, info, [] (uint8_t *target, const core::Material *material) { 31 4609 : auto &images = material->getImages(); 32 4609 : if (!images.empty()) { 33 : MaterialData material; 34 4609 : auto &image = images.front(); 35 4609 : material.samplerImageIdx = image.descriptor | (image.sampler << 16); 36 4609 : material.setIdx = image.set; 37 4609 : material.flags = 0; 38 4609 : material.atlasIdx = 0; 39 4609 : if (image.image->atlas) { 40 563 : if (auto &index = image.image->atlas->getIndexBuffer()) { 41 563 : material.flags |= XL_GLSL_MATERIAL_FLAG_HAS_ATLAS_INDEX; 42 563 : material.atlasIdx |= index->getDescriptor(); 43 : 44 563 : auto indexSize = image.image->atlas->getIndexData().size() / sizeof(DataAtlasIndex); 45 563 : auto pow2index = std::countr_zero(indexSize); 46 : 47 563 : material.flags |= (pow2index << XL_GLSL_MATERIAL_FLAG_ATLAS_POW2_INDEX_BIT_OFFSET); 48 : } 49 563 : if (auto &data = image.image->atlas->getDataBuffer()) { 50 563 : material.flags |= XL_GLSL_MATERIAL_FLAG_HAS_ATLAS_DATA; 51 563 : material.atlasIdx |= (data->getDescriptor() << 16); 52 : } 53 : } 54 4609 : memcpy(target, &material, sizeof(MaterialData)); 55 4609 : return true; 56 : } 57 0 : return false; 58 20 : }, sizeof(MaterialData)); 59 : } 60 : 61 4650 : auto MaterialAttachment::makeFrameHandle(const FrameQueue &handle) -> Rc<AttachmentHandle> { 62 9300 : return Rc<MaterialAttachmentHandle>::create(this, handle); 63 : } 64 : 65 9300 : MaterialAttachmentHandle::~MaterialAttachmentHandle() { } 66 : 67 4650 : bool MaterialAttachmentHandle::init(const Rc<Attachment> &a, const FrameQueue &handle) { 68 4650 : if (BufferAttachmentHandle::init(a, handle)) { 69 4650 : return true; 70 : } 71 0 : return false; 72 : } 73 : 74 4640 : bool MaterialAttachmentHandle::isDescriptorDirty(const PassHandle &, const PipelineDescriptor &desc, 75 : uint32_t, bool isExternal) const { 76 4640 : return _materials && _materials->getGeneration() != desc.boundGeneration; 77 : } 78 : 79 543 : bool MaterialAttachmentHandle::writeDescriptor(const core::QueuePassHandle &handle, DescriptorBufferInfo &info) { 80 543 : if (!_materials) { 81 0 : return false; 82 : } 83 : 84 543 : auto b = _materials->getBuffer(); 85 543 : if (!b) { 86 0 : return false; 87 : } 88 543 : info.buffer = static_cast<Buffer *>(b.get()); 89 543 : info.offset = 0; 90 543 : info.range = info.buffer->getSize(); 91 543 : info.descriptor->boundGeneration = _materials->getGeneration(); 92 543 : return true; 93 543 : } 94 : 95 4640 : const MaterialAttachment *MaterialAttachmentHandle::getMaterialAttachment() const { 96 4640 : return static_cast<MaterialAttachment *>(_attachment.get()); 97 : } 98 : 99 9280 : const Rc<core::MaterialSet> MaterialAttachmentHandle::getSet() const { 100 9280 : if (!_materials) { 101 4640 : _materials = getMaterialAttachment()->getMaterials(); 102 : } 103 9280 : return _materials; 104 : } 105 : 106 : }