AronaCore/core/rhi/render_target.cpp
2024-02-20 10:06:45 +08:00

96 lines
3.7 KiB
C++

#include "render_target.h"
#include "renderer.h"
#include "application/application.h"
#include "utils/utils.hpp"
void render_target::init(const int width, const int height, const vk::Format in_format) {
width_ = width;
height_ = height;
format = in_format;
create(width, height);
}
void* render_target::lock(lock_state state) const {
const auto r = application::get()->get_renderer();
const auto& device = r->device;
vk::ImageSubresource subresource;
subresource.setAspectMask(vk::ImageAspectFlagBits::eColor);
subresource.setMipLevel(0);
subresource.setArrayLayer(0);
const vk::SubresourceLayout subresource_layout = device.getImageSubresourceLayout(image, subresource);
void* data;
const vk::Result result = device.mapMemory(memory, 0, VK_WHOLE_SIZE, vk::MemoryMapFlags(), &data);
check_vk_result(result);
return static_cast<uint8_t*>(data) + subresource_layout.offset;
}
void render_target::unlock() {
const auto r = application::get()->get_renderer();
const auto& device = r->device;
device.unmapMemory(memory);
}
void render_target::create(int width, int height) {
auto r = application::get()->get_renderer();
const auto& device = r->device;
const auto& physical_device = r->physical_device;
vk::ImageCreateInfo image_create_info;
image_create_info.setImageType(vk::ImageType::e2D);
image_create_info.setFormat(format);
image_create_info.setExtent({static_cast<uint32_t>(width), static_cast<uint32_t>(height), 1});
image_create_info.setMipLevels(1);
image_create_info.setArrayLayers(1);
image_create_info.setSamples(vk::SampleCountFlagBits::e1);
image_create_info.setTiling(vk::ImageTiling::eOptimal);
image_create_info.setUsage(vk::ImageUsageFlagBits::eSampled | vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eColorAttachment);
image_create_info.setSharingMode(vk::SharingMode::eExclusive);
image_create_info.setInitialLayout(vk::ImageLayout::eUndefined);
image = device.createImage(image_create_info);
vk::PhysicalDeviceMemoryProperties memory_properties = physical_device.getMemoryProperties();
vk::MemoryRequirements memory_requirements = device.getImageMemoryRequirements(image);
const uint32_t memory_type = vk::su::findMemoryType(memory_properties, memory_requirements.memoryTypeBits, vk::MemoryPropertyFlagBits::eDeviceLocal);
vk::MemoryAllocateInfo memory_allocate_info;
memory_allocate_info.setAllocationSize(memory_requirements.size);
memory_allocate_info.setMemoryTypeIndex(memory_type);
memory = device.allocateMemory(memory_allocate_info);
device.bindImageMemory(image, memory, 0);
vk::ImageViewCreateInfo image_view_create_info;
image_view_create_info.setImage(image);
image_view_create_info.setViewType(vk::ImageViewType::e2D);
image_view_create_info.setFormat(format);
image_view_create_info.setSubresourceRange({vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1});
image_view = device.createImageView(image_view_create_info);
vk::FramebufferCreateInfo framebuffer_create_info;
framebuffer_create_info.setRenderPass(r->main_window_data.RenderPass);
framebuffer_create_info.setAttachmentCount(1);
framebuffer_create_info.setAttachments(image_view);
framebuffer_create_info.setWidth(width);
framebuffer_create_info.setHeight(height);
framebuffer_create_info.setLayers(1);
framebuffer = device.createFramebuffer(framebuffer_create_info);
}
void render_target::on_resize(int width, int height) {
const auto r = application::get()->get_renderer();
const auto& device = r->device;
device.destroyFramebuffer(framebuffer);
device.destroyImageView(image_view);
device.destroyImage(image);
device.freeMemory(memory);
create(width, height);
}