summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_vulkan
diff options
context:
space:
mode:
authorGravatar bunnei2020-04-22 22:09:38 -0400
committerGravatar GitHub2020-04-22 22:09:38 -0400
commitbf2ddb8fd5feaeaf2806fe102de8e3089f893137 (patch)
treeb97d388da23608c00808b6662e3c0564fc4f6d59 /src/video_core/renderer_vulkan
parentMerge pull request #3767 from ReinUsesLisp/point-size-pipeline (diff)
parentGL_Fence_Manager: use GL_TIMEOUT_IGNORED instead of a loop, (diff)
downloadyuzu-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.cpp101
-rw-r--r--src/video_core/renderer_vulkan/vk_fence_manager.h74
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h3
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp55
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h8
-rw-r--r--src/video_core/renderer_vulkan/wrapper.cpp18
-rw-r--r--src/video_core/renderer_vulkan/wrapper.h20
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
15namespace Vulkan {
16
17InnerFence::InnerFence(const VKDevice& device, VKScheduler& scheduler, u32 payload, bool is_stubbed)
18 : VideoCommon::FenceBase(payload, is_stubbed), device{device}, scheduler{scheduler} {}
19
20InnerFence::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
24InnerFence::~InnerFence() = default;
25
26void 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
41bool InnerFence::IsSignaled() const {
42 if (is_stubbed) {
43 return true;
44 }
45 ASSERT(event);
46 return IsEventSignalled();
47}
48
49void 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
63bool 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
74VKFenceManager::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
81Fence VKFenceManager::CreateFence(u32 value, bool is_stubbed) {
82 return std::make_shared<InnerFence>(device, scheduler, value, is_stubbed);
83}
84
85Fence VKFenceManager::CreateFence(GPUVAddr addr, u32 value, bool is_stubbed) {
86 return std::make_shared<InnerFence>(device, scheduler, addr, value, is_stubbed);
87}
88
89void VKFenceManager::QueueFence(Fence& fence) {
90 fence->Queue();
91}
92
93bool VKFenceManager::IsFenceSignaled(Fence& fence) const {
94 return fence->IsSignaled();
95}
96
97void 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
12namespace Core {
13class System;
14}
15
16namespace VideoCore {
17class RasterizerInterface;
18}
19
20namespace Vulkan {
21
22class VKBufferCache;
23class VKDevice;
24class VKQueryCache;
25class VKScheduler;
26class VKTextureCache;
27
28class InnerFence : public VideoCommon::FenceBase {
29public:
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
42private:
43 bool IsEventSignalled() const;
44
45 const VKDevice& device;
46 VKScheduler& scheduler;
47 vk::Event event;
48 u64 ticks = 0;
49};
50using Fence = std::shared_ptr<InnerFence>;
51
52using GenericFenceManager =
53 VideoCommon::FenceManager<Fence, VKTextureCache, VKBufferCache, VKQueryCache>;
54
55class VKFenceManager final : public GenericFenceManager {
56public:
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
62protected:
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
69private:
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
365void RasterizerVulkan::Clear() { 370void 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
512bool 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
507void RasterizerVulkan::InvalidateRegion(VAddr addr, u64 size) { 519void 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
529void 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
539void RasterizerVulkan::SyncGuestHost() {
540 texture_cache.SyncGuestHost();
541 buffer_cache.SyncGuestHost();
542}
543
544void 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
553void 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
562void RasterizerVulkan::ReleaseFences() {
563 auto& gpu{system.GPU()};
564 if (!gpu.IsAsync()) {
565 return;
566 }
567 fence_manager.WaitPendingFences();
568}
569
517void RasterizerVulkan::FlushAndInvalidateRegion(VAddr addr, u64 size) { 570void 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
276void Destroy(VkDevice device, VkEvent handle, const DeviceDispatch& dld) noexcept {
277 dld.vkDestroyEvent(device, handle, nullptr);
278}
279
272void Destroy(VkDevice device, VkFence handle, const DeviceDispatch& dld) noexcept { 280void 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
610Event 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
602SwapchainKHR Device::CreateSwapchainKHR(const VkSwapchainCreateInfoKHR& ci) const { 620SwapchainKHR 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;
279void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept; 283void Destroy(VkDevice, VkDescriptorSetLayout, const DeviceDispatch&) noexcept;
280void Destroy(VkDevice, VkDescriptorUpdateTemplateKHR, const DeviceDispatch&) noexcept; 284void Destroy(VkDevice, VkDescriptorUpdateTemplateKHR, const DeviceDispatch&) noexcept;
281void Destroy(VkDevice, VkDeviceMemory, const DeviceDispatch&) noexcept; 285void Destroy(VkDevice, VkDeviceMemory, const DeviceDispatch&) noexcept;
286void Destroy(VkDevice, VkEvent, const DeviceDispatch&) noexcept;
282void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept; 287void Destroy(VkDevice, VkFence, const DeviceDispatch&) noexcept;
283void Destroy(VkDevice, VkFramebuffer, const DeviceDispatch&) noexcept; 288void Destroy(VkDevice, VkFramebuffer, const DeviceDispatch&) noexcept;
284void Destroy(VkDevice, VkImage, const DeviceDispatch&) noexcept; 289void 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
656class Event : public Handle<VkEvent, VkDevice, DeviceDispatch> {
657 using Handle<VkEvent, VkDevice, DeviceDispatch>::Handle;
658
659public:
660 VkResult GetStatus() const noexcept {
661 return dld->vkGetEventStatus(owner, handle);
662 }
663};
664
651class Device : public Handle<VkDevice, NoOwner, DeviceDispatch> { 665class 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 {