You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-04 12:00:25 +00:00
Finish splitting functionality of the Vulkan and D3D12 backends into RenderingDeviceDriver.
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
|
||||
#include "core/templates/hash_map.h"
|
||||
#include "core/templates/paged_allocator.h"
|
||||
#include "drivers/vulkan/rendering_context_driver_vulkan.h"
|
||||
#include "servers/rendering/rendering_device_driver.h"
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
@@ -48,8 +49,6 @@
|
||||
#include <vulkan/vulkan.h>
|
||||
#endif
|
||||
|
||||
class VulkanContext;
|
||||
|
||||
// Design principles:
|
||||
// - Vulkan structs are zero-initialized and fields not requiring a non-zero value are omitted (except in cases where expresivity reasons apply).
|
||||
class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
|
||||
@@ -57,9 +56,99 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
|
||||
/**** GENERIC ****/
|
||||
/*****************/
|
||||
|
||||
VulkanContext *context = nullptr;
|
||||
VkDevice vk_device = VK_NULL_HANDLE; // Owned by the context.
|
||||
struct CommandQueue;
|
||||
struct SwapChain;
|
||||
|
||||
struct Queue {
|
||||
VkQueue queue = VK_NULL_HANDLE;
|
||||
uint32_t virtual_count = 0;
|
||||
BinaryMutex submit_mutex;
|
||||
};
|
||||
|
||||
struct SubgroupCapabilities {
|
||||
uint32_t size = 0;
|
||||
uint32_t min_size = 0;
|
||||
uint32_t max_size = 0;
|
||||
VkShaderStageFlags supported_stages = 0;
|
||||
VkSubgroupFeatureFlags supported_operations = 0;
|
||||
VkBool32 quad_operations_in_all_stages = false;
|
||||
bool size_control_is_supported = false;
|
||||
|
||||
uint32_t supported_stages_flags_rd() const;
|
||||
String supported_stages_desc() const;
|
||||
uint32_t supported_operations_flags_rd() const;
|
||||
String supported_operations_desc() const;
|
||||
};
|
||||
|
||||
struct VRSCapabilities {
|
||||
bool pipeline_vrs_supported = false; // We can specify our fragment rate on a pipeline level.
|
||||
bool primitive_vrs_supported = false; // We can specify our fragment rate on each drawcall.
|
||||
bool attachment_vrs_supported = false; // We can provide a density map attachment on our framebuffer.
|
||||
|
||||
Size2i min_texel_size;
|
||||
Size2i max_texel_size;
|
||||
|
||||
Size2i texel_size; // The texel size we'll use
|
||||
};
|
||||
|
||||
struct ShaderCapabilities {
|
||||
bool shader_float16_is_supported = false;
|
||||
bool shader_int8_is_supported = false;
|
||||
};
|
||||
|
||||
struct StorageBufferCapabilities {
|
||||
bool storage_buffer_16_bit_access_is_supported = false;
|
||||
bool uniform_and_storage_buffer_16_bit_access_is_supported = false;
|
||||
bool storage_push_constant_16_is_supported = false;
|
||||
bool storage_input_output_16 = false;
|
||||
};
|
||||
|
||||
struct DeviceFunctions {
|
||||
PFN_vkCreateSwapchainKHR CreateSwapchainKHR = nullptr;
|
||||
PFN_vkDestroySwapchainKHR DestroySwapchainKHR = nullptr;
|
||||
PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR = nullptr;
|
||||
PFN_vkAcquireNextImageKHR AcquireNextImageKHR = nullptr;
|
||||
PFN_vkQueuePresentKHR QueuePresentKHR = nullptr;
|
||||
PFN_vkCreateRenderPass2KHR CreateRenderPass2KHR = nullptr;
|
||||
};
|
||||
|
||||
VkDevice vk_device = VK_NULL_HANDLE;
|
||||
RenderingContextDriverVulkan *context_driver = nullptr;
|
||||
RenderingContextDriver::Device context_device = {};
|
||||
VkPhysicalDevice physical_device = VK_NULL_HANDLE;
|
||||
VkPhysicalDeviceProperties physical_device_properties = {};
|
||||
VkPhysicalDeviceFeatures physical_device_features = {};
|
||||
VkPhysicalDeviceFeatures requested_device_features = {};
|
||||
HashMap<CharString, bool> requested_device_extensions;
|
||||
HashSet<CharString> enabled_device_extension_names;
|
||||
TightLocalVector<TightLocalVector<Queue>> queue_families;
|
||||
TightLocalVector<VkQueueFamilyProperties> queue_family_properties;
|
||||
RDD::Capabilities device_capabilities;
|
||||
SubgroupCapabilities subgroup_capabilities;
|
||||
MultiviewCapabilities multiview_capabilities;
|
||||
VRSCapabilities vrs_capabilities;
|
||||
ShaderCapabilities shader_capabilities;
|
||||
StorageBufferCapabilities storage_buffer_capabilities;
|
||||
bool pipeline_cache_control_support = false;
|
||||
DeviceFunctions device_functions;
|
||||
|
||||
void _register_requested_device_extension(const CharString &p_extension_name, bool p_required);
|
||||
Error _initialize_device_extensions();
|
||||
Error _check_device_features();
|
||||
Error _check_device_capabilities();
|
||||
Error _add_queue_create_info(LocalVector<VkDeviceQueueCreateInfo> &r_queue_create_info);
|
||||
Error _initialize_device(const LocalVector<VkDeviceQueueCreateInfo> &p_queue_create_info);
|
||||
Error _initialize_allocator();
|
||||
Error _initialize_pipeline_cache();
|
||||
VkResult _create_render_pass(VkDevice p_device, const VkRenderPassCreateInfo2 *p_create_info, const VkAllocationCallbacks *p_allocator, VkRenderPass *p_render_pass);
|
||||
bool _release_image_semaphore(CommandQueue *p_command_queue, uint32_t p_semaphore_index, bool p_release_on_swap_chain);
|
||||
bool _recreate_image_semaphore(CommandQueue *p_command_queue, uint32_t p_semaphore_index, bool p_release_on_swap_chain);
|
||||
void _set_object_name(VkObjectType p_object_type, uint64_t p_object_handle, String p_object_name);
|
||||
|
||||
public:
|
||||
Error initialize(uint32_t p_device_index, uint32_t p_frame_count) override final;
|
||||
|
||||
private:
|
||||
/****************/
|
||||
/**** MEMORY ****/
|
||||
/****************/
|
||||
@@ -154,32 +243,104 @@ public:
|
||||
VectorView<BufferBarrier> p_buffer_barriers,
|
||||
VectorView<TextureBarrier> p_texture_barriers) override final;
|
||||
|
||||
/*************************/
|
||||
/**** COMMAND BUFFERS ****/
|
||||
/*************************/
|
||||
private:
|
||||
#ifdef DEBUG_ENABLED
|
||||
// Vulkan doesn't need to know if the command buffers created in a pool
|
||||
// will be primary or secondary, but RDD works like that, so we will enforce.
|
||||
/****************/
|
||||
/**** FENCES ****/
|
||||
/****************/
|
||||
|
||||
HashSet<CommandPoolID> secondary_cmd_pools;
|
||||
HashSet<CommandBufferID> secondary_cmd_buffers;
|
||||
#endif
|
||||
private:
|
||||
struct Fence {
|
||||
VkFence vk_fence = VK_NULL_HANDLE;
|
||||
CommandQueue *queue_signaled_from = nullptr;
|
||||
};
|
||||
|
||||
public:
|
||||
virtual FenceID fence_create() override final;
|
||||
virtual Error fence_wait(FenceID p_fence) override final;
|
||||
virtual void fence_free(FenceID p_fence) override final;
|
||||
|
||||
/********************/
|
||||
/**** SEMAPHORES ****/
|
||||
/********************/
|
||||
|
||||
virtual SemaphoreID semaphore_create() override final;
|
||||
virtual void semaphore_free(SemaphoreID p_semaphore) override final;
|
||||
|
||||
/******************/
|
||||
/**** COMMANDS ****/
|
||||
/******************/
|
||||
|
||||
// ----- QUEUE FAMILY -----
|
||||
|
||||
virtual CommandQueueFamilyID command_queue_family_get(BitField<CommandQueueFamilyBits> p_cmd_queue_family_bits, RenderingContextDriver::SurfaceID p_surface = 0) override final;
|
||||
|
||||
// ----- QUEUE -----
|
||||
private:
|
||||
struct CommandQueue {
|
||||
LocalVector<VkSemaphore> image_semaphores;
|
||||
LocalVector<SwapChain *> image_semaphores_swap_chains;
|
||||
LocalVector<uint32_t> pending_semaphores_for_execute;
|
||||
LocalVector<uint32_t> pending_semaphores_for_fence;
|
||||
LocalVector<uint32_t> free_image_semaphores;
|
||||
LocalVector<Pair<Fence *, uint32_t>> image_semaphores_for_fences;
|
||||
uint32_t queue_family = 0;
|
||||
uint32_t queue_index = 0;
|
||||
};
|
||||
|
||||
public:
|
||||
virtual CommandQueueID command_queue_create(CommandQueueFamilyID p_cmd_queue_family, bool p_identify_as_main_queue = false) override final;
|
||||
virtual Error command_queue_execute(CommandQueueID p_cmd_queue, VectorView<CommandBufferID> p_cmd_buffers, VectorView<SemaphoreID> p_wait_semaphores, VectorView<SemaphoreID> p_signal_semaphores, FenceID p_signal_fence) override final;
|
||||
virtual Error command_queue_present(CommandQueueID p_cmd_queue, VectorView<SwapChainID> p_swap_chains, VectorView<SemaphoreID> p_wait_semaphores) override final;
|
||||
virtual void command_queue_free(CommandQueueID p_cmd_queue) override final;
|
||||
|
||||
private:
|
||||
// ----- POOL -----
|
||||
|
||||
virtual CommandPoolID command_pool_create(CommandBufferType p_cmd_buffer_type) override final;
|
||||
struct CommandPool {
|
||||
VkCommandPool vk_command_pool = VK_NULL_HANDLE;
|
||||
CommandBufferType buffer_type = COMMAND_BUFFER_TYPE_PRIMARY;
|
||||
};
|
||||
|
||||
public:
|
||||
virtual CommandPoolID command_pool_create(CommandQueueFamilyID p_cmd_queue_family, CommandBufferType p_cmd_buffer_type) override final;
|
||||
virtual void command_pool_free(CommandPoolID p_cmd_pool) override final;
|
||||
|
||||
// ----- BUFFER -----
|
||||
|
||||
virtual CommandBufferID command_buffer_create(CommandBufferType p_cmd_buffer_type, CommandPoolID p_cmd_pool) override final;
|
||||
virtual CommandBufferID command_buffer_create(CommandPoolID p_cmd_pool) override final;
|
||||
virtual bool command_buffer_begin(CommandBufferID p_cmd_buffer) override final;
|
||||
virtual bool command_buffer_begin_secondary(CommandBufferID p_cmd_buffer, RenderPassID p_render_pass, uint32_t p_subpass, FramebufferID p_framebuffer) override final;
|
||||
virtual void command_buffer_end(CommandBufferID p_cmd_buffer) override final;
|
||||
virtual void command_buffer_execute_secondary(CommandBufferID p_cmd_buffer, VectorView<CommandBufferID> p_secondary_cmd_buffers) override final;
|
||||
|
||||
/********************/
|
||||
/**** SWAP CHAIN ****/
|
||||
/********************/
|
||||
|
||||
private:
|
||||
struct SwapChain {
|
||||
VkSwapchainKHR vk_swapchain = VK_NULL_HANDLE;
|
||||
RenderingContextDriver::SurfaceID surface = RenderingContextDriver::SurfaceID();
|
||||
VkFormat format = VK_FORMAT_UNDEFINED;
|
||||
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||
TightLocalVector<VkImage> images;
|
||||
TightLocalVector<VkImageView> image_views;
|
||||
TightLocalVector<FramebufferID> framebuffers;
|
||||
LocalVector<CommandQueue *> command_queues_acquired;
|
||||
LocalVector<uint32_t> command_queues_acquired_semaphores;
|
||||
RenderPassID render_pass;
|
||||
uint32_t image_index = 0;
|
||||
};
|
||||
|
||||
void _swap_chain_release(SwapChain *p_swap_chain);
|
||||
|
||||
public:
|
||||
virtual SwapChainID swap_chain_create(RenderingContextDriver::SurfaceID p_surface) override final;
|
||||
virtual Error swap_chain_resize(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, uint32_t p_desired_framebuffer_count) override final;
|
||||
virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override final;
|
||||
virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final;
|
||||
virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final;
|
||||
virtual void swap_chain_free(SwapChainID p_swap_chain) override final;
|
||||
|
||||
/*********************/
|
||||
/**** FRAMEBUFFER ****/
|
||||
/*********************/
|
||||
@@ -329,6 +490,7 @@ private:
|
||||
|
||||
static int caching_instance_count;
|
||||
PipelineCache pipelines_cache;
|
||||
String pipeline_cache_id;
|
||||
|
||||
public:
|
||||
virtual void pipeline_free(PipelineID p_pipeline) override final;
|
||||
@@ -439,25 +601,17 @@ public:
|
||||
virtual void command_begin_label(CommandBufferID p_cmd_buffer, const char *p_label_name, const Color &p_color) override final;
|
||||
virtual void command_end_label(CommandBufferID p_cmd_buffer) override final;
|
||||
|
||||
/****************/
|
||||
/**** SCREEN ****/
|
||||
/****************/
|
||||
|
||||
virtual DataFormat screen_get_format() override final;
|
||||
|
||||
/********************/
|
||||
/**** SUBMISSION ****/
|
||||
/********************/
|
||||
|
||||
virtual void begin_segment(CommandBufferID p_cmd_buffer, uint32_t p_frame_index, uint32_t p_frames_drawn) override final;
|
||||
virtual void begin_segment(uint32_t p_frame_index, uint32_t p_frames_drawn) override final;
|
||||
virtual void end_segment() override final;
|
||||
|
||||
/**************/
|
||||
/**** MISC ****/
|
||||
/**************/
|
||||
|
||||
VkPhysicalDeviceLimits limits = {};
|
||||
|
||||
virtual void set_object_name(ObjectType p_type, ID p_driver_id, const String &p_name) override final;
|
||||
virtual uint64_t get_resource_native_handle(DriverResource p_type, ID p_driver_id) override final;
|
||||
virtual uint64_t get_total_memory_used() override final;
|
||||
@@ -465,6 +619,10 @@ public:
|
||||
virtual uint64_t api_trait_get(ApiTrait p_trait) override final;
|
||||
virtual bool has_feature(Features p_feature) override final;
|
||||
virtual const MultiviewCapabilities &get_multiview_capabilities() override final;
|
||||
virtual String get_api_name() const override final;
|
||||
virtual String get_api_version() const override final;
|
||||
virtual String get_pipeline_cache_uuid() const override final;
|
||||
virtual const Capabilities &get_capabilities() const override final;
|
||||
|
||||
private:
|
||||
/*********************/
|
||||
@@ -482,7 +640,7 @@ private:
|
||||
/******************/
|
||||
|
||||
public:
|
||||
RenderingDeviceDriverVulkan(VulkanContext *p_context, VkDevice p_vk_device);
|
||||
RenderingDeviceDriverVulkan(RenderingContextDriverVulkan *p_context_driver);
|
||||
virtual ~RenderingDeviceDriverVulkan();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user