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;

}

}

相关推荐
kyriewen43 分钟前
我把今年流传的前端 AI 面试题整理了一遍——4 类场景题+回答框架(附速查表)
前端·面试·程序员
计算机魔术师1 小时前
国产多模态模型正面硬刚Opus旗舰:差距从30%缩到3%
前端
风骏时光牛马1 小时前
程序员进阶:深度思考,解锁职场成长的底层逻辑
前端
IT_陈寒2 小时前
用了Proxy才发现以前的JavaScript白写了
前端·人工智能·后端
爱丶不疚2 小时前
Eval: Agent 说的 Eval 是什么?从单测、TDD 到 Sentry 聊起
前端·ai编程·vibecoding
求道於盲2 小时前
python中的类型标注
前端
计算机魔术师2 小时前
从硅谷测试到全球铺开,ChatGPT广告的10亿美元秘密
前端
古法安卓3 小时前
Android-日志系统源码解析
android·java·android studio
专业抄代码选手3 小时前
08|Fiber 上的 `useState`:状态终于属于具体组件
前端·javascript·react.js
默_笙3 小时前
😭 Vibe Coding 翻车实录:AI 编程为什么必须先写"剧本"
前端·javascript