From 80de01a5b4a7f57ec7850079fbd38fac76b9d08f Mon Sep 17 00:00:00 2001 From: Liam Date: Wed, 3 Jan 2024 22:46:59 -0500 Subject: video_core: simplify accelerated surface fetch and crop handling between APIs --- src/video_core/renderer_vulkan/renderer_vulkan.cpp | 22 ++---- src/video_core/renderer_vulkan/renderer_vulkan.h | 4 +- src/video_core/renderer_vulkan/vk_blit_screen.cpp | 89 ++++++---------------- src/video_core/renderer_vulkan/vk_blit_screen.h | 20 +++-- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 27 +++---- src/video_core/renderer_vulkan/vk_rasterizer.h | 14 ++-- 6 files changed, 61 insertions(+), 115 deletions(-) (limited to 'src/video_core/renderer_vulkan') diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 1631276c6..e1fe53bbd 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -98,9 +98,9 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, present_manager(instance, render_window, device, memory_allocator, scheduler, swapchain, surface), blit_screen(device_memory, render_window, device, memory_allocator, swapchain, - present_manager, scheduler, screen_info), - rasterizer(render_window, gpu, device_memory, screen_info, device, memory_allocator, - state_tracker, scheduler) { + present_manager, scheduler), + rasterizer(render_window, gpu, device_memory, device, memory_allocator, state_tracker, + scheduler) { if (Settings::values.renderer_force_max_clock.GetValue() && device.ShouldBoostClocks()) { turbo_mode.emplace(instance, dld); scheduler.RegisterOnSubmit([this] { turbo_mode->QueueSubmitted(); }); @@ -124,17 +124,10 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { if (!render_window.IsShown()) { return; } - // Update screen info if the framebuffer size has changed. - screen_info.width = framebuffer->width; - screen_info.height = framebuffer->height; - - const DAddr framebuffer_addr = framebuffer->address + framebuffer->offset; - const bool use_accelerated = - rasterizer.AccelerateDisplay(*framebuffer, framebuffer_addr, framebuffer->stride); - RenderScreenshot(*framebuffer, use_accelerated); + RenderScreenshot(*framebuffer); Frame* frame = present_manager.GetRenderFrame(); - blit_screen.DrawToSwapchain(frame, *framebuffer, use_accelerated); + blit_screen.DrawToSwapchain(rasterizer, frame, *framebuffer); scheduler.Flush(*frame->render_ready); present_manager.Present(frame); @@ -168,8 +161,7 @@ void RendererVulkan::Report() const { telemetry_session.AddField(field, "GPU_Vulkan_Extensions", extensions); } -void Vulkan::RendererVulkan::RenderScreenshot(const Tegra::FramebufferConfig& framebuffer, - bool use_accelerated) { +void Vulkan::RendererVulkan::RenderScreenshot(const Tegra::FramebufferConfig& framebuffer) { if (!renderer_settings.screenshot_requested) { return; } @@ -221,7 +213,7 @@ void Vulkan::RendererVulkan::RenderScreenshot(const Tegra::FramebufferConfig& fr }); const VkExtent2D render_area{.width = layout.width, .height = layout.height}; const vk::Framebuffer screenshot_fb = blit_screen.CreateFramebuffer(*dst_view, render_area); - blit_screen.Draw(framebuffer, *screenshot_fb, layout, render_area, use_accelerated); + blit_screen.Draw(rasterizer, framebuffer, *screenshot_fb, layout, render_area); const auto buffer_size = static_cast(layout.width * layout.height * 4); const VkBufferCreateInfo dst_buffer_info{ diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 11c52287a..d7d006b20 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -59,7 +59,7 @@ public: private: void Report() const; - void RenderScreenshot(const Tegra::FramebufferConfig& framebuffer, bool use_accelerated); + void RenderScreenshot(const Tegra::FramebufferConfig& framebuffer); Core::TelemetrySession& telemetry_session; Tegra::MaxwellDeviceMemoryManager& device_memory; @@ -72,8 +72,6 @@ private: vk::DebugUtilsMessenger debug_messenger; vk::SurfaceKHR surface; - ScreenInfo screen_info; - Device device; MemoryAllocator memory_allocator; StateTracker state_tracker; diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 610f27c84..c21a9c8fe 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp @@ -124,11 +124,10 @@ struct BlitScreen::BufferData { BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, Core::Frontend::EmuWindow& render_window_, const Device& device_, MemoryAllocator& memory_allocator_, Swapchain& swapchain_, - PresentManager& present_manager_, Scheduler& scheduler_, - const ScreenInfo& screen_info_) + PresentManager& present_manager_, Scheduler& scheduler_) : device_memory{device_memory_}, render_window{render_window_}, device{device_}, memory_allocator{memory_allocator_}, swapchain{swapchain_}, present_manager{present_manager_}, - scheduler{scheduler_}, image_count{swapchain.GetImageCount()}, screen_info{screen_info_} { + scheduler{scheduler_}, image_count{swapchain.GetImageCount()} { resource_ticks.resize(image_count); swapchain_view_format = swapchain.GetImageViewFormat(); @@ -138,56 +137,6 @@ BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, BlitScreen::~BlitScreen() = default; -static Common::Rectangle NormalizeCrop(const Tegra::FramebufferConfig& framebuffer, - const ScreenInfo& screen_info) { - f32 left, top, right, bottom; - - if (!framebuffer.crop_rect.IsEmpty()) { - // If crop rectangle is not empty, apply properties from rectangle. - left = static_cast(framebuffer.crop_rect.left); - top = static_cast(framebuffer.crop_rect.top); - right = static_cast(framebuffer.crop_rect.right); - bottom = static_cast(framebuffer.crop_rect.bottom); - } else { - // Otherwise, fall back to framebuffer dimensions. - left = 0; - top = 0; - right = static_cast(framebuffer.width); - bottom = static_cast(framebuffer.height); - } - - // Apply transformation flags. - auto framebuffer_transform_flags = framebuffer.transform_flags; - - if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipH)) { - // Switch left and right. - std::swap(left, right); - } - if (True(framebuffer_transform_flags & Service::android::BufferTransformFlags::FlipV)) { - // Switch top and bottom. - std::swap(top, bottom); - } - - framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipH; - framebuffer_transform_flags &= ~Service::android::BufferTransformFlags::FlipV; - if (True(framebuffer_transform_flags)) { - UNIMPLEMENTED_MSG("Unsupported framebuffer_transform_flags={}", - static_cast(framebuffer_transform_flags)); - } - - // Get the screen properties. - const f32 screen_width = static_cast(screen_info.width); - const f32 screen_height = static_cast(screen_info.height); - - // Normalize coordinate space. - left /= screen_width; - top /= screen_height; - right /= screen_width; - bottom /= screen_height; - - return Common::Rectangle(left, top, right, bottom); -} - void BlitScreen::Recreate() { present_manager.WaitPresent(); scheduler.Finish(); @@ -195,9 +144,16 @@ void BlitScreen::Recreate() { CreateDynamicResources(); } -void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, +void BlitScreen::Draw(RasterizerVulkan& rasterizer, const Tegra::FramebufferConfig& framebuffer, const VkFramebuffer& host_framebuffer, const Layout::FramebufferLayout layout, - VkExtent2D render_area, bool use_accelerated) { + VkExtent2D render_area) { + + const auto texture_info = rasterizer.AccelerateDisplay( + framebuffer, framebuffer.address + framebuffer.offset, framebuffer.stride); + const u32 texture_width = texture_info ? texture_info->width : framebuffer.width; + const u32 texture_height = texture_info ? texture_info->height : framebuffer.height; + const bool use_accelerated = texture_info.has_value(); + RefreshResources(framebuffer); // Finish any pending renderpass @@ -206,13 +162,13 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, scheduler.Wait(resource_ticks[image_index]); resource_ticks[image_index] = scheduler.CurrentTick(); - VkImage source_image = use_accelerated ? screen_info.image : *raw_images[image_index]; + VkImage source_image = texture_info ? texture_info->image : *raw_images[image_index]; VkImageView source_image_view = - use_accelerated ? screen_info.image_view : *raw_image_views[image_index]; + texture_info ? texture_info->image_view : *raw_image_views[image_index]; BufferData data; SetUniformData(data, layout); - SetVertexData(data, framebuffer, layout); + SetVertexData(data, framebuffer, layout, texture_width, texture_height); const std::span mapped_span = buffer.Mapped(); std::memcpy(mapped_span.data(), &data, sizeof(data)); @@ -405,10 +361,10 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, source_image_view = smaa->Draw(scheduler, image_index, source_image, source_image_view); } if (fsr) { - const auto crop_rect = NormalizeCrop(framebuffer, screen_info); + const auto crop_rect = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height); const VkExtent2D fsr_input_size{ - .width = Settings::values.resolution_info.ScaleUp(screen_info.width), - .height = Settings::values.resolution_info.ScaleUp(screen_info.height), + .width = Settings::values.resolution_info.ScaleUp(texture_width), + .height = Settings::values.resolution_info.ScaleUp(texture_height), }; VkImageView fsr_image_view = fsr->Draw(scheduler, image_index, source_image_view, fsr_input_size, crop_rect); @@ -480,8 +436,8 @@ void BlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, }); } -void BlitScreen::DrawToSwapchain(Frame* frame, const Tegra::FramebufferConfig& framebuffer, - bool use_accelerated) { +void BlitScreen::DrawToSwapchain(RasterizerVulkan& rasterizer, Frame* frame, + const Tegra::FramebufferConfig& framebuffer) { // Recreate dynamic resources if the the image count or input format changed const VkFormat current_framebuffer_format = std::exchange(framebuffer_view_format, GetFormat(framebuffer)); @@ -500,7 +456,7 @@ void BlitScreen::DrawToSwapchain(Frame* frame, const Tegra::FramebufferConfig& f } const VkExtent2D render_area{frame->width, frame->height}; - Draw(framebuffer, *frame->framebuffer, layout, render_area, use_accelerated); + Draw(rasterizer, framebuffer, *frame->framebuffer, layout, render_area); if (++image_index >= image_count) { image_index = 0; } @@ -1434,7 +1390,8 @@ void BlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayou } void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, - const Layout::FramebufferLayout layout) const { + const Layout::FramebufferLayout layout, u32 texture_width, + u32 texture_height) const { f32 left, top, right, bottom; if (fsr) { @@ -1446,7 +1403,7 @@ void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& bottom = 1; } else { // Get the normalized crop rectangle. - const auto crop = NormalizeCrop(framebuffer, screen_info); + const auto crop = Tegra::NormalizeCrop(framebuffer, texture_width, texture_height); // Apply the crop. left = crop.left; diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h index 3eff76009..40338886a 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.h +++ b/src/video_core/renderer_vulkan/vk_blit_screen.h @@ -32,8 +32,6 @@ enum class PixelFormat : u32; namespace Vulkan { -struct ScreenInfo; - class Device; class FSR; class RasterizerVulkan; @@ -44,7 +42,7 @@ class PresentManager; struct Frame; -struct ScreenInfo { +struct FramebufferTextureInfo { VkImage image{}; VkImageView image_view{}; u32 width{}; @@ -56,17 +54,17 @@ public: explicit BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory, Core::Frontend::EmuWindow& render_window, const Device& device, MemoryAllocator& memory_manager, Swapchain& swapchain, - PresentManager& present_manager, Scheduler& scheduler, - const ScreenInfo& screen_info); + PresentManager& present_manager, Scheduler& scheduler); ~BlitScreen(); void Recreate(); - void Draw(const Tegra::FramebufferConfig& framebuffer, const VkFramebuffer& host_framebuffer, - const Layout::FramebufferLayout layout, VkExtent2D render_area, bool use_accelerated); + void Draw(RasterizerVulkan& rasterizer, const Tegra::FramebufferConfig& framebuffer, + const VkFramebuffer& host_framebuffer, const Layout::FramebufferLayout layout, + VkExtent2D render_area); - void DrawToSwapchain(Frame* frame, const Tegra::FramebufferConfig& framebuffer, - bool use_accelerated); + void DrawToSwapchain(RasterizerVulkan& rasterizer, Frame* frame, + const Tegra::FramebufferConfig& framebuffer); [[nodiscard]] vk::Framebuffer CreateFramebuffer(const VkImageView& image_view, VkExtent2D extent); @@ -99,7 +97,8 @@ private: void UpdateAADescriptorSet(VkImageView image_view, bool nn) const; void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const; void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, - const Layout::FramebufferLayout layout) const; + const Layout::FramebufferLayout layout, u32 texture_width, + u32 texture_height) const; void CreateSMAA(VkExtent2D smaa_size); void CreateFSR(); @@ -116,7 +115,6 @@ private: Scheduler& scheduler; std::size_t image_count; std::size_t image_index{}; - const ScreenInfo& screen_info; vk::ShaderModule vertex_shader; vk::ShaderModule fxaa_vertex_shader; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 5bf41b81f..e593d7225 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -165,10 +165,9 @@ DrawParams MakeDrawParams(const MaxwellDrawState& draw_state, u32 num_instances, RasterizerVulkan::RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, Tegra::MaxwellDeviceMemoryManager& device_memory_, - ScreenInfo& screen_info_, const Device& device_, - MemoryAllocator& memory_allocator_, StateTracker& state_tracker_, - Scheduler& scheduler_) - : gpu{gpu_}, device_memory{device_memory_}, screen_info{screen_info_}, device{device_}, + const Device& device_, MemoryAllocator& memory_allocator_, + StateTracker& state_tracker_, Scheduler& scheduler_) + : gpu{gpu_}, device_memory{device_memory_}, device{device_}, memory_allocator{memory_allocator_}, state_tracker{state_tracker_}, scheduler{scheduler_}, staging_pool(device, memory_allocator, scheduler), descriptor_pool(device, scheduler), guest_descriptor_queue(device, scheduler), compute_pass_descriptor_queue(device, scheduler), @@ -783,23 +782,25 @@ void RasterizerVulkan::AccelerateInlineToMemory(GPUVAddr address, size_t copy_si query_cache.InvalidateRegion(*cpu_addr, copy_size); } -bool RasterizerVulkan::AccelerateDisplay(const Tegra::FramebufferConfig& config, - DAddr framebuffer_addr, u32 pixel_stride) { +std::optional RasterizerVulkan::AccelerateDisplay( + const Tegra::FramebufferConfig& config, DAddr framebuffer_addr, u32 pixel_stride) { if (!framebuffer_addr) { - return false; + return {}; } std::scoped_lock lock{texture_cache.mutex}; ImageView* const image_view = texture_cache.TryFindFramebufferImageView(config, framebuffer_addr); if (!image_view) { - return false; + return {}; } query_cache.NotifySegment(false); - screen_info.image = image_view->ImageHandle(); - screen_info.image_view = image_view->Handle(Shader::TextureType::Color2D); - screen_info.width = image_view->size.width; - screen_info.height = image_view->size.height; - return true; + + FramebufferTextureInfo info{}; + info.image = image_view->ImageHandle(); + info.image_view = image_view->Handle(Shader::TextureType::Color2D); + info.width = image_view->size.width; + info.height = image_view->size.height; + return info; } void RasterizerVulkan::LoadDiskResources(u64 title_id, std::stop_token stop_loading, diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 881ee0993..0617b37f0 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -43,7 +43,7 @@ class Maxwell3D; namespace Vulkan { -struct ScreenInfo; +struct FramebufferTextureInfo; class StateTracker; @@ -78,9 +78,8 @@ class RasterizerVulkan final : public VideoCore::RasterizerInterface, public: explicit RasterizerVulkan(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_, Tegra::MaxwellDeviceMemoryManager& device_memory_, - ScreenInfo& screen_info_, const Device& device_, - MemoryAllocator& memory_allocator_, StateTracker& state_tracker_, - Scheduler& scheduler_); + const Device& device_, MemoryAllocator& memory_allocator_, + StateTracker& state_tracker_, Scheduler& scheduler_); ~RasterizerVulkan() override; void Draw(bool is_indexed, u32 instance_count) override; @@ -126,8 +125,6 @@ public: Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override; void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size, std::span memory) override; - bool AccelerateDisplay(const Tegra::FramebufferConfig& config, DAddr framebuffer_addr, - u32 pixel_stride) override; void LoadDiskResources(u64 title_id, std::stop_token stop_loading, const VideoCore::DiskResourceLoadCallback& callback) override; @@ -137,6 +134,10 @@ public: void ReleaseChannel(s32 channel_id) override; + std::optional AccelerateDisplay(const Tegra::FramebufferConfig& config, + VAddr framebuffer_addr, + u32 pixel_stride); + private: static constexpr size_t MAX_TEXTURES = 192; static constexpr size_t MAX_IMAGES = 48; @@ -182,7 +183,6 @@ private: Tegra::GPU& gpu; Tegra::MaxwellDeviceMemoryManager& device_memory; - ScreenInfo& screen_info; const Device& device; MemoryAllocator& memory_allocator; StateTracker& state_tracker; -- cgit v1.2.3