diff options
| author | 2020-04-22 22:09:38 -0400 | |
|---|---|---|
| committer | 2020-04-22 22:09:38 -0400 | |
| commit | bf2ddb8fd5feaeaf2806fe102de8e3089f893137 (patch) | |
| tree | b97d388da23608c00808b6662e3c0564fc4f6d59 /src/video_core/renderer_vulkan | |
| parent | Merge pull request #3767 from ReinUsesLisp/point-size-pipeline (diff) | |
| parent | GL_Fence_Manager: use GL_TIMEOUT_IGNORED instead of a loop, (diff) | |
| download | yuzu-bf2ddb8fd5feaeaf2806fe102de8e3089f893137.tar.gz yuzu-bf2ddb8fd5feaeaf2806fe102de8e3089f893137.tar.xz yuzu-bf2ddb8fd5feaeaf2806fe102de8e3089f893137.zip | |
Merge pull request #3677 from FernandoS27/better-sync
Introduce Predictive Flushing and Improve ASYNC GPU
Diffstat (limited to 'src/video_core/renderer_vulkan')
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_fence_manager.cpp | 101 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_fence_manager.h | 74 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 16 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_pipeline_cache.h | 3 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 55 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.h | 8 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.cpp | 18 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/wrapper.h | 20 |
8 files changed, 290 insertions, 5 deletions
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.cpp b/src/video_core/renderer_vulkan/vk_fence_manager.cpp new file mode 100644 index 000000000..a02be5487 --- /dev/null +++ b/src/video_core/renderer_vulkan/vk_fence_manager.cpp | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | #include <thread> | ||
| 7 | |||
| 8 | #include "video_core/renderer_vulkan/vk_buffer_cache.h" | ||
| 9 | #include "video_core/renderer_vulkan/vk_device.h" | ||
| 10 | #include "video_core/renderer_vulkan/vk_fence_manager.h" | ||
| 11 | #include "video_core/renderer_vulkan/vk_scheduler.h" | ||
| 12 | #include "video_core/renderer_vulkan/vk_texture_cache.h" | ||
| 13 | #include "video_core/renderer_vulkan/wrapper.h" | ||
| 14 | |||
| 15 | namespace Vulkan { | ||
| 16 | |||
| 17 | InnerFence::InnerFence(const VKDevice& device, VKScheduler& scheduler, u32 payload, bool is_stubbed) | ||
| 18 | : VideoCommon::FenceBase(payload, is_stubbed), device{device}, scheduler{scheduler} {} | ||
| 19 | |||
| 20 | InnerFence::InnerFence(const VKDevice& device, VKScheduler& scheduler, GPUVAddr address, | ||
| 21 | u32 payload, bool is_stubbed) | ||
| 22 | : VideoCommon::FenceBase(address, payload, is_stubbed), device{device}, scheduler{scheduler} {} | ||
| 23 | |||
| 24 | InnerFence::~InnerFence() = default; | ||
| 25 | |||
| 26 | void InnerFence::Queue() { | ||
| 27 | if (is_stubbed) { | ||
| 28 | return; | ||
| 29 | } | ||
| 30 | ASSERT(!event); | ||
| 31 | |||
| 32 | event = device.GetLogical().CreateEvent(); | ||
| 33 | ticks = scheduler.Ticks(); | ||
| 34 | |||
| 35 | scheduler.RequestOutsideRenderPassOperationContext(); | ||
| 36 | scheduler.Record([event = *event](vk::CommandBuffer cmdbuf) { | ||
| 37 | cmdbuf.SetEvent(event, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); | ||
| 38 | }); | ||
| 39 | } | ||
| 40 | |||
| 41 | bool InnerFence::IsSignaled() const { | ||
| 42 | if (is_stubbed) { | ||
| 43 | return true; | ||
| 44 | } | ||
| 45 | ASSERT(event); | ||
| 46 | return IsEventSignalled(); | ||
| 47 | } | ||
| 48 | |||
| 49 | void InnerFence::Wait() { | ||
| 50 | if (is_stubbed) { | ||
| 51 | return; | ||
| 52 | } | ||
| 53 | ASSERT(event); | ||
| 54 | |||
| 55 | if (ticks >= scheduler.Ticks()) { | ||
| 56 | scheduler.Flush(); | ||
| 57 | } | ||
| 58 | while (!IsEventSignalled()) { | ||
| 59 | std::this_thread::yield(); | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | bool InnerFence::IsEventSignalled() const { | ||
| 64 | switch (const VkResult result = event.GetStatus()) { | ||
| 65 | case VK_EVENT_SET: | ||
| 66 | return true; | ||
| 67 | case VK_EVENT_RESET: | ||
| 68 | return false; | ||
| 69 | default: | ||
| 70 | throw vk::Exception(result); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | VKFenceManager::VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | ||
| 75 | const VKDevice& device, VKScheduler& scheduler, | ||
| 76 | VKTextureCache& texture_cache, VKBufferCache& buffer_cache, | ||
| 77 | VKQueryCache& query_cache) | ||
| 78 | : GenericFenceManager(system, rasterizer, texture_cache, buffer_cache, query_cache), | ||
| 79 | device{device}, scheduler{scheduler} {} | ||
| 80 | |||
| 81 | Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) { | ||
| 82 | return std::make_shared<InnerFence>(device, scheduler, value, is_stubbed); | ||
| 83 | } | ||
| 84 | |||
| 85 | Fence VKFenceManager::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) { | ||
| 86 | return std::make_shared<InnerFence>(device, scheduler, addr, value, is_stubbed); | ||
| 87 | } | ||
| 88 | |||
| 89 | void VKFenceManager::QueueFence(Fence& fence) { | ||
| 90 | fence->Queue(); | ||
| 91 | } | ||
| 92 | |||
| 93 | bool VKFenceManager::IsFenceSignaled(Fence& fence) const { | ||
| 94 | return fence->IsSignaled(); | ||
| 95 | } | ||
| 96 | |||
| 97 | void VKFenceManager::WaitFence(Fence& fence) { | ||
| 98 | fence->Wait(); | ||
| 99 | } | ||
| 100 | |||
| 101 | } // namespace Vulkan | ||
diff --git a/src/video_core/renderer_vulkan/vk_fence_manager.h b/src/video_core/renderer_vulkan/vk_fence_manager.h new file mode 100644 index 000000000..04d07fe6a --- /dev/null +++ b/src/video_core/renderer_vulkan/vk_fence_manager.h | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | #include "video_core/fence_manager.h" | ||
| 10 | #include "video_core/renderer_vulkan/wrapper.h" | ||
| 11 | |||
| 12 | namespace Core { | ||
| 13 | class System; | ||
| 14 | } | ||
| 15 | |||
| 16 | namespace VideoCore { | ||
| 17 | class RasterizerInterface; | ||
| 18 | } | ||
| 19 | |||
| 20 | namespace Vulkan { | ||
| 21 | |||
| 22 | class VKBufferCache; | ||
| 23 | class VKDevice; | ||
| 24 | class VKQueryCache; | ||
| 25 | class VKScheduler; | ||
| 26 | class VKTextureCache; | ||
| 27 | |||
| 28 | class InnerFence : public VideoCommon::FenceBase { | ||
| 29 | public: | ||
| 30 | explicit InnerFence(const VKDevice& device, VKScheduler& scheduler, u32 payload, | ||
| 31 | bool is_stubbed); | ||
| 32 | explicit InnerFence(const VKDevice& device, VKScheduler& scheduler, GPUVAddr address, | ||
| 33 | u32 payload, bool is_stubbed); | ||
| 34 | ~InnerFence(); | ||
| 35 | |||
| 36 | void Queue(); | ||
| 37 | |||
| 38 | bool IsSignaled() const; | ||
| 39 | |||
| 40 | void Wait(); | ||
| 41 | |||
| 42 | private: | ||
| 43 | bool IsEventSignalled() const; | ||
| 44 | |||
| 45 | const VKDevice& device; | ||
| 46 | VKScheduler& scheduler; | ||
| 47 | vk::Event event; | ||
| 48 | u64 ticks = 0; | ||
| 49 | }; | ||
| 50 | using Fence = std::shared_ptr<InnerFence>; | ||
| 51 | |||
| 52 | using GenericFenceManager = | ||
| 53 | VideoCommon::FenceManager<Fence, VKTextureCache, VKBufferCache, VKQueryCache>; | ||
| 54 | |||
| 55 | class VKFenceManager final : public GenericFenceManager { | ||
| 56 | public: | ||
| 57 | explicit VKFenceManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer, | ||
| 58 | const VKDevice& device, VKScheduler& scheduler, | ||
| 59 | VKTextureCache& texture_cache, VKBufferCache& buffer_cache, | ||
| 60 | VKQueryCache& query_cache); | ||
| 61 | |||
| 62 | protected: | ||
| 63 | Fence CreateFence(u32 value, bool is_stubbed) override; | ||
| 64 | Fence CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) override; | ||
| 65 | void QueueFence(Fence& fence) override; | ||
| 66 | bool IsFenceSignaled(Fence& fence) const override; | ||
| 67 | void WaitFence(Fence& fence) override; | ||
| 68 | |||
| 69 | private: | ||
| 70 | const VKDevice& device; | ||
| 71 | VKScheduler& scheduler; | ||
| 72 | }; | ||
| 73 | |||
| 74 | } // namespace Vulkan | ||
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a792130fd..91b1b16a5 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | |||
| @@ -207,7 +207,7 @@ std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { | |||
| 207 | const GPUVAddr program_addr{GetShaderAddress(system, program)}; | 207 | const GPUVAddr program_addr{GetShaderAddress(system, program)}; |
| 208 | const std::optional cpu_addr = memory_manager.GpuToCpuAddress(program_addr); | 208 | const std::optional cpu_addr = memory_manager.GpuToCpuAddress(program_addr); |
| 209 | ASSERT(cpu_addr); | 209 | ASSERT(cpu_addr); |
| 210 | auto shader = cpu_addr ? TryGet(*cpu_addr) : nullptr; | 210 | auto shader = cpu_addr ? TryGet(*cpu_addr) : null_shader; |
| 211 | if (!shader) { | 211 | if (!shader) { |
| 212 | const auto host_ptr{memory_manager.GetPointer(program_addr)}; | 212 | const auto host_ptr{memory_manager.GetPointer(program_addr)}; |
| 213 | 213 | ||
| @@ -218,7 +218,11 @@ std::array<Shader, Maxwell::MaxShaderProgram> VKPipelineCache::GetShaders() { | |||
| 218 | 218 | ||
| 219 | shader = std::make_shared<CachedShader>(system, stage, program_addr, *cpu_addr, | 219 | shader = std::make_shared<CachedShader>(system, stage, program_addr, *cpu_addr, |
| 220 | std::move(code), stage_offset); | 220 | std::move(code), stage_offset); |
| 221 | Register(shader); | 221 | if (cpu_addr) { |
| 222 | Register(shader); | ||
| 223 | } else { | ||
| 224 | null_shader = shader; | ||
| 225 | } | ||
| 222 | } | 226 | } |
| 223 | shaders[index] = std::move(shader); | 227 | shaders[index] = std::move(shader); |
| 224 | } | 228 | } |
| @@ -261,7 +265,7 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | |||
| 261 | const auto cpu_addr = memory_manager.GpuToCpuAddress(program_addr); | 265 | const auto cpu_addr = memory_manager.GpuToCpuAddress(program_addr); |
| 262 | ASSERT(cpu_addr); | 266 | ASSERT(cpu_addr); |
| 263 | 267 | ||
| 264 | auto shader = cpu_addr ? TryGet(*cpu_addr) : nullptr; | 268 | auto shader = cpu_addr ? TryGet(*cpu_addr) : null_kernel; |
| 265 | if (!shader) { | 269 | if (!shader) { |
| 266 | // No shader found - create a new one | 270 | // No shader found - create a new one |
| 267 | const auto host_ptr = memory_manager.GetPointer(program_addr); | 271 | const auto host_ptr = memory_manager.GetPointer(program_addr); |
| @@ -271,7 +275,11 @@ VKComputePipeline& VKPipelineCache::GetComputePipeline(const ComputePipelineCach | |||
| 271 | shader = std::make_shared<CachedShader>(system, Tegra::Engines::ShaderType::Compute, | 275 | shader = std::make_shared<CachedShader>(system, Tegra::Engines::ShaderType::Compute, |
| 272 | program_addr, *cpu_addr, std::move(code), | 276 | program_addr, *cpu_addr, std::move(code), |
| 273 | kernel_main_offset); | 277 | kernel_main_offset); |
| 274 | Register(shader); | 278 | if (cpu_addr) { |
| 279 | Register(shader); | ||
| 280 | } else { | ||
| 281 | null_kernel = shader; | ||
| 282 | } | ||
| 275 | } | 283 | } |
| 276 | 284 | ||
| 277 | Specialization specialization; | 285 | Specialization specialization; |
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 7ccdb7083..602a0a340 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h | |||
| @@ -182,6 +182,9 @@ private: | |||
| 182 | VKUpdateDescriptorQueue& update_descriptor_queue; | 182 | VKUpdateDescriptorQueue& update_descriptor_queue; |
| 183 | VKRenderPassCache& renderpass_cache; | 183 | VKRenderPassCache& renderpass_cache; |
| 184 | 184 | ||
| 185 | Shader null_shader{}; | ||
| 186 | Shader null_kernel{}; | ||
| 187 | |||
| 185 | std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; | 188 | std::array<Shader, Maxwell::MaxShaderProgram> last_shaders; |
| 186 | 189 | ||
| 187 | GraphicsPipelineCacheKey last_graphics_key; | 190 | GraphicsPipelineCacheKey last_graphics_key; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index b58a88664..8a1f57891 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include "common/microprofile.h" | 17 | #include "common/microprofile.h" |
| 18 | #include "core/core.h" | 18 | #include "core/core.h" |
| 19 | #include "core/memory.h" | 19 | #include "core/memory.h" |
| 20 | #include "core/settings.h" | ||
| 20 | #include "video_core/engines/kepler_compute.h" | 21 | #include "video_core/engines/kepler_compute.h" |
| 21 | #include "video_core/engines/maxwell_3d.h" | 22 | #include "video_core/engines/maxwell_3d.h" |
| 22 | #include "video_core/renderer_vulkan/fixed_pipeline_state.h" | 23 | #include "video_core/renderer_vulkan/fixed_pipeline_state.h" |
| @@ -299,7 +300,9 @@ RasterizerVulkan::RasterizerVulkan(Core::System& system, Core::Frontend::EmuWind | |||
| 299 | pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, | 300 | pipeline_cache(system, *this, device, scheduler, descriptor_pool, update_descriptor_queue, |
| 300 | renderpass_cache), | 301 | renderpass_cache), |
| 301 | buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), | 302 | buffer_cache(*this, system, device, memory_manager, scheduler, staging_pool), |
| 302 | sampler_cache(device), query_cache(system, *this, device, scheduler) { | 303 | sampler_cache(device), |
| 304 | fence_manager(system, *this, device, scheduler, texture_cache, buffer_cache, query_cache), | ||
| 305 | query_cache(system, *this, device, scheduler) { | ||
| 303 | scheduler.SetQueryCache(query_cache); | 306 | scheduler.SetQueryCache(query_cache); |
| 304 | } | 307 | } |
| 305 | 308 | ||
| @@ -360,6 +363,8 @@ void RasterizerVulkan::Draw(bool is_indexed, bool is_instanced) { | |||
| 360 | }); | 363 | }); |
| 361 | 364 | ||
| 362 | EndTransformFeedback(); | 365 | EndTransformFeedback(); |
| 366 | |||
| 367 | system.GPU().TickWork(); | ||
| 363 | } | 368 | } |
| 364 | 369 | ||
| 365 | void RasterizerVulkan::Clear() { | 370 | void RasterizerVulkan::Clear() { |
| @@ -504,6 +509,13 @@ void RasterizerVulkan::FlushRegion(VAddr addr, u64 size) { | |||
| 504 | query_cache.FlushRegion(addr, size); | 509 | query_cache.FlushRegion(addr, size); |
| 505 | } | 510 | } |
| 506 | 511 | ||
| 512 | bool RasterizerVulkan::MustFlushRegion(VAddr addr, u64 size) { | ||
| 513 | if (!Settings::IsGPULevelHigh()) { | ||
| 514 | return buffer_cache.MustFlushRegion(addr, size); | ||
| 515 | } | ||
| 516 | return texture_cache.MustFlushRegion(addr, size) || buffer_cache.MustFlushRegion(addr, size); | ||
| 517 | } | ||
| 518 | |||
| 507 | void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { | 519 | void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { |
| 508 | if (addr == 0 || size == 0) { | 520 | if (addr == 0 || size == 0) { |
| 509 | return; | 521 | return; |
| @@ -514,6 +526,47 @@ void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { | |||
| 514 | query_cache.InvalidateRegion(addr, size); | 526 | query_cache.InvalidateRegion(addr, size); |
| 515 | } | 527 | } |
| 516 | 528 | ||
| 529 | void RasterizerVulkan::OnCPUWrite(VAddr addr, u64 size) { | ||
| 530 | if (addr == 0 || size == 0) { | ||
| 531 | return; | ||
| 532 | } | ||
| 533 | texture_cache.OnCPUWrite(addr, size); | ||
| 534 | pipeline_cache.InvalidateRegion(addr, size); | ||
| 535 | buffer_cache.OnCPUWrite(addr, size); | ||
| 536 | query_cache.InvalidateRegion(addr, size); | ||
| 537 | } | ||
| 538 | |||
| 539 | void RasterizerVulkan::SyncGuestHost() { | ||
| 540 | texture_cache.SyncGuestHost(); | ||
| 541 | buffer_cache.SyncGuestHost(); | ||
| 542 | } | ||
| 543 | |||
| 544 | void RasterizerVulkan::SignalSemaphore(GPUVAddr addr, u32 value) { | ||
| 545 | auto& gpu{system.GPU()}; | ||
| 546 | if (!gpu.IsAsync()) { | ||
| 547 | gpu.MemoryManager().Write<u32>(addr, value); | ||
| 548 | return; | ||
| 549 | } | ||
| 550 | fence_manager.SignalSemaphore(addr, value); | ||
| 551 | } | ||
| 552 | |||
| 553 | void RasterizerVulkan::SignalSyncPoint(u32 value) { | ||
| 554 | auto& gpu{system.GPU()}; | ||
| 555 | if (!gpu.IsAsync()) { | ||
| 556 | gpu.IncrementSyncPoint(value); | ||
| 557 | return; | ||
| 558 | } | ||
| 559 | fence_manager.SignalSyncPoint(value); | ||
| 560 | } | ||
| 561 | |||
| 562 | void RasterizerVulkan::ReleaseFences() { | ||
| 563 | auto& gpu{system.GPU()}; | ||
| 564 | if (!gpu.IsAsync()) { | ||
| 565 | return; | ||
| 566 | } | ||
| 567 | fence_manager.WaitPendingFences(); | ||
| 568 | } | ||
| 569 | |||
| 517 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 570 | void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { |
| 518 | FlushRegion(addr, size); | 571 | FlushRegion(addr, size); |
| 519 | InvalidateRegion(addr, size); | 572 | InvalidateRegion(addr, size); |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index d9108f862..2fa46b0cc 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "video_core/renderer_vulkan/vk_buffer_cache.h" | 21 | #include "video_core/renderer_vulkan/vk_buffer_cache.h" |
| 22 | #include "video_core/renderer_vulkan/vk_compute_pass.h" | 22 | #include "video_core/renderer_vulkan/vk_compute_pass.h" |
| 23 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" | 23 | #include "video_core/renderer_vulkan/vk_descriptor_pool.h" |
| 24 | #include "video_core/renderer_vulkan/vk_fence_manager.h" | ||
| 24 | #include "video_core/renderer_vulkan/vk_memory_manager.h" | 25 | #include "video_core/renderer_vulkan/vk_memory_manager.h" |
| 25 | #include "video_core/renderer_vulkan/vk_pipeline_cache.h" | 26 | #include "video_core/renderer_vulkan/vk_pipeline_cache.h" |
| 26 | #include "video_core/renderer_vulkan/vk_query_cache.h" | 27 | #include "video_core/renderer_vulkan/vk_query_cache.h" |
| @@ -118,7 +119,13 @@ public: | |||
| 118 | void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override; | 119 | void Query(GPUVAddr gpu_addr, VideoCore::QueryType type, std::optional<u64> timestamp) override; |
| 119 | void FlushAll() override; | 120 | void FlushAll() override; |
| 120 | void FlushRegion(VAddr addr, u64 size) override; | 121 | void FlushRegion(VAddr addr, u64 size) override; |
| 122 | bool MustFlushRegion(VAddr addr, u64 size) override; | ||
| 121 | void InvalidateRegion(VAddr addr, u64 size) override; | 123 | void InvalidateRegion(VAddr addr, u64 size) override; |
| 124 | void OnCPUWrite(VAddr addr, u64 size) override; | ||
| 125 | void SyncGuestHost() override; | ||
| 126 | void SignalSemaphore(GPUVAddr addr, u32 value) override; | ||
| 127 | void SignalSyncPoint(u32 value) override; | ||
| 128 | void ReleaseFences() override; | ||
| 122 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; | 129 | void FlushAndInvalidateRegion(VAddr addr, u64 size) override; |
| 123 | void FlushCommands() override; | 130 | void FlushCommands() override; |
| 124 | void TickFrame() override; | 131 | void TickFrame() override; |
| @@ -261,6 +268,7 @@ private: | |||
| 261 | VKPipelineCache pipeline_cache; | 268 | VKPipelineCache pipeline_cache; |
| 262 | VKBufferCache buffer_cache; | 269 | VKBufferCache buffer_cache; |
| 263 | VKSamplerCache sampler_cache; | 270 | VKSamplerCache sampler_cache; |
| 271 | VKFenceManager fence_manager; | ||
| 264 | VKQueryCache query_cache; | 272 | VKQueryCache query_cache; |
| 265 | 273 | ||
| 266 | std::array<View, Maxwell::NumRenderTargets> color_attachments; | 274 | std::array<View, Maxwell::NumRenderTargets> color_attachments; |
diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp index 3a52a3a6f..539f3c974 100644 --- a/src/video_core/renderer_vulkan/wrapper.cpp +++ b/src/video_core/renderer_vulkan/wrapper.cpp | |||
| @@ -63,6 +63,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 63 | X(vkCmdSetBlendConstants); | 63 | X(vkCmdSetBlendConstants); |
| 64 | X(vkCmdSetDepthBias); | 64 | X(vkCmdSetDepthBias); |
| 65 | X(vkCmdSetDepthBounds); | 65 | X(vkCmdSetDepthBounds); |
| 66 | X(vkCmdSetEvent); | ||
| 66 | X(vkCmdSetScissor); | 67 | X(vkCmdSetScissor); |
| 67 | X(vkCmdSetStencilCompareMask); | 68 | X(vkCmdSetStencilCompareMask); |
| 68 | X(vkCmdSetStencilReference); | 69 | X(vkCmdSetStencilReference); |
| @@ -75,6 +76,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 75 | X(vkCreateDescriptorPool); | 76 | X(vkCreateDescriptorPool); |
| 76 | X(vkCreateDescriptorSetLayout); | 77 | X(vkCreateDescriptorSetLayout); |
| 77 | X(vkCreateDescriptorUpdateTemplateKHR); | 78 | X(vkCreateDescriptorUpdateTemplateKHR); |
| 79 | X(vkCreateEvent); | ||
| 78 | X(vkCreateFence); | 80 | X(vkCreateFence); |
| 79 | X(vkCreateFramebuffer); | 81 | X(vkCreateFramebuffer); |
| 80 | X(vkCreateGraphicsPipelines); | 82 | X(vkCreateGraphicsPipelines); |
| @@ -93,6 +95,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 93 | X(vkDestroyDescriptorPool); | 95 | X(vkDestroyDescriptorPool); |
| 94 | X(vkDestroyDescriptorSetLayout); | 96 | X(vkDestroyDescriptorSetLayout); |
| 95 | X(vkDestroyDescriptorUpdateTemplateKHR); | 97 | X(vkDestroyDescriptorUpdateTemplateKHR); |
| 98 | X(vkDestroyEvent); | ||
| 96 | X(vkDestroyFence); | 99 | X(vkDestroyFence); |
| 97 | X(vkDestroyFramebuffer); | 100 | X(vkDestroyFramebuffer); |
| 98 | X(vkDestroyImage); | 101 | X(vkDestroyImage); |
| @@ -112,6 +115,7 @@ void Load(VkDevice device, DeviceDispatch& dld) noexcept { | |||
| 112 | X(vkFreeMemory); | 115 | X(vkFreeMemory); |
| 113 | X(vkGetBufferMemoryRequirements); | 116 | X(vkGetBufferMemoryRequirements); |
| 114 | X(vkGetDeviceQueue); | 117 | X(vkGetDeviceQueue); |
| 118 | X(vkGetEventStatus); | ||
| 115 | X(vkGetFenceStatus); | 119 | X(vkGetFenceStatus); |
| 116 | X(vkGetImageMemoryRequirements); | 120 | X(vkGetImageMemoryRequirements); |
| 117 | X(vkGetQueryPoolResults); | 121 | X(vkGetQueryPoolResults); |
| @@ -269,6 +273,10 @@ void Destroy(VkDevice device, VkDeviceMemory handle, const DeviceDispatch& dld) | |||
| 269 | dld.vkFreeMemory(device, handle, nullptr); | 273 | dld.vkFreeMemory(device, handle, nullptr); |
| 270 | } | 274 | } |
| 271 | 275 | ||
| 276 | void Destroy(VkDevice device, VkEvent handle, const DeviceDispatch& dld) noexcept { | ||
| 277 | dld.vkDestroyEvent(device, handle, nullptr); | ||
| 278 | } | ||
| 279 | |||
| 272 | void Destroy(VkDevice device, VkFence handle, const DeviceDispatch& dld) noexcept { | 280 | void Destroy(VkDevice device, VkFence handle, const DeviceDispatch& dld) noexcept { |
| 273 | dld.vkDestroyFence(device, handle, nullptr); | 281 | dld.vkDestroyFence(device, handle, nullptr); |
| 274 | } | 282 | } |
| @@ -599,6 +607,16 @@ ShaderModule Device::CreateShaderModule(const VkShaderModuleCreateInfo& ci) cons | |||
| 599 | return ShaderModule(object, handle, *dld); | 607 | return ShaderModule(object, handle, *dld); |
| 600 | } | 608 | } |
| 601 | 609 | ||
| 610 | Event Device::CreateEvent() const { | ||
| 611 | VkEventCreateInfo ci; | ||
| 612 | ci.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO; | ||
| 613 | ci.pNext = nullptr; | ||
| 614 | ci.flags = 0; | ||
| 615 | VkEvent object; | ||
| 616 | Check(dld->vkCreateEvent(handle, &ci, nullptr, &object)); | ||
| 617 | return Event(object, handle, *dld); | ||
| 618 | } | ||
| 619 | |||
| 602 | SwapchainKHR Device::CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const { | 620 | SwapchainKHR Device::CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const { |
| 603 | VkSwapchainKHR object; | 621 | VkSwapchainKHR object; |
| 604 | Check(dld->vkCreateSwapchainKHR(handle, &ci, nullptr, &object)); | 622 | Check(dld->vkCreateSwapchainKHR(handle, &ci, nullptr, &object)); |
diff --git a/src/video_core/renderer_vulkan/wrapper.h b/src/video_core/renderer_vulkan/wrapper.h index 6fe0294d8..bda16a2cb 100644 --- a/src/video_core/renderer_vulkan/wrapper.h +++ b/src/video_core/renderer_vulkan/wrapper.h | |||
| @@ -199,6 +199,7 @@ struct DeviceDispatch : public InstanceDispatch { | |||
| 199 | PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants; | 199 | PFN_vkCmdSetBlendConstants vkCmdSetBlendConstants; |
| 200 | PFN_vkCmdSetDepthBias vkCmdSetDepthBias; | 200 | PFN_vkCmdSetDepthBias vkCmdSetDepthBias; |
| 201 | PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; | 201 | PFN_vkCmdSetDepthBounds vkCmdSetDepthBounds; |
| 202 | PFN_vkCmdSetEvent vkCmdSetEvent; | ||
| 202 | PFN_vkCmdSetScissor vkCmdSetScissor; | 203 | PFN_vkCmdSetScissor vkCmdSetScissor; |
| 203 | PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; | 204 | PFN_vkCmdSetStencilCompareMask vkCmdSetStencilCompareMask; |
| 204 | PFN_vkCmdSetStencilReference vkCmdSetStencilReference; | 205 | PFN_vkCmdSetStencilReference vkCmdSetStencilReference; |
| @@ -211,6 +212,7 @@ struct DeviceDispatch : public InstanceDispatch { | |||
| 211 | PFN_vkCreateDescriptorPool vkCreateDescriptorPool; | 212 | PFN_vkCreateDescriptorPool vkCreateDescriptorPool; |
| 212 | PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; | 213 | PFN_vkCreateDescriptorSetLayout vkCreateDescriptorSetLayout; |
| 213 | PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR; | 214 | PFN_vkCreateDescriptorUpdateTemplateKHR vkCreateDescriptorUpdateTemplateKHR; |
| 215 | PFN_vkCreateEvent vkCreateEvent; | ||
| 214 | PFN_vkCreateFence vkCreateFence; | 216 | PFN_vkCreateFence vkCreateFence; |
| 215 | PFN_vkCreateFramebuffer vkCreateFramebuffer; | 217 | PFN_vkCreateFramebuffer vkCreateFramebuffer; |
| 216 | PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines; | 218 | PFN_vkCreateGraphicsPipelines vkCreateGraphicsPipelines; |
| @@ -229,6 +231,7 @@ struct DeviceDispatch : public InstanceDispatch { | |||
| 229 | PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool; | 231 | PFN_vkDestroyDescriptorPool vkDestroyDescriptorPool; |
| 230 | PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; | 232 | PFN_vkDestroyDescriptorSetLayout vkDestroyDescriptorSetLayout; |
| 231 | PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR; | 233 | PFN_vkDestroyDescriptorUpdateTemplateKHR vkDestroyDescriptorUpdateTemplateKHR; |
| 234 | PFN_vkDestroyEvent vkDestroyEvent; | ||
| 232 | PFN_vkDestroyFence vkDestroyFence; | 235 | PFN_vkDestroyFence vkDestroyFence; |
| 233 | PFN_vkDestroyFramebuffer vkDestroyFramebuffer; | 236 | PFN_vkDestroyFramebuffer vkDestroyFramebuffer; |
| 234 | PFN_vkDestroyImage vkDestroyImage; | 237 | PFN_vkDestroyImage vkDestroyImage; |
| @@ -248,6 +251,7 @@ struct DeviceDispatch : public InstanceDispatch { | |||
| 248 | PFN_vkFreeMemory vkFreeMemory; | 251 | PFN_vkFreeMemory vkFreeMemory; |
| 249 | PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; | 252 | PFN_vkGetBufferMemoryRequirements vkGetBufferMemoryRequirements; |
| 250 | PFN_vkGetDeviceQueue vkGetDeviceQueue; | 253 | PFN_vkGetDeviceQueue vkGetDeviceQueue; |
| 254 | PFN_vkGetEventStatus vkGetEventStatus; | ||
| 251 | PFN_vkGetFenceStatus vkGetFenceStatus; | 255 | PFN_vkGetFenceStatus vkGetFenceStatus; |
| 252 | PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; | 256 | PFN_vkGetImageMemoryRequirements vkGetImageMemoryRequirements; |
| 253 | PFN_vkGetQueryPoolResults vkGetQueryPoolResults; | 257 | PFN_vkGetQueryPoolResults vkGetQueryPoolResults; |
| @@ -279,6 +283,7 @@ void Destroy(VkDevice, VkDescriptorPool, const DeviceDispatch&) noexcept; | |||
| 279 | void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept; | 283 | void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept; |
| 280 | void Destroy(VkDevice, VkDescriptorUpdateTemplateKHR, const DeviceDispatch&) noexcept; | 284 | void Destroy(VkDevice, VkDescriptorUpdateTemplateKHR, const DeviceDispatch&) noexcept; |
| 281 | void Destroy(VkDevice, VkDeviceMemory, const DeviceDispatch&) noexcept; | 285 | void Destroy(VkDevice, VkDeviceMemory, const DeviceDispatch&) noexcept; |
| 286 | void Destroy(VkDevice, VkEvent, const DeviceDispatch&) noexcept; | ||
| 282 | void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept; | 287 | void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept; |
| 283 | void Destroy(VkDevice, VkFramebuffer, const DeviceDispatch&) noexcept; | 288 | void Destroy(VkDevice, VkFramebuffer, const DeviceDispatch&) noexcept; |
| 284 | void Destroy(VkDevice, VkImage, const DeviceDispatch&) noexcept; | 289 | void Destroy(VkDevice, VkImage, const DeviceDispatch&) noexcept; |
| @@ -648,6 +653,15 @@ public: | |||
| 648 | std::vector<VkImage> GetImages() const; | 653 | std::vector<VkImage> GetImages() const; |
| 649 | }; | 654 | }; |
| 650 | 655 | ||
| 656 | class Event : public Handle<VkEvent, VkDevice, DeviceDispatch> { | ||
| 657 | using Handle<VkEvent, VkDevice, DeviceDispatch>::Handle; | ||
| 658 | |||
| 659 | public: | ||
| 660 | VkResult GetStatus() const noexcept { | ||
| 661 | return dld->vkGetEventStatus(owner, handle); | ||
| 662 | } | ||
| 663 | }; | ||
| 664 | |||
| 651 | class Device : public Handle<VkDevice, NoOwner, DeviceDispatch> { | 665 | class Device : public Handle<VkDevice, NoOwner, DeviceDispatch> { |
| 652 | using Handle<VkDevice, NoOwner, DeviceDispatch>::Handle; | 666 | using Handle<VkDevice, NoOwner, DeviceDispatch>::Handle; |
| 653 | 667 | ||
| @@ -695,6 +709,8 @@ public: | |||
| 695 | 709 | ||
| 696 | ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const; | 710 | ShaderModule CreateShaderModule(const VkShaderModuleCreateInfo& ci) const; |
| 697 | 711 | ||
| 712 | Event CreateEvent() const; | ||
| 713 | |||
| 698 | SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const; | 714 | SwapchainKHR CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const; |
| 699 | 715 | ||
| 700 | DeviceMemory TryAllocateMemory(const VkMemoryAllocateInfo& ai) const noexcept; | 716 | DeviceMemory TryAllocateMemory(const VkMemoryAllocateInfo& ai) const noexcept; |
| @@ -938,6 +954,10 @@ public: | |||
| 938 | dld->vkCmdSetDepthBounds(handle, min_depth_bounds, max_depth_bounds); | 954 | dld->vkCmdSetDepthBounds(handle, min_depth_bounds, max_depth_bounds); |
| 939 | } | 955 | } |
| 940 | 956 | ||
| 957 | void SetEvent(VkEvent event, VkPipelineStageFlags stage_flags) const noexcept { | ||
| 958 | dld->vkCmdSetEvent(handle, event, stage_flags); | ||
| 959 | } | ||
| 960 | |||
| 941 | void BindTransformFeedbackBuffersEXT(u32 first, u32 count, const VkBuffer* buffers, | 961 | void BindTransformFeedbackBuffersEXT(u32 first, u32 count, const VkBuffer* buffers, |
| 942 | const VkDeviceSize* offsets, | 962 | const VkDeviceSize* offsets, |
| 943 | const VkDeviceSize* sizes) const noexcept { | 963 | const VkDeviceSize* sizes) const noexcept { |