summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-03-05 10:54:46 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-03-05 10:54:46 -0500
commit6b0f3cb77bf46ebc4d4e6f538c53fadba8f56f90 (patch)
treebbbed5ecb1789dd1bda91db7304d1c38b637e3bb
parent78ca2865441df428228d158796c346e1df75d302 (diff)
pke: refactor ui buffer creation
-rw-r--r--src/static-ui.cpp241
-rw-r--r--src/window.cpp132
-rw-r--r--src/window.hpp21
3 files changed, 186 insertions, 208 deletions
diff --git a/src/static-ui.cpp b/src/static-ui.cpp
index 7f930b4..8c8f920 100644
--- a/src/static-ui.cpp
+++ b/src/static-ui.cpp
@@ -39,214 +39,39 @@ void pke_ui_init() {
}
void pke_ui_init_bindings() {
- 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);
+ pkvk_buffer_create_data create_data{};
+ create_data.buffer_byte_length[0] = sizeof(pkeIntrinsicsPlane.vert[0]) * 4;
+ create_data.buffer_byte_length[1] = sizeof(pkeIntrinsicsPlane.uv[0]) * 4;
+ create_data.buffer_byte_length[2] = sizeof(pkeIntrinsicsPlane.index[0]) * 6;
+ create_data.buffer_byte_length[3] = sizeof(pke_ui_box_instance_buffer_item);
+ create_data.src_data[0] = &pkeIntrinsicsPlane.vert;
+ create_data.src_data[1] = &pkeIntrinsicsPlane.uv;
+ create_data.src_data[2] = &pkeIntrinsicsPlane.index;
+ create_data.src_data[3] = nullptr;
+ create_data.n_buffers = 4;
+ create_data.index_index = 2;
+ create_data.index_instance = 3;
+
+ pkvk_buffer_create_data_out out{};
+ pkvk_buffer_create(&create_data, &out);
+
+ pke_ui_master.bindings.bd_vertex.buffer = out.buffers[0];
+ pke_ui_master.bindings.bd_vertex.firstBinding = 0;
+ pke_ui_master.bindings.bd_vertex.bindingCount = 1;
+ pke_ui_master.bindings.bd_uv.buffer = out.buffers[1];
+ pke_ui_master.bindings.bd_uv.firstBinding = 1;
+ pke_ui_master.bindings.bd_uv.bindingCount = 1;
+ pke_ui_master.bindings.bd_index.buffer = out.buffers[2];
+ pke_ui_master.bindings.bd_index.firstBinding = 0;
+ pke_ui_master.bindings.bd_index.bindingCount = 1;
+ pke_ui_master.bindings.index_count = 6;
+ pke_ui_master.bindings.bd_instance.buffer = out.buffers[3];
+ pke_ui_master.bindings.bd_instance.firstBinding = 2;
+ pke_ui_master.bindings.bd_instance.bindingCount = 1;
+ pke_ui_master.bindings.deviceMemoryVert = out.device_memory_vertex;
+ pke_ui_master.bindings.deviceMemoryInst = out.device_memory_instance;
+
+ pke_ui_master.bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(pke_ui_box_instance_buffer_item);
}
/* UI layout notes
diff --git a/src/window.cpp b/src/window.cpp
index ea1deb5..c0b72da 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -284,6 +284,138 @@ void PKVK_EndBuffer(PKVK_TmpBufferDetails &tmpBufferDetails, PKVK_TmpBufferFlags
tmpBufferDetails = {};
}
+void pkvk_buffer_create(pkvk_buffer_create_data *data, pkvk_buffer_create_data_out *out) {
+ 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);
+ arr_vert_mem_reqs.bkt = pkeSettings.mem.bkt;
+
+ /*
+ * buffer setup
+ */
+ VkBuffer tmpBuffer;
+ 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;
+
+ for (uint8_t i = 0; i < data->n_buffers; ++i) {
+ bufferCI.size = data->buffer_byte_length[i];
+ if (i == data->index_index) {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
+ } else if (i == data->index_instance) {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ } else {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ }
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &tmpBuffer);
+ VkMemoryRequirements tmp;
+ vkGetBufferMemoryRequirements(vkDevice, tmpBuffer, &tmp);
+ if (i == data->index_instance) {
+ out->memory_requirements_instance = tmp;
+ } else {
+ pk_arr_append(&arr_vert_mem_reqs, &tmp);
+ }
+ vkDestroyBuffer(vkDevice, tmpBuffer, vkAllocator);
+ }
+ CalculateCombinedMemReqs(arr_vert_mem_reqs.next, (VkMemoryRequirements*)arr_vert_mem_reqs.data, out->memory_requirements_vertex);
+
+ /*
+ * memory allocation
+ */
+
+ VkMemoryAllocateInfo vkMemoryAllocateInfo;
+ vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ vkMemoryAllocateInfo.pNext = nullptr;
+
+ // verts
+ vkMemoryAllocateInfo.allocationSize = out->memory_requirements_vertex.size;
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(out->memory_requirements_vertex.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &out->device_memory_vertex);
+
+ // inst
+ vkMemoryAllocateInfo.allocationSize = out->memory_requirements_instance.size;
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(out->memory_requirements_instance.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+ vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &out->device_memory_instance);
+
+ // data transfer
+ PKVK_TmpBufferDetails tmpBufferDetails{};
+ VkDeviceSize size = 0;
+ VkDeviceSize running_offset = 0;
+ VkDeviceSize alignment_padding = 0;
+ VkBufferCopy buffer_copy{};
+ buffer_copy.dstOffset = 0;
+
+ // vert
+ PKVK_BeginBuffer(transferFamilyIndex, out->memory_requirements_vertex.size, 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;
+ vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
+
+ for (uint8_t i = 0; i < data->n_buffers; ++i) {
+ size = data->buffer_byte_length[i];
+ if (i == data->index_instance) {
+ alignment_padding = size % out->memory_requirements_instance.alignment;
+ alignment_padding = alignment_padding == 0 ? 0 : out->memory_requirements_instance.alignment - alignment_padding;
+ } else {
+ alignment_padding = size % out->memory_requirements_vertex.alignment;
+ alignment_padding = alignment_padding == 0 ? 0 : out->memory_requirements_vertex.alignment - alignment_padding;
+ }
+ size += alignment_padding;
+
+ bufferCI.size = size;
+ if (i == data->index_index) {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT;
+ } else if (i == data->index_instance) {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ } else {
+ bufferCI.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
+ }
+
+ vkCreateBuffer(vkDevice, &bufferCI, vkAllocator, &out->buffers[i]);
+ if (i == data->index_instance) {
+ vkBindBufferMemory(vkDevice, out->buffers[i], out->device_memory_instance, 0);
+ } else {
+ vkBindBufferMemory(vkDevice, out->buffers[i], out->device_memory_vertex, running_offset);
+ }
+
+ if (data->src_data[i] != nullptr) {
+ assert(tmpBufferDetails.deviceData != nullptr);
+ memcpy((char *)tmpBufferDetails.deviceData + running_offset, data->src_data[i], data->buffer_byte_length[i]);
+ buffer_copy.srcOffset = running_offset;
+ buffer_copy.size = data->buffer_byte_length[i];
+ running_offset += size;
+ vkCmdCopyBuffer(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, out->buffers[i], 1, &buffer_copy);
+ }
+ }
+
+ vkEndCommandBuffer(tmpBufferDetails.cmdBuffer);
+
+ VkSubmitInfo submit_info;
+ submit_info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
+ submit_info.pNext = nullptr;
+ submit_info.waitSemaphoreCount = 0;
+ submit_info.pWaitSemaphores = nullptr;
+ submit_info.pWaitDstStageMask = nullptr;
+ submit_info.commandBufferCount = 1;
+ submit_info.pCommandBuffers = &tmpBufferDetails.cmdBuffer;
+ submit_info.signalSemaphoreCount = 0;
+ submit_info.pSignalSemaphores = nullptr;
+ vkQueueSubmit(tmpBufferDetails.queue, 1, &submit_info, nullptr);
+ vkQueueWaitIdle(tmpBufferDetails.queue);
+
+ PKVK_EndBuffer(tmpBufferDetails);
+}
+
unsigned int FindQueueFamilyIndex(VkPhysicalDevice device, char hasPresentSupport = -1, VkQueueFlagBits includeBits = (VkQueueFlagBits)0U, VkQueueFlagBits excludeBits = (VkQueueFlagBits)0U) {
if (hasPresentSupport == -1 && includeBits == 0 && excludeBits == 0) {
diff --git a/src/window.hpp b/src/window.hpp
index de1a2ac..c96f4c0 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -115,4 +115,25 @@ struct PKVK_TmpBufferDetails {
void PKVK_BeginBuffer(unsigned int family_index, VkDeviceSize requestedMemorySize, PKVK_TmpBufferDetails &tmpBufferDetails, PKVK_TmpBufferFlags flags = PKVK_TmpBufferFlags_ALL);
void PKVK_EndBuffer(PKVK_TmpBufferDetails &tmpBufferDetails, PKVK_TmpBufferFlags flags = PKVK_TmpBufferFlags_ALL);
+#define PKVK_BUFFER_CREATE_DATA_ARR_MAX_LENGTH 8
+
+struct pkvk_buffer_create_data {
+ uint32_t buffer_byte_length[PKVK_BUFFER_CREATE_DATA_ARR_MAX_LENGTH];
+ void *src_data[PKVK_BUFFER_CREATE_DATA_ARR_MAX_LENGTH];
+ uint8_t n_buffers;
+ uint8_t index_index;
+ uint8_t index_instance;
+};
+struct pkvk_buffer_create_data_out {
+ VkBuffer buffers[PKVK_BUFFER_CREATE_DATA_ARR_MAX_LENGTH];
+ VkDeviceMemory device_memory_vertex;
+ VkDeviceMemory device_memory_instance;
+ VkMemoryRequirements memory_requirements_vertex;
+ VkMemoryRequirements memory_requirements_instance;
+};
+// creates vertex and instance buffers + memory + bind
+// DOES upload vertex data
+// DOES NOT upload instance data
+void pkvk_buffer_create(pkvk_buffer_create_data *data, pkvk_buffer_create_data_out *out);
+
#endif /* PKE_WINDOW_HPP */