vulkan游戏引擎的vulkan/shaders下的image实现

1.vulkan_image.h

#pragma once

#include "vulkan_types.inl"

void vulkan_image_create(

vulkan_context* context,

VkImageType image_type,

u32 width,

u32 height,

VkFormat format,

VkImageTiling tiling,

VkImageUsageFlags usage,

VkMemoryPropertyFlags memory_flags,

b32 create_view,

VkImageAspectFlags view_aspect_flags,

vulkan_image* out_image);

void vulkan_image_view_create(

vulkan_context* context,

VkFormat format,

vulkan_image* image,

VkImageAspectFlags aspect_flags

);

void vulkan_image_transtion_layout(

vulkan_context* context,

vulkan_command_buffer* command_buffer,

vulkan_image* image,

VkImageLayout old_layout,

VkImageLayout new_layout

);

void vulkan_image_copy_from_buffer(

vulkan_context* context,

vulkan_image* image,

VkBuffer buffer,

vulkan_command_buffer* command_buffer

);

void vulkan_image_destroy(vulkan_context* context,vulkan_image* image);

2.vulkan_image.c

#include "vulkan_image.h"

#include "vulkan_device.h"

#include "core/kmemory.h"

#include "core/logger.h"

void vulkan_image_create(

vulkan_context* context,

VkImageType image_type,

u32 width,

u32 height,

VkFormat format,

VkImageTiling tiling,

VkImageUsageFlags usage,

VkMemoryPropertyFlags memory_flags,

b32 create_view,

VkImageAspectFlags view_aspect_flags,

vulkan_image* out_image

){

out_image->width = width;

out_image->height = height;

VkImageCreateInfo image_create_info = {VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO};

image_create_info.imageType = VK_IMAGE_TYPE_2D;

image_create_info.extent.width = width;

image_create_info.extent.height = height;

image_create_info.extent.depth = 1;

image_create_info.mipLevels = 4;

image_create_info.arrayLayers = 1;

image_create_info.format = format;

image_create_info.tiling = tiling;

image_create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;

image_create_info.usage = usage;

image_create_info.samples = VK_SAMPLE_COUNT_1_BIT;

image_create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;

VK_CHECK(vkCreateImage(context->device.logical_device,&image_create_info,context->allocator,&out_image->handle));

VkMemoryRequirements memory_requirements;

vkGetImageMemoryRequirements(context->device.logical_device,out_image->handle,&memory_requirements);

i32 memory_type = context->find_memory_index(memory_requirements.memoryTypeBits,memory_flags);

if(memory_type == -1)

{

KERROR("Required memory type not found. Image not valid.");

}

//Allocate memory

VkMemoryAllocateInfo memory_allocate_info = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO};

memory_allocate_info.allocationSize = memory_requirements.size;

memory_allocate_info.memoryTypeIndex = memory_type;

VK_CHECK(vkAllocateMemory(context->device.logical_device,&memory_allocate_info,context->allocator,&out_image->memory));

//Bind the memory

VK_CHECK(vkBindImageMemory(context->device.logical_device,out_image->handle,out_image->memory,0));

if(create_view)

{

out_image->view =0 ;

vulkan_image_view_create(context,format,out_image,view_aspect_flags);

}

}

void vulkan_image_view_create(

vulkan_context* context,

VkFormat format,

vulkan_image* image,

VkImageAspectFlags aspect_flags)

{

VkImageViewCreateInfo view_create_info = {VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO};

view_create_info.image = image->handle;

view_create_info.viewType = VK_IMAGE_VIEW_TYPE_2D;

view_create_info.format = format;

view_create_info.subresourceRange.aspectMask = aspect_flags;

view_create_info.subresourceRange.baseMipLevel = 0;

view_create_info.subresourceRange.levelCount = 1;

view_create_info.subresourceRange.baseArrayLayer = 0;

view_create_info.subresourceRange.layerCount = 1;

VK_CHECK(vkCreateImageView(context->device.logical_device,&view_create_info,context->allocator,&image->view));

}

void vulkan_image_transtion_layout(

vulkan_context* context,

vulkan_command_buffer* command_buffer,

vulkan_image* image,

VkImageLayout old_layout,

VkImageLayout new_layout

)

{

VkImageMemoryBarrier barrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER};

barrier.oldLayout = old_layout;

barrier.newLayout = new_layout;

barrier.srcQueueFamilyIndex = context->device.graphics_queue_index;

barrier.dstQueueFamilyIndex = context->device.graphics_queue_index;

barrier.image = image->handle;

barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

barrier.subresourceRange.baseMipLevel = 0;

barrier.subresourceRange.levelCount = 1;

barrier.subresourceRange.baseArrayLayer = 0;

barrier.subresourceRange.layerCount = 1;

VkPipelineStageFlags source_stage;

VkPipelineStageFlags dest_stage;

if(old_layout == VK_IMAGE_LAYOUT_UNDEFINED && new_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)

{

barrier.srcAccessMask = 0;

barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;

source_stage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;

dest_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;

}else if(old_layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && new_layout == VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)

{

barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;

barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;

source_stage = VK_PIPELINE_STAGE_TRANSFER_BIT;

dest_stage = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;

} else

{

KFATAL("unsupport layout transtion!");

return;

}

vkCmdPipelineBarrier(

command_buffer->handle,

source_stage,dest_stage,

0,

0,0,

0,0,

1,&barrier

);

}

void vulkan_image_copy_from_buffer(

vulkan_context* context,

vulkan_image* image,

VkBuffer buffer,

vulkan_command_buffer* command_buffer

)

{

VkBufferImageCopy region;

kzero_memory(&region, sizeof(VkBufferImageCopy));

region.bufferOffset = 0;

region.bufferRowLength = 0;

region.bufferImageHeight = 0;

region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

region.imageSubresource.mipLevel = 0;

region.imageSubresource.baseArrayLayer = 0;

region.imageSubresource.layerCount = 1;

region.imageExtent.width = image->width;

region.imageExtent.height = image->height;

region.imageExtent.depth = 1;

vkCmdCopyBufferToImage(

command_buffer->handle,

buffer,

image->handle,

VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,

1,

&region

);

}

void vulkan_image_destroy(vulkan_context* context,vulkan_image* image)

{

if(image->view)

{

vkDestroyImageView(context->device.logical_device,image->view,context->allocator);

image->view = 0;

}

if(image->memory)

{

vkFreeMemory(context->device.logical_device,image->memory,context->allocator);

image->memory = 0;

}

if(image->handle)

{

vkDestroyImage(context->device.logical_device,image->handle,context->allocator);

image->handle = 0;

}

}

相关推荐
Arva .2 分钟前
说说线程的生命周期和状态
java·开发语言
二两锅巴2 分钟前
📺 无需Electron!前端实现多显示器浏览器窗口精准控制与通信
前端
炸土豆6 分钟前
防抖节流里的this传递
前端·javascript
用户4099322502127 分钟前
Vue3中动态样式数组的后项覆盖规则如何与计算属性结合实现复杂状态样式管理?
前端·ai编程·trae
tryxr9 分钟前
HashTable、HashMap、ConcurrentHashMap 之间的区别
java·开发语言·hash
山璞9 分钟前
Flutter3.32 中使用 webview4.13 与 vue3 项目的 h5 页面通信,以及如何调试
前端·flutter
努力早日退休12 分钟前
Antd Image标签父元素会比图片本身高几个像素的原因
前端
林希_Rachel_傻希希12 分钟前
手写Promise--教学版本
前端·javascript·面试
无事好时节14 分钟前
Linux 线程
java·开发语言·rpc
ETA816 分钟前
`console.log([1,2,3].map(parseInt))` 深入理解 JavaScript 中的高阶函数与类型机制
前端·javascript