mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-19 19:15:26 +00:00
Vk: allow to record overlays
This commit is contained in:
parent
e2118cddad
commit
1b5a6a351f
3 changed files with 56 additions and 27 deletions
|
@ -29,9 +29,9 @@ namespace vk
|
|||
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkBool32 has_input_attachments, VkRenderPass renderpass, const std::vector<vk::image*>& image_list)
|
||||
{
|
||||
framebuffer_storage_key key(width, height, has_input_attachments);
|
||||
auto &queue = g_framebuffers_cache[key.encoded];
|
||||
auto& queue = g_framebuffers_cache[key.encoded];
|
||||
|
||||
for (auto &fbo : queue)
|
||||
for (const auto& fbo : queue)
|
||||
{
|
||||
if (fbo->matches(image_list, width, height))
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ namespace vk
|
|||
std::vector<std::unique_ptr<vk::image_view>> image_views;
|
||||
image_views.reserve(image_list.size());
|
||||
|
||||
for (auto &e : image_list)
|
||||
for (const auto& e : image_list)
|
||||
{
|
||||
const VkImageSubresourceRange subres = { e->aspect(), 0, 1, 0, 1 };
|
||||
image_views.push_back(std::make_unique<vk::image_view>(dev, e, VK_IMAGE_VIEW_TYPE_2D, vk::default_component_map, subres));
|
||||
|
@ -58,9 +58,9 @@ namespace vk
|
|||
vk::framebuffer_holder* get_framebuffer(VkDevice dev, u16 width, u16 height, VkBool32 has_input_attachments, VkRenderPass renderpass, VkFormat format, VkImage attachment)
|
||||
{
|
||||
framebuffer_storage_key key(width, height, has_input_attachments);
|
||||
auto &queue = g_framebuffers_cache[key.encoded];
|
||||
auto& queue = g_framebuffers_cache[key.encoded];
|
||||
|
||||
for (const auto &e : queue)
|
||||
for (const auto& e : queue)
|
||||
{
|
||||
if (e->attachments[0]->info.image == attachment)
|
||||
{
|
||||
|
|
|
@ -658,6 +658,21 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
}
|
||||
}
|
||||
|
||||
const bool has_overlay = (m_overlay_manager && m_overlay_manager->has_visible());
|
||||
const auto render_overlays = [&](vk::framebuffer_holder* fbo, const areau& area)
|
||||
{
|
||||
if (!has_overlay) return;
|
||||
|
||||
// Lock to avoid modification during run-update chain
|
||||
auto ui_renderer = vk::get_overlay_pass<vk::ui_overlay_renderer>();
|
||||
std::lock_guard lock(*m_overlay_manager);
|
||||
|
||||
for (const auto& view : m_overlay_manager->get_views())
|
||||
{
|
||||
ui_renderer->run(*m_current_command_buffer, area, fbo, single_target_pass, m_texture_upload_buffer_ring_info, *view.get());
|
||||
}
|
||||
};
|
||||
|
||||
if (image_to_flip)
|
||||
{
|
||||
const bool use_full_rgb_range_output = g_cfg.video.full_rgb_range_output.get();
|
||||
|
@ -744,9 +759,34 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
copy_info.imageExtent.height = buffer_height;
|
||||
copy_info.imageExtent.depth = 1;
|
||||
|
||||
image_to_flip->push_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
vk::copy_image_to_buffer(*m_current_command_buffer, image_to_flip, &sshot_vkbuf, copy_info);
|
||||
image_to_flip->pop_layout(*m_current_command_buffer);
|
||||
std::unique_ptr<vk::image> tmp_tex;
|
||||
vk::image* image_to_copy = image_to_flip;
|
||||
|
||||
if (g_cfg.video.record_with_overlays && has_overlay)
|
||||
{
|
||||
const auto key = vk::get_renderpass_key(m_swapchain->get_surface_format());
|
||||
single_target_pass = vk::get_renderpass(*m_device, key);
|
||||
ensure(single_target_pass != VK_NULL_HANDLE);
|
||||
|
||||
tmp_tex = std::make_unique<vk::image>(*m_device, m_device->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
image_to_flip->type(), image_to_flip->format(), image_to_flip->width(), image_to_flip->height(), 1, 1, image_to_flip->layers(), VK_SAMPLE_COUNT_1_BIT, image_to_flip->current_layout,
|
||||
VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT,
|
||||
0, VMM_ALLOCATION_POOL_UNDEFINED);
|
||||
|
||||
const areai rect = areai(0, 0, buffer_width, buffer_height);
|
||||
vk::copy_image(*m_current_command_buffer, image_to_flip, tmp_tex.get(), rect, rect, 1);
|
||||
|
||||
vk::framebuffer_holder* sshot_fbo = vk::get_framebuffer(*m_device, buffer_width, buffer_height, VK_FALSE, single_target_pass, { tmp_tex.get() });
|
||||
sshot_fbo->add_ref();
|
||||
render_overlays(sshot_fbo, areau(rect));
|
||||
sshot_fbo->release();
|
||||
|
||||
image_to_copy = tmp_tex.get();
|
||||
}
|
||||
|
||||
image_to_copy->push_layout(*m_current_command_buffer, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
vk::copy_image_to_buffer(*m_current_command_buffer, image_to_copy, &sshot_vkbuf, copy_info);
|
||||
image_to_copy->pop_layout(*m_current_command_buffer);
|
||||
|
||||
flush_command_queue(true);
|
||||
const auto src = sshot_vkbuf.map(0, sshot_size);
|
||||
|
@ -754,7 +794,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
memcpy(sshot_frame.data(), src, sshot_size);
|
||||
sshot_vkbuf.unmap();
|
||||
|
||||
const bool is_bgra = image_to_flip->format() == VK_FORMAT_B8G8R8A8_UNORM;
|
||||
const bool is_bgra = image_to_copy->format() == VK_FORMAT_B8G8R8A8_UNORM;
|
||||
|
||||
if (g_user_asked_for_screenshot.exchange(false))
|
||||
{
|
||||
|
@ -767,7 +807,6 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
}
|
||||
}
|
||||
|
||||
const bool has_overlay = (m_overlay_manager && m_overlay_manager->has_visible());
|
||||
if (g_cfg.video.debug_overlay || has_overlay)
|
||||
{
|
||||
if (target_layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)
|
||||
|
@ -799,17 +838,7 @@ void VKGSRender::flip(const rsx::display_flip_info_t& info)
|
|||
|
||||
direct_fbo->add_ref();
|
||||
|
||||
if (has_overlay)
|
||||
{
|
||||
// Lock to avoid modification during run-update chain
|
||||
auto ui_renderer = vk::get_overlay_pass<vk::ui_overlay_renderer>();
|
||||
std::lock_guard lock(*m_overlay_manager);
|
||||
|
||||
for (const auto& view : m_overlay_manager->get_views())
|
||||
{
|
||||
ui_renderer->run(*m_current_command_buffer, areau(aspect_ratio), direct_fbo, single_target_pass, m_texture_upload_buffer_ring_info, *view.get());
|
||||
}
|
||||
}
|
||||
render_overlays(direct_fbo, areau(aspect_ratio));
|
||||
|
||||
if (g_cfg.video.debug_overlay)
|
||||
{
|
||||
|
|
|
@ -47,35 +47,35 @@ namespace vk
|
|||
vkDestroyFramebuffer(m_device, value, nullptr);
|
||||
}
|
||||
|
||||
u32 width()
|
||||
u32 width() const
|
||||
{
|
||||
return m_width;
|
||||
}
|
||||
|
||||
u32 height()
|
||||
u32 height() const
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
u8 samples()
|
||||
u8 samples() const
|
||||
{
|
||||
ensure(!attachments.empty());
|
||||
return attachments[0]->image()->samples();
|
||||
}
|
||||
|
||||
VkFormat format()
|
||||
VkFormat format() const
|
||||
{
|
||||
ensure(!attachments.empty());
|
||||
return attachments[0]->image()->format();
|
||||
}
|
||||
|
||||
VkFormat depth_format()
|
||||
VkFormat depth_format() const
|
||||
{
|
||||
ensure(!attachments.empty());
|
||||
return attachments.back()->image()->format();
|
||||
}
|
||||
|
||||
bool matches(const std::vector<vk::image*>& fbo_images, u32 width, u32 height)
|
||||
bool matches(const std::vector<vk::image*>& fbo_images, u32 width, u32 height) const
|
||||
{
|
||||
if (m_width != width || m_height != height)
|
||||
return false;
|
||||
|
|
Loading…
Add table
Reference in a new issue