diff --git a/include/vuk/Context.hpp b/include/vuk/Context.hpp index e0d98c54..6936eb9b 100644 --- a/include/vuk/Context.hpp +++ b/include/vuk/Context.hpp @@ -80,6 +80,19 @@ namespace vuk { class Context : public ContextCreateParameters::FunctionPointers { public: + /// @brief Create a new Context + /// @param params Vulkan parameters initialized beforehand + Context(ContextCreateParameters params); + ~Context(); + + Context(const Context&) = delete; + Context& operator=(const Context&) = delete; + + Context(Context&&) noexcept; + Context& operator=(Context&&) noexcept; + + // Vulkan instance, device and queues + VkInstance instance; VkDevice device; VkPhysicalDevice physical_device; @@ -95,54 +108,54 @@ namespace vuk { Queue* compute_queue = nullptr; Queue* transfer_queue = nullptr; + // Vulkan properties + VkPhysicalDeviceProperties physical_device_properties; VkPhysicalDeviceRayTracingPipelinePropertiesKHR rt_properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PIPELINE_PROPERTIES_KHR }; VkPhysicalDeviceAccelerationStructurePropertiesKHR as_properties{ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_PROPERTIES_KHR }; size_t min_buffer_alignment; - VkPipelineCache vk_pipeline_cache = VK_NULL_HANDLE; - - Result wait_for_domains(std::span> queue_waits); - - uint64_t get_frame_count() const; - - /// @brief Create a new Context - /// @param params Vulkan parameters initialized beforehand - Context(ContextCreateParameters params); - ~Context(); - - Context(const Context&) = delete; - Context& operator=(const Context&) = delete; - - Context(Context&&) noexcept; - Context& operator=(Context&&) noexcept; - + // Debug functions + + /// @brief If debug utils is available and debug names & markers are supported bool debug_enabled() const; - void set_name(const Texture& iv, Name name); + /// @brief Set debug name for Texture + void set_name(const Texture&, Name name); + + /// @brief Set debug name for object template void set_name(const T& t, Name name); + /// @brief Add debug region to command buffer + /// @param name Name of the region + /// @param color Display color of the region void begin_region(const VkCommandBuffer&, Name name, std::array color = { 1, 1, 1, 1 }); + /// @brief End debug region in command buffer void end_region(const VkCommandBuffer&); + // Pipeline management + + /// Internal pipeline cache to use + VkPipelineCache vk_pipeline_cache = VK_NULL_HANDLE; + + /// @brief Create a pipeline base that can be recalled by name void create_named_pipeline(Name name, PipelineBaseCreateInfo pbci); + /// @brief Recall name pipeline base PipelineBaseInfo* get_named_pipeline(Name name); PipelineBaseInfo* get_pipeline(const PipelineBaseCreateInfo& pbci); + /// @brief Reflect given pipeline base Program get_pipeline_reflection_info(const PipelineBaseCreateInfo& pbci); + /// @brief Explicitly compile give ShaderSource into a ShaderModule ShaderModule compile_shader(ShaderSource source, std::string path); + /// @brief Load a Vulkan pipeline cache bool load_pipeline_cache(std::span data); + /// @brief Retrieve the current Vulkan pipeline cache std::vector save_pipeline_cache(); - Queue& domain_to_queue(DomainFlags) const; - uint32_t domain_to_queue_index(DomainFlags) const; - uint32_t domain_to_queue_family_index(DomainFlags) const; - - Query create_timestamp_query(); - // Allocator support /// @brief Return an allocator over the direct resource - resources will be allocated from the Vulkan runtime @@ -151,6 +164,8 @@ namespace vuk { Texture allocate_texture(Allocator& allocator, ImageCreateInfo ici, SourceLocationAtFrame loc = VUK_HERE_AND_NOW()); + // Swapchain management + /// @brief Add a swapchain to be managed by the Context /// @return Reference to the new swapchain that can be used during presentation SwapchainRef add_swapchain(Swapchain); @@ -159,26 +174,29 @@ namespace vuk { /// the swapchain is not destroyed void remove_swapchain(SwapchainRef); + // Frame management + + /// @brief Retrieve the current frame count + uint64_t get_frame_count() const; + /// @brief Advance internal counter used for caching and garbage collect caches void next_frame(); /// @brief Wait for the device to become idle. Useful for only a few synchronisation events, like resizing or shutting down. Result wait_idle(); - /// @brief Create a wrapped handle type (eg. a ImageView) from an externally sourced Vulkan handle - /// @tparam T Vulkan handle type to wrap - /// @param payload Vulkan handle to wrap - /// @return The wrapped handle. - template - Handle wrap(T payload); - Result submit_graphics(std::span, VkFence); Result submit_transfer(std::span, VkFence); Result submit_graphics(std::span); Result submit_transfer(std::span); + Result wait_for_domains(std::span> queue_waits); + // Query functionality + /// @brief Create a timestamp query to record timing information + Query create_timestamp_query(); + /// @brief Checks if a timestamp query is available /// @param q the Query to check /// @return true if the timestamp is available @@ -198,14 +216,14 @@ namespace vuk { /// @brief Retrieve results from `TimestampQueryPool`s and make them available to retrieve_timestamp and retrieve_duration Result make_timestamp_results_available(std::span pools); - DescriptorSetStrategyFlags default_descriptor_set_strategy = {}; - // Caches /// @brief Acquire a cached sampler Sampler acquire_sampler(const SamplerCreateInfo& cu, uint64_t absolute_frame); /// @brief Acquire a cached descriptor pool struct DescriptorPool& acquire_descriptor_pool(const struct DescriptorSetLayoutAllocInfo& dslai, uint64_t absolute_frame); + /// @brief Force collection of caches + void collect(uint64_t frame); // Persistent descriptor sets @@ -213,10 +231,28 @@ namespace vuk { Unique create_persistent_descriptorset(Allocator& allocator, const PipelineBaseInfo& base, unsigned set, unsigned num_descriptors); Unique create_persistent_descriptorset(Allocator& allocator, const PersistentDescriptorSetCreateInfo&); - void collect(uint64_t frame); + // Misc. + /// @brief Descriptor set strategy to use by default, can be overridden on the CommandBuffer + DescriptorSetStrategyFlags default_descriptor_set_strategy = {}; + /// @brief Retrieve a unique uint64_t value uint64_t get_unique_handle_id(); + /// @brief Create a wrapped handle type (eg. a ImageView) from an externally sourced Vulkan handle + /// @tparam T Vulkan handle type to wrap + /// @param payload Vulkan handle to wrap + /// @return The wrapped handle. + template + Handle wrap(T payload); + + Queue& domain_to_queue(DomainFlags) const; + uint32_t domain_to_queue_index(DomainFlags) const; + uint32_t domain_to_queue_family_index(DomainFlags) const; + + private: + struct ContextImpl* impl; + friend struct ContextImpl; + // internal functions void destroy(const struct DescriptorPool& dp); void destroy(const ShaderModule& sm); @@ -232,9 +268,6 @@ namespace vuk { DescriptorSetLayoutAllocInfo create(const struct DescriptorSetLayoutCreateInfo& cinfo); DescriptorPool create(const struct DescriptorSetLayoutAllocInfo& cinfo); Sampler create(const struct SamplerCreateInfo& cinfo); - - private: - struct ContextImpl* impl; }; template diff --git a/src/ContextImpl.hpp b/src/ContextImpl.hpp index c2272373..6c575afc 100644 --- a/src/ContextImpl.hpp +++ b/src/ContextImpl.hpp @@ -15,18 +15,18 @@ #include namespace vuk { - template - struct FN { - static T create_fn(void* ctx, const create_info_t& ci) { - return reinterpret_cast(ctx)->create(ci); - } + struct ContextImpl { + template + struct FN { + static T create_fn(void* ctx, const create_info_t& ci) { + return reinterpret_cast(ctx)->create(ci); + } - static void destroy_fn(void* ctx, const T& v) { - return reinterpret_cast(ctx)->destroy(v); - } - }; + static void destroy_fn(void* ctx, const T& v) { + return reinterpret_cast(ctx)->destroy(v); + } + }; - struct ContextImpl { VkDevice device; std::unique_ptr device_vk_resource;