diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 0f54dd5ade..bb7eb9bdaa 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2024 Torzu Emulator Project @@ -22,7 +22,8 @@ BlitScreen::BlitScreen(Tegra::MaxwellDeviceMemoryManager& device_memory_, const MemoryAllocator& memory_allocator_, PresentManager& present_manager_, Scheduler& scheduler_, const PresentFilters& filters_) : device_memory{device_memory_}, device{device_}, memory_allocator{memory_allocator_}, - present_manager{present_manager_}, scheduler{scheduler_}, filters{filters_}, image_count{1}, + present_manager{present_manager_}, scheduler{scheduler_}, filters{filters_}, + image_count{1}, image_index{0}, swapchain_view_format{VK_FORMAT_B8G8R8A8_UNORM} {} BlitScreen::~BlitScreen() = default; @@ -87,57 +88,49 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame, bool resource_update_required = false; bool presentation_recreate_required = false; - // Recreate dynamic resources if the adapting filter changed if (!window_adapt || scaling_filter != filters.get_scaling_filter()) { resource_update_required = true; } - // Recreate dynamic resources if the image count changed - const size_t old_swapchain_image_count = - std::exchange(image_count, current_swapchain_image_count); - if (old_swapchain_image_count != current_swapchain_image_count) { + if (image_count != current_swapchain_image_count) { resource_update_required = true; + image_count = current_swapchain_image_count; } - // Recreate the presentation frame if the format or dimensions of the window changed - const VkFormat old_swapchain_view_format = - std::exchange(swapchain_view_format, current_swapchain_view_format); - if (old_swapchain_view_format != current_swapchain_view_format || + if (swapchain_view_format != current_swapchain_view_format || layout.width != frame->width || layout.height != frame->height) { resource_update_required = true; presentation_recreate_required = true; + swapchain_view_format = current_swapchain_view_format; } - // If we have a pending resource update, perform it if (resource_update_required) { - // Wait for idle to ensure no resources are in use WaitIdle(); - - // Update window adapt pass SetWindowAdaptPass(); - // Update frame format if needed if (presentation_recreate_required) { present_manager.RecreateFrame(frame, layout.width, layout.height, swapchain_view_format, window_adapt->GetRenderPass()); } + + image_index = 0; } - // Add additional layers if needed const VkExtent2D window_size{ .width = layout.screen.GetWidth(), .height = layout.screen.GetHeight(), }; - while (layers.size() < framebuffers.size()) { - layers.emplace_back(device, memory_allocator, scheduler, device_memory, image_count, - window_size, window_adapt->GetDescriptorSetLayout(), filters); + if (layers.size() != framebuffers.size()) { + layers.clear(); + for (size_t i = 0; i < framebuffers.size(); ++i) { + layers.emplace_back(device, memory_allocator, scheduler, device_memory, image_count, + window_size, window_adapt->GetDescriptorSetLayout(), filters); + } } - // Perform the draw window_adapt->Draw(rasterizer, scheduler, image_index, layers, framebuffers, layout, frame); - // Advance to next image if (++image_index >= image_count) { image_index = 0; } @@ -146,16 +139,20 @@ void BlitScreen::DrawToFrame(RasterizerVulkan& rasterizer, Frame* frame, vk::Framebuffer BlitScreen::CreateFramebuffer(const Layout::FramebufferLayout& layout, VkImageView image_view, VkFormat current_view_format) { - const bool format_updated = - std::exchange(swapchain_view_format, current_view_format) != current_view_format; + bool format_updated = swapchain_view_format != current_view_format; + swapchain_view_format = current_view_format; + if (!window_adapt || scaling_filter != filters.get_scaling_filter() || format_updated) { WaitIdle(); SetWindowAdaptPass(); + image_index = 0; } + const VkExtent2D extent{ .width = layout.width, .height = layout.height, }; + return CreateFramebuffer(image_view, extent, window_adapt->GetRenderPass()); } diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp index 13ecfd20a6..b535097b36 100644 --- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp +++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp @@ -121,10 +121,8 @@ VkResult MasterSemaphore::SubmitQueue(vk::CommandBuffer& cmdbuf, vk::CommandBuff } } -static constexpr std::array wait_stage_masks{ - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, -}; +static constexpr VkPipelineStageFlags wait_stage_mask = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf, vk::CommandBuffer& upload_cmdbuf, @@ -143,7 +141,7 @@ VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf, const VkSemaphore* p_wait_sems = (num_wait_semaphores > 0) ? &wait_semaphore : nullptr; const VkPipelineStageFlags* p_wait_masks = - (num_wait_semaphores > 0) ? wait_stage_masks.data() : nullptr; + (num_wait_semaphores > 0) ? &wait_stage_mask : nullptr; const VkSemaphore* p_signal_sems = (num_signal_semaphores > 0) ? signal_semaphores.data() : nullptr; const u64 wait_zero = 0; // dummy for binary wait @@ -180,7 +178,7 @@ VkResult MasterSemaphore::SubmitQueueFence(vk::CommandBuffer& cmdbuf, const VkSemaphore* p_wait_sems = (num_wait_semaphores > 0) ? &wait_semaphore : nullptr; const VkPipelineStageFlags* p_wait_masks = - (num_wait_semaphores > 0) ? wait_stage_masks.data() : nullptr; + (num_wait_semaphores > 0) ? &wait_stage_mask : nullptr; const VkSemaphore* p_signal_sems = (num_signal_semaphores > 0) ? &signal_semaphore : nullptr; const std::array cmdbuffers{*upload_cmdbuf, *cmdbuf}; diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index e526d606dc..0a032cdae0 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -270,8 +270,8 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, }; - upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, WRITE_BARRIER); + upload_cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, WRITE_BARRIER); upload_cmdbuf.End(); cmdbuf.End(); @@ -372,15 +372,9 @@ void Scheduler::EndRenderPass() }; } cmdbuf.EndRenderPass(); - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, - VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, - 0, - nullptr, - nullptr, - vk::Span(barriers.data(), num_images) // Batched image barriers - ); + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, nullptr, nullptr, vk::Span(barriers.data(), num_images)); }); state.renderpass = nullptr; diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 348e49fb6d..d51564dcb3 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -2500,7 +2500,7 @@ void TextureCacheRuntime::TransitionImageLayout(Image& image) { }; scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([barrier](vk::CommandBuffer cmdbuf) { - cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, barrier); }); } diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 3d98f2cbf7..15f48ca8f4 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -557,20 +557,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } if (is_nvidia) { - const u32 nv_major_version = (properties.properties.driverVersion >> 22) & 0x3ff; const auto arch = GetNvidiaArch(); if (arch >= NvidiaArchitecture::Arch_AmpereOrNewer) { LOG_WARNING(Render_Vulkan, "Ampere and newer have broken float16 math"); features.shader_float16_int8.shaderFloat16 = false; } - if (nv_major_version >= 510) { - LOG_WARNING(Render_Vulkan, - "NVIDIA Drivers >= 510 do not support MSAA->MSAA image blits. " - "MSAA scaling will use 3D helpers. MSAA resolves work normally."); - cant_blit_msaa = true; - } - // Mali/ NVIDIA proprietary drivers: Shader stencil export not supported // Use hardware depth/stencil blits instead when available if (!extensions.shader_stencil_export) {