diff --git a/examples/VulkanUI/main.cpp b/examples/VulkanUI/main.cpp index 05dfbaf..325c38a 100644 --- a/examples/VulkanUI/main.cpp +++ b/examples/VulkanUI/main.cpp @@ -54,7 +54,6 @@ int main() { window.FinishInit(); - RendertargetBase<3> rendertargetBase(1280, 720); RenderingElement2DVulkan element( { 0.5, //anchorX: relative position where this elements x anchor (top-left) is placed to its parent x anchor @@ -73,13 +72,7 @@ int main() { reinterpret_cast, true>*>(element.buffers[i])->value[1] = {0, 1, 0, 1}; reinterpret_cast, true>*>(element.buffers[i])->FlushDevice(); } - - InitializeRenderingElement2DVulkanBuffer(); - element.UpdatePosition(rendertargetBase, rendertargetBase.transform); - - renderingElement2DVulkanTransformBuffer[0].FlushDevice(); - renderingElement2DVulkanTransformBuffer[1].FlushDevice(); - renderingElement2DVulkanTransformBuffer[2].FlushDevice(); + RendertargetVulkan rendertarget(1280, 720, {&element}); VkImageDescriptorInfoEXT imageInfo0 = { .sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT, @@ -130,7 +123,7 @@ int main() { .size = Device::descriptorHeapProperties.imageDescriptorSize }, - WriteRenderingElement2DVulkanDescriptors(infos, ranges, 3, descriptorHeap.bufferStartOffset, descriptorHeap); + rendertarget.WriteDescriptors(infos, ranges, 3, descriptorHeap.bufferStartOffset, descriptorHeap); window.pipeline = &pipeline; window.descriptorHeap = &descriptorHeap; diff --git a/implementations/Crafter.Graphics-Rendertarget.cpp b/implementations/Crafter.Graphics-Rendertarget.cpp new file mode 100644 index 0000000..f453ca3 --- /dev/null +++ b/implementations/Crafter.Graphics-Rendertarget.cpp @@ -0,0 +1,160 @@ +/* +Crafter®.Graphics +Copyright (C) 2026 Catcrafts® +catcrafts.net + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License version 3.0 as published by the Free Software Foundation; + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +module; +#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN +#include +#endif +module Crafter.Graphics:Rendertarget_impl; +#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN +import :Rendertarget; +import :Window; +import :DescriptorHeapVulkan; +import :RenderingElement2DVulkan; +import std; +using namespace Crafter; + +RendertargetVulkan::RendertargetVulkan(std::uint16_t sizeX, std::uint16_t sizeY, std::vector&& elementss) : RendertargetBase(sizeX, sizeY), elements(std::move(elementss)) { + for(Transform2D* child : transform.children) { + SetOrderResursive(child); + } + for(std::uint8_t frame = 0; frame < Window::numFrames; frame++) { + transformBuffer[frame].Resize(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, elements.size()+1); + RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(transformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); + std::uint16_t* sizePtr = reinterpret_cast(transformBuffer[frame].value); + *sizePtr = static_cast(elements.size()); + for(std::uint16_t i = 0; i < elements.size(); i++) { + elements[i]->ScaleElement(transform); + val[i].scaled = elements[i]->scaled; + val[i].bufferX = elements[i]->bufferX; + val[i].bufferY = elements[i]->bufferY; + } + transformBuffer[frame].FlushDevice(); + } +} + +RendertargetVulkan::RendertargetVulkan(std::uint16_t sizeX, std::uint16_t sizeY) : RendertargetBase(sizeX, sizeY) { + +} + +void RendertargetVulkan::UpdateBuffer(std::uint8_t frame) { + elements.clear(); + for(Transform2D* child : transform.children) { + SetOrderResursive(child); + } + transformBuffer[frame].Resize(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, elements.size()+1); + RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(transformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); + std::uint16_t* sizePtr = reinterpret_cast(transformBuffer[frame].value); + *sizePtr = static_cast(elements.size()); + for(std::uint16_t i = 0; i < elements.size(); i++) { + elements[i]->ScaleElement(transform); + val[i].scaled = elements[i]->scaled; + val[i].bufferX = elements[i]->bufferX; + val[i].bufferY = elements[i]->bufferY; + } + transformBuffer[frame].FlushDevice(); +} + +void RendertargetVulkan::ReorderBuffer(std::uint8_t frame) { + RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(transformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); + elements.clear(); + for(Transform2D* child : transform.children) { + SetOrderResursive(child); + } + for(std::uint16_t i = 0; i < elements.size(); i++) { + val[i].scaled = elements[i]->scaled; + val[i].bufferX = elements[i]->bufferX; + val[i].bufferY = elements[i]->bufferY; + } +} + +void RendertargetVulkan::WriteDescriptors(std::span infos, std::span ranges, std::uint16_t start, std::uint32_t bufferOffset, DescriptorHeapVulkan& descriptorHeap) { + VkDeviceAddressRangeKHR transformRanges[Window::numFrames] = { + { + .address = transformBuffer[0].address, + .size = transformBuffer[0].size + }, + { + .address = transformBuffer[1].address, + .size = transformBuffer[1].size + }, + { + .address = transformBuffer[2].address, + .size = transformBuffer[2].size + } + }; + + for(std::uint8_t i = 0; i < Window::numFrames; i++) { + ranges[start + i] = { + .address = descriptorHeap.resourceHeap[i].value + bufferOffset, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }; + infos[start + i] = { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &transformRanges[i]} + }; + } + + start += 3; + bufferOffset += Device::descriptorHeapProperties.bufferDescriptorSize; + + std::vector bufferRanges(elements.size() * Window::numFrames); + + std::uint16_t rangeOffset = 0; + + for(std::uint8_t i2 = 0; i2 < Window::numFrames; i2++) { + for(std::uint16_t i = 0; i < elements.size(); i++) { + ranges[start + i] = { + .address = descriptorHeap.resourceHeap[i2].value + bufferOffset + Device::descriptorHeapProperties.bufferDescriptorSize * i, + .size = Device::descriptorHeapProperties.bufferDescriptorSize + }; + infos[start + i] = { + .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, + .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, + .data = { .pAddressRange = &bufferRanges[i]} + }; + bufferRanges[rangeOffset + i] = { + .address = elements[i]->buffers[i2]->address, + .size = elements[i]->buffers[i2]->size + }; + } + start += elements.size(); + rangeOffset += elements.size(); + } + + Device::vkWriteResourceDescriptorsEXT(Device::device, start, infos.data(), ranges.data()); + + for(std::uint8_t i = 0; i < Window::numFrames; i++) { + descriptorHeap.resourceHeap[i].FlushDevice(); + } +} + +void RendertargetVulkan::SetOrderResursive(Transform2D* elementTransform) { + std::sort(elementTransform->children.begin(), elementTransform->children.end(), [](Transform2D* a, Transform2D* b){ return a->anchor.z < b->anchor.z; }); + for(Transform2D* childTransform : elementTransform->children) { + RenderingElement2DVulkanBase* renderer = dynamic_cast(childTransform); + if(renderer) { + renderer->index = elements.size(); + elements.push_back(renderer); + } + SetOrderResursive(childTransform); + } +} +#endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-ForwardDeclarations.cppm b/interfaces/Crafter.Graphics-ForwardDeclarations.cppm index 9a5adca..3534166 100644 --- a/interfaces/Crafter.Graphics-ForwardDeclarations.cppm +++ b/interfaces/Crafter.Graphics-ForwardDeclarations.cppm @@ -21,9 +21,7 @@ export module Crafter.Graphics:ForwardDeclarations; import std; export namespace Crafter { - template struct RendertargetBase; - struct GridElement; struct Window; } \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-GridElement.cppm b/interfaces/Crafter.Graphics-GridElement.cppm index 7465b5e..30565bf 100644 --- a/interfaces/Crafter.Graphics-GridElement.cppm +++ b/interfaces/Crafter.Graphics-GridElement.cppm @@ -33,8 +33,7 @@ export namespace Crafter { GridElement(std::uint32_t columns, std::uint32_t rows, std::int32_t spacingX, std::int32_t spacingY, std::int32_t paddingX, std::int32_t paddingY, Anchor2D anchor) : Transform2D(anchor), columns(columns), rows(rows), spacingX(spacingX), spacingY(spacingY), paddingX(paddingX), paddingY(paddingY) { } - template - void UpdatePositionImpl(RendertargetBase& window, Transform2D& parent) { + void UpdatePosition(RendertargetBase& window, Transform2D& parent) override { ScaleElement(parent); std::int32_t cellWidth = (paddingX * 2) - (spacingX * (columns - 1)) / columns; std::int32_t cellHeight = (paddingY * 2) - (spacingY * (rows - 1)) / rows; @@ -61,11 +60,5 @@ export namespace Crafter { } } } - void UpdatePosition(RendertargetBase<1>& window, Transform2D& parent) override { - UpdatePositionImpl<1>(window, parent); - } - void UpdatePosition(RendertargetBase<3>& window, Transform2D& parent) override { - UpdatePositionImpl<3>(window, parent); - } }; } \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-RenderingElement2D.cppm b/interfaces/Crafter.Graphics-RenderingElement2D.cppm index 22c04f0..dc2c184 100644 --- a/interfaces/Crafter.Graphics-RenderingElement2D.cppm +++ b/interfaces/Crafter.Graphics-RenderingElement2D.cppm @@ -130,7 +130,7 @@ export namespace Crafter { } - void UpdatePosition(RendertargetBase& window, Transform2D& parent) override { + void UpdatePosition(RendertargetBase& window, Transform2D& parent) override { ScaleData2D oldScale = this->scaled; this->ScaleElement(parent); if constexpr(Scaling && !Rotating) { @@ -153,7 +153,7 @@ export namespace Crafter { } } - std::vector ResizeText(RendertargetBase& window, Transform2D& parent, const std::string_view text, float& size, Font& font, TextOverflowMode overflowMode = TextOverflowMode::Clip, TextScaleMode scaleMode = TextScaleMode::None) { + std::vector ResizeText(RendertargetBase& window, Transform2D& parent, const std::string_view text, float& size, Font& font, TextOverflowMode overflowMode = TextOverflowMode::Clip, TextScaleMode scaleMode = TextScaleMode::None) { float scale = stbtt_ScaleForPixelHeight(&font.font, size); int baseline = (int)(font.ascent * scale); diff --git a/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm b/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm index 5827287..f8faf00 100644 --- a/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm +++ b/interfaces/Crafter.Graphics-RenderingElement2DVulkan.cppm @@ -33,13 +33,6 @@ import :Window; import :DescriptorHeapVulkan; export namespace Crafter { - struct __attribute__((packed)) RenderingElement2DVulkanTransformInfo { - ScaleData2D scaled; // 0 - 8 bytes - std::uint16_t bufferX; // 8 - 2 bytes - std::uint16_t bufferY; // 10 - 2 bytes - //12 bytes total; - }; - struct RenderingElement2DVulkanBase : Transform2D { std::uint16_t index; std::uint16_t bufferX; @@ -56,14 +49,10 @@ export namespace Crafter { } }; - std::vector renderingElement2DVulkans; - VulkanBuffer renderingElement2DVulkanTransformBuffer[Window::numFrames]; - template struct RenderingElement2DVulkan : RenderingElement2DVulkanBase { - RenderingElement2DVulkan(Anchor2D anchor, RendertargetBase& target, Transform2D& parent) requires(Owning) : RenderingElement2DVulkanBase(anchor) { - renderingElement2DVulkans.push_back(this); - UpdatePosition(target, parent); + RenderingElement2DVulkan(Anchor2D anchor, RendertargetBase& target, Transform2D& parent) requires(Owning) : RenderingElement2DVulkanBase(anchor) { + GetScale(target, parent); this->bufferX = this->scaled.size.x; this->bufferY = this->scaled.size.y; for(std::uint8_t i = 0; i < Window::numFrames; i++) { @@ -73,7 +62,6 @@ export namespace Crafter { } RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY) requires(Owning) : RenderingElement2DVulkanBase(anchor, bufferX, bufferY) { - renderingElement2DVulkans.push_back(this); for(std::uint8_t i = 0; i < Window::numFrames; i++) { buffers[i] = new VulkanBuffer, Mapped>(); static_cast, Mapped>*>(buffers[i])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY); @@ -81,7 +69,7 @@ export namespace Crafter { } RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY, std::array&& buffers) requires(!Owning) : RenderingElement2DVulkanBase(anchor, bufferX, bufferY, std::move(buffers)) { - renderingElement2DVulkans.push_back(this); + } RenderingElement2DVulkan(Anchor2D anchor, const std::filesystem::path& assetPath, bool single) requires(Owning && Mapped) : RenderingElement2DVulkanBase(anchor) { @@ -94,15 +82,15 @@ export namespace Crafter { for(std::uint8_t i = 1; i < Window::numFrames; i++) { buffers[i] = buffers[0]; } - TextureAsset<_Float16>::LoadInfo(assetPath, buffers[0].value, this->bufferX, this->bufferY); + TextureAsset<_Float16>::Load(assetPath, reinterpret_cast<_Float16*>(static_cast, Mapped>*>(buffers[0])->value), this->bufferX, this->bufferY); } else { for(std::uint8_t i = 0; i < Window::numFrames; i++) { buffers[i] = new VulkanBuffer, Mapped>(); static_cast, Mapped>*>(buffers[i])->Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, bufferX * bufferY); } - TextureAsset<_Float16>::LoadInfo(assetPath, buffers[0].value, this->bufferX, this->bufferY); + TextureAsset<_Float16>::Load(assetPath, reinterpret_cast<_Float16*>(static_cast, Mapped>*>(buffers[0])->value), this->bufferX, this->bufferY); for(std::uint8_t i = 1; i < Window::numFrames; i++) { - std::memcpy(buffers[i].value, buffers[0].value, this->bufferX * this->bufferY * sizeof(_Float16)); + std::memcpy(static_cast, Mapped>*>(buffers[i])->value, static_cast, Mapped>*>(buffers[0])->value, this->bufferX * this->bufferY * sizeof(_Float16)); } } } @@ -113,113 +101,27 @@ export namespace Crafter { delete static_cast, Mapped>*>(buffer); } } - auto it = std::find(renderingElement2DVulkans.begin(), renderingElement2DVulkans.end(), this); - if (it != renderingElement2DVulkans.end()) { - renderingElement2DVulkans.erase(it); - } } RenderingElement2DVulkan(RenderingElement2DVulkan&) = delete; RenderingElement2DVulkan& operator=(RenderingElement2DVulkan&) = delete; - void UpdatePosition(RendertargetBase& window, Transform2D& parent) override { + void UpdatePosition(RendertargetBase& window2, Transform2D& parent) override { + RendertargetVulkan& window = static_cast(window2); this->ScaleElement(parent); - RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(renderingElement2DVulkanTransformBuffer[window.frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); + RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(window.transformBuffer[window.frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); val[index].scaled = this->scaled; for(Transform2D* child : this->children) { child->UpdatePosition(window, *this); } } + + void GetScale(RendertargetBase& window, Transform2D& parent) { + this->ScaleElement(parent); + for(Transform2D* child : this->children) { + child->UpdatePosition(window, *this); + } + } }; - - void WriteRenderingElement2DVulkanDescriptors(std::span infos, std::span ranges, std::uint16_t start, std::uint32_t bufferOffset, DescriptorHeapVulkan& descriptorHeap) { - VkDeviceAddressRangeKHR transformRanges[Window::numFrames] = { - { - .address = renderingElement2DVulkanTransformBuffer[0].address, - .size = renderingElement2DVulkanTransformBuffer[0].size - }, - { - .address = renderingElement2DVulkanTransformBuffer[1].address, - .size = renderingElement2DVulkanTransformBuffer[1].size - }, - { - .address = renderingElement2DVulkanTransformBuffer[2].address, - .size = renderingElement2DVulkanTransformBuffer[2].size - } - }; - - for(std::uint8_t i = 0; i < Window::numFrames; i++) { - ranges[start + i] = { - .address = descriptorHeap.resourceHeap[i].value + bufferOffset, - .size = Device::descriptorHeapProperties.bufferDescriptorSize - }; - infos[start + i] = { - .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, - .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .data = { .pAddressRange = &transformRanges[i]} - }; - } - - start += 3; - bufferOffset += Device::descriptorHeapProperties.bufferDescriptorSize; - - std::vector bufferRanges(renderingElement2DVulkans.size() * Window::numFrames); - - std::uint16_t rangeOffset = 0; - - for(std::uint8_t i2 = 0; i2 < Window::numFrames; i2++) { - for(std::uint16_t i = 0; i < renderingElement2DVulkans.size(); i++) { - ranges[start + i] = { - .address = descriptorHeap.resourceHeap[i2].value + bufferOffset + Device::descriptorHeapProperties.bufferDescriptorSize * i, - .size = Device::descriptorHeapProperties.bufferDescriptorSize - }; - infos[start + i] = { - .sType = VK_STRUCTURE_TYPE_RESOURCE_DESCRIPTOR_INFO_EXT, - .type = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, - .data = { .pAddressRange = &bufferRanges[i]} - }; - bufferRanges[rangeOffset + i] = { - .address = renderingElement2DVulkans[i]->buffers[i2]->address, - .size = renderingElement2DVulkans[i]->buffers[i2]->size - }; - } - start += renderingElement2DVulkans.size(); - rangeOffset += renderingElement2DVulkans.size(); - } - - Device::vkWriteResourceDescriptorsEXT(Device::device, start, infos.data(), ranges.data()); - - for(std::uint8_t i = 0; i < Window::numFrames; i++) { - descriptorHeap.resourceHeap[i].FlushDevice(); - } - } - - void InitializeRenderingElement2DVulkanBuffer() { - for(std::uint8_t frame = 0; frame < Window::numFrames; frame++) { - renderingElement2DVulkanTransformBuffer[frame].Create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, renderingElement2DVulkans.size()+1); - RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); - std::uint16_t* sizePtr = reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value); - *sizePtr = renderingElement2DVulkans.size(); - for(std::uint16_t i = 0; i < renderingElement2DVulkans.size(); i++) { - val[i].scaled = renderingElement2DVulkans[i]->scaled; - val[i].bufferX = renderingElement2DVulkans[i]->bufferX; - val[i].bufferY = renderingElement2DVulkans[i]->bufferY; - renderingElement2DVulkans[i]->index = i; - } - } - } - - void UpdateRenderingElement2DVulkanBuffer(std::uint8_t frame) { - renderingElement2DVulkanTransformBuffer[frame].Resize(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_2_SHADER_DEVICE_ADDRESS_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT, renderingElement2DVulkans.size()+1); - RenderingElement2DVulkanTransformInfo* val = reinterpret_cast(reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo)); - std::uint16_t* sizePtr = reinterpret_cast(renderingElement2DVulkanTransformBuffer[frame].value); - *sizePtr = renderingElement2DVulkans.size(); - for(std::uint16_t i = 0; i < renderingElement2DVulkans.size(); i++) { - val[i].scaled = renderingElement2DVulkans[i]->scaled; - val[i].bufferX = renderingElement2DVulkans[i]->bufferX; - val[i].bufferY = renderingElement2DVulkans[i]->bufferY; - renderingElement2DVulkans[i]->index = i + 1; - } - } } #endif \ No newline at end of file diff --git a/interfaces/Crafter.Graphics-Rendertarget.cppm b/interfaces/Crafter.Graphics-Rendertarget.cppm index da850ef..8ca5c6f 100644 --- a/interfaces/Crafter.Graphics-Rendertarget.cppm +++ b/interfaces/Crafter.Graphics-Rendertarget.cppm @@ -16,6 +16,12 @@ You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + +module; +#include "../lib/stb_truetype.h" +#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN +#include +#endif export module Crafter.Graphics:Rendertarget; import Crafter.Math; import Crafter.Asset; @@ -23,9 +29,12 @@ import std; import :Types; import :Transform2D; import :RenderingElement2DBase; +#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN +import :Device; +import :VulkanBuffer; +#endif export namespace Crafter { - template struct RendertargetBase { #ifdef CRAFTER_TIMING std::vector> renderTimings; @@ -33,7 +42,6 @@ export namespace Crafter { Transform2D transform; std::uint16_t sizeX; std::uint16_t sizeY; - std::uint8_t frame; RendertargetBase() = default; RendertargetBase(std::uint16_t sizeX, std::uint16_t sizeY) : sizeX(sizeX), sizeY(sizeY), transform({0, 0, 1, 1, 0, 0, 0}){ transform.scaled.size.x = sizeX; @@ -42,12 +50,39 @@ export namespace Crafter { transform.scaled.position.y = 0; } }; + + #ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN + struct RenderingElement2DVulkanBase; + + struct __attribute__((packed)) RenderingElement2DVulkanTransformInfo { + ScaleData2D scaled; // 0 - 8 bytes + std::uint16_t bufferX; // 8 - 2 bytes + std::uint16_t bufferY; // 10 - 2 bytes + //12 bytes total; + }; + + + struct DescriptorHeapVulkan; + struct RendertargetVulkan : RendertargetBase { + std::uint8_t frame; + std::vector elements; + VulkanBuffer transformBuffer[3]; + + RendertargetVulkan() = default; + RendertargetVulkan(std::uint16_t sizeX, std::uint16_t sizeY, std::vector&& elements); + RendertargetVulkan(std::uint16_t sizeX, std::uint16_t sizeY); + void UpdateBuffer(std::uint8_t frame); + void ReorderBuffer(std::uint8_t frame); + void WriteDescriptors(std::span infos, std::span ranges, std::uint16_t start, std::uint32_t bufferOffset, DescriptorHeapVulkan& descriptorHeap); + void SetOrderResursive(Transform2D* elementTransform); + }; + #endif template - struct Rendertarget : RendertargetBase { + struct Rendertarget : RendertargetBase { Vector* buffer[Frames]; Rendertarget() = default; - Rendertarget(std::uint16_t sizeX, std::uint16_t sizeY) : RendertargetBase(sizeX, sizeY) { + Rendertarget(std::uint16_t sizeX, std::uint16_t sizeY) : RendertargetBase(sizeX, sizeY) { } void RenderElement(Transform2D* elementTransform, std::uint8_t frame, std::vector&& dirtyRects) { diff --git a/interfaces/Crafter.Graphics-Transform2D.cppm b/interfaces/Crafter.Graphics-Transform2D.cppm index bab45e5..f24bb6a 100644 --- a/interfaces/Crafter.Graphics-Transform2D.cppm +++ b/interfaces/Crafter.Graphics-Transform2D.cppm @@ -49,14 +49,7 @@ export namespace Crafter { Transform2D& operator=(Transform2D&) = delete; virtual ~Transform2D() = default; - virtual void UpdatePosition(RendertargetBase<1>& window, Transform2D& parent) { - ScaleElement(parent); - for(Transform2D* child : children) { - child->UpdatePosition(window, *this); - } - } - - virtual void UpdatePosition(RendertargetBase<3>& window, Transform2D& parent) { + virtual void UpdatePosition(RendertargetBase& window, Transform2D& parent) { ScaleElement(parent); for(Transform2D* child : children) { child->UpdatePosition(window, *this); diff --git a/project.json b/project.json index c19bdf0..752dc42 100644 --- a/project.json +++ b/project.json @@ -10,7 +10,8 @@ "implementations/Crafter.Graphics-Transform2D", "implementations/Crafter.Graphics-Device", "implementations/Crafter.Graphics-Mesh", - "implementations/Crafter.Graphics-RenderingElement3D" + "implementations/Crafter.Graphics-RenderingElement3D", + "implementations/Crafter.Graphics-Rendertarget" ], "interfaces": [ "interfaces/Crafter.Graphics-Window",