From 73d973dad6e2e1ad1c5abdd545aa3876fa64b9d9 Mon Sep 17 00:00:00 2001 From: MrPurple666 Date: Sun, 13 Apr 2025 17:19:59 -0300 Subject: [PATCH] Based on CamilleLaVey code, fix MSAA and Depth Stencil --- .../renderer_vulkan/renderer_vulkan.cpp | 73 +++++++++++++++++++ .../renderer_vulkan/renderer_vulkan.h | 3 + 2 files changed, 76 insertions(+) diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 041fb9e054..2ff38226cb 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp @@ -517,6 +517,79 @@ void RendererVulkan::RenderAppletCaptureLayer( CaptureFormat); } +void RendererVulkan::FixMSAADepthStencil(VkCommandBuffer cmd_buffer, const Framebuffer& framebuffer) { + if (framebuffer.Samples() == VK_SAMPLE_COUNT_1_BIT) { + return; + } + + // Use the scheduler's command buffer wrapper + scheduler.Record([&](vk::CommandBuffer cmdbuf) { + // Find the depth/stencil image in the framebuffer's attachments + for (u32 i = 0; i < framebuffer.NumImages(); ++i) { + if (framebuffer.HasAspectDepthBit() && (framebuffer.ImageRanges()[i].aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)) { + VkImageMemoryBarrier barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, + .dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + .newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = framebuffer.Images()[i], + .subresourceRange = framebuffer.ImageRanges()[i] + }; + + cmdbuf.PipelineBarrier(VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, + VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, nullptr, nullptr, barrier); + break; + } + } + }); +} + +void RendererVulkan::ResolveMSAA(VkCommandBuffer cmd_buffer, const Framebuffer& framebuffer) { + if (framebuffer.Samples() == VK_SAMPLE_COUNT_1_BIT) { + return; + } + + // Use the scheduler's command buffer wrapper + scheduler.Record([&](vk::CommandBuffer cmdbuf) { + // Find color attachments + for (u32 i = 0; i < framebuffer.NumColorBuffers(); ++i) { + if (framebuffer.HasAspectColorBit(i)) { + VkImageResolve resolve_region{ + .srcSubresource{ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1, + }, + .srcOffset = {0, 0, 0}, + .dstSubresource{ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .mipLevel = 0, + .baseArrayLayer = 0, + .layerCount = 1, + }, + .dstOffset = {0, 0, 0}, + .extent{ + .width = framebuffer.RenderArea().width, + .height = framebuffer.RenderArea().height, + .depth = 1 + } + }; + + cmdbuf.ResolveImage( + framebuffer.Images()[i], VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + framebuffer.Images()[i], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + resolve_region + ); + } + } + }); +} + bool RendererVulkan::HandleVulkanError(VkResult result, const std::string& operation) { if (result == VK_SUCCESS) { return true; diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index 983bf8c9b4..57e2942873 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h @@ -58,6 +58,9 @@ public: return device.GetDriverName(); } + void FixMSAADepthStencil(VkCommandBuffer cmd_buffer, const Framebuffer& framebuffer); + void ResolveMSAA(VkCommandBuffer cmd_buffer, const Framebuffer& framebuffer); + // Enhanced platform-specific initialization void InitializePlatformSpecific();