From bc64fc073118d397fe1609ab6a4cdee7507284bc Mon Sep 17 00:00:00 2001 From: Gregory Wells Date: Sat, 14 Jun 2025 14:39:40 -0400 Subject: [PATCH] write all the vulkan functions --- .../vulkan/src/buffers/vulkan_buffer.c | 15 +- .../vulkan/src/buffers/vulkan_buffer.h | 1 + .../vulkan/src/textures/vulkan_texture.c | 136 +++++++++++++++++- .../vulkan/src/textures/vulkan_texture.h | 14 +- 4 files changed, 152 insertions(+), 14 deletions(-) diff --git a/rendering_api/vulkan/src/buffers/vulkan_buffer.c b/rendering_api/vulkan/src/buffers/vulkan_buffer.c index 891fa85..2bdc67a 100644 --- a/rendering_api/vulkan/src/buffers/vulkan_buffer.c +++ b/rendering_api/vulkan/src/buffers/vulkan_buffer.c @@ -119,13 +119,14 @@ void* gnMapBufferFn(gnBufferHandle buffer) { vkMapMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, 0, buffer->info.size, 0, &data); return data; } -void gnDestroyBufferFn(gnBufferHandle buffer) { - if (buffer->buffer->useStagingBuffer == gnTrue) { - vkDestroyBuffer(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.buffer, NULL); - vkFreeMemory(buffer->device->outputDevice->device, buffer->buffer->stagingBuffer.memory, NULL); - } - vkDestroyBuffer(buffer->device->outputDevice->device, buffer->buffer->buffer.buffer, NULL); - vkFreeMemory(buffer->device->outputDevice->device, buffer->buffer->buffer.memory, NULL); +void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device) { + vkDestroyBuffer(device, buffer->buffer, NULL); + vkFreeMemory(device, buffer->memory, NULL); +} + +void gnDestroyBufferFn(gnBufferHandle buffer) { + if (buffer->buffer->useStagingBuffer == gnTrue) gnDestroyVulkanBuffer(&buffer->buffer->stagingBuffer, buffer->device->outputDevice->device); + gnDestroyVulkanBuffer(&buffer->buffer->buffer, buffer->device->outputDevice->device); free(buffer->buffer); } diff --git a/rendering_api/vulkan/src/buffers/vulkan_buffer.h b/rendering_api/vulkan/src/buffers/vulkan_buffer.h index 9febcbb..621ae20 100644 --- a/rendering_api/vulkan/src/buffers/vulkan_buffer.h +++ b/rendering_api/vulkan/src/buffers/vulkan_buffer.h @@ -7,6 +7,7 @@ typedef struct VkGryphnBuffer { VkBuffer buffer; VkDeviceMemory memory; } VkGryphnBuffer; +void gnDestroyVulkanBuffer(VkGryphnBuffer* buffer, VkDevice device); struct gnPlatformBuffer_t { VkGryphnBuffer buffer; diff --git a/rendering_api/vulkan/src/textures/vulkan_texture.c b/rendering_api/vulkan/src/textures/vulkan_texture.c index 32d6690..7638f4c 100644 --- a/rendering_api/vulkan/src/textures/vulkan_texture.c +++ b/rendering_api/vulkan/src/textures/vulkan_texture.c @@ -2,6 +2,7 @@ #include "vulkan_texture.h" #include "output_device/vulkan_output_devices.h" #include "output_device/vulkan_physical_device.h" +#include "core/debugger/gryphn_debugger.h" VkImageType vkGryphnTextureType(gnTextureType type) { switch(type) { @@ -9,9 +10,103 @@ case GN_TEXTURE_2D: return VK_IMAGE_TYPE_3D; } } +void VkTransitionImageLayout(gnDevice device, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout) { + VkCommandBuffer transferBuffer = gnBeginVulkanTransferOperation(device); + + VkPipelineStageFlags sourceStage, destinationStage; + VkAccessFlags sourceAccessMask, destinationAccessMask; + + if (oldLayout == VK_IMAGE_LAYOUT_UNDEFINED && newLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL) { + sourceAccessMask = 0; + sourceStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + + destinationAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + destinationStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + } else if (oldLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && newLayout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL) { + sourceAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; + sourceStage = VK_PIPELINE_STAGE_TRANSFER_BIT; + + destinationStage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT; + destinationAccessMask = VK_ACCESS_SHADER_READ_BIT; + } + + VkImageMemoryBarrier barrier = { + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .image = image, + + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .srcAccessMask = sourceAccessMask, + .oldLayout = oldLayout, + + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstAccessMask = destinationAccessMask, + .newLayout = newLayout, + + + .subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .subresourceRange.baseMipLevel = 0, + .subresourceRange.levelCount = 1, + .subresourceRange.baseArrayLayer = 0, + .subresourceRange.layerCount = 1, + + }; + + vkCmdPipelineBarrier( + transferBuffer, + sourceStage, destinationStage, + 0, + 0, NULL, + 0, NULL, + 1, &barrier + ); + + gnEndVulkanTransferOperation(device, transferBuffer); +} + +void VkCopyBufferToImage(VkGryphnBuffer buffer, VkGryphnImage image, uint32_t width, uint32_t height, gnDevice device) { + VkCommandBuffer transferBuffer = gnBeginVulkanTransferOperation(device); + + VkBufferImageCopy region = { + .bufferOffset = 0, + .bufferRowLength = 0, + .bufferImageHeight = 0, + + .imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .imageSubresource.mipLevel = 0, + .imageSubresource.baseArrayLayer = 0, + .imageSubresource.layerCount = 1, + + .imageOffset = (VkOffset3D){0, 0, 0}, + .imageExtent = (VkExtent3D){ + width, + height, + 1 + } + }; + + vkCmdCopyBufferToImage( + transferBuffer, + buffer.buffer, image.image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + 1, ®ion + ); + + gnEndVulkanTransferOperation(device, transferBuffer); +} + gnReturnCode gnCreateTextureFn(gnTexture texture, gnDevice device, const gnTextureInfo info) { texture->texture = malloc(sizeof(struct gnPlatformTexture_t)); + size_t imageSize = info.width * info.height; + if (info.format == GN_FORMAT_BGRA8_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 GN_FAILED_TO_CREATE_BUFFER; + texture->texture->size = imageSize; + VkImageCreateInfo imageInfo = { .sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, .sharingMode = VK_SHARING_MODE_EXCLUSIVE, @@ -30,11 +125,11 @@ gnReturnCode gnCreateTextureFn(gnTexture texture, gnDevice device, const gnTextu .format = vkGryphnFormatToVulkanFormat(info.format) }; - if (vkCreateImage(device->outputDevice->device, &imageInfo, NULL, &texture->texture->image) != VK_SUCCESS) + if (vkCreateImage(device->outputDevice->device, &imageInfo, NULL, &texture->texture->image.image) != VK_SUCCESS) return GN_FAILED_TO_CREATE_IMAGE; VkMemoryRequirements memRequirements; - vkGetImageMemoryRequirements(device->outputDevice->device, texture->texture->image, &memRequirements); + vkGetImageMemoryRequirements(device->outputDevice->device, texture->texture->image.image, &memRequirements); gnBool foundMemory = gnFalse; VkMemoryAllocateInfo allocInfo = { @@ -44,10 +139,43 @@ gnReturnCode gnCreateTextureFn(gnTexture texture, gnDevice device, const gnTextu }; if (!foundMemory) return GN_FAILED_TO_ALLOCATE_MEMORY; - if (vkAllocateMemory(device->outputDevice->device, &allocInfo, NULL, &texture->texture->memory) != VK_SUCCESS) + if (vkAllocateMemory(device->outputDevice->device, &allocInfo, NULL, &texture->texture->image.memory) != VK_SUCCESS) return GN_FAILED_TO_ALLOCATE_MEMORY; - vkBindImageMemory(device->outputDevice->device, texture->texture->image, texture->texture->memory, 0); + vkBindImageMemory(device->outputDevice->device, texture->texture->image.image, texture->texture->image.memory, 0); + + texture->texture->width = info.width; + texture->texture->height = info.height; return GN_SUCCESS; } + +void gnTextureDataFn(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); + + if (texture->texture->beenWrittenToo) { + gnDebuggerSetErrorMessage(texture->device->instance->debugger, (gnMessageData){ + .message = gnCreateString("this texture has alreay been written too with gnTextureData (vulkan) i need to implement the functionality to write to it multible times") + }); + } + + //gnDevice device, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout + VkTransitionImageLayout(texture->device, texture->texture->image.image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + VkCopyBufferToImage(texture->texture->buffer, texture->texture->image, texture->texture->width, texture->texture->height, texture->device); + VkTransitionImageLayout(texture->device, texture->texture->image.image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + + texture->texture->beenWrittenToo = gnTrue; +} + +void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device) { + vkDestroyImage(device, image->image, NULL); + vkFreeMemory(device, image->memory, NULL); +} + +void gnDestroyTextureFn(gnTexture texture) { + gnDestroyVulkanBuffer(&texture->texture->buffer, texture->device->outputDevice->device); + gnDestroyVulkanImage(&texture->texture->image, texture->device->outputDevice->device); +} diff --git a/rendering_api/vulkan/src/textures/vulkan_texture.h b/rendering_api/vulkan/src/textures/vulkan_texture.h index aeffd1b..b11e17d 100644 --- a/rendering_api/vulkan/src/textures/vulkan_texture.h +++ b/rendering_api/vulkan/src/textures/vulkan_texture.h @@ -3,10 +3,18 @@ #include "core/textures/gryphn_texture.h" #include "buffers/vulkan_buffer.h" -typedef struct gnPlatformTexture_t { - VkGryphnBuffer buffer; - +typedef struct VkGryphnImage { VkImage image; VkDeviceMemory memory; VkImageView imageView; +} VkGryphnImage; +void gnDestroyVulkanImage(VkGryphnImage* image, VkDevice device); + +typedef struct gnPlatformTexture_t { + VkGryphnBuffer buffer; + VkGryphnImage image; + + size_t size; + uint32_t width, height; + gnBool beenWrittenToo; } gnPlatformTexture;