rendertargetvulkan
This commit is contained in:
parent
8b12dc39b3
commit
1c1a142f52
9 changed files with 221 additions and 146 deletions
|
|
@ -54,7 +54,6 @@ int main() {
|
||||||
|
|
||||||
window.FinishInit();
|
window.FinishInit();
|
||||||
|
|
||||||
RendertargetBase<3> rendertargetBase(1280, 720);
|
|
||||||
RenderingElement2DVulkan<true, true> element(
|
RenderingElement2DVulkan<true, true> element(
|
||||||
{
|
{
|
||||||
0.5, //anchorX: relative position where this elements x anchor (top-left) is placed to its parent x anchor
|
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<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(element.buffers[i])->value[1] = {0, 1, 0, 1};
|
reinterpret_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(element.buffers[i])->value[1] = {0, 1, 0, 1};
|
||||||
reinterpret_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(element.buffers[i])->FlushDevice();
|
reinterpret_cast<VulkanBuffer<Vector<_Float16, 4, 4>, true>*>(element.buffers[i])->FlushDevice();
|
||||||
}
|
}
|
||||||
|
RendertargetVulkan rendertarget(1280, 720, {&element});
|
||||||
InitializeRenderingElement2DVulkanBuffer();
|
|
||||||
element.UpdatePosition(rendertargetBase, rendertargetBase.transform);
|
|
||||||
|
|
||||||
renderingElement2DVulkanTransformBuffer[0].FlushDevice();
|
|
||||||
renderingElement2DVulkanTransformBuffer[1].FlushDevice();
|
|
||||||
renderingElement2DVulkanTransformBuffer[2].FlushDevice();
|
|
||||||
|
|
||||||
VkImageDescriptorInfoEXT imageInfo0 = {
|
VkImageDescriptorInfoEXT imageInfo0 = {
|
||||||
.sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT,
|
.sType = VK_STRUCTURE_TYPE_IMAGE_DESCRIPTOR_INFO_EXT,
|
||||||
|
|
@ -130,7 +123,7 @@ int main() {
|
||||||
.size = Device::descriptorHeapProperties.imageDescriptorSize
|
.size = Device::descriptorHeapProperties.imageDescriptorSize
|
||||||
},
|
},
|
||||||
|
|
||||||
WriteRenderingElement2DVulkanDescriptors(infos, ranges, 3, descriptorHeap.bufferStartOffset, descriptorHeap);
|
rendertarget.WriteDescriptors(infos, ranges, 3, descriptorHeap.bufferStartOffset, descriptorHeap);
|
||||||
|
|
||||||
window.pipeline = &pipeline;
|
window.pipeline = &pipeline;
|
||||||
window.descriptorHeap = &descriptorHeap;
|
window.descriptorHeap = &descriptorHeap;
|
||||||
|
|
|
||||||
160
implementations/Crafter.Graphics-Rendertarget.cpp
Normal file
160
implementations/Crafter.Graphics-Rendertarget.cpp
Normal file
|
|
@ -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 <vulkan/vulkan.h>
|
||||||
|
#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<RenderingElement2DVulkanBase*>&& 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<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(transformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo));
|
||||||
|
std::uint16_t* sizePtr = reinterpret_cast<std::uint16_t*>(transformBuffer[frame].value);
|
||||||
|
*sizePtr = static_cast<std::uint16_t>(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<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(transformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo));
|
||||||
|
std::uint16_t* sizePtr = reinterpret_cast<std::uint16_t*>(transformBuffer[frame].value);
|
||||||
|
*sizePtr = static_cast<std::uint16_t>(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<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(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<VkResourceDescriptorInfoEXT> infos, std::span<VkHostAddressRangeEXT> 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<VkDeviceAddressRangeKHR> 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<RenderingElement2DVulkanBase*>(childTransform);
|
||||||
|
if(renderer) {
|
||||||
|
renderer->index = elements.size();
|
||||||
|
elements.push_back(renderer);
|
||||||
|
}
|
||||||
|
SetOrderResursive(childTransform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -21,9 +21,7 @@ export module Crafter.Graphics:ForwardDeclarations;
|
||||||
import std;
|
import std;
|
||||||
|
|
||||||
export namespace Crafter {
|
export namespace Crafter {
|
||||||
template<std::uint8_t Frames = 1>
|
|
||||||
struct RendertargetBase;
|
struct RendertargetBase;
|
||||||
|
|
||||||
struct GridElement;
|
struct GridElement;
|
||||||
struct Window;
|
struct Window;
|
||||||
}
|
}
|
||||||
|
|
@ -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) {
|
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<std::uint8_t Frames>
|
void UpdatePosition(RendertargetBase& window, Transform2D& parent) override {
|
||||||
void UpdatePositionImpl(RendertargetBase<Frames>& window, Transform2D& parent) {
|
|
||||||
ScaleElement(parent);
|
ScaleElement(parent);
|
||||||
std::int32_t cellWidth = (paddingX * 2) - (spacingX * (columns - 1)) / columns;
|
std::int32_t cellWidth = (paddingX * 2) - (spacingX * (columns - 1)) / columns;
|
||||||
std::int32_t cellHeight = (paddingY * 2) - (spacingY * (rows - 1)) / rows;
|
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -130,7 +130,7 @@ export namespace Crafter {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void UpdatePosition(RendertargetBase<Frames>& window, Transform2D& parent) override {
|
void UpdatePosition(RendertargetBase& window, Transform2D& parent) override {
|
||||||
ScaleData2D oldScale = this->scaled;
|
ScaleData2D oldScale = this->scaled;
|
||||||
this->ScaleElement(parent);
|
this->ScaleElement(parent);
|
||||||
if constexpr(Scaling && !Rotating) {
|
if constexpr(Scaling && !Rotating) {
|
||||||
|
|
@ -153,7 +153,7 @@ export namespace Crafter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string_view> ResizeText(RendertargetBase<Frames>& window, Transform2D& parent, const std::string_view text, float& size, Font& font, TextOverflowMode overflowMode = TextOverflowMode::Clip, TextScaleMode scaleMode = TextScaleMode::None) {
|
std::vector<std::string_view> 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);
|
float scale = stbtt_ScaleForPixelHeight(&font.font, size);
|
||||||
int baseline = (int)(font.ascent * scale);
|
int baseline = (int)(font.ascent * scale);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,13 +33,6 @@ import :Window;
|
||||||
import :DescriptorHeapVulkan;
|
import :DescriptorHeapVulkan;
|
||||||
|
|
||||||
export namespace Crafter {
|
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 {
|
struct RenderingElement2DVulkanBase : Transform2D {
|
||||||
std::uint16_t index;
|
std::uint16_t index;
|
||||||
std::uint16_t bufferX;
|
std::uint16_t bufferX;
|
||||||
|
|
@ -56,14 +49,10 @@ export namespace Crafter {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<RenderingElement2DVulkanBase*> renderingElement2DVulkans;
|
|
||||||
VulkanBuffer<RenderingElement2DVulkanTransformInfo, true> renderingElement2DVulkanTransformBuffer[Window::numFrames];
|
|
||||||
|
|
||||||
template<bool Owning, bool Mapped>
|
template<bool Owning, bool Mapped>
|
||||||
struct RenderingElement2DVulkan : RenderingElement2DVulkanBase {
|
struct RenderingElement2DVulkan : RenderingElement2DVulkanBase {
|
||||||
RenderingElement2DVulkan(Anchor2D anchor, RendertargetBase<Window::numFrames>& target, Transform2D& parent) requires(Owning) : RenderingElement2DVulkanBase(anchor) {
|
RenderingElement2DVulkan(Anchor2D anchor, RendertargetBase& target, Transform2D& parent) requires(Owning) : RenderingElement2DVulkanBase(anchor) {
|
||||||
renderingElement2DVulkans.push_back(this);
|
GetScale(target, parent);
|
||||||
UpdatePosition(target, parent);
|
|
||||||
this->bufferX = this->scaled.size.x;
|
this->bufferX = this->scaled.size.x;
|
||||||
this->bufferY = this->scaled.size.y;
|
this->bufferY = this->scaled.size.y;
|
||||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
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) {
|
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++) {
|
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||||
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, 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);
|
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, 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<VulkanBufferBase*, Window::numFrames>&& buffers) requires(!Owning) : RenderingElement2DVulkanBase(anchor, bufferX, bufferY, std::move(buffers)) {
|
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY, std::array<VulkanBufferBase*, Window::numFrames>&& 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) {
|
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++) {
|
for(std::uint8_t i = 1; i < Window::numFrames; i++) {
|
||||||
buffers[i] = buffers[0];
|
buffers[i] = buffers[0];
|
||||||
}
|
}
|
||||||
TextureAsset<_Float16>::LoadInfo(assetPath, buffers[0].value, this->bufferX, this->bufferY);
|
TextureAsset<_Float16>::Load(assetPath, reinterpret_cast<_Float16*>(static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value), this->bufferX, this->bufferY);
|
||||||
} else {
|
} else {
|
||||||
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
for(std::uint8_t i = 0; i < Window::numFrames; i++) {
|
||||||
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
buffers[i] = new VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>();
|
||||||
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, 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);
|
static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, 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<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value), this->bufferX, this->bufferY);
|
||||||
for(std::uint8_t i = 1; i < Window::numFrames; i++) {
|
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<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[i])->value, static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffers[0])->value, this->bufferX * this->bufferY * sizeof(_Float16));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -113,113 +101,27 @@ export namespace Crafter {
|
||||||
delete static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffer);
|
delete static_cast<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped>*>(buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto it = std::find(renderingElement2DVulkans.begin(), renderingElement2DVulkans.end(), this);
|
|
||||||
if (it != renderingElement2DVulkans.end()) {
|
|
||||||
renderingElement2DVulkans.erase(it);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingElement2DVulkan(RenderingElement2DVulkan&) = delete;
|
RenderingElement2DVulkan(RenderingElement2DVulkan&) = delete;
|
||||||
RenderingElement2DVulkan& operator=(RenderingElement2DVulkan&) = delete;
|
RenderingElement2DVulkan& operator=(RenderingElement2DVulkan&) = delete;
|
||||||
|
|
||||||
void UpdatePosition(RendertargetBase<Window::numFrames>& window, Transform2D& parent) override {
|
void UpdatePosition(RendertargetBase& window2, Transform2D& parent) override {
|
||||||
|
RendertargetVulkan& window = static_cast<RendertargetVulkan&>(window2);
|
||||||
this->ScaleElement(parent);
|
this->ScaleElement(parent);
|
||||||
RenderingElement2DVulkanTransformInfo* val = reinterpret_cast<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(renderingElement2DVulkanTransformBuffer[window.frame].value) + sizeof(RenderingElement2DVulkanTransformInfo));
|
RenderingElement2DVulkanTransformInfo* val = reinterpret_cast<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(window.transformBuffer[window.frame].value) + sizeof(RenderingElement2DVulkanTransformInfo));
|
||||||
val[index].scaled = this->scaled;
|
val[index].scaled = this->scaled;
|
||||||
for(Transform2D* child : this->children) {
|
for(Transform2D* child : this->children) {
|
||||||
child->UpdatePosition(window, *this);
|
child->UpdatePosition(window, *this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
void WriteRenderingElement2DVulkanDescriptors(std::span<VkResourceDescriptorInfoEXT> infos, std::span<VkHostAddressRangeEXT> ranges, std::uint16_t start, std::uint32_t bufferOffset, DescriptorHeapVulkan& descriptorHeap) {
|
void GetScale(RendertargetBase& window, Transform2D& parent) {
|
||||||
VkDeviceAddressRangeKHR transformRanges[Window::numFrames] = {
|
this->ScaleElement(parent);
|
||||||
{
|
for(Transform2D* child : this->children) {
|
||||||
.address = renderingElement2DVulkanTransformBuffer[0].address,
|
child->UpdatePosition(window, *this);
|
||||||
.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<VkDeviceAddressRangeKHR> 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<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(renderingElement2DVulkanTransformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo));
|
|
||||||
std::uint16_t* sizePtr = reinterpret_cast<std::uint16_t*>(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<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(renderingElement2DVulkanTransformBuffer[frame].value) + sizeof(RenderingElement2DVulkanTransformInfo));
|
|
||||||
std::uint16_t* sizePtr = reinterpret_cast<std::uint16_t*>(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
|
#endif
|
||||||
|
|
@ -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
|
License along with this library; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
module;
|
||||||
|
#include "../lib/stb_truetype.h"
|
||||||
|
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#endif
|
||||||
export module Crafter.Graphics:Rendertarget;
|
export module Crafter.Graphics:Rendertarget;
|
||||||
import Crafter.Math;
|
import Crafter.Math;
|
||||||
import Crafter.Asset;
|
import Crafter.Asset;
|
||||||
|
|
@ -23,9 +29,12 @@ import std;
|
||||||
import :Types;
|
import :Types;
|
||||||
import :Transform2D;
|
import :Transform2D;
|
||||||
import :RenderingElement2DBase;
|
import :RenderingElement2DBase;
|
||||||
|
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
|
||||||
|
import :Device;
|
||||||
|
import :VulkanBuffer;
|
||||||
|
#endif
|
||||||
|
|
||||||
export namespace Crafter {
|
export namespace Crafter {
|
||||||
template<std::uint8_t Frames>
|
|
||||||
struct RendertargetBase {
|
struct RendertargetBase {
|
||||||
#ifdef CRAFTER_TIMING
|
#ifdef CRAFTER_TIMING
|
||||||
std::vector<std::tuple<const Transform*, std::uint32_t, std::uint32_t, std::chrono::nanoseconds>> renderTimings;
|
std::vector<std::tuple<const Transform*, std::uint32_t, std::uint32_t, std::chrono::nanoseconds>> renderTimings;
|
||||||
|
|
@ -33,7 +42,6 @@ export namespace Crafter {
|
||||||
Transform2D transform;
|
Transform2D transform;
|
||||||
std::uint16_t sizeX;
|
std::uint16_t sizeX;
|
||||||
std::uint16_t sizeY;
|
std::uint16_t sizeY;
|
||||||
std::uint8_t frame;
|
|
||||||
RendertargetBase() = default;
|
RendertargetBase() = default;
|
||||||
RendertargetBase(std::uint16_t sizeX, std::uint16_t sizeY) : sizeX(sizeX), sizeY(sizeY), transform({0, 0, 1, 1, 0, 0, 0}){
|
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;
|
transform.scaled.size.x = sizeX;
|
||||||
|
|
@ -43,11 +51,38 @@ export namespace Crafter {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#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<RenderingElement2DVulkanBase*> elements;
|
||||||
|
VulkanBuffer<RenderingElement2DVulkanTransformInfo, true> transformBuffer[3];
|
||||||
|
|
||||||
|
RendertargetVulkan() = default;
|
||||||
|
RendertargetVulkan(std::uint16_t sizeX, std::uint16_t sizeY, std::vector<RenderingElement2DVulkanBase*>&& 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<VkResourceDescriptorInfoEXT> infos, std::span<VkHostAddressRangeEXT> ranges, std::uint16_t start, std::uint32_t bufferOffset, DescriptorHeapVulkan& descriptorHeap);
|
||||||
|
void SetOrderResursive(Transform2D* elementTransform);
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
template<typename T, std::uint8_t Channels, std::uint8_t Alignment, std::uint8_t Frames>
|
template<typename T, std::uint8_t Channels, std::uint8_t Alignment, std::uint8_t Frames>
|
||||||
struct Rendertarget : RendertargetBase<Frames> {
|
struct Rendertarget : RendertargetBase {
|
||||||
Vector<T, Channels, Alignment>* buffer[Frames];
|
Vector<T, Channels, Alignment>* buffer[Frames];
|
||||||
Rendertarget() = default;
|
Rendertarget() = default;
|
||||||
Rendertarget(std::uint16_t sizeX, std::uint16_t sizeY) : RendertargetBase<Frames>(sizeX, sizeY) {
|
Rendertarget(std::uint16_t sizeX, std::uint16_t sizeY) : RendertargetBase(sizeX, sizeY) {
|
||||||
|
|
||||||
}
|
}
|
||||||
void RenderElement(Transform2D* elementTransform, std::uint8_t frame, std::vector<ClipRect>&& dirtyRects) {
|
void RenderElement(Transform2D* elementTransform, std::uint8_t frame, std::vector<ClipRect>&& dirtyRects) {
|
||||||
|
|
|
||||||
|
|
@ -49,14 +49,7 @@ export namespace Crafter {
|
||||||
Transform2D& operator=(Transform2D&) = delete;
|
Transform2D& operator=(Transform2D&) = delete;
|
||||||
virtual ~Transform2D() = default;
|
virtual ~Transform2D() = default;
|
||||||
|
|
||||||
virtual void UpdatePosition(RendertargetBase<1>& window, Transform2D& parent) {
|
virtual void UpdatePosition(RendertargetBase& window, Transform2D& parent) {
|
||||||
ScaleElement(parent);
|
|
||||||
for(Transform2D* child : children) {
|
|
||||||
child->UpdatePosition(window, *this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void UpdatePosition(RendertargetBase<3>& window, Transform2D& parent) {
|
|
||||||
ScaleElement(parent);
|
ScaleElement(parent);
|
||||||
for(Transform2D* child : children) {
|
for(Transform2D* child : children) {
|
||||||
child->UpdatePosition(window, *this);
|
child->UpdatePosition(window, *this);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
"implementations/Crafter.Graphics-Transform2D",
|
"implementations/Crafter.Graphics-Transform2D",
|
||||||
"implementations/Crafter.Graphics-Device",
|
"implementations/Crafter.Graphics-Device",
|
||||||
"implementations/Crafter.Graphics-Mesh",
|
"implementations/Crafter.Graphics-Mesh",
|
||||||
"implementations/Crafter.Graphics-RenderingElement3D"
|
"implementations/Crafter.Graphics-RenderingElement3D",
|
||||||
|
"implementations/Crafter.Graphics-Rendertarget"
|
||||||
],
|
],
|
||||||
"interfaces": [
|
"interfaces": [
|
||||||
"interfaces/Crafter.Graphics-Window",
|
"interfaces/Crafter.Graphics-Window",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue