Merge pull request #2146 from ReinUsesLisp/vulkan-scheduler
vk_scheduler: Implement a scheduler
This commit is contained in:
		
						commit
						f7090bacc5
					
				| @ -109,7 +109,9 @@ if (ENABLE_VULKAN) | ||||
|         renderer_vulkan/vk_memory_manager.cpp | ||||
|         renderer_vulkan/vk_memory_manager.h | ||||
|         renderer_vulkan/vk_resource_manager.cpp | ||||
|         renderer_vulkan/vk_resource_manager.h) | ||||
|         renderer_vulkan/vk_resource_manager.h | ||||
|         renderer_vulkan/vk_scheduler.cpp | ||||
|         renderer_vulkan/vk_scheduler.h) | ||||
| 
 | ||||
|     target_include_directories(video_core PRIVATE ../../externals/Vulkan-Headers/include) | ||||
|     target_compile_definitions(video_core PRIVATE HAS_VULKAN) | ||||
|  | ||||
							
								
								
									
										60
									
								
								src/video_core/renderer_vulkan/vk_scheduler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/video_core/renderer_vulkan/vk_scheduler.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,60 @@ | ||||
| // Copyright 2019 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/assert.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "video_core/renderer_vulkan/declarations.h" | ||||
| #include "video_core/renderer_vulkan/vk_device.h" | ||||
| #include "video_core/renderer_vulkan/vk_resource_manager.h" | ||||
| #include "video_core/renderer_vulkan/vk_scheduler.h" | ||||
| 
 | ||||
| namespace Vulkan { | ||||
| 
 | ||||
| VKScheduler::VKScheduler(const VKDevice& device, VKResourceManager& resource_manager) | ||||
|     : device{device}, resource_manager{resource_manager} { | ||||
|     next_fence = &resource_manager.CommitFence(); | ||||
|     AllocateNewContext(); | ||||
| } | ||||
| 
 | ||||
| VKScheduler::~VKScheduler() = default; | ||||
| 
 | ||||
| VKExecutionContext VKScheduler::GetExecutionContext() const { | ||||
|     return VKExecutionContext(current_fence, current_cmdbuf); | ||||
| } | ||||
| 
 | ||||
| VKExecutionContext VKScheduler::Flush(vk::Semaphore semaphore) { | ||||
|     SubmitExecution(semaphore); | ||||
|     current_fence->Release(); | ||||
|     AllocateNewContext(); | ||||
|     return GetExecutionContext(); | ||||
| } | ||||
| 
 | ||||
| VKExecutionContext VKScheduler::Finish(vk::Semaphore semaphore) { | ||||
|     SubmitExecution(semaphore); | ||||
|     current_fence->Wait(); | ||||
|     current_fence->Release(); | ||||
|     AllocateNewContext(); | ||||
|     return GetExecutionContext(); | ||||
| } | ||||
| 
 | ||||
| void VKScheduler::SubmitExecution(vk::Semaphore semaphore) { | ||||
|     const auto& dld = device.GetDispatchLoader(); | ||||
|     current_cmdbuf.end(dld); | ||||
| 
 | ||||
|     const auto queue = device.GetGraphicsQueue(); | ||||
|     const vk::SubmitInfo submit_info(0, nullptr, nullptr, 1, ¤t_cmdbuf, semaphore ? 1u : 0u, | ||||
|                                      &semaphore); | ||||
|     queue.submit({submit_info}, *current_fence, dld); | ||||
| } | ||||
| 
 | ||||
| void VKScheduler::AllocateNewContext() { | ||||
|     current_fence = next_fence; | ||||
|     current_cmdbuf = resource_manager.CommitCommandBuffer(*current_fence); | ||||
|     next_fence = &resource_manager.CommitFence(); | ||||
| 
 | ||||
|     const auto& dld = device.GetDispatchLoader(); | ||||
|     current_cmdbuf.begin({vk::CommandBufferUsageFlagBits::eOneTimeSubmit}, dld); | ||||
| } | ||||
| 
 | ||||
| } // namespace Vulkan
 | ||||
							
								
								
									
										69
									
								
								src/video_core/renderer_vulkan/vk_scheduler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								src/video_core/renderer_vulkan/vk_scheduler.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,69 @@ | ||||
| // Copyright 2019 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "video_core/renderer_vulkan/declarations.h" | ||||
| 
 | ||||
| namespace Vulkan { | ||||
| 
 | ||||
| class VKDevice; | ||||
| class VKExecutionContext; | ||||
| class VKFence; | ||||
| class VKResourceManager; | ||||
| 
 | ||||
| /// The scheduler abstracts command buffer and fence management with an interface that's able to do
 | ||||
| /// OpenGL-like operations on Vulkan command buffers.
 | ||||
| class VKScheduler { | ||||
| public: | ||||
|     explicit VKScheduler(const VKDevice& device, VKResourceManager& resource_manager); | ||||
|     ~VKScheduler(); | ||||
| 
 | ||||
|     /// Gets the current execution context.
 | ||||
|     [[nodiscard]] VKExecutionContext GetExecutionContext() const; | ||||
| 
 | ||||
|     /// Sends the current execution context to the GPU. It invalidates the current execution context
 | ||||
|     /// and returns a new one.
 | ||||
|     VKExecutionContext Flush(vk::Semaphore semaphore = nullptr); | ||||
| 
 | ||||
|     /// Sends the current execution context to the GPU and waits for it to complete. It invalidates
 | ||||
|     /// the current execution context and returns a new one.
 | ||||
|     VKExecutionContext Finish(vk::Semaphore semaphore = nullptr); | ||||
| 
 | ||||
| private: | ||||
|     void SubmitExecution(vk::Semaphore semaphore); | ||||
| 
 | ||||
|     void AllocateNewContext(); | ||||
| 
 | ||||
|     const VKDevice& device; | ||||
|     VKResourceManager& resource_manager; | ||||
|     vk::CommandBuffer current_cmdbuf; | ||||
|     VKFence* current_fence = nullptr; | ||||
|     VKFence* next_fence = nullptr; | ||||
| }; | ||||
| 
 | ||||
| class VKExecutionContext { | ||||
|     friend class VKScheduler; | ||||
| 
 | ||||
| public: | ||||
|     VKExecutionContext() = default; | ||||
| 
 | ||||
|     VKFence& GetFence() const { | ||||
|         return *fence; | ||||
|     } | ||||
| 
 | ||||
|     vk::CommandBuffer GetCommandBuffer() const { | ||||
|         return cmdbuf; | ||||
|     } | ||||
| 
 | ||||
| private: | ||||
|     explicit VKExecutionContext(VKFence* fence, vk::CommandBuffer cmdbuf) | ||||
|         : fence{fence}, cmdbuf{cmdbuf} {} | ||||
| 
 | ||||
|     VKFence* fence{}; | ||||
|     vk::CommandBuffer cmdbuf; | ||||
| }; | ||||
| 
 | ||||
| } // namespace Vulkan
 | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei