summaryrefslogtreecommitdiff
path: root/src/static-ui.cpp
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-03-04 13:44:30 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-03-04 14:04:17 -0500
commit78ca2865441df428228d158796c346e1df75d302 (patch)
treeebcbea508c88162c99fd3fa217aae79cc9440217 /src/static-ui.cpp
parent3ca179e53bb4840a88c95e26b7eb11b36e1830dd (diff)
pke: ui draws on screen as expected
Diffstat (limited to 'src/static-ui.cpp')
-rw-r--r--src/static-ui.cpp411
1 files changed, 393 insertions, 18 deletions
diff --git a/src/static-ui.cpp b/src/static-ui.cpp
index 0c5d124..7f930b4 100644
--- a/src/static-ui.cpp
+++ b/src/static-ui.cpp
@@ -1,13 +1,17 @@
#include "static-ui.hpp"
+#include "dynamic-array.hpp"
+#include "game-settings.hpp"
#include "pk.h"
+#include "static-plane.hpp"
#include "vendor-glm-include.hpp"
#include "window.hpp"
#include <cassert>
#include <cstdio>
#include <cstring>
+#include <vulkan/vulkan_core.h>
struct pke_ui_box_instance_buffer_item {
glm::mat4 pos_scale;
@@ -35,7 +39,214 @@ void pke_ui_init() {
}
void pke_ui_init_bindings() {
- // TODO vulkan
+ PKVK_TmpBufferDetails tmpBufferDetails{};
+ pk_arr arr_vert_mem_reqs;
+ memset(&arr_vert_mem_reqs, 0, sizeof(pk_arr));
+ arr_vert_mem_reqs.alignment = alignof(VkMemoryRequirements);
+ arr_vert_mem_reqs.stride = sizeof(VkMemoryRequirements);
+ pk_arr arr_inst_mem_reqs(arr_vert_mem_reqs);
+ VkDeviceSize index;
+ constexpr VkDeviceSize expectedBufferCount = 3;
+ constexpr VkDeviceSize starting_ui_box_count = 4;
+
+ VkMemoryRequirements combined_vert_mem_reqs;
+
+ /*
+ * vulkan setup
+ */
+ VkBuffer buffer;
+ VkBufferCreateInfo bufferCI;
+ bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ bufferCI.pNext = nullptr;
+ bufferCI.flags = {};
+ bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ bufferCI.queueFamilyIndexCount = 1;
+ bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex;
+
+ /*
+ * Vulkan resource setup
+ */
+ // vertex
+ {
+ for (uint64_t idx = 0; idx < expectedBufferCount; ++idx) {
+ if (idx == 0) {
+ // vertex
+ bufferCI.size = sizeof(glm::vec2) * 4;
+ } else if (idx == 1) {
+ // uv
+ bufferCI.size = sizeof(glm::vec2) * 4;
+ } else if (idx == 2) {
+ // index
+ bufferCI.size = sizeof(uint16_t) * 6;
+ }
+ if (idx == 2) {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
+ } else {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ }
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &buffer);
+ VkMemoryRequirements tmp;
+ vkGetBufferMemoryRequirements(vkDevice, buffer, &tmp);
+ pk_arr_append(&arr_vert_mem_reqs, &tmp);
+ vkDestroyBuffer(vkDevice, buffer, vkAllocator);
+ }
+ }
+ // instance
+ {
+ bufferCI.size = 0;
+ bufferCI.size += sizeof(glm::vec2); // pos_scale
+ bufferCI.size += sizeof(glm::vec2); // px_scale
+ bufferCI.size += sizeof(float); // width
+ bufferCI.size += (sizeof(float) * 1); // padding
+ bufferCI.size *= starting_ui_box_count;
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &buffer);
+ VkMemoryRequirements tmp;
+ vkGetBufferMemoryRequirements(vkDevice, buffer, &tmp);
+ pk_arr_append(&arr_inst_mem_reqs, &tmp);
+ vkDestroyBuffer(vkDevice, buffer, vkAllocator);
+ }
+
+ /*
+ * Vulkan memory allocation
+ */
+
+ VkMemoryAllocateInfo vkMemoryAllocateInfo;
+ vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ vkMemoryAllocateInfo.pNext = nullptr;
+
+ // verts
+ CalculateCombinedMemReqs(arr_vert_mem_reqs.next, (VkMemoryRequirements*)arr_vert_mem_reqs.data, combined_vert_mem_reqs);
+ vkMemoryAllocateInfo.allocationSize = combined_vert_mem_reqs.size;
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(combined_vert_mem_reqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &pke_ui_master.bindings.deviceMemoryVert);
+
+ /*
+ * Vulkan data transfer
+ */
+ VkDeviceSize runningOffset = 0;
+ VkDeviceSize alignmentPadding = 0;
+ // vert
+ PKVK_BeginBuffer(transferFamilyIndex, combined_vert_mem_reqs.size, tmpBufferDetails);
+ {
+ index = 0;
+ runningOffset = 0;
+
+ uint32_t offsetVert = runningOffset;
+ uint32_t sizeVert = sizeof(pkeIntrinsicsPlane.vert[0]) * 4;
+ pke_ui_master.bindings.bd_vertex.firstBinding = index;
+ pke_ui_master.bindings.bd_vertex.bindingCount = 1;
+ alignmentPadding = sizeVert % combined_vert_mem_reqs.alignment;
+ alignmentPadding = alignmentPadding == 0 ? 0 : combined_vert_mem_reqs.alignment - alignmentPadding;
+ sizeVert += alignmentPadding;
+ bufferCI.size = sizeVert;
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &pke_ui_master.bindings.bd_vertex.buffer);
+ vkBindBufferMemory(vkDevice, pke_ui_master.bindings.bd_vertex.buffer, pke_ui_master.bindings.deviceMemoryVert, offsetVert);
+ runningOffset += sizeVert;
+ index += 1;
+
+ // uv
+ uint32_t offsetUV = runningOffset;
+ uint32_t sizeUV = sizeof(pkeIntrinsicsPlane.uv[0]) * 4;
+ pke_ui_master.bindings.bd_uv.firstBinding = index;
+ pke_ui_master.bindings.bd_uv.bindingCount = 1;
+ alignmentPadding = sizeUV % combined_vert_mem_reqs.alignment;
+ alignmentPadding = alignmentPadding == 0 ? 0 : combined_vert_mem_reqs.alignment - alignmentPadding;
+ sizeUV += alignmentPadding;
+ bufferCI.size = sizeUV;
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &pke_ui_master.bindings.bd_uv.buffer);
+ vkBindBufferMemory(vkDevice, pke_ui_master.bindings.bd_uv.buffer, pke_ui_master.bindings.deviceMemoryVert, offsetUV);
+ runningOffset += sizeUV;
+ index += 1;
+
+ // 2023-09-27 - JCB
+ // I don't know where else to put this
+ pke_ui_master.bindings.bd_instance.firstBinding = index;
+ pke_ui_master.bindings.bd_instance.bindingCount = 1;
+ // no index += 1 because index just happens to be the right value here for
+ // the binding index, whereas binding the IndexBuffer doesn't need a binding index.
+
+ // index
+ uint32_t offsetIndex = runningOffset;
+ uint32_t sizeIndex = sizeof(pkeIntrinsicsPlane.index[0]) * 6;
+ pke_ui_master.bindings.bd_index.bindingCount = 1;
+ pke_ui_master.bindings.index_count = 6;
+ alignmentPadding = sizeIndex % combined_vert_mem_reqs.alignment;
+ alignmentPadding = alignmentPadding == 0 ? 0 : combined_vert_mem_reqs.alignment - alignmentPadding;
+ sizeIndex += alignmentPadding;
+ bufferCI.size = sizeIndex;
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &pke_ui_master.bindings.bd_index.buffer);
+ vkBindBufferMemory(vkDevice, pke_ui_master.bindings.bd_index.buffer, pke_ui_master.bindings.deviceMemoryVert, offsetIndex);
+ runningOffset += sizeIndex;
+ // index += 1;
+
+ assert(runningOffset == combined_vert_mem_reqs.size);
+
+ runningOffset = 0;
+
+ char *dstPtr = nullptr;
+ char *srcPtr = nullptr;
+
+ dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + runningOffset;
+ srcPtr = reinterpret_cast<char *>(pkeIntrinsicsPlane.vert);
+ memcpy(dstPtr, srcPtr, sizeVert);
+ runningOffset += sizeVert;
+
+ dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + runningOffset;
+ srcPtr = reinterpret_cast<char *>(pkeIntrinsicsPlane.uv);
+ memcpy(dstPtr, srcPtr, sizeUV);
+ runningOffset += sizeUV;
+
+ dstPtr = static_cast<char *>(tmpBufferDetails.deviceData) + runningOffset;
+ srcPtr = reinterpret_cast<char *>(pkeIntrinsicsPlane.index);
+ memcpy(dstPtr, srcPtr, sizeIndex);
+ // runningOffset += sizeIndex;
+
+ VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
+ vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkCommandBufferBeginInfo.pNext = nullptr;
+ // TODO consider single-use?
+ vkCommandBufferBeginInfo.flags = 0;
+ vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
+ vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
+ VkBufferCopy bufferCopys[expectedBufferCount];
+ for (VkDeviceSize i = 0; i < expectedBufferCount; ++i) {
+ bufferCopys[i].dstOffset = 0;
+ }
+ index = 0;
+ bufferCopys[index].srcOffset = offsetVert;
+ bufferCopys[index].size = sizeVert;
+ vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, pke_ui_master.bindings.bd_vertex.buffer, 1, &bufferCopys[index]);
+ index+=1;
+
+ bufferCopys[index].srcOffset = offsetUV;
+ bufferCopys[index].size = sizeUV;
+ vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, pke_ui_master.bindings.bd_uv.buffer, 1, &bufferCopys[index]);
+ index+=1;
+
+ bufferCopys[index].srcOffset = offsetIndex;
+ bufferCopys[index].size = sizeIndex;
+ vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, pke_ui_master.bindings.bd_index.buffer, 1, &bufferCopys[index]);
+ // index+=1;
+
+ vkEndCommandBuffer(tmpBufferDetails.cmdBuffer);
+
+ VkSubmitInfo submitInfo;
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.pNext = nullptr;
+ submitInfo.waitSemaphoreCount = 0;
+ submitInfo.pWaitSemaphores = nullptr;
+ submitInfo.pWaitDstStageMask = nullptr;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &tmpBufferDetails.cmdBuffer;
+ submitInfo.signalSemaphoreCount = 0;
+ submitInfo.pSignalSemaphores = nullptr;
+ vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr);
+ vkQueueWaitIdle(tmpBufferDetails.queue);
+ }
+ PKVK_EndBuffer(tmpBufferDetails);
}
/* UI layout notes
@@ -45,9 +256,12 @@ Some restrictions:
- consider writing a method to calculate text
*/
-void pke_ui_calc_px(pke_ui_box *box) {
+void pke_ui_calc_px(pke_ui_box *box, DynArray<pke_ui_box_instance_buffer_item> &buffer) {
assert(box != nullptr);
+ // val = desired_padding + border_width
+ static const float built_in_offset = 2.0;
glm::vec2 size;
+ glm::vec2 parent_size_padded;
glm::vec2 parent_pos_and_offset;
assert(box->pos_top_left_x >= 0.0);
@@ -58,12 +272,14 @@ void pke_ui_calc_px(pke_ui_box *box) {
if (box->internal.parent != nullptr) {
parent_pos_and_offset.x = box->internal.parent->internal.px_corner_x + box->internal.parent->internal.px_offset_x;
parent_pos_and_offset.y = box->internal.parent->internal.px_corner_y + box->internal.parent->internal.px_offset_y;
- size.x = box->internal.parent->internal.px_width - box->internal.parent->internal.px_offset_x;
- size.y = box->internal.parent->internal.px_height - box->internal.parent->internal.px_offset_y;
+ parent_size_padded.x = box->internal.parent->internal.px_width;
+ parent_size_padded.y = box->internal.parent->internal.px_height;
// built-in padding
- size -= glm::vec2(2);
+ parent_size_padded -= glm::vec2(built_in_offset * 2);
+ size = parent_size_padded;
} else {
parent_pos_and_offset = glm::vec2(0);
+ parent_size_padded = glm::vec2(Extent.width, Extent.height);
size = glm::vec2(Extent.width, Extent.height);
}
@@ -76,6 +292,8 @@ void pke_ui_calc_px(pke_ui_box *box) {
box->internal.px_corner_y = 0
+ parent_pos_and_offset.y
+ box->pos_top_left_y;
+ size.x = PK_MIN(size.x, box->max_width);
+ size.y = PK_MIN(size.y, box->max_height);
} else {
assert(box->pos_top_left_x < 1.0);
assert(box->pos_top_left_y < 1.0);
@@ -87,20 +305,46 @@ void pke_ui_calc_px(pke_ui_box *box) {
box->internal.px_corner_y += px_top;
size -= px_left;
size -= px_top;
+ size.x = PK_MIN(size.x, box->max_width * parent_size_padded.x);
+ size.y = PK_MIN(size.y, box->max_height * parent_size_padded.y);
}
- size.x = PK_MIN(size.x, box->max_width);
- size.y = PK_MIN(size.y, box->max_height);
if (box->internal.parent != nullptr) {
box->internal.parent->internal.px_offset_y += size.y;
}
// built-in padding
- box->internal.px_offset_x = 1;
- box->internal.px_offset_y = 1;
+ box->internal.px_offset_x = built_in_offset;
+ box->internal.px_offset_y = built_in_offset;
box->internal.px_width = size.x;
box->internal.px_height = size.y;
+
+ // update buffer
+ glm::vec3 scale = glm::vec3(box->internal.px_width / (float)Extent.width, box->internal.px_height / (float)Extent.height, 1.0);
+ glm::vec3 translate = glm::vec3(1);
+ // ((val) - (width/2)) / (width/2)
+ // place left line of box at edge of screen
+ translate.x = (box->internal.px_width / 2.0);
+ // box position
+ translate.x += box->internal.px_corner_x;
+ translate.x -= ((float)Extent.width / 2.0);
+ translate.x /= ((float)Extent.width / 2.0);
+ // ((val) - (height/2)) / (height/2)
+ // place top line of box at edge of screen
+ translate.y = (box->internal.px_height / 2.0);
+ // box position
+ translate.y += box->internal.px_corner_y;
+ translate.y -= ((float)Extent.height / 2.0);
+ translate.y /= ((float)Extent.height / 2.0);
+ translate.z = 0;
+
+ pke_ui_box_instance_buffer_item *buffer_item = &buffer.Push();
+ buffer_item->pos_scale = glm::translate(glm::mat4(1), translate);
+ buffer_item->pos_scale = glm::scale(buffer_item->pos_scale, scale);
+ buffer_item->px_scale.x = (2.0 / (float)Extent.width);
+ buffer_item->px_scale.y = (2.0 / (float)Extent.height);
+ buffer_item->depth = (float)box->layer;
}
-void pke_ui_recalc_sizes_recursive(pke_ui_box *box, uint8_t depth = 0) {
+void pke_ui_recalc_sizes_recursive(DynArray<pke_ui_box_instance_buffer_item> &arr, pke_ui_box *box, uint8_t depth = 0) {
uint64_t flags_masked;
for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) {
@@ -112,14 +356,105 @@ void pke_ui_recalc_sizes_recursive(pke_ui_box *box, uint8_t depth = 0) {
}
for (pke_ui_box_count_T i = 0; i < box->internal.h_children; ++i) {
- pke_ui_calc_px(box->internal.children[i]);
- pke_ui_recalc_sizes_recursive(box->internal.children[i], depth + 1);
+ pke_ui_calc_px(box->internal.children[i], arr);
+ pke_ui_recalc_sizes_recursive(arr, box->internal.children[i], depth + 1);
}
}
+void pke_ui_update_instance_buffer(DynArray<pke_ui_box_instance_buffer_item> &arr) {
+ VkResult vkResult;
+ if (arr.Count() > pke_ui_master.bindings.instance_buffer_max_count) {
+ VkBuffer newBuffer;
+ VkBufferCreateInfo bufferCI;
+ bufferCI.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
+ bufferCI.pNext = nullptr;
+ bufferCI.flags = {};
+ bufferCI.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ bufferCI.queueFamilyIndexCount = 1;
+ bufferCI.pQueueFamilyIndices = &graphicsFamilyIndex;
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ bufferCI.size = sizeof(pke_ui_box_instance_buffer_item) * arr.Count();
+ vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer);
+ assert(vkResult == VK_SUCCESS);
+ VkMemoryRequirements vkMemReqs;
+ vkGetBufferMemoryRequirements(vkDevice, newBuffer, &vkMemReqs);
+ assert(sizeof(pke_ui_box_instance_buffer_item) % vkMemReqs.alignment == 0);
+
+ vkDestroyBuffer(vkDevice, newBuffer, vkAllocator);
+ newBuffer = VK_NULL_HANDLE;
+
+ bufferCI.size = vkMemReqs.size + (vkMemReqs.alignment - (vkMemReqs.size & vkMemReqs.alignment));
+ vkResult = vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &newBuffer);
+ assert(vkResult == VK_SUCCESS);
+
+ VkDeviceMemory new_memory;
+ VkMemoryAllocateInfo vkMemoryAllocateInfo;
+ vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ vkMemoryAllocateInfo.pNext = nullptr;
+ vkMemoryAllocateInfo.allocationSize = bufferCI.size;
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(vkMemReqs.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+ vkResult = vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &new_memory);
+ assert(vkResult == VK_SUCCESS);
+
+ vkResult = vkBindBufferMemory(vkDevice, newBuffer, new_memory, 0);
+ assert(vkResult == VK_SUCCESS);
+ if (pke_ui_master.bindings.bd_instance.buffer != VK_NULL_HANDLE) {
+ vkDestroyBuffer(vkDevice, pke_ui_master.bindings.bd_instance.buffer, vkAllocator);
+ }
+ if (pke_ui_master.bindings.deviceMemoryInst != VK_NULL_HANDLE) {
+ vkFreeMemory(vkDevice, pke_ui_master.bindings.deviceMemoryInst, vkAllocator);
+ }
+ pke_ui_master.bindings.bd_instance.buffer = newBuffer;
+ pke_ui_master.bindings.deviceMemoryInst = new_memory;
+ pke_ui_master.bindings.instance_buffer_max_count = arr.Count();
+ }
+ PKVK_TmpBufferDetails tmpBufferDetails{};
+ PKVK_BeginBuffer(graphicsFamilyIndex, sizeof(pke_ui_box_instance_buffer_item) * arr.Count(), tmpBufferDetails);
+ {
+ VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
+ vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkCommandBufferBeginInfo.pNext = nullptr;
+ // TODO consider single-use?
+ vkCommandBufferBeginInfo.flags = 0;
+ vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
+ vkResult = vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
+ assert(vkResult == VK_SUCCESS);
+
+ memcpy(tmpBufferDetails.deviceData, arr.GetPtr(), sizeof(pke_ui_box_instance_buffer_item) * arr.Count());
+
+ VkBufferCopy vk_buffer_copy{};
+ vk_buffer_copy.srcOffset = 0;
+ vk_buffer_copy.dstOffset = 0;
+ vk_buffer_copy.size = sizeof(pke_ui_box_instance_buffer_item) * arr.Count();
+ vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, pke_ui_master.bindings.bd_instance.buffer, 1, &vk_buffer_copy);
+
+ vkResult = vkEndCommandBuffer(tmpBufferDetails.cmdBuffer);
+ assert(vkResult == VK_SUCCESS);
+
+ VkSubmitInfo submitInfo;
+ submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submitInfo.pNext = nullptr;
+ submitInfo.waitSemaphoreCount = 0;
+ submitInfo.pWaitSemaphores = nullptr;
+ submitInfo.pWaitDstStageMask = nullptr;
+ submitInfo.commandBufferCount = 1;
+ submitInfo.pCommandBuffers = &tmpBufferDetails.cmdBuffer;
+ submitInfo.signalSemaphoreCount = 0;
+ submitInfo.pSignalSemaphores = nullptr;
+ vkResult = vkQueueSubmit(tmpBufferDetails.queue, 1, &submitInfo, nullptr);
+ assert(vkResult == VK_SUCCESS);
+ vkResult = vkQueueWaitIdle(tmpBufferDetails.queue);
+ assert(vkResult == VK_SUCCESS);
+ }
+ PKVK_EndBuffer(tmpBufferDetails);
+ pke_ui_master.bindings.instance_counter = arr.Count();
+}
+
void pke_ui_tick(double delta) {
(void)delta;
- if (pke_ui_master.should_recalc_ui == true) {
+ if (pke_ui_master.should_recalc_ui == true || pkeSettings.rt.was_framebuffer_resized == true) {
+ DynArray<pke_ui_box_instance_buffer_item> arr;
pke_ui_master.should_recalc_ui = false;
pke_ui_master.px_scale = glm::vec2(
2.0 / (float)Extent.width,
@@ -127,9 +462,10 @@ void pke_ui_tick(double delta) {
);
for (pke_ui_box_count_T i = 0; i < pke_ui_master.h_root_boxes; ++i) {
pke_ui_box *box = pke_ui_master.root_boxes[i];
- pke_ui_calc_px(box);
- pke_ui_recalc_sizes_recursive(box, 0);
+ pke_ui_calc_px(box, arr);
+ pke_ui_recalc_sizes_recursive(arr, box, 0);
}
+ pke_ui_update_instance_buffer(arr);
}
}
@@ -152,7 +488,44 @@ void pke_ui_teardown() {
pke_ui_master.root_boxes = nullptr;
pke_ui_master.h_root_boxes = 0;
pke_ui_master.r_root_boxes = 0;
- // TODO vulkan
+
+ if (pke_ui_master.bindings.bd_vertex.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, pke_ui_master.bindings.bd_vertex.buffer, vkAllocator);
+ pke_ui_master.bindings.bd_vertex.buffer = VK_NULL_HANDLE;
+ pke_ui_master.bindings.bd_vertex.firstBinding = 0;
+ pke_ui_master.bindings.bd_vertex.bindingCount = 0;
+ pke_ui_master.bindings.bd_vertex.offsets[0] = 0;
+
+ if (pke_ui_master.bindings.bd_uv.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, pke_ui_master.bindings.bd_uv.buffer, vkAllocator);
+ pke_ui_master.bindings.bd_uv.buffer = VK_NULL_HANDLE;
+ pke_ui_master.bindings.bd_uv.firstBinding = 0;
+ pke_ui_master.bindings.bd_uv.bindingCount = 0;
+ pke_ui_master.bindings.bd_uv.offsets[0] = 0;
+
+ if (pke_ui_master.bindings.bd_index.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, pke_ui_master.bindings.bd_index.buffer, vkAllocator);
+ pke_ui_master.bindings.bd_index.buffer = VK_NULL_HANDLE;
+ pke_ui_master.bindings.bd_index.bindingCount = 0;
+ pke_ui_master.bindings.bd_index.offsets[0] = 0;
+ pke_ui_master.bindings.index_count = 0;
+
+ if (pke_ui_master.bindings.bd_instance.buffer != VK_NULL_HANDLE)
+ vkDestroyBuffer(vkDevice, pke_ui_master.bindings.bd_instance.buffer, vkAllocator);
+ pke_ui_master.bindings.bd_instance.buffer = VK_NULL_HANDLE;
+ pke_ui_master.bindings.bd_instance.firstBinding = 0;
+ pke_ui_master.bindings.bd_instance.bindingCount = 0;
+ pke_ui_master.bindings.instance_counter = 0;
+ pke_ui_master.bindings.instance_buffer_max_count = 0;
+ pke_ui_master.bindings.bd_instance.offsets[0] = 0;
+
+ if (pke_ui_master.bindings.deviceMemoryInst != VK_NULL_HANDLE)
+ vkFreeMemory(vkDevice, pke_ui_master.bindings.deviceMemoryInst, vkAllocator);
+ pke_ui_master.bindings.deviceMemoryInst = VK_NULL_HANDLE;
+
+ if (pke_ui_master.bindings.deviceMemoryVert != VK_NULL_HANDLE)
+ vkFreeMemory(vkDevice, pke_ui_master.bindings.deviceMemoryVert, vkAllocator);
+ pke_ui_master.bindings.deviceMemoryVert = VK_NULL_HANDLE;
}
pke_ui_box *pke_ui_box_new_root() {
@@ -163,13 +536,14 @@ pke_ui_box *pke_ui_box_new_root() {
for (pke_ui_box_count_T i = 0; i < pke_ui_master.h_root_boxes; ++i) {
boxes[i] = pke_ui_master.root_boxes[i];
}
- pk_delete<pke_ui_box*>(pke_ui_master.root_boxes, prev_r_root_boxes);
+ if (pke_ui_master.root_boxes != nullptr) pk_delete<pke_ui_box*>(pke_ui_master.root_boxes, prev_r_root_boxes);
pke_ui_master.root_boxes = boxes;
}
pke_ui_box *box = pk_new<pke_ui_box>(pke_ui_master.bkt);
memset(box, 0, sizeof(pke_ui_box));
pke_ui_master.root_boxes[pke_ui_master.h_root_boxes] = box;
pke_ui_master.h_root_boxes += 1;
+ pke_ui_master.should_recalc_ui = true;
return box;
}
@@ -177,7 +551,7 @@ pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent) {
assert(parent != nullptr);
if (parent->internal.h_children == parent->internal.r_children) {
pke_ui_box_count_T prev_r_children = parent->internal.r_children;
- parent->internal.r_children *= PK_MIN(1.5, 2);
+ parent->internal.r_children = PK_MAX(parent->internal.r_children * 1.5, 2);
pke_ui_box **boxes = pk_new<pke_ui_box*>(parent->internal.r_children);
for (pke_ui_box_count_T i = 0; i < parent->internal.h_children; ++i) {
boxes[i] = parent->internal.children[i];
@@ -192,6 +566,7 @@ pke_ui_box *pke_ui_box_new_child(pke_ui_box *parent) {
parent->internal.children[parent->internal.h_children] = box;
parent->internal.h_children += 1;
box->internal.parent = parent;
+ pke_ui_master.should_recalc_ui = true;
return box;
}