From 4f2bda26fc200adf2129374d2c023ca377ff3cff Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 21 Mar 2016 18:20:30 +0100 Subject: [PATCH] vulkan: Simplify framebuffer class and release them at frame flip --- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 35 +++++++++----- rpcs3/Emu/RSX/VK/VKGSRender.h | 2 +- rpcs3/Emu/RSX/VK/VKHelpers.h | 84 ++++++++++++++++++++++----------- 3 files changed, 82 insertions(+), 39 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index fd5bd297a2..4e906e3f7b 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -467,6 +467,7 @@ VKGSRender::~VKGSRender() null_buffer.release(); null_buffer_view.release(); m_buffer_view_to_clean.clear(); + m_framebuffer_to_clean.clear(); for (auto &render_pass : m_render_passes) if (render_pass) @@ -576,7 +577,7 @@ void VKGSRender::end() VkRenderPassBeginInfo rp_begin = {}; rp_begin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rp_begin.renderPass = current_render_pass; - rp_begin.framebuffer = m_framebuffer; + rp_begin.framebuffer = m_framebuffer_to_clean.back()->value; rp_begin.renderArea.offset.x = 0; rp_begin.renderArea.offset.y = 0; rp_begin.renderArea.extent.width = m_frame->client_size().width; @@ -1066,30 +1067,42 @@ void VKGSRender::prepare_rtts() //Bind created rtts as current fbo... std::vector draw_buffers = vk::get_draw_buffers(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])); - m_framebuffer.destroy(); - std::vector fbo_images; + std::vector > fbo_images; for (u8 index: draw_buffers) { vk::texture *raw = std::get<1>(m_rtts.m_bound_render_targets[index]); - VkImageView as_image = (*raw); - fbo_images.push_back(as_image); + + VkImageSubresourceRange subres = {}; + subres.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + subres.baseArrayLayer = 0; + subres.baseMipLevel = 0; + subres.layerCount = 1; + subres.levelCount = 1; + + fbo_images.push_back(std::make_unique(*m_device, *raw, VK_IMAGE_VIEW_TYPE_2D, raw->get_format(), vk::default_component_map(), subres)); } + m_draw_buffers_count = fbo_images.size(); + if (std::get<1>(m_rtts.m_bound_depth_stencil) != nullptr) { vk::texture *raw = (std::get<1>(m_rtts.m_bound_depth_stencil)); - VkImageView depth_image = (*raw); - fbo_images.push_back(depth_image); + + VkImageSubresourceRange subres = {}; + subres.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; + subres.baseArrayLayer = 0; + subres.baseMipLevel = 0; + subres.layerCount = 1; + subres.levelCount = 1; + + fbo_images.push_back(std::make_unique(*m_device, *raw, VK_IMAGE_VIEW_TYPE_2D, raw->get_format(), vk::default_component_map(), subres)); } size_t idx = vk::get_render_pass_location(vk::get_compatible_surface_format(m_surface.color_format), vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), (u8)draw_buffers.size()); VkRenderPass current_render_pass = m_render_passes[idx]; - m_framebuffer.create((*m_device), current_render_pass, fbo_images.data(), fbo_images.size(), - clip_width, clip_height); - - m_draw_buffers_count = draw_buffers.size(); + m_framebuffer_to_clean.push_back(std::make_unique(*m_device, current_render_pass, clip_width, clip_height, std::move(fbo_images))); } void VKGSRender::execute_command_buffer(bool wait) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index e1d92908a2..1e9a0c2c3a 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -151,11 +151,11 @@ private: vk::descriptor_pool descriptor_pool; std::vector > m_buffer_view_to_clean; + std::vector > m_framebuffer_to_clean; u32 m_draw_calls = 0; u8 m_draw_buffers_count = 0; - vk::framebuffer m_framebuffer; public: VKGSRender(); diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index e46889eb42..0cdc56c128 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -332,6 +332,35 @@ namespace vk } }; + struct image_view + { + VkImageView value; + VkImageViewCreateInfo info = {}; + + image_view(VkDevice dev, VkImage image, VkImageViewType view_type, VkFormat format, VkComponentMapping mapping, VkImageSubresourceRange range) + : m_device(dev) + { + info.format = format; + info.image = image; + info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO; + info.viewType = view_type; + info.components = mapping; + info.subresourceRange = range; + + CHECK_RESULT(vkCreateImageView(m_device, &info, nullptr, &value)); + } + + ~image_view() + { + vkDestroyImageView(m_device, value, nullptr); + } + + image_view(const image_view&) = delete; + image_view(image_view&&) = delete; + private: + VkDevice m_device; + }; + class texture { VkImageView m_view = nullptr; @@ -501,42 +530,43 @@ namespace vk VkDevice m_device; }; - class framebuffer + struct framebuffer { - VkFramebuffer m_vk_framebuffer = nullptr; - vk::render_device *owner = nullptr; - + VkFramebuffer value; + VkFramebufferCreateInfo info = {}; + std::vector> attachements; public: - framebuffer() {} - ~framebuffer() {} - - void create(vk::render_device &dev, VkRenderPass pass, VkImageView *attachments, u32 nb_attachments, u32 width, u32 height) + framebuffer(VkDevice dev, VkRenderPass pass, u32 width, u32 height, std::vector> &&atts) + : m_device(dev), attachements(std::move(atts)) { - VkFramebufferCreateInfo infos = {}; - infos.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; - infos.width = width; - infos.height = height; - infos.attachmentCount = nb_attachments; - infos.pAttachments = attachments; - infos.renderPass = pass; - infos.layers = 1; + std::vector image_view_array(attachements.size()); + size_t i = 0; + for (const auto &att : attachements) + { + image_view_array[i++] = att->value; + } - vkCreateFramebuffer(dev, &infos, nullptr, &m_vk_framebuffer); - owner = &dev; + info.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; + info.width = width; + info.height = height; + info.attachmentCount = image_view_array.size(); + info.pAttachments = image_view_array.data(); + info.renderPass = pass; + info.layers = 1; + + CHECK_RESULT(vkCreateFramebuffer(dev, &info, nullptr, &value)); } - void destroy() + ~framebuffer() { - if (!owner) return; - - vkDestroyFramebuffer((*owner), m_vk_framebuffer, nullptr); - owner = nullptr; + vkDestroyFramebuffer(m_device, value, nullptr); } - operator VkFramebuffer() const - { - return m_vk_framebuffer; - } + framebuffer(const framebuffer&) = delete; + framebuffer(framebuffer&&) = delete; + + private: + VkDevice m_device; }; class swap_chain_image