vulkan: Simplify framebuffer class and release them at frame flip

This commit is contained in:
Vincent Lejeune 2016-03-21 18:20:30 +01:00
parent a14dd8ea51
commit 4f2bda26fc
3 changed files with 82 additions and 39 deletions

View File

@ -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<u8> draw_buffers = vk::get_draw_buffers(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]));
m_framebuffer.destroy();
std::vector<VkImageView> fbo_images;
std::vector<std::unique_ptr<vk::image_view> > 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<vk::image_view>(*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<vk::image_view>(*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<vk::framebuffer>(*m_device, current_render_pass, clip_width, clip_height, std::move(fbo_images)));
}
void VKGSRender::execute_command_buffer(bool wait)

View File

@ -151,11 +151,11 @@ private:
vk::descriptor_pool descriptor_pool;
std::vector<std::unique_ptr<vk::buffer_view> > m_buffer_view_to_clean;
std::vector<std::unique_ptr<vk::framebuffer> > m_framebuffer_to_clean;
u32 m_draw_calls = 0;
u8 m_draw_buffers_count = 0;
vk::framebuffer m_framebuffer;
public:
VKGSRender();

View File

@ -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<std::unique_ptr<vk::image_view>> 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<std::unique_ptr<vk::image_view>> &&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<VkImageView> 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