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;

}

}

相关推荐
致博软件F2BPM2 分钟前
Element Plus和Ant Design Vue深度对比分析与选型指南
前端·javascript·vue.js
慧一居士1 小时前
flex 布局完整功能介绍和示例演示
前端
DoraBigHead1 小时前
小哆啦解题记——两数失踪事件
前端·算法·面试
胚芽鞘6815 小时前
关于java项目中maven的理解
java·数据库·maven
岁忧6 小时前
(LeetCode 面试经典 150 题 ) 11. 盛最多水的容器 (贪心+双指针)
java·c++·算法·leetcode·面试·go
CJi0NG6 小时前
【自用】JavaSE--算法、正则表达式、异常
java
一斤代码6 小时前
vue3 下载图片(标签内容可转图)
前端·javascript·vue
Hellyc6 小时前
用户查询优惠券之缓存击穿
java·redis·缓存
中微子6 小时前
React Router 源码深度剖析解决面试中的深层次问题
前端·react.js
光影少年6 小时前
从前端转go开发的学习路线
前端·学习·golang