summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJonathan Bradley <jcb@pikum.xyz>2025-03-05 12:07:11 -0500
committerJonathan Bradley <jcb@pikum.xyz>2025-03-05 12:07:11 -0500
commita825df5bd950ad1917c3ba991e71b8612c940112 (patch)
treef8669f1dc89b75e84356f216bd409c08490352b2 /src
parent2204437ea7a4b00c13d24e2221378b9f44366861 (diff)
pke: refactor ui texture upload
Diffstat (limited to 'src')
-rw-r--r--src/font.cpp216
-rw-r--r--src/window.cpp211
-rw-r--r--src/window.hpp13
3 files changed, 236 insertions, 204 deletions
diff --git a/src/font.cpp b/src/font.cpp
index cc4a897..0a4ccbd 100644
--- a/src/font.cpp
+++ b/src/font.cpp
@@ -454,21 +454,17 @@ FontType* FontType_GetFonts(FontTypeIndex &count) {
}
FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle, AssetHandle glyphsHandle, FontTypeMSDFSettings *msdf_settings, FontTypeSpacing *spacing) {
- PKVK_TmpBufferDetails tmpBufferDetails{};
VkResult vkResult;
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_texture_mem_reqs(arr_vert_mem_reqs);
constexpr VkDeviceSize startingGlyphCount = 4;
assert(fontTextureHandle != AssetHandle_MAX);
assert(glyphsHandle != AssetHandle_MAX);
assert(msdf_settings != nullptr);
assert(spacing != nullptr);
- VkMemoryRequirements combined_texture_mem_reqs;
-
const Asset *fontTexture = AM_Get(fontTextureHandle);
FontTypeIndex idx = ftd.h_ft;
ftd.h_ft += FontTypeIndex{1};
@@ -505,6 +501,8 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle
ft->atlas_size.x = (float)txtr_x;
ft->atlas_size.y = (float)txtr_y;
+ // buffers
+
glm::vec2 atlas_size_buffer[4];
for (int i = 0; i < 4; ++i) {
atlas_size_buffer[i] = ft->atlas_size;
@@ -550,211 +548,21 @@ FontTypeIndex FontType_RegisterFont(pk_cstr title, AssetHandle fontTextureHandle
ft->bindings.instance_buffer_max_count = out.memory_requirements_instance.size / sizeof(FontInstanceBufferItem);
// texture
- VkImageCreateInfo imageCreateInfo{};
- VkImageSubresourceRange vkImageSubresourceRange;
- {
- imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
- imageCreateInfo.pNext = nullptr;
- imageCreateInfo.flags = 0;
- imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
- imageCreateInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
- imageCreateInfo.extent.width = txtr_x;
- imageCreateInfo.extent.height = txtr_y;
- imageCreateInfo.extent.depth = 1;
- imageCreateInfo.mipLevels = 1;
- imageCreateInfo.arrayLayers = 1;
- imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
- imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
- imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
- imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
- imageCreateInfo.queueFamilyIndexCount = 0;
- imageCreateInfo.pQueueFamilyIndices = nullptr;
- imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-
- vkImageSubresourceRange.aspectMask = VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT;
- vkImageSubresourceRange.baseMipLevel = 0u;
- vkImageSubresourceRange.levelCount = 1u;
- vkImageSubresourceRange.baseArrayLayer = 0u;
- vkImageSubresourceRange.layerCount = 1u;
-
- VkImage tmpImage;
- vkResult = vkCreateImage(vkDevice, &imageCreateInfo, vkAllocator, &tmpImage);
- assert(vkResult == VK_SUCCESS);
-
- VkMemoryRequirements imageMemoryRequirements;
- vkGetImageMemoryRequirements(vkDevice, tmpImage, &imageMemoryRequirements);
- pk_arr_append(&arr_texture_mem_reqs, &imageMemoryRequirements);
+ pkvk_texture_upload_data txtr_data{};
+ txtr_data.bytes = txtr_bytes;
+ txtr_data.n_bytes = imageSizeBytes;
+ txtr_data.width = (uint32_t)txtr_x;
+ txtr_data.height = (uint32_t)txtr_y;
- vkDestroyImage(vkDevice, tmpImage, vkAllocator);
- }
+ pkvk_texture_upload_data_out txtr_out{};
+ pkvk_texture_upload(&txtr_data, &txtr_out);
- /*
- * Vulkan memory allocation
- */
+ ft->gr.textureImage = txtr_out.image;
+ ft->gr.textureImageView = txtr_out.image_view;
+ ft->gr.deviceMemoryTexture = txtr_out.device_memory;
- VkMemoryAllocateInfo vkMemoryAllocateInfo;
- vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
- vkMemoryAllocateInfo.pNext = nullptr;
-
- // texture
- CalculateCombinedMemReqs(arr_texture_mem_reqs.next, (VkMemoryRequirements*)arr_texture_mem_reqs.data, combined_texture_mem_reqs);
- // assert(combined_texture_mem_reqs.size == fontTexture->size && "Size of image texture shouldn't change?");
- vkMemoryAllocateInfo.allocationSize = combined_texture_mem_reqs.size;
- vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(combined_texture_mem_reqs.memoryTypeBits, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
- if (vkMemoryAllocateInfo.memoryTypeIndex == 0) {
- vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(combined_texture_mem_reqs.memoryTypeBits, 0);
- }
- vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &ft->gr.deviceMemoryTexture);
-
- // texture // transition image layout and copy to buffer
- tmpBufferDetails = {};
- PKVK_BeginBuffer(transferFamilyIndex, combined_texture_mem_reqs.size, tmpBufferDetails);
- memcpy(tmpBufferDetails.deviceData, txtr_bytes, imageSizeBytes);
free(txtr_bytes);
- {
- VkDeviceSize paddedImageSize = combined_texture_mem_reqs.size + (combined_texture_mem_reqs.alignment - (combined_texture_mem_reqs.size % combined_texture_mem_reqs.alignment));
- assert(paddedImageSize % combined_texture_mem_reqs.alignment == 0);
-
- VkImageViewCreateInfo vkImageViewCreateInfo;
- vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
- vkImageViewCreateInfo.pNext = nullptr;
- vkImageViewCreateInfo.flags = 0;
- vkImageViewCreateInfo.image = ft->gr.textureImage;
- vkImageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
- vkImageViewCreateInfo.format = imageCreateInfo.format;
- vkImageViewCreateInfo.components = VkComponentMapping {
- .r = VK_COMPONENT_SWIZZLE_IDENTITY,
- .g = VK_COMPONENT_SWIZZLE_IDENTITY,
- .b = VK_COMPONENT_SWIZZLE_IDENTITY,
- .a = VK_COMPONENT_SWIZZLE_IDENTITY,
- };
- vkImageViewCreateInfo.subresourceRange = vkImageSubresourceRange;
-
- vkResult = vkCreateImage(vkDevice, &imageCreateInfo, vkAllocator, &ft->gr.textureImage);
- assert(vkResult == VK_SUCCESS);
- vkResult = vkBindImageMemory(vkDevice, ft->gr.textureImage, ft->gr.deviceMemoryTexture, 0);
- assert(vkResult == VK_SUCCESS);
-
- vkImageViewCreateInfo.image = ft->gr.textureImage;
- vkResult = vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &ft->gr.textureImageView);
- assert(vkResult == VK_SUCCESS);
-
- VkImageMemoryBarrier vkImageMemoryBarrier;
- vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- vkImageMemoryBarrier.pNext = nullptr;
- vkImageMemoryBarrier.srcAccessMask = {};
- vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
- vkImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- vkImageMemoryBarrier.image = ft->gr.textureImage;
- vkImageMemoryBarrier.subresourceRange = VkImageSubresourceRange {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .baseMipLevel = 0,
- // TODO MipMap
- .levelCount = 1,
- .baseArrayLayer = 0,
- .layerCount = 1,
- };
-
- VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
- vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- vkCommandBufferBeginInfo.pNext = nullptr;
- vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
-
- vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
-
- vkCmdPipelineBarrier(tmpBufferDetails.cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
-
- VkBufferImageCopy vkBufferImageCopy;
- vkBufferImageCopy.bufferOffset = 0;
- vkBufferImageCopy.bufferRowLength = txtr_x;
- vkBufferImageCopy.bufferImageHeight = txtr_y;
- vkBufferImageCopy.imageSubresource = VkImageSubresourceLayers {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .mipLevel = 0,
- .baseArrayLayer = 0,
- .layerCount = 1,
- };
- vkBufferImageCopy.imageOffset = VkOffset3D {
- .x = 0,
- .y = 0,
- .z = 0,
- };
- vkBufferImageCopy.imageExtent = VkExtent3D {
- .width = static_cast<uint32_t>(txtr_x),
- .height = static_cast<uint32_t>(txtr_y),
- .depth = 1,
- };
- vkCmdCopyBufferToImage(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, ft->gr.textureImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkBufferImageCopy);
-
- 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);
- vkResetCommandBuffer(tmpBufferDetails.cmdBuffer, 0);
- }
- PKVK_EndBuffer(tmpBufferDetails);
- PKVK_BeginBuffer(graphicsFamilyIndex, 0, tmpBufferDetails);
- {
- VkImageMemoryBarrier vkImageMemoryBarrier;
- vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
- vkImageMemoryBarrier.pNext = nullptr;
- vkImageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
- vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
- vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
- vkImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
- vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
- vkImageMemoryBarrier.image = ft->gr.textureImage;
- vkImageMemoryBarrier.subresourceRange = VkImageSubresourceRange {
- .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
- .baseMipLevel = 0,
- // TODO MipMap
- .levelCount = 1,
- .baseArrayLayer = 0,
- .layerCount = 1,
- };
-
- VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
- vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
- vkCommandBufferBeginInfo.pNext = nullptr;
- vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
- vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
-
- vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
-
- vkCmdPipelineBarrier(tmpBufferDetails.cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
-
- 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);
/*
* Vulkan descriptor sets
diff --git a/src/window.cpp b/src/window.cpp
index 0cb9399..81c39e7 100644
--- a/src/window.cpp
+++ b/src/window.cpp
@@ -417,6 +417,217 @@ void pkvk_buffer_create(pkvk_buffer_create_data *data, pkvk_buffer_create_data_o
PKVK_EndBuffer(tmpBufferDetails);
}
+void pkvk_texture_upload(pkvk_texture_upload_data *data, pkvk_texture_upload_data_out *out) {
+ VkResult vkResult;
+ VkMemoryRequirements image_memory_requirements;
+ PKVK_TmpBufferDetails tmpBufferDetails{};
+
+ /*
+ * get memory requirements
+ */
+
+ VkImageCreateInfo imageCreateInfo{};
+ VkImageSubresourceRange vkImageSubresourceRange;
+ {
+ imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+ imageCreateInfo.pNext = nullptr;
+ imageCreateInfo.flags = 0;
+ imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
+ imageCreateInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
+ imageCreateInfo.extent.width = data->width;
+ imageCreateInfo.extent.height = data->height;
+ imageCreateInfo.extent.depth = 1;
+ imageCreateInfo.mipLevels = 1;
+ imageCreateInfo.arrayLayers = 1;
+ imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
+ imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
+ imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
+ imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+ imageCreateInfo.queueFamilyIndexCount = 0;
+ imageCreateInfo.pQueueFamilyIndices = nullptr;
+ imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+ vkImageSubresourceRange.aspectMask = VkImageAspectFlagBits::VK_IMAGE_ASPECT_COLOR_BIT;
+ vkImageSubresourceRange.baseMipLevel = 0u;
+ vkImageSubresourceRange.levelCount = 1u;
+ vkImageSubresourceRange.baseArrayLayer = 0u;
+ vkImageSubresourceRange.layerCount = 1u;
+
+ VkImage tmpImage;
+ vkResult = vkCreateImage(vkDevice, &imageCreateInfo, vkAllocator, &tmpImage);
+ assert(vkResult == VK_SUCCESS);
+ vkGetImageMemoryRequirements(vkDevice, tmpImage, &image_memory_requirements);
+ vkDestroyImage(vkDevice, tmpImage, vkAllocator);
+ }
+
+ /*
+ * memory allocation
+ */
+
+ VkMemoryAllocateInfo vkMemoryAllocateInfo;
+ vkMemoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
+ vkMemoryAllocateInfo.pNext = nullptr;
+
+ // texture
+ vkMemoryAllocateInfo.allocationSize = image_memory_requirements.size;
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(image_memory_requirements.memoryTypeBits, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT);
+ if (vkMemoryAllocateInfo.memoryTypeIndex == 0) {
+ vkMemoryAllocateInfo.memoryTypeIndex = FindMemoryTypeIndex(image_memory_requirements.memoryTypeBits, 0);
+ }
+ vkAllocateMemory(vkDevice, &vkMemoryAllocateInfo, vkAllocator, &out->device_memory);
+
+ /*
+ * transition layout & copy to buffer
+ */
+
+ PKVK_BeginBuffer(transferFamilyIndex, image_memory_requirements.size, tmpBufferDetails);
+ memcpy(tmpBufferDetails.deviceData, data->bytes, data->n_bytes);
+ {
+ VkDeviceSize paddedImageSize = image_memory_requirements.size + (image_memory_requirements.alignment - (image_memory_requirements.size % image_memory_requirements.alignment));
+ assert(paddedImageSize % image_memory_requirements.alignment == 0);
+
+ VkImageViewCreateInfo vkImageViewCreateInfo;
+ vkImageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
+ vkImageViewCreateInfo.pNext = nullptr;
+ vkImageViewCreateInfo.flags = 0;
+ vkImageViewCreateInfo.image = out->image;
+ vkImageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
+ vkImageViewCreateInfo.format = imageCreateInfo.format;
+ vkImageViewCreateInfo.components = VkComponentMapping {
+ .r = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .g = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .b = VK_COMPONENT_SWIZZLE_IDENTITY,
+ .a = VK_COMPONENT_SWIZZLE_IDENTITY,
+ };
+ vkImageViewCreateInfo.subresourceRange = vkImageSubresourceRange;
+
+ vkResult = vkCreateImage(vkDevice, &imageCreateInfo, vkAllocator, &out->image);
+ assert(vkResult == VK_SUCCESS);
+ vkResult = vkBindImageMemory(vkDevice, out->image, out->device_memory, 0);
+ assert(vkResult == VK_SUCCESS);
+
+ vkImageViewCreateInfo.image = out->image;
+ vkResult = vkCreateImageView(vkDevice, &vkImageViewCreateInfo, vkAllocator, &out->image_view);
+ assert(vkResult == VK_SUCCESS);
+
+ VkImageMemoryBarrier vkImageMemoryBarrier;
+ vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ vkImageMemoryBarrier.pNext = nullptr;
+ vkImageMemoryBarrier.srcAccessMask = {};
+ vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+ vkImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ vkImageMemoryBarrier.image = out->image;
+ vkImageMemoryBarrier.subresourceRange = VkImageSubresourceRange {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ // TODO MipMap
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ };
+
+ VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
+ vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkCommandBufferBeginInfo.pNext = nullptr;
+ vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
+
+ vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
+
+ vkCmdPipelineBarrier(tmpBufferDetails.cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
+
+ VkBufferImageCopy vkBufferImageCopy;
+ vkBufferImageCopy.bufferOffset = 0;
+ vkBufferImageCopy.bufferRowLength = data->width;
+ vkBufferImageCopy.bufferImageHeight = data->height;
+ vkBufferImageCopy.imageSubresource = VkImageSubresourceLayers {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .mipLevel = 0,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ };
+ vkBufferImageCopy.imageOffset = VkOffset3D {
+ .x = 0,
+ .y = 0,
+ .z = 0,
+ };
+ vkBufferImageCopy.imageExtent = VkExtent3D {
+ .width = data->width,
+ .height = data->height,
+ .depth = 1,
+ };
+ vkCmdCopyBufferToImage(tmpBufferDetails.cmdBuffer, tmpBufferDetails.buffer, out->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &vkBufferImageCopy);
+
+ 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);
+ vkResetCommandBuffer(tmpBufferDetails.cmdBuffer, 0);
+ }
+ PKVK_EndBuffer(tmpBufferDetails);
+ tmpBufferDetails = {};
+ PKVK_BeginBuffer(graphicsFamilyIndex, 0, tmpBufferDetails);
+ {
+ VkImageMemoryBarrier vkImageMemoryBarrier;
+ vkImageMemoryBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ vkImageMemoryBarrier.pNext = nullptr;
+ vkImageMemoryBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+ vkImageMemoryBarrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
+ vkImageMemoryBarrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+ vkImageMemoryBarrier.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ vkImageMemoryBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ vkImageMemoryBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
+ vkImageMemoryBarrier.image = out->image;
+ vkImageMemoryBarrier.subresourceRange = VkImageSubresourceRange {
+ .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+ .baseMipLevel = 0,
+ // TODO MipMap
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ };
+
+ VkCommandBufferBeginInfo vkCommandBufferBeginInfo;
+ vkCommandBufferBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
+ vkCommandBufferBeginInfo.pNext = nullptr;
+ vkCommandBufferBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
+ vkCommandBufferBeginInfo.pInheritanceInfo = nullptr;
+
+ vkBeginCommandBuffer(tmpBufferDetails.cmdBuffer, &vkCommandBufferBeginInfo);
+
+ vkCmdPipelineBarrier(tmpBufferDetails.cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, 0, nullptr, 0, nullptr, 1, &vkImageMemoryBarrier);
+
+ 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);
+}
+
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 c96f4c0..5ff415d 100644
--- a/src/window.hpp
+++ b/src/window.hpp
@@ -136,4 +136,17 @@ struct pkvk_buffer_create_data_out {
// DOES NOT upload instance data
void pkvk_buffer_create(pkvk_buffer_create_data *data, pkvk_buffer_create_data_out *out);
+struct pkvk_texture_upload_data {
+ void *bytes;
+ uint32_t n_bytes;
+ uint32_t width;
+ uint32_t height;
+};
+struct pkvk_texture_upload_data_out {
+ VkImage image;
+ VkImageView image_view;
+ VkDeviceMemory device_memory;
+};
+void pkvk_texture_upload(pkvk_texture_upload_data *data, pkvk_texture_upload_data_out *out);
+
#endif /* PKE_WINDOW_HPP */