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;

}

}

相关推荐
San813_LDD1 小时前
[C语言]《Dev-C++ 报错解决手册(Day0607 精华版)》
java·前端·javascript
Anastasiozzzz2 小时前
从有限状态机到智能体图:传统 FSM 与 Agent Graph的演进
java·人工智能·python·ai
xiaofeichaichai7 小时前
Webpack
前端·webpack·node.js
mxwin7 小时前
Unity URP 中的法线生成完全指南
unity·游戏引擎
问心无愧05137 小时前
ctf show web入门111
android·前端·笔记
游乐码7 小时前
Unity基础(十五)LineRender画线功能
unity·游戏引擎
唐某人丶7 小时前
模型越来越强,我们还需要 Agent 工程吗?—— 从价值重估到 Harness 实践
前端·agent·ai编程
智码看视界7 小时前
现代Web开发基础:全栈工程师的起航点
前端·后端·c5全栈
JS菌8 小时前
手写一个 AI Agent 全栈项目:从沙箱执行到子智能体的完整实现
前端·人工智能·后端