diff options
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 114 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.h | 10 |
3 files changed, 71 insertions, 55 deletions
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index a8d04dc61..7ced5006b 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -162,7 +162,7 @@ void RendererVulkan::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { | |||
| 162 | if (has_been_recreated) { | 162 | if (has_been_recreated) { |
| 163 | blit_screen.Recreate(); | 163 | blit_screen.Recreate(); |
| 164 | } | 164 | } |
| 165 | const VkSemaphore render_semaphore = blit_screen.Draw(*framebuffer, use_accelerated); | 165 | const VkSemaphore render_semaphore = blit_screen.DrawToSwapchain(*framebuffer, use_accelerated); |
| 166 | scheduler.Flush(render_semaphore); | 166 | scheduler.Flush(render_semaphore); |
| 167 | scheduler.WaitWorker(); | 167 | scheduler.WaitWorker(); |
| 168 | swapchain.Present(render_semaphore); | 168 | swapchain.Present(render_semaphore); |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 516f428e7..f1e8082d2 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -130,7 +130,10 @@ void VKBlitScreen::Recreate() { | |||
| 130 | CreateDynamicResources(); | 130 | CreateDynamicResources(); |
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, bool use_accelerated) { | 133 | VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, |
| 134 | const VkFramebuffer& host_framebuffer, | ||
| 135 | const Layout::FramebufferLayout layout, VkExtent2D render_area, | ||
| 136 | bool use_accelerated) { | ||
| 134 | RefreshResources(framebuffer); | 137 | RefreshResources(framebuffer); |
| 135 | 138 | ||
| 136 | // Finish any pending renderpass | 139 | // Finish any pending renderpass |
| @@ -145,8 +148,8 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, bool | |||
| 145 | use_accelerated ? screen_info.image_view : *raw_image_views[image_index]); | 148 | use_accelerated ? screen_info.image_view : *raw_image_views[image_index]); |
| 146 | 149 | ||
| 147 | BufferData data; | 150 | BufferData data; |
| 148 | SetUniformData(data, framebuffer); | 151 | SetUniformData(data, layout); |
| 149 | SetVertexData(data, framebuffer); | 152 | SetVertexData(data, framebuffer, layout); |
| 150 | 153 | ||
| 151 | const std::span<u8> mapped_span = buffer_commit.Map(); | 154 | const std::span<u8> mapped_span = buffer_commit.Map(); |
| 152 | std::memcpy(mapped_span.data(), &data, sizeof(data)); | 155 | std::memcpy(mapped_span.data(), &data, sizeof(data)); |
| @@ -220,52 +223,61 @@ VkSemaphore VKBlitScreen::Draw(const Tegra::FramebufferConfig& framebuffer, bool | |||
| 220 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, write_barrier); | 223 | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0, write_barrier); |
| 221 | }); | 224 | }); |
| 222 | } | 225 | } |
| 223 | scheduler.Record([this, image_index, size = swapchain.GetSize()](vk::CommandBuffer cmdbuf) { | 226 | scheduler.Record( |
| 224 | const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f; | 227 | [this, host_framebuffer, image_index, size = render_area](vk::CommandBuffer cmdbuf) { |
| 225 | const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f; | 228 | const f32 bg_red = Settings::values.bg_red.GetValue() / 255.0f; |
| 226 | const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f; | 229 | const f32 bg_green = Settings::values.bg_green.GetValue() / 255.0f; |
| 227 | const VkClearValue clear_color{ | 230 | const f32 bg_blue = Settings::values.bg_blue.GetValue() / 255.0f; |
| 228 | .color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}}, | 231 | const VkClearValue clear_color{ |
| 229 | }; | 232 | .color = {.float32 = {bg_red, bg_green, bg_blue, 1.0f}}, |
| 230 | const VkRenderPassBeginInfo renderpass_bi{ | 233 | }; |
| 231 | .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, | 234 | const VkRenderPassBeginInfo renderpass_bi{ |
| 232 | .pNext = nullptr, | 235 | .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, |
| 233 | .renderPass = *renderpass, | 236 | .pNext = nullptr, |
| 234 | .framebuffer = *framebuffers[image_index], | 237 | .renderPass = *renderpass, |
| 235 | .renderArea = | 238 | .framebuffer = host_framebuffer, |
| 236 | { | 239 | .renderArea = |
| 237 | .offset = {0, 0}, | 240 | { |
| 238 | .extent = size, | 241 | .offset = {0, 0}, |
| 239 | }, | 242 | .extent = size, |
| 240 | .clearValueCount = 1, | 243 | }, |
| 241 | .pClearValues = &clear_color, | 244 | .clearValueCount = 1, |
| 242 | }; | 245 | .pClearValues = &clear_color, |
| 243 | const VkViewport viewport{ | 246 | }; |
| 244 | .x = 0.0f, | 247 | const VkViewport viewport{ |
| 245 | .y = 0.0f, | 248 | .x = 0.0f, |
| 246 | .width = static_cast<float>(size.width), | 249 | .y = 0.0f, |
| 247 | .height = static_cast<float>(size.height), | 250 | .width = static_cast<float>(size.width), |
| 248 | .minDepth = 0.0f, | 251 | .height = static_cast<float>(size.height), |
| 249 | .maxDepth = 1.0f, | 252 | .minDepth = 0.0f, |
| 250 | }; | 253 | .maxDepth = 1.0f, |
| 251 | const VkRect2D scissor{ | 254 | }; |
| 252 | .offset = {0, 0}, | 255 | const VkRect2D scissor{ |
| 253 | .extent = size, | 256 | .offset = {0, 0}, |
| 254 | }; | 257 | .extent = size, |
| 255 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); | 258 | }; |
| 256 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); | 259 | cmdbuf.BeginRenderPass(renderpass_bi, VK_SUBPASS_CONTENTS_INLINE); |
| 257 | cmdbuf.SetViewport(0, viewport); | 260 | cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); |
| 258 | cmdbuf.SetScissor(0, scissor); | 261 | cmdbuf.SetViewport(0, viewport); |
| 259 | 262 | cmdbuf.SetScissor(0, scissor); | |
| 260 | cmdbuf.BindVertexBuffer(0, *buffer, offsetof(BufferData, vertices)); | 263 | |
| 261 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_layout, 0, | 264 | cmdbuf.BindVertexBuffer(0, *buffer, offsetof(BufferData, vertices)); |
| 262 | descriptor_sets[image_index], {}); | 265 | cmdbuf.BindDescriptorSets(VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline_layout, 0, |
| 263 | cmdbuf.Draw(4, 1, 0, 0); | 266 | descriptor_sets[image_index], {}); |
| 264 | cmdbuf.EndRenderPass(); | 267 | cmdbuf.Draw(4, 1, 0, 0); |
| 265 | }); | 268 | cmdbuf.EndRenderPass(); |
| 269 | }); | ||
| 266 | return *semaphores[image_index]; | 270 | return *semaphores[image_index]; |
| 267 | } | 271 | } |
| 268 | 272 | ||
| 273 | VkSemaphore VKBlitScreen::DrawToSwapchain(const Tegra::FramebufferConfig& framebuffer, | ||
| 274 | bool use_accelerated) { | ||
| 275 | const std::size_t image_index = swapchain.GetImageIndex(); | ||
| 276 | const VkExtent2D render_area = swapchain.GetSize(); | ||
| 277 | const Layout::FramebufferLayout layout = render_window.GetFramebufferLayout(); | ||
| 278 | return Draw(framebuffer, *framebuffers[image_index], layout, render_area, use_accelerated); | ||
| 279 | } | ||
| 280 | |||
| 269 | void VKBlitScreen::CreateStaticResources() { | 281 | void VKBlitScreen::CreateStaticResources() { |
| 270 | CreateShaders(); | 282 | CreateShaders(); |
| 271 | CreateSemaphores(); | 283 | CreateSemaphores(); |
| @@ -752,15 +764,13 @@ void VKBlitScreen::UpdateDescriptorSet(std::size_t image_index, VkImageView imag | |||
| 752 | device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {}); | 764 | device.GetLogical().UpdateDescriptorSets(std::array{ubo_write, sampler_write}, {}); |
| 753 | } | 765 | } |
| 754 | 766 | ||
| 755 | void VKBlitScreen::SetUniformData(BufferData& data, | 767 | void VKBlitScreen::SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const { |
| 756 | const Tegra::FramebufferConfig& framebuffer) const { | ||
| 757 | const auto& layout = render_window.GetFramebufferLayout(); | ||
| 758 | data.uniform.modelview_matrix = | 768 | data.uniform.modelview_matrix = |
| 759 | MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height)); | 769 | MakeOrthographicMatrix(static_cast<f32>(layout.width), static_cast<f32>(layout.height)); |
| 760 | } | 770 | } |
| 761 | 771 | ||
| 762 | void VKBlitScreen::SetVertexData(BufferData& data, | 772 | void VKBlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, |
| 763 | const Tegra::FramebufferConfig& framebuffer) const { | 773 | const Layout::FramebufferLayout layout) const { |
| 764 | const auto& framebuffer_transform_flags = framebuffer.transform_flags; | 774 | const auto& framebuffer_transform_flags = framebuffer.transform_flags; |
| 765 | const auto& framebuffer_crop_rect = framebuffer.crop_rect; | 775 | const auto& framebuffer_crop_rect = framebuffer.crop_rect; |
| 766 | 776 | ||
| @@ -798,7 +808,7 @@ void VKBlitScreen::SetVertexData(BufferData& data, | |||
| 798 | static_cast<f32>(screen_info.height); | 808 | static_cast<f32>(screen_info.height); |
| 799 | } | 809 | } |
| 800 | 810 | ||
| 801 | const auto& screen = render_window.GetFramebufferLayout().screen; | 811 | const auto& screen = layout.screen; |
| 802 | const auto x = static_cast<f32>(screen.left); | 812 | const auto x = static_cast<f32>(screen.left); |
| 803 | const auto y = static_cast<f32>(screen.top); | 813 | const auto y = static_cast<f32>(screen.top); |
| 804 | const auto w = static_cast<f32>(screen.GetWidth()); | 814 | const auto w = static_cast<f32>(screen.GetWidth()); |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.h b/src/video_core/renderer_vulkan/vk_blit_screen.h index 5e3177685..44b93b4af 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.h +++ b/src/video_core/renderer_vulkan/vk_blit_screen.h | |||
| @@ -56,8 +56,13 @@ public: | |||
| 56 | void Recreate(); | 56 | void Recreate(); |
| 57 | 57 | ||
| 58 | [[nodiscard]] VkSemaphore Draw(const Tegra::FramebufferConfig& framebuffer, | 58 | [[nodiscard]] VkSemaphore Draw(const Tegra::FramebufferConfig& framebuffer, |
| 59 | const VkFramebuffer& host_framebuffer, | ||
| 60 | const Layout::FramebufferLayout layout, VkExtent2D render_area, | ||
| 59 | bool use_accelerated); | 61 | bool use_accelerated); |
| 60 | 62 | ||
| 63 | [[nodiscard]] VkSemaphore DrawToSwapchain(const Tegra::FramebufferConfig& framebuffer, | ||
| 64 | bool use_accelerated); | ||
| 65 | |||
| 61 | private: | 66 | private: |
| 62 | struct BufferData; | 67 | struct BufferData; |
| 63 | 68 | ||
| @@ -81,8 +86,9 @@ private: | |||
| 81 | void CreateRawImages(const Tegra::FramebufferConfig& framebuffer); | 86 | void CreateRawImages(const Tegra::FramebufferConfig& framebuffer); |
| 82 | 87 | ||
| 83 | void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const; | 88 | void UpdateDescriptorSet(std::size_t image_index, VkImageView image_view) const; |
| 84 | void SetUniformData(BufferData& data, const Tegra::FramebufferConfig& framebuffer) const; | 89 | void SetUniformData(BufferData& data, const Layout::FramebufferLayout layout) const; |
| 85 | void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer) const; | 90 | void SetVertexData(BufferData& data, const Tegra::FramebufferConfig& framebuffer, |
| 91 | const Layout::FramebufferLayout layout) const; | ||
| 86 | 92 | ||
| 87 | u64 CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const; | 93 | u64 CalculateBufferSize(const Tegra::FramebufferConfig& framebuffer) const; |
| 88 | u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, | 94 | u64 GetRawImageOffset(const Tegra::FramebufferConfig& framebuffer, |