diff options
| author | 2023-06-05 21:43:43 -0700 | |
|---|---|---|
| committer | 2023-06-05 21:43:43 -0700 | |
| commit | cb95d7fe1b6d81899fe6b279400da2c991e3132c (patch) | |
| tree | a856ac45b1053009c4c11ee141c49d7faa4c8a19 /src/video_core/renderer_vulkan | |
| parent | Merge pull request #10611 from liamwhite/audio-deadlock (diff) | |
| parent | Merge pull request #10633 from t895/variable-surface-ratio (diff) | |
| download | yuzu-cb95d7fe1b6d81899fe6b279400da2c991e3132c.tar.gz yuzu-cb95d7fe1b6d81899fe6b279400da2c991e3132c.tar.xz yuzu-cb95d7fe1b6d81899fe6b279400da2c991e3132c.zip | |
Merge pull request #10508 from yuzu-emu/lime
Project Lime - yuzu Android Port
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.cpp | 9 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/renderer_vulkan.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_blit_screen.cpp | 54 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_buffer_cache.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 17 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_present_manager.cpp | 52 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_present_manager.h | 15 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_scheduler.cpp | 14 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_swapchain.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_swapchain.h | 4 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_turbo_mode.cpp | 21 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_turbo_mode.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_update_descriptor.h | 2 |
16 files changed, 212 insertions, 32 deletions
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index b75d7220d..9a0b10568 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp | |||
| @@ -347,6 +347,14 @@ VkPrimitiveTopology PrimitiveTopology([[maybe_unused]] const Device& device, | |||
| 347 | 347 | ||
| 348 | VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, | 348 | VkFormat VertexFormat(const Device& device, Maxwell::VertexAttribute::Type type, |
| 349 | Maxwell::VertexAttribute::Size size) { | 349 | Maxwell::VertexAttribute::Size size) { |
| 350 | if (device.MustEmulateScaledFormats()) { | ||
| 351 | if (type == Maxwell::VertexAttribute::Type::SScaled) { | ||
| 352 | type = Maxwell::VertexAttribute::Type::SInt; | ||
| 353 | } else if (type == Maxwell::VertexAttribute::Type::UScaled) { | ||
| 354 | type = Maxwell::VertexAttribute::Type::UInt; | ||
| 355 | } | ||
| 356 | } | ||
| 357 | |||
| 350 | const VkFormat format{([&]() { | 358 | const VkFormat format{([&]() { |
| 351 | switch (type) { | 359 | switch (type) { |
| 352 | case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway: | 360 | case Maxwell::VertexAttribute::Type::UnusedEnumDoNotUseBecauseItWillGoAway: |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 8e31eba34..77128c6e2 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include "common/settings.h" | 16 | #include "common/settings.h" |
| 17 | #include "common/telemetry.h" | 17 | #include "common/telemetry.h" |
| 18 | #include "core/core_timing.h" | 18 | #include "core/core_timing.h" |
| 19 | #include "core/frontend/emu_window.h" | 19 | #include "core/frontend/graphics_context.h" |
| 20 | #include "core/telemetry_session.h" | 20 | #include "core/telemetry_session.h" |
| 21 | #include "video_core/gpu.h" | 21 | #include "video_core/gpu.h" |
| 22 | #include "video_core/renderer_vulkan/renderer_vulkan.h" | 22 | #include "video_core/renderer_vulkan/renderer_vulkan.h" |
| @@ -84,8 +84,8 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, | |||
| 84 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, | 84 | Core::Memory::Memory& cpu_memory_, Tegra::GPU& gpu_, |
| 85 | std::unique_ptr<Core::Frontend::GraphicsContext> context_) try | 85 | std::unique_ptr<Core::Frontend::GraphicsContext> context_) try |
| 86 | : RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_), | 86 | : RendererBase(emu_window, std::move(context_)), telemetry_session(telemetry_session_), |
| 87 | cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary()), | 87 | cpu_memory(cpu_memory_), gpu(gpu_), library(OpenLibrary(context.get())), |
| 88 | instance(CreateInstance(library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, | 88 | instance(CreateInstance(*library, dld, VK_API_VERSION_1_1, render_window.GetWindowInfo().type, |
| 89 | Settings::values.renderer_debug.GetValue())), | 89 | Settings::values.renderer_debug.GetValue())), |
| 90 | debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), | 90 | debug_callback(Settings::values.renderer_debug ? CreateDebugCallback(instance) : nullptr), |
| 91 | surface(CreateSurface(instance, render_window.GetWindowInfo())), | 91 | surface(CreateSurface(instance, render_window.GetWindowInfo())), |
| @@ -93,7 +93,8 @@ RendererVulkan::RendererVulkan(Core::TelemetrySession& telemetry_session_, | |||
| 93 | state_tracker(), scheduler(device, state_tracker), | 93 | state_tracker(), scheduler(device, state_tracker), |
| 94 | swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, | 94 | swapchain(*surface, device, scheduler, render_window.GetFramebufferLayout().width, |
| 95 | render_window.GetFramebufferLayout().height, false), | 95 | render_window.GetFramebufferLayout().height, false), |
| 96 | present_manager(render_window, device, memory_allocator, scheduler, swapchain), | 96 | present_manager(instance, render_window, device, memory_allocator, scheduler, swapchain, |
| 97 | surface), | ||
| 97 | blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, present_manager, | 98 | blit_screen(cpu_memory, render_window, device, memory_allocator, swapchain, present_manager, |
| 98 | scheduler, screen_info), | 99 | scheduler, screen_info), |
| 99 | rasterizer(render_window, gpu, cpu_memory, screen_info, device, memory_allocator, | 100 | rasterizer(render_window, gpu, cpu_memory, screen_info, device, memory_allocator, |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.h b/src/video_core/renderer_vulkan/renderer_vulkan.h index f44367cb2..b2e8cbd1b 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.h +++ b/src/video_core/renderer_vulkan/renderer_vulkan.h | |||
| @@ -54,6 +54,10 @@ public: | |||
| 54 | return device.GetDriverName(); | 54 | return device.GetDriverName(); |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | void NotifySurfaceChanged() override { | ||
| 58 | present_manager.NotifySurfaceChanged(); | ||
| 59 | } | ||
| 60 | |||
| 57 | private: | 61 | private: |
| 58 | void Report() const; | 62 | void Report() const; |
| 59 | 63 | ||
| @@ -63,7 +67,7 @@ private: | |||
| 63 | Core::Memory::Memory& cpu_memory; | 67 | Core::Memory::Memory& cpu_memory; |
| 64 | Tegra::GPU& gpu; | 68 | Tegra::GPU& gpu; |
| 65 | 69 | ||
| 66 | Common::DynamicLibrary library; | 70 | std::shared_ptr<Common::DynamicLibrary> library; |
| 67 | vk::InstanceDispatch dld; | 71 | vk::InstanceDispatch dld; |
| 68 | 72 | ||
| 69 | vk::Instance instance; | 73 | vk::Instance instance; |
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index 1e0fdd3d9..7cdde992b 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp | |||
| @@ -37,6 +37,10 @@ | |||
| 37 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" | 37 | #include "video_core/vulkan_common/vulkan_memory_allocator.h" |
| 38 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 38 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 39 | 39 | ||
| 40 | #ifdef ANDROID | ||
| 41 | extern u32 GetAndroidScreenRotation(); | ||
| 42 | #endif | ||
| 43 | |||
| 40 | namespace Vulkan { | 44 | namespace Vulkan { |
| 41 | 45 | ||
| 42 | namespace { | 46 | namespace { |
| @@ -74,7 +78,48 @@ struct ScreenRectVertex { | |||
| 74 | } | 78 | } |
| 75 | }; | 79 | }; |
| 76 | 80 | ||
| 77 | constexpr std::array<f32, 4 * 4> MakeOrthographicMatrix(f32 width, f32 height) { | 81 | #ifdef ANDROID |
| 82 | |||
| 83 | std::array<f32, 4 * 4> MakeOrthographicMatrix(f32 width, f32 height) { | ||
| 84 | constexpr u32 ROTATION_0 = 0; | ||
| 85 | constexpr u32 ROTATION_90 = 1; | ||
| 86 | constexpr u32 ROTATION_180 = 2; | ||
| 87 | constexpr u32 ROTATION_270 = 3; | ||
| 88 | |||
| 89 | // clang-format off | ||
| 90 | switch (GetAndroidScreenRotation()) { | ||
| 91 | case ROTATION_0: | ||
| 92 | // Desktop | ||
| 93 | return { 2.f / width, 0.f, 0.f, 0.f, | ||
| 94 | 0.f, 2.f / height, 0.f, 0.f, | ||
| 95 | 0.f, 0.f, 1.f, 0.f, | ||
| 96 | -1.f, -1.f, 0.f, 1.f}; | ||
| 97 | case ROTATION_180: | ||
| 98 | // Reverse desktop | ||
| 99 | return {-2.f / width, 0.f, 0.f, 0.f, | ||
| 100 | 0.f, -2.f / height, 0.f, 0.f, | ||
| 101 | 0.f, 0.f, 1.f, 0.f, | ||
| 102 | 1.f, 1.f, 0.f, 1.f}; | ||
| 103 | case ROTATION_270: | ||
| 104 | // Reverse landscape | ||
| 105 | return { 0.f, -2.f / width, 0.f, 0.f, | ||
| 106 | 2.f / height, 0.f, 0.f, 0.f, | ||
| 107 | 0.f, 0.f, 1.f, 0.f, | ||
| 108 | -1.f, 1.f, 0.f, 1.f}; | ||
| 109 | case ROTATION_90: | ||
| 110 | default: | ||
| 111 | // Landscape | ||
| 112 | return { 0.f, 2.f / width, 0.f, 0.f, | ||
| 113 | -2.f / height, 0.f, 0.f, 0.f, | ||
| 114 | 0.f, 0.f, 1.f, 0.f, | ||
| 115 | 1.f, -1.f, 0.f, 1.f}; | ||
| 116 | } | ||
| 117 | // clang-format on | ||
| 118 | } | ||
| 119 | |||
| 120 | #else | ||
| 121 | |||
| 122 | std::array<f32, 4 * 4> MakeOrthographicMatrix(f32 width, f32 height) { | ||
| 78 | // clang-format off | 123 | // clang-format off |
| 79 | return { 2.f / width, 0.f, 0.f, 0.f, | 124 | return { 2.f / width, 0.f, 0.f, 0.f, |
| 80 | 0.f, 2.f / height, 0.f, 0.f, | 125 | 0.f, 2.f / height, 0.f, 0.f, |
| @@ -83,6 +128,8 @@ constexpr std::array<f32, 4 * 4> MakeOrthographicMatrix(f32 width, f32 height) { | |||
| 83 | // clang-format on | 128 | // clang-format on |
| 84 | } | 129 | } |
| 85 | 130 | ||
| 131 | #endif | ||
| 132 | |||
| 86 | u32 GetBytesPerPixel(const Tegra::FramebufferConfig& framebuffer) { | 133 | u32 GetBytesPerPixel(const Tegra::FramebufferConfig& framebuffer) { |
| 87 | using namespace VideoCore::Surface; | 134 | using namespace VideoCore::Surface; |
| 88 | return BytesPerBlock(PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)); | 135 | return BytesPerBlock(PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)); |
| @@ -441,7 +488,12 @@ void BlitScreen::DrawToSwapchain(Frame* frame, const Tegra::FramebufferConfig& f | |||
| 441 | if (const std::size_t swapchain_images = swapchain.GetImageCount(); | 488 | if (const std::size_t swapchain_images = swapchain.GetImageCount(); |
| 442 | swapchain_images != image_count || current_srgb != is_srgb) { | 489 | swapchain_images != image_count || current_srgb != is_srgb) { |
| 443 | current_srgb = is_srgb; | 490 | current_srgb = is_srgb; |
| 491 | #ifdef ANDROID | ||
| 492 | // Android is already ordered the same as Switch. | ||
| 493 | image_view_format = current_srgb ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM; | ||
| 494 | #else | ||
| 444 | image_view_format = current_srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; | 495 | image_view_format = current_srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; |
| 496 | #endif | ||
| 445 | image_count = swapchain_images; | 497 | image_count = swapchain_images; |
| 446 | Recreate(); | 498 | Recreate(); |
| 447 | } | 499 | } |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp index 9627eb129..daa128399 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp | |||
| @@ -303,9 +303,13 @@ BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& m | |||
| 303 | DescriptorPool& descriptor_pool) | 303 | DescriptorPool& descriptor_pool) |
| 304 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, | 304 | : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, |
| 305 | staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_}, | 305 | staging_pool{staging_pool_}, guest_descriptor_queue{guest_descriptor_queue_}, |
| 306 | uint8_pass(device, scheduler, descriptor_pool, staging_pool, compute_pass_descriptor_queue), | ||
| 307 | quad_index_pass(device, scheduler, descriptor_pool, staging_pool, | 306 | quad_index_pass(device, scheduler, descriptor_pool, staging_pool, |
| 308 | compute_pass_descriptor_queue) { | 307 | compute_pass_descriptor_queue) { |
| 308 | if (device.GetDriverID() != VK_DRIVER_ID_QUALCOMM_PROPRIETARY) { | ||
| 309 | // TODO: FixMe: Uint8Pass compute shader does not build on some Qualcomm drivers. | ||
| 310 | uint8_pass = std::make_unique<Uint8Pass>(device, scheduler, descriptor_pool, staging_pool, | ||
| 311 | compute_pass_descriptor_queue); | ||
| 312 | } | ||
| 309 | quad_array_index_buffer = std::make_shared<QuadArrayIndexBuffer>(device_, memory_allocator_, | 313 | quad_array_index_buffer = std::make_shared<QuadArrayIndexBuffer>(device_, memory_allocator_, |
| 310 | scheduler_, staging_pool_); | 314 | scheduler_, staging_pool_); |
| 311 | quad_strip_index_buffer = std::make_shared<QuadStripIndexBuffer>(device_, memory_allocator_, | 315 | quad_strip_index_buffer = std::make_shared<QuadStripIndexBuffer>(device_, memory_allocator_, |
| @@ -442,7 +446,9 @@ void BufferCacheRuntime::BindIndexBuffer(PrimitiveTopology topology, IndexFormat | |||
| 442 | topology == PrimitiveTopology::QuadStrip); | 446 | topology == PrimitiveTopology::QuadStrip); |
| 443 | } else if (vk_index_type == VK_INDEX_TYPE_UINT8_EXT && !device.IsExtIndexTypeUint8Supported()) { | 447 | } else if (vk_index_type == VK_INDEX_TYPE_UINT8_EXT && !device.IsExtIndexTypeUint8Supported()) { |
| 444 | vk_index_type = VK_INDEX_TYPE_UINT16; | 448 | vk_index_type = VK_INDEX_TYPE_UINT16; |
| 445 | std::tie(vk_buffer, vk_offset) = uint8_pass.Assemble(num_indices, buffer, offset); | 449 | if (uint8_pass) { |
| 450 | std::tie(vk_buffer, vk_offset) = uint8_pass->Assemble(num_indices, buffer, offset); | ||
| 451 | } | ||
| 446 | } | 452 | } |
| 447 | if (vk_buffer == VK_NULL_HANDLE) { | 453 | if (vk_buffer == VK_NULL_HANDLE) { |
| 448 | // Vulkan doesn't support null index buffers. Replace it with our own null buffer. | 454 | // Vulkan doesn't support null index buffers. Replace it with our own null buffer. |
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h index 5e9602905..794dd0758 100644 --- a/src/video_core/renderer_vulkan/vk_buffer_cache.h +++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h | |||
| @@ -139,7 +139,7 @@ private: | |||
| 139 | vk::Buffer null_buffer; | 139 | vk::Buffer null_buffer; |
| 140 | MemoryCommit null_buffer_commit; | 140 | MemoryCommit null_buffer_commit; |
| 141 | 141 | ||
| 142 | Uint8Pass uint8_pass; | 142 | std::unique_ptr<Uint8Pass> uint8_pass; |
| 143 | QuadIndexedPass quad_index_pass; | 143 | QuadIndexedPass quad_index_pass; |
| 144 | }; | 144 | }; |
| 145 | 145 | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 66dfe5733..9482e91b0 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -114,14 +114,16 @@ Shader::AttributeType CastAttributeType(const FixedPipelineState::VertexAttribut | |||
| 114 | return Shader::AttributeType::Disabled; | 114 | return Shader::AttributeType::Disabled; |
| 115 | case Maxwell::VertexAttribute::Type::SNorm: | 115 | case Maxwell::VertexAttribute::Type::SNorm: |
| 116 | case Maxwell::VertexAttribute::Type::UNorm: | 116 | case Maxwell::VertexAttribute::Type::UNorm: |
| 117 | case Maxwell::VertexAttribute::Type::UScaled: | ||
| 118 | case Maxwell::VertexAttribute::Type::SScaled: | ||
| 119 | case Maxwell::VertexAttribute::Type::Float: | 117 | case Maxwell::VertexAttribute::Type::Float: |
| 120 | return Shader::AttributeType::Float; | 118 | return Shader::AttributeType::Float; |
| 121 | case Maxwell::VertexAttribute::Type::SInt: | 119 | case Maxwell::VertexAttribute::Type::SInt: |
| 122 | return Shader::AttributeType::SignedInt; | 120 | return Shader::AttributeType::SignedInt; |
| 123 | case Maxwell::VertexAttribute::Type::UInt: | 121 | case Maxwell::VertexAttribute::Type::UInt: |
| 124 | return Shader::AttributeType::UnsignedInt; | 122 | return Shader::AttributeType::UnsignedInt; |
| 123 | case Maxwell::VertexAttribute::Type::UScaled: | ||
| 124 | return Shader::AttributeType::UnsignedScaled; | ||
| 125 | case Maxwell::VertexAttribute::Type::SScaled: | ||
| 126 | return Shader::AttributeType::SignedScaled; | ||
| 125 | } | 127 | } |
| 126 | return Shader::AttributeType::Float; | 128 | return Shader::AttributeType::Float; |
| 127 | } | 129 | } |
| @@ -286,14 +288,17 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device | |||
| 286 | texture_cache{texture_cache_}, shader_notify{shader_notify_}, | 288 | texture_cache{texture_cache_}, shader_notify{shader_notify_}, |
| 287 | use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()}, | 289 | use_asynchronous_shaders{Settings::values.use_asynchronous_shaders.GetValue()}, |
| 288 | use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()}, | 290 | use_vulkan_pipeline_cache{Settings::values.use_vulkan_driver_pipeline_cache.GetValue()}, |
| 289 | workers(std::max(std::thread::hardware_concurrency(), 2U) - 1, "VkPipelineBuilder"), | 291 | workers(device.GetDriverID() == VK_DRIVER_ID_QUALCOMM_PROPRIETARY |
| 292 | ? 1 | ||
| 293 | : (std::max(std::thread::hardware_concurrency(), 2U) - 1), | ||
| 294 | "VkPipelineBuilder"), | ||
| 290 | serialization_thread(1, "VkPipelineSerialization") { | 295 | serialization_thread(1, "VkPipelineSerialization") { |
| 291 | const auto& float_control{device.FloatControlProperties()}; | 296 | const auto& float_control{device.FloatControlProperties()}; |
| 292 | const VkDriverId driver_id{device.GetDriverID()}; | 297 | const VkDriverId driver_id{device.GetDriverID()}; |
| 293 | profile = Shader::Profile{ | 298 | profile = Shader::Profile{ |
| 294 | .supported_spirv = device.SupportedSpirvVersion(), | 299 | .supported_spirv = device.SupportedSpirvVersion(), |
| 295 | .unified_descriptor_binding = true, | 300 | .unified_descriptor_binding = true, |
| 296 | .support_descriptor_aliasing = true, | 301 | .support_descriptor_aliasing = device.IsDescriptorAliasingSupported(), |
| 297 | .support_int8 = device.IsInt8Supported(), | 302 | .support_int8 = device.IsInt8Supported(), |
| 298 | .support_int16 = device.IsShaderInt16Supported(), | 303 | .support_int16 = device.IsShaderInt16Supported(), |
| 299 | .support_int64 = device.IsShaderInt64Supported(), | 304 | .support_int64 = device.IsShaderInt64Supported(), |
| @@ -324,6 +329,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device | |||
| 324 | .support_derivative_control = true, | 329 | .support_derivative_control = true, |
| 325 | .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), | 330 | .support_geometry_shader_passthrough = device.IsNvGeometryShaderPassthroughSupported(), |
| 326 | .support_native_ndc = device.IsExtDepthClipControlSupported(), | 331 | .support_native_ndc = device.IsExtDepthClipControlSupported(), |
| 332 | .support_scaled_attributes = !device.MustEmulateScaledFormats(), | ||
| 327 | 333 | ||
| 328 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), | 334 | .warp_size_potentially_larger_than_guest = device.IsWarpSizePotentiallyBiggerThanGuest(), |
| 329 | 335 | ||
| @@ -341,7 +347,8 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, const Device& device | |||
| 341 | .has_broken_signed_operations = false, | 347 | .has_broken_signed_operations = false, |
| 342 | .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY, | 348 | .has_broken_fp16_float_controls = driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY, |
| 343 | .ignore_nan_fp_comparisons = false, | 349 | .ignore_nan_fp_comparisons = false, |
| 344 | }; | 350 | .has_broken_spirv_subgroup_mask_vector_extract_dynamic = |
| 351 | driver_id == VK_DRIVER_ID_QUALCOMM_PROPRIETARY}; | ||
| 345 | host_info = Shader::HostTranslateInfo{ | 352 | host_info = Shader::HostTranslateInfo{ |
| 346 | .support_float16 = device.IsFloat16Supported(), | 353 | .support_float16 = device.IsFloat16Supported(), |
| 347 | .support_int64 = device.IsShaderInt64Supported(), | 354 | .support_int64 = device.IsShaderInt64Supported(), |
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index c49583013..10ace0420 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp | |||
| @@ -4,10 +4,12 @@ | |||
| 4 | #include "common/microprofile.h" | 4 | #include "common/microprofile.h" |
| 5 | #include "common/settings.h" | 5 | #include "common/settings.h" |
| 6 | #include "common/thread.h" | 6 | #include "common/thread.h" |
| 7 | #include "core/frontend/emu_window.h" | ||
| 7 | #include "video_core/renderer_vulkan/vk_present_manager.h" | 8 | #include "video_core/renderer_vulkan/vk_present_manager.h" |
| 8 | #include "video_core/renderer_vulkan/vk_scheduler.h" | 9 | #include "video_core/renderer_vulkan/vk_scheduler.h" |
| 9 | #include "video_core/renderer_vulkan/vk_swapchain.h" | 10 | #include "video_core/renderer_vulkan/vk_swapchain.h" |
| 10 | #include "video_core/vulkan_common/vulkan_device.h" | 11 | #include "video_core/vulkan_common/vulkan_device.h" |
| 12 | #include "video_core/vulkan_common/vulkan_surface.h" | ||
| 11 | 13 | ||
| 12 | namespace Vulkan { | 14 | namespace Vulkan { |
| 13 | 15 | ||
| @@ -92,14 +94,17 @@ bool CanBlitToSwapchain(const vk::PhysicalDevice& physical_device, VkFormat form | |||
| 92 | 94 | ||
| 93 | } // Anonymous namespace | 95 | } // Anonymous namespace |
| 94 | 96 | ||
| 95 | PresentManager::PresentManager(Core::Frontend::EmuWindow& render_window_, const Device& device_, | 97 | PresentManager::PresentManager(const vk::Instance& instance_, |
| 98 | Core::Frontend::EmuWindow& render_window_, const Device& device_, | ||
| 96 | MemoryAllocator& memory_allocator_, Scheduler& scheduler_, | 99 | MemoryAllocator& memory_allocator_, Scheduler& scheduler_, |
| 97 | Swapchain& swapchain_) | 100 | Swapchain& swapchain_, vk::SurfaceKHR& surface_) |
| 98 | : render_window{render_window_}, device{device_}, | 101 | : instance{instance_}, render_window{render_window_}, device{device_}, |
| 99 | memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_}, | 102 | memory_allocator{memory_allocator_}, scheduler{scheduler_}, swapchain{swapchain_}, |
| 100 | blit_supported{CanBlitToSwapchain(device.GetPhysical(), swapchain.GetImageViewFormat())}, | 103 | surface{surface_}, blit_supported{CanBlitToSwapchain(device.GetPhysical(), |
| 104 | swapchain.GetImageViewFormat())}, | ||
| 101 | use_present_thread{Settings::values.async_presentation.GetValue()}, | 105 | use_present_thread{Settings::values.async_presentation.GetValue()}, |
| 102 | image_count{swapchain.GetImageCount()} { | 106 | image_count{swapchain.GetImageCount()}, last_render_surface{ |
| 107 | render_window_.GetWindowInfo().render_surface} { | ||
| 103 | 108 | ||
| 104 | auto& dld = device.GetLogical(); | 109 | auto& dld = device.GetLogical(); |
| 105 | cmdpool = dld.CreateCommandPool({ | 110 | cmdpool = dld.CreateCommandPool({ |
| @@ -286,14 +291,45 @@ void PresentManager::PresentThread(std::stop_token token) { | |||
| 286 | } | 291 | } |
| 287 | } | 292 | } |
| 288 | 293 | ||
| 294 | void PresentManager::NotifySurfaceChanged() { | ||
| 295 | #ifdef ANDROID | ||
| 296 | std::scoped_lock lock{recreate_surface_mutex}; | ||
| 297 | recreate_surface_cv.notify_one(); | ||
| 298 | #endif | ||
| 299 | } | ||
| 300 | |||
| 289 | void PresentManager::CopyToSwapchain(Frame* frame) { | 301 | void PresentManager::CopyToSwapchain(Frame* frame) { |
| 290 | MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); | 302 | MICROPROFILE_SCOPE(Vulkan_CopyToSwapchain); |
| 291 | 303 | ||
| 292 | const auto recreate_swapchain = [&] { | 304 | const auto recreate_swapchain = [&] { |
| 293 | swapchain.Create(frame->width, frame->height, frame->is_srgb); | 305 | swapchain.Create(*surface, frame->width, frame->height, frame->is_srgb); |
| 294 | image_count = swapchain.GetImageCount(); | 306 | image_count = swapchain.GetImageCount(); |
| 295 | }; | 307 | }; |
| 296 | 308 | ||
| 309 | #ifdef ANDROID | ||
| 310 | std::unique_lock lock{recreate_surface_mutex}; | ||
| 311 | |||
| 312 | const auto needs_recreation = [&] { | ||
| 313 | if (last_render_surface != render_window.GetWindowInfo().render_surface) { | ||
| 314 | return true; | ||
| 315 | } | ||
| 316 | if (swapchain.NeedsRecreation(frame->is_srgb)) { | ||
| 317 | return true; | ||
| 318 | } | ||
| 319 | return false; | ||
| 320 | }; | ||
| 321 | |||
| 322 | recreate_surface_cv.wait_for(lock, std::chrono::milliseconds(400), | ||
| 323 | [&]() { return !needs_recreation(); }); | ||
| 324 | |||
| 325 | // If the frontend recreated the surface, recreate the renderer surface and swapchain. | ||
| 326 | if (last_render_surface != render_window.GetWindowInfo().render_surface) { | ||
| 327 | last_render_surface = render_window.GetWindowInfo().render_surface; | ||
| 328 | surface = CreateSurface(instance, render_window.GetWindowInfo()); | ||
| 329 | recreate_swapchain(); | ||
| 330 | } | ||
| 331 | #endif | ||
| 332 | |||
| 297 | // If the size or colorspace of the incoming frames has changed, recreate the swapchain | 333 | // If the size or colorspace of the incoming frames has changed, recreate the swapchain |
| 298 | // to account for that. | 334 | // to account for that. |
| 299 | const bool srgb_changed = swapchain.NeedsRecreation(frame->is_srgb); | 335 | const bool srgb_changed = swapchain.NeedsRecreation(frame->is_srgb); |
| @@ -436,7 +472,7 @@ void PresentManager::CopyToSwapchain(Frame* frame) { | |||
| 436 | 472 | ||
| 437 | // Submit the image copy/blit to the swapchain | 473 | // Submit the image copy/blit to the swapchain |
| 438 | { | 474 | { |
| 439 | std::scoped_lock lock{scheduler.submit_mutex}; | 475 | std::scoped_lock submit_lock{scheduler.submit_mutex}; |
| 440 | switch (const VkResult result = | 476 | switch (const VkResult result = |
| 441 | device.GetGraphicsQueue().Submit(submit_info, *frame->present_done)) { | 477 | device.GetGraphicsQueue().Submit(submit_info, *frame->present_done)) { |
| 442 | case VK_SUCCESS: | 478 | case VK_SUCCESS: |
| @@ -454,4 +490,4 @@ void PresentManager::CopyToSwapchain(Frame* frame) { | |||
| 454 | swapchain.Present(render_semaphore); | 490 | swapchain.Present(render_semaphore); |
| 455 | } | 491 | } |
| 456 | 492 | ||
| 457 | } // namespace Vulkan | 493 | } // namespace Vulkan \ No newline at end of file |
diff --git a/src/video_core/renderer_vulkan/vk_present_manager.h b/src/video_core/renderer_vulkan/vk_present_manager.h index 420a775e2..4ac2e2395 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.h +++ b/src/video_core/renderer_vulkan/vk_present_manager.h | |||
| @@ -37,8 +37,9 @@ struct Frame { | |||
| 37 | 37 | ||
| 38 | class PresentManager { | 38 | class PresentManager { |
| 39 | public: | 39 | public: |
| 40 | PresentManager(Core::Frontend::EmuWindow& render_window, const Device& device, | 40 | PresentManager(const vk::Instance& instance, Core::Frontend::EmuWindow& render_window, |
| 41 | MemoryAllocator& memory_allocator, Scheduler& scheduler, Swapchain& swapchain); | 41 | const Device& device, MemoryAllocator& memory_allocator, Scheduler& scheduler, |
| 42 | Swapchain& swapchain, vk::SurfaceKHR& surface); | ||
| 42 | ~PresentManager(); | 43 | ~PresentManager(); |
| 43 | 44 | ||
| 44 | /// Returns the last used presentation frame | 45 | /// Returns the last used presentation frame |
| @@ -54,30 +55,38 @@ public: | |||
| 54 | /// Waits for the present thread to finish presenting all queued frames. | 55 | /// Waits for the present thread to finish presenting all queued frames. |
| 55 | void WaitPresent(); | 56 | void WaitPresent(); |
| 56 | 57 | ||
| 58 | /// This is called to notify the rendering backend of a surface change | ||
| 59 | void NotifySurfaceChanged(); | ||
| 60 | |||
| 57 | private: | 61 | private: |
| 58 | void PresentThread(std::stop_token token); | 62 | void PresentThread(std::stop_token token); |
| 59 | 63 | ||
| 60 | void CopyToSwapchain(Frame* frame); | 64 | void CopyToSwapchain(Frame* frame); |
| 61 | 65 | ||
| 62 | private: | 66 | private: |
| 67 | const vk::Instance& instance; | ||
| 63 | Core::Frontend::EmuWindow& render_window; | 68 | Core::Frontend::EmuWindow& render_window; |
| 64 | const Device& device; | 69 | const Device& device; |
| 65 | MemoryAllocator& memory_allocator; | 70 | MemoryAllocator& memory_allocator; |
| 66 | Scheduler& scheduler; | 71 | Scheduler& scheduler; |
| 67 | Swapchain& swapchain; | 72 | Swapchain& swapchain; |
| 73 | vk::SurfaceKHR& surface; | ||
| 68 | vk::CommandPool cmdpool; | 74 | vk::CommandPool cmdpool; |
| 69 | std::vector<Frame> frames; | 75 | std::vector<Frame> frames; |
| 70 | std::queue<Frame*> present_queue; | 76 | std::queue<Frame*> present_queue; |
| 71 | std::queue<Frame*> free_queue; | 77 | std::queue<Frame*> free_queue; |
| 72 | std::condition_variable_any frame_cv; | 78 | std::condition_variable_any frame_cv; |
| 73 | std::condition_variable free_cv; | 79 | std::condition_variable free_cv; |
| 80 | std::condition_variable recreate_surface_cv; | ||
| 74 | std::mutex swapchain_mutex; | 81 | std::mutex swapchain_mutex; |
| 82 | std::mutex recreate_surface_mutex; | ||
| 75 | std::mutex queue_mutex; | 83 | std::mutex queue_mutex; |
| 76 | std::mutex free_mutex; | 84 | std::mutex free_mutex; |
| 77 | std::jthread present_thread; | 85 | std::jthread present_thread; |
| 78 | bool blit_supported; | 86 | bool blit_supported; |
| 79 | bool use_present_thread; | 87 | bool use_present_thread; |
| 80 | std::size_t image_count; | 88 | std::size_t image_count{}; |
| 89 | void* last_render_surface{}; | ||
| 81 | }; | 90 | }; |
| 82 | 91 | ||
| 83 | } // namespace Vulkan | 92 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 8d3a9736b..84e3a30cc 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -188,7 +188,14 @@ void RasterizerVulkan::PrepareDraw(bool is_indexed, Func&& draw_func) { | |||
| 188 | FlushWork(); | 188 | FlushWork(); |
| 189 | gpu_memory->FlushCaching(); | 189 | gpu_memory->FlushCaching(); |
| 190 | 190 | ||
| 191 | #if ANDROID | ||
| 192 | if (Settings::IsGPULevelHigh()) { | ||
| 193 | // This is problematic on Android, disable on GPU Normal. | ||
| 194 | query_cache.UpdateCounters(); | ||
| 195 | } | ||
| 196 | #else | ||
| 191 | query_cache.UpdateCounters(); | 197 | query_cache.UpdateCounters(); |
| 198 | #endif | ||
| 192 | 199 | ||
| 193 | GraphicsPipeline* const pipeline{pipeline_cache.CurrentGraphicsPipeline()}; | 200 | GraphicsPipeline* const pipeline{pipeline_cache.CurrentGraphicsPipeline()}; |
| 194 | if (!pipeline) { | 201 | if (!pipeline) { |
| @@ -272,7 +279,14 @@ void RasterizerVulkan::DrawTexture() { | |||
| 272 | SCOPE_EXIT({ gpu.TickWork(); }); | 279 | SCOPE_EXIT({ gpu.TickWork(); }); |
| 273 | FlushWork(); | 280 | FlushWork(); |
| 274 | 281 | ||
| 282 | #if ANDROID | ||
| 283 | if (Settings::IsGPULevelHigh()) { | ||
| 284 | // This is problematic on Android, disable on GPU Normal. | ||
| 285 | query_cache.UpdateCounters(); | ||
| 286 | } | ||
| 287 | #else | ||
| 275 | query_cache.UpdateCounters(); | 288 | query_cache.UpdateCounters(); |
| 289 | #endif | ||
| 276 | 290 | ||
| 277 | texture_cache.SynchronizeGraphicsDescriptors(); | 291 | texture_cache.SynchronizeGraphicsDescriptors(); |
| 278 | texture_cache.UpdateRenderTargets(false); | 292 | texture_cache.UpdateRenderTargets(false); |
| @@ -743,7 +757,11 @@ void RasterizerVulkan::LoadDiskResources(u64 title_id, std::stop_token stop_load | |||
| 743 | } | 757 | } |
| 744 | 758 | ||
| 745 | void RasterizerVulkan::FlushWork() { | 759 | void RasterizerVulkan::FlushWork() { |
| 760 | #ifdef ANDROID | ||
| 761 | static constexpr u32 DRAWS_TO_DISPATCH = 1024; | ||
| 762 | #else | ||
| 746 | static constexpr u32 DRAWS_TO_DISPATCH = 4096; | 763 | static constexpr u32 DRAWS_TO_DISPATCH = 4096; |
| 764 | #endif // ANDROID | ||
| 747 | 765 | ||
| 748 | // Only check multiples of 8 draws | 766 | // Only check multiples of 8 draws |
| 749 | static_assert(DRAWS_TO_DISPATCH % 8 == 0); | 767 | static_assert(DRAWS_TO_DISPATCH % 8 == 0); |
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 80455ec08..17ef61147 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp | |||
| @@ -239,7 +239,14 @@ u64 Scheduler::SubmitExecution(VkSemaphore signal_semaphore, VkSemaphore wait_se | |||
| 239 | void Scheduler::AllocateNewContext() { | 239 | void Scheduler::AllocateNewContext() { |
| 240 | // Enable counters once again. These are disabled when a command buffer is finished. | 240 | // Enable counters once again. These are disabled when a command buffer is finished. |
| 241 | if (query_cache) { | 241 | if (query_cache) { |
| 242 | #if ANDROID | ||
| 243 | if (Settings::IsGPULevelHigh()) { | ||
| 244 | // This is problematic on Android, disable on GPU Normal. | ||
| 245 | query_cache->UpdateCounters(); | ||
| 246 | } | ||
| 247 | #else | ||
| 242 | query_cache->UpdateCounters(); | 248 | query_cache->UpdateCounters(); |
| 249 | #endif | ||
| 243 | } | 250 | } |
| 244 | } | 251 | } |
| 245 | 252 | ||
| @@ -250,7 +257,14 @@ void Scheduler::InvalidateState() { | |||
| 250 | } | 257 | } |
| 251 | 258 | ||
| 252 | void Scheduler::EndPendingOperations() { | 259 | void Scheduler::EndPendingOperations() { |
| 260 | #if ANDROID | ||
| 261 | if (Settings::IsGPULevelHigh()) { | ||
| 262 | // This is problematic on Android, disable on GPU Normal. | ||
| 263 | query_cache->DisableStreams(); | ||
| 264 | } | ||
| 265 | #else | ||
| 253 | query_cache->DisableStreams(); | 266 | query_cache->DisableStreams(); |
| 267 | #endif | ||
| 254 | EndRenderPass(); | 268 | EndRenderPass(); |
| 255 | } | 269 | } |
| 256 | 270 | ||
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 8c0dec590..afcf34fba 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp | |||
| @@ -107,16 +107,17 @@ VkCompositeAlphaFlagBitsKHR ChooseAlphaFlags(const VkSurfaceCapabilitiesKHR& cap | |||
| 107 | Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, | 107 | Swapchain::Swapchain(VkSurfaceKHR surface_, const Device& device_, Scheduler& scheduler_, |
| 108 | u32 width_, u32 height_, bool srgb) | 108 | u32 width_, u32 height_, bool srgb) |
| 109 | : surface{surface_}, device{device_}, scheduler{scheduler_} { | 109 | : surface{surface_}, device{device_}, scheduler{scheduler_} { |
| 110 | Create(width_, height_, srgb); | 110 | Create(surface_, width_, height_, srgb); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | Swapchain::~Swapchain() = default; | 113 | Swapchain::~Swapchain() = default; |
| 114 | 114 | ||
| 115 | void Swapchain::Create(u32 width_, u32 height_, bool srgb) { | 115 | void Swapchain::Create(VkSurfaceKHR surface_, u32 width_, u32 height_, bool srgb) { |
| 116 | is_outdated = false; | 116 | is_outdated = false; |
| 117 | is_suboptimal = false; | 117 | is_suboptimal = false; |
| 118 | width = width_; | 118 | width = width_; |
| 119 | height = height_; | 119 | height = height_; |
| 120 | surface = surface_; | ||
| 120 | 121 | ||
| 121 | const auto physical_device = device.GetPhysical(); | 122 | const auto physical_device = device.GetPhysical(); |
| 122 | const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; | 123 | const auto capabilities{physical_device.GetSurfaceCapabilitiesKHR(surface)}; |
| @@ -266,7 +267,12 @@ void Swapchain::CreateSwapchain(const VkSurfaceCapabilitiesKHR& capabilities, bo | |||
| 266 | 267 | ||
| 267 | images = swapchain.GetImages(); | 268 | images = swapchain.GetImages(); |
| 268 | image_count = static_cast<u32>(images.size()); | 269 | image_count = static_cast<u32>(images.size()); |
| 270 | #ifdef ANDROID | ||
| 271 | // Android is already ordered the same as Switch. | ||
| 272 | image_view_format = srgb ? VK_FORMAT_R8G8B8A8_SRGB : VK_FORMAT_R8G8B8A8_UNORM; | ||
| 273 | #else | ||
| 269 | image_view_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; | 274 | image_view_format = srgb ? VK_FORMAT_B8G8R8A8_SRGB : VK_FORMAT_B8G8R8A8_UNORM; |
| 275 | #endif | ||
| 270 | } | 276 | } |
| 271 | 277 | ||
| 272 | void Swapchain::CreateSemaphores() { | 278 | void Swapchain::CreateSemaphores() { |
diff --git a/src/video_core/renderer_vulkan/vk_swapchain.h b/src/video_core/renderer_vulkan/vk_swapchain.h index bf1ea7254..b8a1465a6 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.h +++ b/src/video_core/renderer_vulkan/vk_swapchain.h | |||
| @@ -24,7 +24,7 @@ public: | |||
| 24 | ~Swapchain(); | 24 | ~Swapchain(); |
| 25 | 25 | ||
| 26 | /// Creates (or recreates) the swapchain with a given size. | 26 | /// Creates (or recreates) the swapchain with a given size. |
| 27 | void Create(u32 width, u32 height, bool srgb); | 27 | void Create(VkSurfaceKHR surface, u32 width, u32 height, bool srgb); |
| 28 | 28 | ||
| 29 | /// Acquires the next image in the swapchain, waits as needed. | 29 | /// Acquires the next image in the swapchain, waits as needed. |
| 30 | bool AcquireNextImage(); | 30 | bool AcquireNextImage(); |
| @@ -118,7 +118,7 @@ private: | |||
| 118 | 118 | ||
| 119 | bool NeedsPresentModeUpdate() const; | 119 | bool NeedsPresentModeUpdate() const; |
| 120 | 120 | ||
| 121 | const VkSurfaceKHR surface; | 121 | VkSurfaceKHR surface; |
| 122 | const Device& device; | 122 | const Device& device; |
| 123 | Scheduler& scheduler; | 123 | Scheduler& scheduler; |
| 124 | 124 | ||
diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp index db04943eb..a802d3c49 100644 --- a/src/video_core/renderer_vulkan/vk_turbo_mode.cpp +++ b/src/video_core/renderer_vulkan/vk_turbo_mode.cpp | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project | 1 | // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #if defined(ANDROID) && defined(ARCHITECTURE_arm64) | ||
| 5 | #include <adrenotools/driver.h> | ||
| 6 | #endif | ||
| 7 | |||
| 4 | #include "common/literals.h" | 8 | #include "common/literals.h" |
| 5 | #include "video_core/host_shaders/vulkan_turbo_mode_comp_spv.h" | 9 | #include "video_core/host_shaders/vulkan_turbo_mode_comp_spv.h" |
| 6 | #include "video_core/renderer_vulkan/renderer_vulkan.h" | 10 | #include "video_core/renderer_vulkan/renderer_vulkan.h" |
| @@ -13,7 +17,10 @@ namespace Vulkan { | |||
| 13 | using namespace Common::Literals; | 17 | using namespace Common::Literals; |
| 14 | 18 | ||
| 15 | TurboMode::TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld) | 19 | TurboMode::TurboMode(const vk::Instance& instance, const vk::InstanceDispatch& dld) |
| 16 | : m_device{CreateDevice(instance, dld, VK_NULL_HANDLE)}, m_allocator{m_device, false} { | 20 | #ifndef ANDROID |
| 21 | : m_device{CreateDevice(instance, dld, VK_NULL_HANDLE)}, m_allocator{m_device, false} | ||
| 22 | #endif | ||
| 23 | { | ||
| 17 | { | 24 | { |
| 18 | std::scoped_lock lk{m_submission_lock}; | 25 | std::scoped_lock lk{m_submission_lock}; |
| 19 | m_submission_time = std::chrono::steady_clock::now(); | 26 | m_submission_time = std::chrono::steady_clock::now(); |
| @@ -30,6 +37,7 @@ void TurboMode::QueueSubmitted() { | |||
| 30 | } | 37 | } |
| 31 | 38 | ||
| 32 | void TurboMode::Run(std::stop_token stop_token) { | 39 | void TurboMode::Run(std::stop_token stop_token) { |
| 40 | #ifndef ANDROID | ||
| 33 | auto& dld = m_device.GetLogical(); | 41 | auto& dld = m_device.GetLogical(); |
| 34 | 42 | ||
| 35 | // Allocate buffer. 2MiB should be sufficient. | 43 | // Allocate buffer. 2MiB should be sufficient. |
| @@ -142,8 +150,14 @@ void TurboMode::Run(std::stop_token stop_token) { | |||
| 142 | // Create a single command buffer. | 150 | // Create a single command buffer. |
| 143 | auto cmdbufs = command_pool.Allocate(1, VK_COMMAND_BUFFER_LEVEL_PRIMARY); | 151 | auto cmdbufs = command_pool.Allocate(1, VK_COMMAND_BUFFER_LEVEL_PRIMARY); |
| 144 | auto cmdbuf = vk::CommandBuffer{cmdbufs[0], m_device.GetDispatchLoader()}; | 152 | auto cmdbuf = vk::CommandBuffer{cmdbufs[0], m_device.GetDispatchLoader()}; |
| 153 | #endif | ||
| 145 | 154 | ||
| 146 | while (!stop_token.stop_requested()) { | 155 | while (!stop_token.stop_requested()) { |
| 156 | #ifdef ANDROID | ||
| 157 | #ifdef ARCHITECTURE_arm64 | ||
| 158 | adrenotools_set_turbo(true); | ||
| 159 | #endif | ||
| 160 | #else | ||
| 147 | // Reset the fence. | 161 | // Reset the fence. |
| 148 | fence.Reset(); | 162 | fence.Reset(); |
| 149 | 163 | ||
| @@ -209,7 +223,7 @@ void TurboMode::Run(std::stop_token stop_token) { | |||
| 209 | 223 | ||
| 210 | // Wait for completion. | 224 | // Wait for completion. |
| 211 | fence.Wait(); | 225 | fence.Wait(); |
| 212 | 226 | #endif | |
| 213 | // Wait for the next graphics queue submission if necessary. | 227 | // Wait for the next graphics queue submission if necessary. |
| 214 | std::unique_lock lk{m_submission_lock}; | 228 | std::unique_lock lk{m_submission_lock}; |
| 215 | Common::CondvarWait(m_submission_cv, lk, stop_token, [this] { | 229 | Common::CondvarWait(m_submission_cv, lk, stop_token, [this] { |
| @@ -217,6 +231,9 @@ void TurboMode::Run(std::stop_token stop_token) { | |||
| 217 | std::chrono::milliseconds{100}; | 231 | std::chrono::milliseconds{100}; |
| 218 | }); | 232 | }); |
| 219 | } | 233 | } |
| 234 | #if defined(ANDROID) && defined(ARCHITECTURE_arm64) | ||
| 235 | adrenotools_set_turbo(false); | ||
| 236 | #endif | ||
| 220 | } | 237 | } |
| 221 | 238 | ||
| 222 | } // namespace Vulkan | 239 | } // namespace Vulkan |
diff --git a/src/video_core/renderer_vulkan/vk_turbo_mode.h b/src/video_core/renderer_vulkan/vk_turbo_mode.h index 99b5ac50b..9341c9867 100644 --- a/src/video_core/renderer_vulkan/vk_turbo_mode.h +++ b/src/video_core/renderer_vulkan/vk_turbo_mode.h | |||
| @@ -23,8 +23,10 @@ public: | |||
| 23 | private: | 23 | private: |
| 24 | void Run(std::stop_token stop_token); | 24 | void Run(std::stop_token stop_token); |
| 25 | 25 | ||
| 26 | #ifndef ANDROID | ||
| 26 | Device m_device; | 27 | Device m_device; |
| 27 | MemoryAllocator m_allocator; | 28 | MemoryAllocator m_allocator; |
| 29 | #endif | ||
| 28 | std::mutex m_submission_lock; | 30 | std::mutex m_submission_lock; |
| 29 | std::condition_variable_any m_submission_cv; | 31 | std::condition_variable_any m_submission_cv; |
| 30 | std::chrono::time_point<std::chrono::steady_clock> m_submission_time{}; | 32 | std::chrono::time_point<std::chrono::steady_clock> m_submission_time{}; |
diff --git a/src/video_core/renderer_vulkan/vk_update_descriptor.h b/src/video_core/renderer_vulkan/vk_update_descriptor.h index 310fb551a..e77b576ec 100644 --- a/src/video_core/renderer_vulkan/vk_update_descriptor.h +++ b/src/video_core/renderer_vulkan/vk_update_descriptor.h | |||
| @@ -31,7 +31,7 @@ struct DescriptorUpdateEntry { | |||
| 31 | class UpdateDescriptorQueue final { | 31 | class UpdateDescriptorQueue final { |
| 32 | // This should be plenty for the vast majority of cases. Most desktop platforms only | 32 | // This should be plenty for the vast majority of cases. Most desktop platforms only |
| 33 | // provide up to 3 swapchain images. | 33 | // provide up to 3 swapchain images. |
| 34 | static constexpr size_t FRAMES_IN_FLIGHT = 5; | 34 | static constexpr size_t FRAMES_IN_FLIGHT = 7; |
| 35 | static constexpr size_t FRAME_PAYLOAD_SIZE = 0x20000; | 35 | static constexpr size_t FRAME_PAYLOAD_SIZE = 0x20000; |
| 36 | static constexpr size_t PAYLOAD_SIZE = FRAME_PAYLOAD_SIZE * FRAMES_IN_FLIGHT; | 36 | static constexpr size_t PAYLOAD_SIZE = FRAME_PAYLOAD_SIZE * FRAMES_IN_FLIGHT; |
| 37 | 37 | ||