diff options
| author | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-04 13:44:30 -0500 |
|---|---|---|
| committer | Jonathan Bradley <jcb@pikum.xyz> | 2025-03-04 14:04:17 -0500 |
| commit | 78ca2865441df428228d158796c346e1df75d302 (patch) | |
| tree | ebcbea508c88162c99fd3fa217aae79cc9440217 /src/static-ui.cpp | |
| parent | 3ca179e53bb4840a88c95e26b7eb11b36e1830dd (diff) | |
pke: ui draws on screen as expected
Diffstat (limited to 'src/static-ui.cpp')
| -rw-r--r-- | src/static-ui.cpp | 411 |
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; } |
