vulkan UI

This commit is contained in:
Jorijn van der Graaf 2026-04-09 00:15:09 +02:00
commit 177f873639
13 changed files with 455 additions and 37 deletions

View file

@ -118,6 +118,7 @@ export namespace Crafter {
inline static PFN_vkCmdBindSamplerHeapEXT vkCmdBindSamplerHeapEXT;
inline static PFN_vkWriteResourceDescriptorsEXT vkWriteResourceDescriptorsEXT;
inline static PFN_vkGetPhysicalDeviceDescriptorSizeEXT vkGetPhysicalDeviceDescriptorSizeEXT;
inline static PFN_vkGetDeviceFaultInfoEXT vkGetDeviceFaultInfoEXT;
inline static VkPhysicalDeviceMemoryProperties memoryProperties;

View file

@ -19,10 +19,15 @@ 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:RenderingElement2DVulkan;
#ifdef CRAFTER_GRAPHICS_RENDERER_VULKAN
import Crafter.Asset;
import std;
import :Transform2D;
import :VulkanBuffer;
import :Types;
import :Window;
@ -32,44 +37,85 @@ export namespace Crafter {
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;
std::uint16_t bufferY;
RenderingElement2DVulkanBase(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY) : bufferX(bufferX), bufferY(bufferY), Transform2D(anchor) {
}
};
std::vector<RenderingElement2DVulkanBase*> renderingElement2DVulkans;
VulkanBuffer<RenderingElement2DVulkanTransformInfo, true, true> renderingElement2DVulkanTransformBuffer[Window::numFrames];
template<bool Owning, bool Mapped>
struct RenderingElement2DVulkan {
std::uint16_t index;
std:array<VulkanBuffer<_Float16, Mapped, false>*, Window::NumFrames> buffers;
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight) requires(Owning) : index(renderingElement2DVulkans.size()-1) {
struct RenderingElement2DVulkan : RenderingElement2DVulkanBase {
std::array<VulkanBuffer<Vector<_Float16, 4, 4>, Mapped, true>*, Window::numFrames> buffers;
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<Vector<_Float16, 4, 4>, Mapped, true>();
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);
}
}
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferWidth, std::uint16_t bufferHeight, std:array<VulkanBuffer<_Float16, Mapped, false>*, Window::NumFrames> buffers) requires(!Owning) : buffers(buffers) {
RenderingElement2DVulkan(Anchor2D anchor, std::uint16_t bufferX, std::uint16_t bufferY, std::array<VulkanBuffer<_Float16, Mapped, true>*, Window::numFrames> buffers) requires(!Owning) : buffers(buffers), RenderingElement2DVulkanBase(anchor, bufferX, bufferY) {
renderingElement2DVulkans.push_back(this);
}
~RenderingElement2DVulkan() {
if constexpr(Owning) {
for(VulkanBuffer<_Float16, Mapped, false>* buffer : buffers) {
for(VulkanBuffer<Vector<_Float16, 4, 4>, Mapped, true>* buffer : buffers) {
delete 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<Frames>& window, Transform2D& parent) override {
ScaleData2D oldScale = this->scaled;
void UpdatePosition(RendertargetBase<Window::numFrames>& window, Transform2D& parent) override {
this->ScaleElement(parent);
if(oldScale.size.x != this->scaled.size.x || oldScale.size.y != this->scaled.size.y) {
this->buffer.resize(this->scaled.size.x * this->scaled.size.y);
}
RenderingElement2DVulkanTransformInfo* val = reinterpret_cast<RenderingElement2DVulkanTransformInfo*>(reinterpret_cast<char*>(renderingElement2DVulkanTransformBuffer[window.frame].value) + sizeof(RenderingElement2DVulkanTransformInfo));
val[index].scaled = this->scaled;
for(Transform2D* child : this->children) {
child->UpdatePosition(window, *this);
}
}
};
inline static std::vector<RenderingElement2DVulkan*> renderingElement2DVulkans;
inline static std::vector<VkDescriptorBufferInfo> renderingElement2DVulkanDescriptors[Window::NumFrames];
inline static VulkanBuffer<RenderingElement2DVulkanTransformInfo, Mapped, false>* renderingElement2DVulkanTransformBuffer[Window::NumFrames];
}
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

View file

@ -33,6 +33,7 @@ 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;
@ -61,8 +62,8 @@ export namespace Crafter {
}
for(ClipRect dirty : dirtyRects) {
dirty.left = std::max(element->scaled.position.x, dirty.left);
dirty.top = std::max(element->scaled.position.y, dirty.top);
dirty.left = std::uint16_t(std::max(element->scaled.position.x, std::int16_t(dirty.left)));
dirty.top = std::uint16_t(std::max(element->scaled.position.y,std::int16_t(dirty.top)));
dirty.right = std::min(std::uint16_t(element->scaled.position.x+element->scaled.size.x), dirty.right);
dirty.bottom = std::min(std::uint16_t(element->scaled.position.y+element->scaled.size.y), dirty.bottom);
@ -147,16 +148,16 @@ export namespace Crafter {
void AddOldRects(Transform2D* elementTransform, std::uint8_t frame, std::vector<ClipRect>& clipRects) {
RenderingElement2DBase<T, Frames>* element = dynamic_cast<RenderingElement2DBase<T, Frames>*>(elementTransform);
if(element) {
if(element->scaled.position.x != element->oldScale[frame].position.x || element->scaled.position.y != element->oldScale[frame].position.y || element->scaled.size.x != element->oldScale[frame].size.x || element->scaled.size.y != element->oldScale[frame].size.y || element->redraw[frame]) {
clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY));
clipRects.emplace_back(std::max(element->oldScale[frame].position.x, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.x + element->oldScale[frame].size.x), this->sizeX), std::max(element->oldScale[frame].position.y, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.y + element->oldScale[frame].size.y), this->sizeY));
element->oldScale[frame] = element->scaled;
element->redraw[frame] = false;
} else if(element->redraw[frame]) {
clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY));
element->oldScale[frame] = element->scaled;
element->redraw[frame] = false;
}
// if(element->scaled.position.x != element->oldScale[frame].position.x || element->scaled.position.y != element->oldScale[frame].position.y || element->scaled.size.x != element->oldScale[frame].size.x || element->scaled.size.y != element->oldScale[frame].size.y || element->redraw[frame]) {
// clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY));
// clipRects.emplace_back(std::max(element->oldScale[frame].position.x, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.x + element->oldScale[frame].size.x), this->sizeX), std::max(element->oldScale[frame].position.y, std::uint16_t(0)), std::min(std::uint16_t(element->oldScale[frame].position.y + element->oldScale[frame].size.y), this->sizeY));
// element->oldScale[frame] = element->scaled;
// element->redraw[frame] = false;
// } else if(element->redraw[frame]) {
// clipRects.emplace_back(std::max(element->scaled.position.x, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.x + element->scaled.size.x), this->sizeX), std::max(element->scaled.position.y, std::uint16_t(0)), std::min(std::uint16_t(element->scaled.position.y + element->scaled.size.y), this->sizeY));
// element->oldScale[frame] = element->scaled;
// element->redraw[frame] = false;
// }
}
for(Transform2D* child : elementTransform->children) {
AddOldRects(child, frame, clipRects);

View file

@ -33,8 +33,8 @@ export namespace Crafter {
};
struct ScaleData2D {
Vector<std::uint16_t, 2, 2> position;
Vector<std::uint16_t, 2, 2> size;
Vector<std::int16_t, 2, 2> position;
Vector<std::int16_t, 2, 2> size;
};
struct ClipRect {

View file

@ -45,6 +45,7 @@ export import :RenderingElement3D;
export import :ImageVulkan;
export import :SamplerVulkan;
export import :DescriptorHeapVulkan;
export import :RenderingElement2DVulkan;
#endif
// export import :WindowWaylandVulkan;