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;

}

}

相关推荐
Full Stack Developme26 分钟前
Java 日期时间处理:分类、用途与性能分析
java·开发语言·数据库
麦兜*3 小时前
Spring Boot 整合量子密钥分发(QKD)实验方案
java·jvm·spring boot·后端·spring·spring cloud·maven
码破苍穹ovo4 小时前
堆----1.数组中的第K个最大元素
java·数据结构·算法·排序算法
2301_793086874 小时前
JVM 01 运行区域
java·开发语言
崎岖Qiu4 小时前
【JVM篇13】:兼顾吞吐量和低停顿的G1垃圾回收器
java·jvm·后端·面试
久念祈5 小时前
C++ - 仿 RabbitMQ 实现消息队列--服务端核心模块实现(五)
java·rabbitmq·java-rabbitmq
我不吃饼干6 小时前
在 React 中实现倒计时功能会有什么坑
前端·react.js
小小小小宇7 小时前
前端PerformanceObserver
前端
王者鳜錸7 小时前
PYTHON从入门到实践-18Django从零开始构建Web应用
前端·python·sqlite
拾光拾趣录7 小时前
ES6到HTTPS全链路连环拷问,99%人第3题就翻车?
前端·面试