From b0db5bfd22f9553873b5734f5c08339bf98d0611 Mon Sep 17 00:00:00 2001 From: Gregory Wells Date: Tue, 12 Aug 2025 14:27:08 -0400 Subject: [PATCH] textures with VMA --- .../apis/vulkan/src/textures/vulkan_texture.c | 70 ++++++++----------- .../apis/vulkan/src/textures/vulkan_texture.h | 9 +-- 2 files changed, 34 insertions(+), 45 deletions(-) diff --git a/projects/apis/vulkan/src/textures/vulkan_texture.c b/projects/apis/vulkan/src/textures/vulkan_texture.c index 029e824..8820b28 100644 --- a/projects/apis/vulkan/src/textures/vulkan_texture.c +++ b/projects/apis/vulkan/src/textures/vulkan_texture.c @@ -143,18 +143,10 @@ void VkCopyBufferToImage(VkGryphnBuffer buffer, VkGryphnImage image, gnExtent3D gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureInfo info) { texture->texture = malloc(sizeof(struct gnPlatformTexture_t)); - size_t imageSize = info.extent.width * info.extent.height; if (info.format == GN_FORMAT_BGRA8_SRGB) { imageSize *= 4; } if (info.format == GN_FORMAT_RGBA8_SRGB) { imageSize *= 4; } - - gnReturnCode staginBufferCreateCode = VkCreateBuffer( - &texture->texture->buffer, imageSize, device, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, VK_BUFFER_USAGE_TRANSFER_SRC_BIT - ); - if (staginBufferCreateCode != GN_SUCCESS) return staginBufferCreateCode; texture->texture->size = imageSize; - VkImageCreateInfo imageInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, @@ -172,27 +164,14 @@ gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureIn .imageType = vkGryphnTextureType(info.type), .format = vkGryphnFormatToVulkanFormat(info.format) }; - - VkResult res = vkCreateImage(device->outputDevice->device, &imageInfo, NULL, &texture->texture->image.image); - if (res != VK_SUCCESS) return VkResultToGnReturnCode(res); - - VkMemoryRequirements memRequirements; - vkGetImageMemoryRequirements(device->outputDevice->device, texture->texture->image.image, &memRequirements); - - gnBool foundMemory = GN_FALSE; - VkMemoryAllocateInfo allocInfo = { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, - .allocationSize = memRequirements.size, - .memoryTypeIndex = VkMemoryIndex(device->outputDevice->physicalDevice, memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &foundMemory) + VmaAllocationCreateInfo allocationInfo = { + .usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE, + .requiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT }; - if (!foundMemory) return GN_FAILED_TO_ALLOCATE_MEMORY; - - VkResult allocationRes = vkAllocateMemory(device->outputDevice->device, &allocInfo, NULL, &texture->texture->image.memory); - if (allocationRes != VK_SUCCESS) return VkResultToGnReturnCode(allocationRes); - vkBindImageMemory(device->outputDevice->device, texture->texture->image.image, texture->texture->image.memory, 0); + VkResult imageCreateInfo = vmaCreateImage(device->outputDevice->allocator, &imageInfo, &allocationInfo, &texture->texture->image.image, &texture->texture->image.allocation, NULL); + if (imageCreateInfo != VK_SUCCESS) return VkResultToGnReturnCode(imageCreateInfo); texture->texture->beenWrittenToo = GN_FALSE; - VkImageViewCreateInfo viewInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, .image = texture->texture->image.image, @@ -242,28 +221,37 @@ gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureIn } void textureData(gnTextureHandle texture, void* pixelData) { - void* data; - vkMapMemory(texture->device->outputDevice->device, texture->texture->buffer.memory, 0, texture->texture->size, 0, &data); - memcpy(data, pixelData, texture->texture->size); - vkUnmapMemory(texture->device->outputDevice->device, texture->texture->buffer.memory); - - //gnDevice device, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout VkTransitionImageLayout(texture->device, texture->texture->image.image, texture->info.format, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - VkCopyBufferToImage(texture->texture->buffer, texture->texture->image, texture->info.extent, texture->device); - VkTransitionImageLayout(texture->device, texture->texture->image.image, texture->info.format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + void* textureData; + VkGryphnBuffer* stagingBuffer = &texture->device->outputDevice->stagingBuffer; + VkDeviceSize sizeLeft = texture->texture->size, dataSize = texture->texture->size; + while (sizeLeft > 0) { + VkDeviceSize chunkSize = (texture->device->outputDevice->stagingBufferSize < sizeLeft) ? texture->device->outputDevice->stagingBufferSize : sizeLeft; + vulkanMapBufferInternal(texture->device, *stagingBuffer, &textureData); + memcpy(textureData, (char*)pixelData + (dataSize - sizeLeft), chunkSize); + vulkanUnmapBufferInternal(texture->device, *stagingBuffer); + + VkBufferCopy copyRegion = { + .srcOffset = 0, + .dstOffset = dataSize - sizeLeft, + .size = chunkSize + }; + sizeLeft -= chunkSize; + + VkCopyBufferToImage(texture->device->outputDevice->stagingBuffer, texture->texture->image, texture->info.extent, texture->device); + } + + VkTransitionImageLayout(texture->device, texture->texture->image.image, texture->info.format, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); texture->texture->beenWrittenToo = GN_TRUE; } -void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device) { - vkDestroyImage(device, image->image, NULL); - vkDestroyImageView(device, image->imageView, NULL); - vkFreeMemory(device, image->memory, NULL); +void gnDestroyVulkanImage(VkGryphnImage* image, gnDevice device) { + vmaDestroyImage(device->outputDevice->allocator, image->image, image->allocation); + vkDestroyImageView(device->outputDevice->device, image->imageView, NULL); } void destroyTexture(gnTexture texture) { vkDestroySampler(texture->device->outputDevice->device, texture->texture->sampler, NULL); - - gnDestroyVulkanBuffer(&texture->texture->buffer, texture->device->outputDevice->device); - gnDestroyVulkanImage(&texture->texture->image, texture->device->outputDevice->device); + gnDestroyVulkanImage(&texture->texture->image, texture->device); } diff --git a/projects/apis/vulkan/src/textures/vulkan_texture.h b/projects/apis/vulkan/src/textures/vulkan_texture.h index eb67e35..a01d3f2 100644 --- a/projects/apis/vulkan/src/textures/vulkan_texture.h +++ b/projects/apis/vulkan/src/textures/vulkan_texture.h @@ -2,21 +2,22 @@ #include #include "textures/gryphn_texture.h" #include "buffers/vulkan_buffer.h" +#include "memory_allocator/vk_mem_alloc.h" typedef struct VkGryphnImage { VkImage image; - VkDeviceMemory memory; + VmaAllocation allocation; VkImageView imageView; } VkGryphnImage; -void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device); +void gnDestroyVulkanImage(VkGryphnImage* image, gnDevice device); typedef struct gnPlatformTexture_t { - VkGryphnBuffer buffer; VkGryphnImage image; VkSampler sampler; - size_t size; gnBool beenWrittenToo; + + VkImageLayout currentLayout; } gnPlatformTexture; gnReturnCode createTexture(gnTexture texture, gnDevice device, const gnTextureInfo info);