diff options
Diffstat (limited to 'drivers/vulkan/rendering_device_driver_vulkan.h')
-rw-r--r-- | drivers/vulkan/rendering_device_driver_vulkan.h | 208 |
1 files changed, 183 insertions, 25 deletions
diff --git a/drivers/vulkan/rendering_device_driver_vulkan.h b/drivers/vulkan/rendering_device_driver_vulkan.h index 1edee6b76e..4abaeecd11 100644 --- a/drivers/vulkan/rendering_device_driver_vulkan.h +++ b/drivers/vulkan/rendering_device_driver_vulkan.h @@ -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 ****/ - /*************************/ + /****************/ + /**** FENCES ****/ + /****************/ + 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. + struct Fence { + VkFence vk_fence = VK_NULL_HANDLE; + CommandQueue *queue_signaled_from = nullptr; + }; - HashSet<CommandPoolID> secondary_cmd_pools; - HashSet<CommandBufferID> secondary_cmd_buffers; -#endif +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(); }; |