diff --git a/source/runtime/render/renderer/raster/RasterRenderer.cpp b/source/runtime/render/renderer/raster/RasterRenderer.cpp index 7ae41fe15..a534646f2 100644 --- a/source/runtime/render/renderer/raster/RasterRenderer.cpp +++ b/source/runtime/render/renderer/raster/RasterRenderer.cpp @@ -78,6 +78,11 @@ RasterRenderer::RasterRenderer( gfx_queue.Sync(); // Other vars + + LOG_INFO( + "Cooperative Matrix & Vector Extensions is Enabled: {}", + device.IsExtensionCooperativeEnabled() ? "Yes" : "No" + ); } RasterRenderer::~RasterRenderer() { diff --git a/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp b/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp index eeccef458..32374e6b0 100644 --- a/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp +++ b/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp @@ -10,7 +10,7 @@ #include "rhi/RHI.h" #include "rhi/RHICommand.h" #include "rhi/RHIResource.h" -#include "rhi/extension/NrdExtension.h" +#include "rhi/plugin/NrdPlugin.h" #include "scene/GpuScene.h" #include "scene/loader/LoaderInterface.h" #include "shader/ShaderResourceManager.h" @@ -145,8 +145,8 @@ void RaytracingRenderer::Run(const SharedPtr editor_config, const ////////////////////////////////////////////////////////////////////////// #if WITH_NRD uint64 nrd_time = 0ull; - auto* nrd_ext = device.LoadExtension(); - auto nrd_interface = nrd_ext->CreateInterface(max_frame_in_flight, resolution.x, resolution.y); + auto* nrd_plugin = device.LoadPlugin(); + auto nrd_interface = nrd_plugin->CreateInterface(max_frame_in_flight, resolution.x, resolution.y); #endif VisualizeConfig visualize_config{}; diff --git a/source/runtime/render/rhi/RHI.h b/source/runtime/render/rhi/RHI.h index 4932ddbe3..912984b26 100644 --- a/source/runtime/render/rhi/RHI.h +++ b/source/runtime/render/rhi/RHI.h @@ -84,14 +84,16 @@ struct DeviceConfig { uint b_support_virtual_texture : 1; }; -class DeviceExtension { +// RuntimePlugin用于承载运行时可选插件 +// 旧名字为DeviceExtension,重命名是为了避免和Vulkan API扩展概念混淆 +class RuntimePlugin { protected: - virtual ~DeviceExtension() = default; + virtual ~RuntimePlugin() = default; }; template concept DeviceExt = - std::is_base_of_v && std::is_same_v; + std::is_base_of_v && std::is_same_v; class RenderDevice { public: @@ -196,7 +198,9 @@ class RenderDevice { } template - RENDER_API Ext* LoadExtension() const; + RENDER_API Ext* LoadPlugin() const; + + RENDER_API bool IsExtensionCooperativeEnabled() const; RENDER_API void FlushDebugMessages() const; RENDER_API void WaitIdle(); diff --git a/source/runtime/render/rhi/RHIImpl.cpp b/source/runtime/render/rhi/RHIImpl.cpp index 0d218bfdf..4414d7267 100644 --- a/source/runtime/render/rhi/RHIImpl.cpp +++ b/source/runtime/render/rhi/RHIImpl.cpp @@ -5,7 +5,7 @@ #include "rhi/RHIResource.h" #include "shader/ShaderResourceManager.h" -#include "rhi/extension/NrdExtension.h" +#include "rhi/plugin/NrdPlugin.h" namespace Moer::Render { PipelineHandle RenderDevice::CreatePipeline(GfxPsoCreateInfo&& _pso_info, PipelineShaderInfo&& _shaders) { return impl->CreatePipeline(std::move(_pso_info), std::move(_shaders)); @@ -123,8 +123,12 @@ RaytracingSceneRef RenderDevice::CreateRaytracingScene() { } template -Ext* RenderDevice::LoadExtension() const { - return static_cast(impl->LoadExtension(Ext::name)); +Ext* RenderDevice::LoadPlugin() const { + return static_cast(impl->LoadPlugin(Ext::name)); +} + +bool RenderDevice::IsExtensionCooperativeEnabled() const { + return impl && impl->IsExtensionCooperativeEnabled(); } void RenderDevice::FlushDebugMessages() const { @@ -135,6 +139,6 @@ void RenderDevice::WaitIdle() { impl->WaitIdle(); } -template RENDER_API Ext::NRDExtension* RenderDevice::LoadExtension() const; +template RENDER_API Ext::NRDPlugin* RenderDevice::LoadPlugin() const; } // namespace Moer::Render \ No newline at end of file diff --git a/source/runtime/render/rhi/RHIImpl.h b/source/runtime/render/rhi/RHIImpl.h index 592862338..dc688c67b 100644 --- a/source/runtime/render/rhi/RHIImpl.h +++ b/source/runtime/render/rhi/RHIImpl.h @@ -1706,7 +1706,7 @@ class RenderDevice::Impl { CreatePipeline(GfxPsoCreateInfo&& _pso_info, PipelineShaderInfo&& _shaders) = 0; //gfx virtual PipelineHandle CreatePipeline(PipelineShaderInfo&& _shaders) = 0; //compute - virtual DeviceExtension* LoadExtension(std::string_view _name) { + virtual RuntimePlugin* LoadPlugin(std::string_view _name) { return nullptr; } @@ -1718,6 +1718,10 @@ class RenderDevice::Impl { ; // do nothing by default } + virtual bool IsExtensionCooperativeEnabled() const { + return false; + } + virtual void WaitIdle() {}; }; diff --git a/source/runtime/render/rhi/extension/NrdExtension.h b/source/runtime/render/rhi/plugin/NrdPlugin.h similarity index 95% rename from source/runtime/render/rhi/extension/NrdExtension.h rename to source/runtime/render/rhi/plugin/NrdPlugin.h index a8888fa7e..12bf42342 100644 --- a/source/runtime/render/rhi/extension/NrdExtension.h +++ b/source/runtime/render/rhi/plugin/NrdPlugin.h @@ -1,5 +1,5 @@ -#ifndef MOER_NRD_EXTENSION_H -#define MOER_NRD_EXTENSION_H +#ifndef MOER_NRD_PLUGIN_H +#define MOER_NRD_PLUGIN_H /** * 因为NVIDIA的NRD为闭源协议,所以MoerEngine无法直接引入NRD相关头文件和库文件,只能以插件的形式提供NRD支持。 @@ -172,10 +172,10 @@ class NRDInterface { UnorderedMap cmd_lists_on_use = {}; }; -class NRDExtension : public DeviceExtension { +class NRDPlugin : public RuntimePlugin { public: - ~NRDExtension() = default; - static constexpr std::string_view name = "NRDExt"; + ~NRDPlugin() = default; + static constexpr std::string_view name = "NRDPlugin"; virtual UniquePtr CreateInterface(uint8 _max_frame_in_flight = 0, uint16 _frame_width = 0, uint16 _frame_height = 0) = 0; diff --git a/source/runtime/render/rhi/vulkan/VulkanDebugCallback.cpp b/source/runtime/render/rhi/vulkan/VulkanDebugCallback.cpp index 23d69064e..0970621e7 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDebugCallback.cpp +++ b/source/runtime/render/rhi/vulkan/VulkanDebugCallback.cpp @@ -3,11 +3,12 @@ #include "log/LogSystem.h" #include "vulkan/vulkan_core.h" -#include +#include #include #include #include #include +#include #include namespace Moer::Render { @@ -22,6 +23,69 @@ struct BufEntry { }; static std::mutex s_debugbuf_mutex; static std::unordered_map s_debugbuf; +static std::atomic_bool s_logged_unknown_coop_matrix_layer{false}; +static std::atomic_bool s_logged_unknown_coop_vector_layer{false}; + +void LogUnknownCooperativeLayerInfo(std::atomic_bool& _once_flag, const char* _extension_name) { + bool expected = false; + if (_once_flag.compare_exchange_strong(expected, true)) { + LOG_INFO( + "VulkanRHI: Validation layer does not recognize {}. Consider updating VulkanSDK to 1.4 or newer " + "for accurate validation results.", + _extension_name + ); + } +} + +bool TryHandleKnownCooperativeLayerWarning(const VkDebugUtilsMessengerCallbackDataEXT* _callback_data) { + if (_callback_data == nullptr || _callback_data->pMessage == nullptr) { + return false; + } + + const std::string_view message(_callback_data->pMessage); + const std::string_view message_id_name( + _callback_data->pMessageIdName != nullptr ? _callback_data->pMessageIdName : "" + ); + if (message.find("is not supported by this layer") == std::string_view::npos) { + const bool is_unknown_pnext_struct = + message.find("unknown VkStructureType") != std::string_view::npos; + if (is_unknown_pnext_struct && message_id_name == "VUID-VkDeviceCreateInfo-pNext-pNext" && + message.find("vkCreateDevice()") != std::string_view::npos && + message.find("VkStructureType (1000491000)") != std::string_view::npos) { + LogUnknownCooperativeLayerInfo( + s_logged_unknown_coop_vector_layer, VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME + ); + return true; + } + + if (is_unknown_pnext_struct && message_id_name == "VUID-VkPhysicalDeviceProperties2-pNext-pNext" && + message.find("vkGetPhysicalDeviceProperties2()") != std::string_view::npos && + message.find("VkStructureType (1000491001)") != std::string_view::npos) { + LogUnknownCooperativeLayerInfo( + s_logged_unknown_coop_vector_layer, VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME + ); + return true; + } + + return false; + } + + if (message.find(VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME) != std::string_view::npos) { + LogUnknownCooperativeLayerInfo( + s_logged_unknown_coop_matrix_layer, VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME + ); + return true; + } + + if (message.find(VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME) != std::string_view::npos) { + LogUnknownCooperativeLayerInfo( + s_logged_unknown_coop_vector_layer, VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME + ); + return true; + } + + return false; +} } // namespace @@ -59,6 +123,10 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback( if (p_callback_data == nullptr) return VK_FALSE; + if (TryHandleKnownCooperativeLayerWarning(p_callback_data)) { + return VK_FALSE; + } + // preserve original formatting: normalize CRLF -> LF, trim leading/trailing whitespace/newlines auto flatten_message = [](const std::string& s) { std::string out; @@ -97,7 +165,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback( sev_val = 0; const auto now = std::chrono::steady_clock::now(); - constexpr auto kMergeWindow = std::chrono::milliseconds(8); + constexpr auto merge_window = std::chrono::milliseconds(8); std::string key = std::to_string(p_callback_data->messageIdNumber) + ":" + (p_callback_data->pMessageIdName ? p_callback_data->pMessageIdName : ""); @@ -113,7 +181,7 @@ VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback( s_debugbuf.emplace(key, BufEntry{part, now, sev_val}); } else { // existing entry - if (now - it->second.ts <= kMergeWindow) { + if (now - it->second.ts <= merge_window) { // within merge window: append (with newline) preserving internal newlines if (!it->second.text.empty() && it->second.text.back() != '\n') it->second.text.push_back('\n'); diff --git a/source/runtime/render/rhi/vulkan/VulkanDevice.cpp b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp index af354635a..b1d152cae 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDevice.cpp +++ b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp @@ -6,13 +6,14 @@ #include "PixelFormat.h" #include "VulkanCommand.h" #include "VulkanDebugCallback.h" -#include "VulkanExtension.h" #include "VulkanMacroUtils.h" #include "VulkanPlatform.h" #include "VulkanQueue.h" #include "VulkanRHIResource.h" #include "VulkanUtil.h" -#include "extension/VulkanNrdExtension.h" +#include "plugin/VulkanNrdPlugin.h" +#include "vulkanextension/VulkanCooperativeSupport.h" +#include "vulkanextension/VulkanExtension.h" #include #include "log/LogSystem.h" @@ -341,11 +342,14 @@ VkPhysicalDevice VulkanDevice::SelectGpu(uint32 _api_version) { */ void VulkanDevice::InitGpu(uint32 _api_version) { // Enable extensions - auto gpu_extensions = VulkanDevice::GetGpuExtensions(m_gpu); + auto gpu_extensions = VulkanDevice::GetGpuExtensions(m_gpu); + m_device_info.enabled_extensions = VulkanDeviceExtension::GetMEEnabledDeviceExtensions(gpu_extensions); // Query core features m_device_info.core_features = VulkanDeviceFeatures::GetGpuFeatures(m_gpu, _api_version); + // 先从 core feature 中提取 cooperative bundle 需要的前置能力。 + UpdateCooperativePrerequisites(m_device_info.core_features, m_device_info.optional_extensions); // Query advanced features, use advanced features as GPU supported, and developers cannot specify them. { VkPhysicalDeviceFeatures2 features2{}; @@ -369,6 +373,9 @@ void VulkanDevice::InitGpu(uint32 _api_version) { extension->PreGpuProperties(this, props2); } vkGetPhysicalDeviceProperties2(m_gpu, &props2); + for (const auto& extension : m_device_info.enabled_extensions) { + extension->PostGpuProperties(this); + } } // Query core memory properties @@ -396,6 +403,8 @@ void VulkanDevice::InitGpu(uint32 _api_version) { m_device_info.core_properties.core_1_0.limits.maxBoundDescriptorSets, m_device_info.core_properties.core_1_0.limits.timestampComputeAndGraphics ); + // 启动时输出 cooperative 支持摘要,便于后续调试 shader/toolchain 问题。 + LogCooperativeSupportSummary(m_device_info.optional_extensions, m_device_info.optional_properties); } void VulkanDevice::CreateDevice(uint32 _api_version) { @@ -428,6 +437,10 @@ void VulkanDevice::CreateDevice(uint32 _api_version) { // setup extension and feature info Moer::Array extensions_loaded; for (const auto& extension : m_device_info.enabled_extensions) { + if (!extension || !extension->ShouldEnableDeviceCreate()) { + // 如果拓展不启用或者不可用,则跳过 + continue; + } extensions_loaded.emplace_back(extension->GetExtensionName().data()); extension->PreCreateDevice(device_create_info); LOG_INFO("Loading VulkanDeviceExtension: {}", extension->GetExtensionName()); @@ -638,12 +651,19 @@ void VulkanDevice::Destroy() { // Assertion failed: m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!" } -Set VulkanDevice::GetGpuExtensions(VkPhysicalDevice _gpu) { - uint32 gpu_extension_count; - // check extensions - vkEnumerateDeviceExtensionProperties(_gpu, nullptr, &gpu_extension_count, nullptr); +Set VulkanDevice::GetGpuExtensions(VkPhysicalDevice _gpu, const char* _layer_name) { + uint32_t gpu_extension_count = 0; + VkResult result = vkEnumerateDeviceExtensionProperties(_gpu, _layer_name, &gpu_extension_count, nullptr); + if (result != VK_SUCCESS || gpu_extension_count == 0) { + return {}; + } + Array gpu_extensions(gpu_extension_count); - vkEnumerateDeviceExtensionProperties(_gpu, nullptr, &gpu_extension_count, gpu_extensions.data()); + result = + vkEnumerateDeviceExtensionProperties(_gpu, _layer_name, &gpu_extension_count, gpu_extensions.data()); + if (result != VK_SUCCESS) { + return {}; + } Set ret; for (const auto& extension : gpu_extensions) @@ -809,13 +829,17 @@ VkDescriptorType METoVkDescriptorType(uint _desc_type) { bool VulkanDevice::HasDeviceExtension(std::string_view _ext_name) const { for (const auto& ext : m_device_info.enabled_extensions) { - if (ext && ext->GetExtensionName() == _ext_name) { + if (ext && ext->ShouldEnableDeviceCreate() && ext->GetExtensionName() == _ext_name) { return true; } } return false; } +bool VulkanDevice::IsExtensionCooperativeEnabled() const { + return m_device_info.optional_extensions.IsExtensionCooperativeEnabled(); +} + bool VulkanDevice::IsAmdGpu() const { VkPhysicalDeviceProperties props{}; vkGetPhysicalDeviceProperties(m_gpu, &props); @@ -1696,7 +1720,7 @@ void VulkanDevice::SetResourceName(uint64 _handle, VkObjectType _type, const std vkSetDebugUtilsObjectNameEXT(m_device, &name_info); } -DeviceExtension* VulkanDevice::LoadExtension(std::string_view _name) { +RuntimePlugin* VulkanDevice::LoadPlugin(std::string_view _name) { auto ite = exts.find(_name.data()); if (ite == exts.end()) return nullptr; @@ -1727,12 +1751,12 @@ void VulkanDevice::LoadDefaultExtensions() { #if WITH_NRD exts.try_emplace( - Moer::Render::Ext::NRDExtension::name.data(), - [](VulkanDevice* _device) -> DeviceExtension* { - return MoerNew(Moer::Render::Ext::VkNRDExtension(_device)); + Moer::Render::Ext::NRDPlugin::name.data(), + [](VulkanDevice* _device) -> RuntimePlugin* { + return MoerNew(Moer::Render::Ext::VkNRDPlugin(_device)); }, - [](DeviceExtension* _ext) { - MoerDelete(static_cast(_ext)); + [](RuntimePlugin* _ext) { + MoerDelete(static_cast(_ext)); } ); #endif diff --git a/source/runtime/render/rhi/vulkan/VulkanDevice.h b/source/runtime/render/rhi/vulkan/VulkanDevice.h index 9c9760de0..321c31559 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDevice.h +++ b/source/runtime/render/rhi/vulkan/VulkanDevice.h @@ -15,11 +15,11 @@ #include "VulkanDescriptor.h" #include "VulkanDeviceFeature.h" #include "VulkanDeviceProperty.h" -#include "VulkanExtension.h" #include "VulkanPlatform.h" #include "VulkanQueue.h" #include "VulkanTypeDefs.h" #include "vulkan/vulkan_core.h" +#include "vulkanextension/VulkanExtension.h" // #include #include "VulkanMemoryAllocator.h" @@ -116,6 +116,7 @@ class VulkanDevice : public RenderDevice::Impl { IOInterfaceRef CreateIOInterface(CopyQueue& _copy_queue) override; void FlushDebugMessages() const override; + bool IsExtensionCooperativeEnabled() const override; void WaitIdle() override; // 判断当前物理设备是否为 AMD(基于 vendorID) @@ -143,14 +144,14 @@ class VulkanDevice : public RenderDevice::Impl { void CopyData(void* _dst, const BufferView& _src, uint64 _size); public: - DeviceExtension* LoadExtension(std::string_view _name) override; + RuntimePlugin* LoadPlugin(std::string_view _name) override; struct Ext { - using Ctor = std::function; - using Dtor = std::function; - DeviceExtension* ext; - Ctor ctor; - Dtor dtor; + using Ctor = std::function; + using Dtor = std::function; + RuntimePlugin* ext; + Ctor ctor; + Dtor dtor; Ext(Ctor ctor, Dtor dtor) : ext{nullptr}, ctor{ctor}, dtor{dtor} {} Ext(Ext const&) = delete; Ext(Ext&& rhs) : ext{rhs.ext}, ctor{rhs.ctor}, dtor{rhs.dtor} { @@ -246,11 +247,11 @@ class VulkanDevice : public RenderDevice::Impl { VkDebugUtilsMessengerEXT m_debug_utils_messenger = VK_NULL_HANDLE; - VmaAllocator m_allocator = VK_NULL_HANDLE; - VulkanDescriptorHeap m_global_descriptor_heap{}; - UniquePtr gfx_queue{}; // VkCommandQueue是MoerEngine的封装! - UniquePtr compute_queue{}; - UniquePtr copy_queue{}; + VmaAllocator m_allocator = VK_NULL_HANDLE; + VulkanDescriptorHeap m_global_descriptor_heap{}; + UniquePtr gfx_queue{}; // VkCommandQueue是MoerEngine的封装! + UniquePtr compute_queue{}; + UniquePtr copy_queue{}; // 这个锁只在AMD GPU上使用,因为AMD GPU没有TransferQueue // 在现代NVIDIA GPU上,这个锁不会被触发,接近0开销,不用在意性能 std::mutex m_shared_queue_submit_mutex; @@ -286,7 +287,7 @@ class VulkanDevice : public RenderDevice::Impl { void Destroy(); - static Set GetGpuExtensions(VkPhysicalDevice _gpu); + static Set GetGpuExtensions(VkPhysicalDevice _gpu, const char* _layer_name = nullptr); static TQueueFamilyPropertiesArray GetQueueFamilyProperties(VkPhysicalDevice _gpu); int32_t GetQueueFamilyIndex( diff --git a/source/runtime/render/rhi/vulkan/VulkanDeviceFeature.h b/source/runtime/render/rhi/vulkan/VulkanDeviceFeature.h index 381812ad6..d02db05a7 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDeviceFeature.h +++ b/source/runtime/render/rhi/vulkan/VulkanDeviceFeature.h @@ -16,6 +16,14 @@ class VulkanDeviceFeatures { bool Contains(const VulkanDeviceFeatures& _other) const; + inline const VkPhysicalDeviceVulkan11Features& GetCore11Features() const { + return core_1_1; + } + + inline const VkPhysicalDeviceVulkan12Features& GetCore12Features() const { + return core_1_2; + } + void PreCreateDevice(VkDeviceCreateInfo& _device_create_info, uint32_t _api_version); VkPhysicalDeviceFeatures core_1_0; diff --git a/source/runtime/render/rhi/vulkan/VulkanDeviceProperty.h b/source/runtime/render/rhi/vulkan/VulkanDeviceProperty.h index 4712d09a0..9ce110711 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDeviceProperty.h +++ b/source/runtime/render/rhi/vulkan/VulkanDeviceProperty.h @@ -2,6 +2,8 @@ #define VULKAN_DEVICE_PROPERTY_H #include "VulkanPlatform.h" +#include "misc/STL.h" + class VulkanCoreDeviceProperties { public: @@ -20,18 +22,24 @@ class VulkanCoreDeviceProperties { class VulkanOptionalDeviceProperties { public: // descriptor buffer - VkPhysicalDeviceDescriptorBufferPropertiesEXT descriptor_buffer_properties; - VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor_properties; + VkPhysicalDeviceDescriptorBufferPropertiesEXT descriptor_buffer_properties{}; + VkPhysicalDevicePushDescriptorPropertiesKHR push_descriptor_properties{}; // ray tracing - VkPhysicalDeviceAccelerationStructurePropertiesKHR acceleration_structure_properties; - VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties; + VkPhysicalDeviceAccelerationStructurePropertiesKHR acceleration_structure_properties{}; + VkPhysicalDeviceRayTracingPipelinePropertiesKHR ray_tracing_pipeline_properties{}; // mesh shader - VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties; + VkPhysicalDeviceMeshShaderPropertiesEXT mesh_shader_properties{}; // memory copy indirect - VkPhysicalDeviceCopyMemoryIndirectPropertiesNV copy_memory_indirect_properties; - VkPhysicalDeviceMemoryDecompressionPropertiesNV memory_decompression_properties; + VkPhysicalDeviceCopyMemoryIndirectPropertiesNV copy_memory_indirect_properties{}; + VkPhysicalDeviceMemoryDecompressionPropertiesNV memory_decompression_properties{}; + + // cooperative + VkPhysicalDeviceCooperativeMatrixPropertiesKHR cooperative_matrix_properties{}; + VkPhysicalDeviceCooperativeVectorPropertiesNV cooperative_vector_properties{}; + Moer::Array cooperative_matrix_supports{}; + Moer::Array cooperative_vector_supports{}; }; #endif \ No newline at end of file diff --git a/source/runtime/render/rhi/vulkan/VulkanExtension.h b/source/runtime/render/rhi/vulkan/VulkanExtension.h deleted file mode 100644 index 6ad45e4b7..000000000 --- a/source/runtime/render/rhi/vulkan/VulkanExtension.h +++ /dev/null @@ -1,100 +0,0 @@ -// -// Created by 74535 on 2023/10/11. -// - -#ifndef VULKAN_EXTENSION_H -#define VULKAN_EXTENSION_H - -#include -#define VULKAN_EXTENSION_OPTIONAL 1 -#define VULKAN_EXTENSION_REQUIRED 0 - -#include "VulkanTypeDefs.h" -#include "log/LogSystem.h" - -struct RHIInfo; -namespace Moer::Render { - -class VulkanDevice; -class VulkanOptionalDeviceExtensions; - -class VulkanExtensionBase { -public: - VulkanExtensionBase(std::string_view _ext_name) : m_extension_name(_ext_name), m_is_enabled(false) {} - virtual ~VulkanExtensionBase() = default; - - inline const std::string_view GetExtensionName() const { - return m_extension_name; - } - - inline void Enable() { - m_is_enabled = true; - } - inline void Disable() { - m_is_enabled = false; - } - inline bool IsEnabled() const { - return m_is_enabled; - } - -protected: - bool m_is_enabled; - const std::string_view m_extension_name; -}; - -class VulkanInstanceExtension : public VulkanExtensionBase { -public: - VulkanInstanceExtension(std::string_view _ext_name) : VulkanExtensionBase(_ext_name) {} - virtual ~VulkanInstanceExtension() = default; - - static TExtensionArray GetMERequiredInstanceExtensions(); -}; - -class VulkanDeviceExtension : public VulkanExtensionBase { -public: - VulkanDeviceExtension(std::string_view _ext_name, bool _is_optional = false) : - VulkanExtensionBase(_ext_name), - m_is_optional(_is_optional), - m_is_usable(true) {} - virtual ~VulkanDeviceExtension() = default; - - static TVulkanDeviceExtensionArray GetMERequiredDeviceExtensions(); - static TVulkanDeviceExtensionArray GetMEEnabledDeviceExtensions(const Set& _gpu_extensions); - - virtual bool IsOptional() const final { - return m_is_optional; - } - virtual void PreGpuFeatures(VkPhysicalDeviceFeatures2& _gpu_features2) {} - virtual void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) {} - virtual void - PreGpuProperties(const VulkanDevice* _device, VkPhysicalDeviceProperties2& _gpu_properties2) {} - virtual void PreCreateDevice(VkDeviceCreateInfo& _device_create_info) {} - -protected: - bool m_is_optional; - bool m_is_usable; -}; - -class VulkanOptionalDeviceExtensions final { -public: - inline bool HasRaytracingExtensions() const { - return m_has_khr_acceleration_structure && (m_has_khr_ray_tracing_pipeline || m_has_khr_ray_query); - } - - // optional extensions - bool m_has_ext_descriptor_buffer; - bool m_has_khr_acceleration_structure; - bool m_has_khr_ray_tracing_pipeline; - bool m_has_khr_ray_query; - bool m_has_ext_mesh_shader; - bool m_allow_mesh_primitive_shading; - - bool m_has_memory_priority; - bool m_has_pageable_device_local_memory; - // nvidia - bool m_has_nv_memory_decompression; - bool m_has_nv_copy_memory_indirect; -}; -} // namespace Moer::Render - -#endif //VULKAN_EXTENSION_H diff --git a/source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.h b/source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.h deleted file mode 100644 index ddb4e39f9..000000000 --- a/source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef VULKAN_NRD_EXTENSION_H -#define VULKAN_NRD_EXTENSION_H - -#include "rhi/extension/NrdExtension.h" - -#include "../VulkanRHIResource.h" - -namespace Moer::Render::Ext { - -class VkNRDExtension : public NRDExtension, public VulkanDeviceObject { -public: - VkNRDExtension(VulkanDevice* _device) : VulkanDeviceObject(_device) {} - ~VkNRDExtension() = default; - - UniquePtr - CreateInterface(uint8 _max_frame_in_flight = 0, uint16 _frame_width = 0, uint16 _frame_height = 0) - override; - - UniquePtr - RecreateInterface(UniquePtr _interface, uint16 _frame_width = 0, uint16 _frame_height = 0) - override; -}; - -}; // namespace Moer::Render::Ext -#endif //VULKAN_CUSTOM_COMMAND_H diff --git a/source/runtime/render/rhi/vulkan/platform/VulkanGenericPlatform.h b/source/runtime/render/rhi/vulkan/platform/VulkanGenericPlatform.h index 6443afda6..1a2018e53 100644 --- a/source/runtime/render/rhi/vulkan/platform/VulkanGenericPlatform.h +++ b/source/runtime/render/rhi/vulkan/platform/VulkanGenericPlatform.h @@ -18,11 +18,7 @@ class VulkanDeviceFeatures; class VulkanGenericPlatform { public: - // Array of required extensions for the platform (Required!) - static void GetInstanceExtensions(Moer::Array& _extensions); static void GetInstanceLayers(Moer::Array& _layers) {} - static void - GetDeviceExtensions(const Moer::Render::VulkanDevice* _device, Moer::Array& _extensions); static void GetDeviceLayers(Moer::Array& _layers) {} // create the platform-specific surface object - required static VkSurfaceKHR CreateSurface(); diff --git a/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.cpp b/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.cpp index 857ef0d00..8470f9754 100644 --- a/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.cpp +++ b/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.cpp @@ -4,8 +4,6 @@ #include "VulkanWindowsPlatform.h" #include "../../VulkanMacroUtils.h" -#include "../../VulkanExtension.h" - #include #if defined(_WIN32) || defined(_WIN64) @@ -13,42 +11,12 @@ #endif namespace Moer::Render { -void VulkanWindowsPlatform::GetInstanceExtensions(TExtensionArray& _extensions) { - _extensions.emplace_back(VK_KHR_WIN32_SURFACE_EXTENSION_NAME); - _extensions.emplace_back(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME); -} - void VulkanWindowsPlatform::GetInstanceLayers(TLayerArray& _layers) { #ifndef NDEBUG _layers.emplace_back("VK_LAYER_KHRONOS_validation"); #endif } -void VulkanWindowsPlatform::GetDeviceExtensions(TVulkanDeviceExtensionArray& _extensions) { - // _extensions.emplace_back(std::make_unique(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME)); - -#if WITH_CUDA - // VK_KHR_external_memory - _extensions.emplace_back(std::make_unique(VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME)); - // VK_KHR_external_memory_win32 - _extensions.emplace_back( - std::make_unique(VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME) - ); - // // VK_KHR_external_semaphore_capabilities - // _extensions.emplace_back( - // std::make_unique(VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME) - // ); - // VK_KHR_external_semaphore - _extensions.emplace_back( - std::make_unique(VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME) - ); - // VK_KHR_external_semaphore_win32 - _extensions.emplace_back( - std::make_unique(VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME) - ); -#endif -} - void VulkanWindowsPlatform::CreateSurface( void* _window_handle, VkInstance _instance, diff --git a/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.h b/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.h index e7fce4ddd..062353f0b 100644 --- a/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.h +++ b/source/runtime/render/rhi/vulkan/platform/windows/VulkanWindowsPlatform.h @@ -31,10 +31,7 @@ namespace Moer::Render { class VulkanWindowsPlatform : public VulkanGenericPlatform { public: - // Array of required extensions for the platform (Required!) - static void GetInstanceExtensions(TExtensionArray& _extensions); static void GetInstanceLayers(TLayerArray& _layers); - static void GetDeviceExtensions(TVulkanDeviceExtensionArray& _extensions); static void GetDeviceLayers(TLayerArray& _layers) {} // create the platform-specific surface object - required static void CreateSurface(void* _window_handle, VkInstance _instance, VkSurfaceKHR& _surface); diff --git a/source/runtime/render/rhi/vulkan/extension/NrdIntegration.cpp b/source/runtime/render/rhi/vulkan/plugin/NrdIntegration.cpp similarity index 100% rename from source/runtime/render/rhi/vulkan/extension/NrdIntegration.cpp rename to source/runtime/render/rhi/vulkan/plugin/NrdIntegration.cpp diff --git a/source/runtime/render/rhi/vulkan/extension/NrdExtension.cpp b/source/runtime/render/rhi/vulkan/plugin/NrdPlugin.cpp similarity index 99% rename from source/runtime/render/rhi/vulkan/extension/NrdExtension.cpp rename to source/runtime/render/rhi/vulkan/plugin/NrdPlugin.cpp index aaeedce45..e06720da9 100644 --- a/source/runtime/render/rhi/vulkan/extension/NrdExtension.cpp +++ b/source/runtime/render/rhi/vulkan/plugin/NrdPlugin.cpp @@ -1,4 +1,4 @@ -#include "rhi/extension/NrdExtension.h" +#include "rhi/plugin/NrdPlugin.h" #if WITH_NRD diff --git a/source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.cpp b/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.cpp similarity index 99% rename from source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.cpp rename to source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.cpp index 1c1e53211..4881c4435 100644 --- a/source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.cpp +++ b/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.cpp @@ -1,4 +1,4 @@ -#include "VulkanNrdExtension.h" +#include "VulkanNrdPlugin.h" #if WITH_NRD @@ -339,12 +339,12 @@ class VkNRDInterface final : public NRDInterface { }; UniquePtr -VkNRDExtension::CreateInterface(uint8 _max_frame_in_flight, uint16 _frame_width, uint16 _frame_height) { +VkNRDPlugin::CreateInterface(uint8 _max_frame_in_flight, uint16 _frame_width, uint16 _frame_height) { return MakeUnique(m_device, _max_frame_in_flight, _frame_width, _frame_height); } -UniquePtr VkNRDExtension::RecreateInterface( +UniquePtr VkNRDPlugin::RecreateInterface( UniquePtr _interface, uint16 _frame_width, uint16 _frame_height diff --git a/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.h b/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.h new file mode 100644 index 000000000..2fb0bf8c3 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.h @@ -0,0 +1,29 @@ +#ifndef VULKAN_NRD_PLUGIN_H +#define VULKAN_NRD_PLUGIN_H + +#include "rhi/plugin/NrdPlugin.h" + +#include "../VulkanRHIResource.h" + +namespace Moer::Render::Ext { + +class VkNRDPlugin : public NRDPlugin, public VulkanDeviceObject { +public: + VkNRDPlugin(VulkanDevice* _device) : VulkanDeviceObject(_device) {} + ~VkNRDPlugin() = default; + + UniquePtr CreateInterface( + uint8 _max_frame_in_flight = 0, + uint16 _frame_width = 0, + uint16 _frame_height = 0 + ) override; + + UniquePtr RecreateInterface( + UniquePtr _interface, + uint16 _frame_width = 0, + uint16 _frame_height = 0 + ) override; +}; + +}; // namespace Moer::Render::Ext +#endif // VULKAN_NRD_PLUGIN_H diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.cpp b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.cpp new file mode 100644 index 000000000..2184db638 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.cpp @@ -0,0 +1,84 @@ +#include "VulkanCooperativeSupport.h" + +#include "log/LogSystem.h" + +#include + +namespace Moer::Render { + +namespace { + +std::string +BuildUnsupportedCooperativeExtensionList(const VulkanOptionalDeviceExtensions& _optional_extensions) { + std::string unsupported_extensions; + + const auto append_extension = [&](std::string_view _extension_name) { + if (!unsupported_extensions.empty()) { + unsupported_extensions += ", "; + } + unsupported_extensions += _extension_name; + }; + + if (!_optional_extensions.SupportsCooperativeMatrix()) { + append_extension(VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME); + } + if (!_optional_extensions.SupportsCooperativeVector()) { + append_extension(VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME); + } + + return unsupported_extensions; +} + +} // namespace + +// 把 cooperative 依赖的 core feature 映射到引擎自己的 capability 状态里。 +void UpdateCooperativePrerequisites( + const VulkanDeviceFeatures& _core_features, + VulkanOptionalDeviceExtensions& _optional_extensions +) { + const auto& core_1_1 = _core_features.GetCore11Features(); + const auto& core_1_2 = _core_features.GetCore12Features(); + + _optional_extensions.m_has_shader_float16 = (core_1_2.shaderFloat16 == VK_TRUE); + _optional_extensions.m_has_shader_int8 = (core_1_2.shaderInt8 == VK_TRUE); + _optional_extensions.m_has_vulkan_memory_model = (core_1_2.vulkanMemoryModel == VK_TRUE); + _optional_extensions.m_has_storage_buffer_16bit_access = (core_1_1.storageBuffer16BitAccess == VK_TRUE); + _optional_extensions.m_has_uniform_and_storage_buffer_16bit_access = + (core_1_1.uniformAndStorageBuffer16BitAccess == VK_TRUE); + _optional_extensions.m_has_storage_buffer_8bit_access = (core_1_2.storageBuffer8BitAccess == VK_TRUE); + _optional_extensions.m_has_uniform_and_storage_buffer_8bit_access = + (core_1_2.uniformAndStorageBuffer8BitAccess == VK_TRUE); +} + +// 把 cooperative 当前的支持情况集中打印出来,便于后续做 shader probe。 +void LogCooperativeSupportSummary( + const VulkanOptionalDeviceExtensions& _optional_extensions, + const VulkanOptionalDeviceProperties& _optional_properties +) { + const std::string unsupported_extensions = BuildUnsupportedCooperativeExtensionList(_optional_extensions); + if (!unsupported_extensions.empty()) { + LOG_INFO( + "VulkanRHI: Cooperative extensions are not supported: {}. Cooperative-related passes in raster " + "renderer will be disabled.", + unsupported_extensions + ); + return; + } + + LOG_INFO( + "VulkanRHI: Cooperative support - matrix={} robust={} matrix_modes={} vector={} training={} " + "vector_modes={} inference_ready={} float16={} int8={} vulkan_memory_model={}", + _optional_extensions.SupportsCooperativeMatrix(), + _optional_extensions.SupportsCooperativeMatrixRobustBufferAccess(), + _optional_properties.cooperative_matrix_supports.size(), + _optional_extensions.SupportsCooperativeVector(), + _optional_extensions.SupportsCooperativeVectorTraining(), + _optional_properties.cooperative_vector_supports.size(), + _optional_extensions.HasCooperativeInferenceEnabled(), + _optional_extensions.m_has_shader_float16, + _optional_extensions.m_has_shader_int8, + _optional_extensions.m_has_vulkan_memory_model + ); +} + +} // namespace Moer::Render \ No newline at end of file diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.h b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.h new file mode 100644 index 000000000..f26c59338 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.h @@ -0,0 +1,31 @@ +/** + * Cooperative support 辅助模块 + * + * 1. 负责从 Vulkan core feature 中提取 cooperative 相关前置条件。 + * 2. 负责输出 cooperative 能力摘要日志。 + * 3. 这里只做状态整理与展示,不参与 extension 注册或 device 创建。 + */ +#ifndef VULKAN_COOPERATIVE_SUPPORT_H +#define VULKAN_COOPERATIVE_SUPPORT_H + +#include "../VulkanDeviceFeature.h" +#include "../VulkanDeviceProperty.h" +#include "VulkanExtension.h" + +namespace Moer::Render { + +// 从 core 1.1/1.2 feature 中提取 cooperative bundle 需要的前置能力。 +void UpdateCooperativePrerequisites( + const VulkanDeviceFeatures& _core_features, + VulkanOptionalDeviceExtensions& _optional_extensions +); + +// 输出 cooperative 扩展、枚举结果和前置能力的摘要日志。 +void LogCooperativeSupportSummary( + const VulkanOptionalDeviceExtensions& _optional_extensions, + const VulkanOptionalDeviceProperties& _optional_properties +); + +} // namespace Moer::Render + +#endif // VULKAN_COOPERATIVE_SUPPORT_H \ No newline at end of file diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.cpp b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.cpp new file mode 100644 index 000000000..20f111167 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.cpp @@ -0,0 +1,59 @@ +#include "VulkanExtension.h" +#include "VulkanExtensionRegistry.h" + +namespace Moer::Render { + +namespace { + +template +void ForEachExtensionDesc(EVulkanExtensionKind _kind, Fn&& _fn) { + for (const auto& desc : GetVulkanExtensionDescs()) { + if (desc.kind != _kind) { + continue; + } + _fn(desc); + } +} + +std::shared_ptr CreateDeviceExtension(const VulkanExtensionDesc& _desc) { + if (_desc.factory) { + return _desc.factory(_desc.optional); + } + return std::make_shared(_desc.name, _desc.optional); +} + +} // namespace + +TExtensionArray VulkanInstanceExtension::GetMERequiredInstanceExtensions() { + TExtensionArray extensions; + ForEachExtensionDesc(EVulkanExtensionKind::Instance, [&](const VulkanExtensionDesc& _desc) { + extensions.emplace_back(_desc.name); + }); + return extensions; +} + +TVulkanDeviceExtensionArray VulkanDeviceExtension::GetMERequiredDeviceExtensions() { + TVulkanDeviceExtensionArray extensions; + ForEachExtensionDesc(EVulkanExtensionKind::Device, [&](const VulkanExtensionDesc& _desc) { + extensions.emplace_back(CreateDeviceExtension(_desc)); + }); + return extensions; +} + +TVulkanDeviceExtensionArray +VulkanDeviceExtension::GetMEEnabledDeviceExtensions(const Set& _gpu_extensions) { + auto extensions = GetMERequiredDeviceExtensions(); + + TVulkanDeviceExtensionArray extensions_enabled; + + for (const auto& ext : extensions) { + if (_gpu_extensions.contains(ext->GetExtensionName().data())) { + ext->Enable(); + extensions_enabled.emplace_back(ext); + } + } + + return extensions_enabled; +} + +} // namespace Moer::Render \ No newline at end of file diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h new file mode 100644 index 000000000..61c63a813 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h @@ -0,0 +1,201 @@ +/* +Vulkan extension 架构 + +1. 架构 +- VulkanExtensionRegistry.cpp:维护所有 extension 描述表,是唯一登记入口。 +- VulkanExtension.cpp:读取描述表,生成 instance/device extension 列表。 +- VulkanExtensionFactories.cpp:放复杂 extension 的具体实现。 +- 简单 extension 只写在 Registry 里;复杂 extension 再额外走 Factory。 + +2. 添加 extension +- 先判断它是 Instance 还是 Device,是 required 还是 optional。 +- 如果是简单 extension:直接在 VulkanExtensionRegistry.cpp 加一条 descriptor。 +- 如果是复杂 extension: + 在 VulkanExtensionFactories.cpp 里实现类和 factory, + 然后在 VulkanExtensionRegistry.cpp 里把 descriptor 指到这个 factory。 +- 如果它会影响 capability 或 pNext/feature/property,记得在复杂 extension 实现里补齐对应逻辑。 +*/ + +#ifndef VULKAN_EXTENSION_H +#define VULKAN_EXTENSION_H + +#include +#include + +#include "../VulkanTypeDefs.h" + +struct RHIInfo; +namespace Moer::Render { + +class VulkanDevice; +class VulkanOptionalDeviceExtensions; +class VulkanDeviceExtension; + +enum class EVulkanExtensionKind : uint8_t { + Instance, + Device +}; + +using TVulkanDeviceExtensionFactory = std::shared_ptr (*)(bool); + +struct VulkanExtensionDesc { + EVulkanExtensionKind kind = EVulkanExtensionKind::Device; + std::string_view name = {}; + bool optional = false; + TVulkanDeviceExtensionFactory factory = nullptr; +}; + +class VulkanExtensionBase { +public: + VulkanExtensionBase(std::string_view _ext_name) : m_extension_name(_ext_name), m_is_enabled(false) {} + virtual ~VulkanExtensionBase() = default; + + inline const std::string_view GetExtensionName() const { + return m_extension_name; + } + + inline void Enable() { + m_is_enabled = true; + } + inline void Disable() { + m_is_enabled = false; + } + inline bool IsEnabled() const { + return m_is_enabled; + } + +protected: + bool m_is_enabled; + const std::string_view m_extension_name; +}; + +class VulkanInstanceExtension : public VulkanExtensionBase { +public: + VulkanInstanceExtension(std::string_view _ext_name) : VulkanExtensionBase(_ext_name) {} + virtual ~VulkanInstanceExtension() = default; + + static TExtensionArray GetMERequiredInstanceExtensions(); +}; + +class VulkanDeviceExtension : public VulkanExtensionBase { +public: + VulkanDeviceExtension(std::string_view _ext_name, bool _is_optional = false) : + VulkanExtensionBase(_ext_name), + m_is_optional(_is_optional), + m_is_usable(true) {} + virtual ~VulkanDeviceExtension() = default; + + static TVulkanDeviceExtensionArray GetMERequiredDeviceExtensions(); + static TVulkanDeviceExtensionArray GetMEEnabledDeviceExtensions(const Set& _gpu_extensions); + + virtual bool IsOptional() const final { + return m_is_optional; + } + inline bool IsUsable() const { + return m_is_usable; + } + inline bool ShouldEnableDeviceCreate() const { + return m_is_enabled && m_is_usable; + } + virtual void PreGpuFeatures(VkPhysicalDeviceFeatures2& _gpu_features2) {} + virtual void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) {} + virtual void + PreGpuProperties(const VulkanDevice* _device, VkPhysicalDeviceProperties2& _gpu_properties2) {} + // 给需要额外 property 枚举命令的扩展一个收尾阶段,比如 cooperative。 + virtual void PostGpuProperties(const VulkanDevice* _device) {} + virtual void PreCreateDevice(VkDeviceCreateInfo& _device_create_info) {} + +protected: + bool m_is_optional; + bool m_is_usable; +}; + +class VulkanOptionalDeviceExtensions final { +public: + inline bool HasRaytracingExtensions() const { + return m_has_khr_acceleration_structure && (m_has_khr_ray_tracing_pipeline || m_has_khr_ray_query); + } + + // cooperative 扩展与 feature bit 的原始支持状态。 + inline bool SupportsCooperativeMatrix() const { + return m_has_khr_cooperative_matrix; + } + + inline bool SupportsCooperativeMatrixRobustBufferAccess() const { + return m_has_khr_cooperative_matrix_robust_buffer_access; + } + + inline bool SupportsCooperativeVector() const { + return m_has_nv_cooperative_vector; + } + + inline bool SupportsCooperativeVectorTraining() const { + return m_has_nv_cooperative_vector_training; + } + + inline bool HasCooperativeMatrixEnabled() const { + return SupportsCooperativeMatrix(); + } + + inline bool HasCooperativeVectorEnabled() const { + return SupportsCooperativeVector(); + } + + inline bool HasCooperativeVectorTrainingEnabled() const { + return SupportsCooperativeVectorTraining(); + } + + // cooperative bundle 依赖的 core feature 前置条件。 + inline bool HasCooperativeLowPrecisionSupport() const { + return m_has_shader_float16 || m_has_shader_int8; + } + + inline bool HasCooperativeStorageSupport() const { + return m_has_storage_buffer_16bit_access || m_has_uniform_and_storage_buffer_16bit_access || + m_has_storage_buffer_8bit_access || m_has_uniform_and_storage_buffer_8bit_access; + } + + inline bool HasCooperativeInferenceSupport() const { + return SupportsCooperativeMatrix() && SupportsCooperativeVector() && m_has_vulkan_memory_model && + HasCooperativeLowPrecisionSupport() && HasCooperativeStorageSupport(); + } + + inline bool HasCooperativeInferenceEnabled() const { + return HasCooperativeMatrixEnabled() && HasCooperativeVectorEnabled() && m_has_vulkan_memory_model && + HasCooperativeLowPrecisionSupport() && HasCooperativeStorageSupport(); + } + + inline bool IsExtensionCooperativeEnabled() const { + return HasCooperativeInferenceEnabled(); + } + + // optional extensions + bool m_has_ext_descriptor_buffer = false; + bool m_has_khr_acceleration_structure = false; + bool m_has_khr_ray_tracing_pipeline = false; + bool m_has_khr_ray_query = false; + bool m_has_ext_mesh_shader = false; + bool m_allow_mesh_primitive_shading = false; + bool m_has_khr_cooperative_matrix = false; + bool m_has_khr_cooperative_matrix_robust_buffer_access = false; + bool m_has_nv_cooperative_vector = false; + bool m_has_nv_cooperative_vector_training = false; + + bool m_has_memory_priority = false; + bool m_has_pageable_device_local_memory = false; + // nvidia + bool m_has_nv_memory_decompression = false; + bool m_has_nv_copy_memory_indirect = false; + + // cooperative bundle 依赖的 core feature 前置条件。 + bool m_has_shader_float16 = false; + bool m_has_shader_int8 = false; + bool m_has_vulkan_memory_model = false; + bool m_has_storage_buffer_16bit_access = false; + bool m_has_uniform_and_storage_buffer_16bit_access = false; + bool m_has_storage_buffer_8bit_access = false; + bool m_has_uniform_and_storage_buffer_8bit_access = false; +}; +} // namespace Moer::Render + +#endif //VULKAN_EXTENSION_H diff --git a/source/runtime/render/rhi/vulkan/VulkanExtension.cpp b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp similarity index 60% rename from source/runtime/render/rhi/vulkan/VulkanExtension.cpp rename to source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp index dd2efd87d..915ba102a 100644 --- a/source/runtime/render/rhi/vulkan/VulkanExtension.cpp +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp @@ -1,13 +1,5 @@ -// -// Created by 74535 on 2023/10/11. -// - -#include "rhi/RHI.h" - -#include "VulkanDevice.h" -#include "VulkanExtension.h" -#include "VulkanMacroUtils.h" -#include "VulkanPlatform.h" +#include "VulkanExtensionFactories.h" +#include "../VulkanDevice.h" template static void AddToPNext(ExistingChainType& _existing, NewStructType& _added) { @@ -16,31 +8,8 @@ static void AddToPNext(ExistingChainType& _existing, NewStructType& _added) { } namespace Moer::Render { +namespace { -TExtensionArray VulkanInstanceExtension::GetMERequiredInstanceExtensions() { - TExtensionArray extensions; - -#define ADD_EXTENSION(ext_name) extensions.push_back(ext_name) - - // generic simple extensions - ADD_EXTENSION(VK_KHR_SURFACE_EXTENSION_NAME); - // ADD_EXTENSION(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME); - ADD_EXTENSION(VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME); - // ADD_EXTENSION(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); - // debug utils, contains debug marker and debug report - ADD_EXTENSION(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); - - // platform specific extensions - VulkanPlatform::GetInstanceExtensions(extensions); - - // custom extensions - -#undef ADD_EXTENSION - - return extensions; -} - -// ***** VK_EXT_swapchain_maintenance1 class VulkanEXTSwapchainMaintenance1Extension final : public VulkanDeviceExtension { public: VulkanEXTSwapchainMaintenance1Extension(bool _is_optional = false) : @@ -63,7 +32,6 @@ class VulkanEXTSwapchainMaintenance1Extension final : public VulkanDeviceExtensi VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT m_swapchain_maintenance1_features; }; -// ***** VK_KHR_acceleration_structure class VulkanKHRAccelerationStructureExtension final : public VulkanDeviceExtension { public: VulkanKHRAccelerationStructureExtension(bool _is_optional = false) : @@ -104,7 +72,6 @@ class VulkanKHRAccelerationStructureExtension final : public VulkanDeviceExtensi VkPhysicalDeviceAccelerationStructureFeaturesKHR m_acceleration_structure_features; }; -// ***** VK_KHR_ray_tracing_pipeline class VulkanKHRRayTracingPipelineExtension final : public VulkanDeviceExtension { public: VulkanKHRRayTracingPipelineExtension(bool _is_optional = false) : @@ -120,7 +87,6 @@ class VulkanKHRRayTracingPipelineExtension final : public VulkanDeviceExtension void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { m_is_usable = (m_ray_tracing_pipeline_features.rayTracingPipeline == VK_TRUE) && (m_ray_tracing_pipeline_features.rayTraversalPrimitiveCulling == VK_TRUE); - _gpu_extensions.m_has_khr_ray_tracing_pipeline = m_is_usable; } @@ -144,7 +110,6 @@ class VulkanKHRRayTracingPipelineExtension final : public VulkanDeviceExtension VkPhysicalDeviceRayTracingPipelineFeaturesKHR m_ray_tracing_pipeline_features; }; -// ***** VK_KHR_ray_query class VulkanKHRRayQueryExtension final : public VulkanDeviceExtension { public: VulkanKHRRayQueryExtension(bool _is_optional = false) : @@ -157,8 +122,7 @@ class VulkanKHRRayQueryExtension final : public VulkanDeviceExtension { } void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { - m_is_usable = (m_ray_query_features.rayQuery == VK_TRUE); - + m_is_usable = (m_ray_query_features.rayQuery == VK_TRUE); _gpu_extensions.m_has_khr_ray_query = m_is_usable; } @@ -172,7 +136,6 @@ class VulkanKHRRayQueryExtension final : public VulkanDeviceExtension { VkPhysicalDeviceRayQueryFeaturesKHR m_ray_query_features; }; -// ***** VK_EXT_descriptor_buffer class VulkanEXTDescriptorBufferExtension final : public VulkanDeviceExtension { public: VulkanEXTDescriptorBufferExtension(bool _is_optional = false) : @@ -188,7 +151,6 @@ class VulkanEXTDescriptorBufferExtension final : public VulkanDeviceExtension { m_is_usable = (m_descriptor_buffer_features.descriptorBuffer == VK_TRUE && m_descriptor_buffer_features.descriptorBufferPushDescriptors == VK_TRUE); - _gpu_extensions.m_has_ext_descriptor_buffer = m_is_usable; } @@ -211,14 +173,12 @@ class VulkanEXTDescriptorBufferExtension final : public VulkanDeviceExtension { VkPhysicalDeviceDescriptorBufferFeaturesEXT m_descriptor_buffer_features; }; -//***** VK_KHR_push_descriptor */ class VulkanKHRPushDescriptorExtension final : public VulkanDeviceExtension { public: VulkanKHRPushDescriptorExtension(bool _is_optional = false) : VulkanDeviceExtension(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, _is_optional) {} void PreGpuFeatures(VkPhysicalDeviceFeatures2& _gpu_features2) override {} - void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override {} void @@ -231,8 +191,6 @@ class VulkanKHRPushDescriptorExtension final : public VulkanDeviceExtension { } void PreCreateDevice(VkDeviceCreateInfo& _device_create_info) override {} - -private: }; class VulkanEXTMemoryDecompressionExtension final : public VulkanDeviceExtension { @@ -249,7 +207,6 @@ class VulkanEXTMemoryDecompressionExtension final : public VulkanDeviceExtension void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { m_is_usable = (m_memory_decompression_features.memoryDecompression == VK_TRUE); - _gpu_extensions.m_has_nv_memory_decompression = m_is_usable; } @@ -286,7 +243,6 @@ class VulkanEXTCopyMemoryIndirectExtension final : public VulkanDeviceExtension void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { m_is_usable = (m_copy_memory_indirect_features.indirectCopy == VK_TRUE); - _gpu_extensions.m_has_nv_copy_memory_indirect = m_is_usable; } @@ -321,8 +277,7 @@ class VulkanEXTMemoryPriorityAllocateInfoExtension final : public VulkanDeviceEx } void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { - m_is_usable = (m_memory_priority_features.memoryPriority == VK_TRUE); - + m_is_usable = (m_memory_priority_features.memoryPriority == VK_TRUE); _gpu_extensions.m_has_memory_priority = m_is_usable; } @@ -350,7 +305,6 @@ class VulkanEXTPageableDeviceLocalMemoryExtension final : public VulkanDeviceExt void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { m_is_usable = (m_pageable_device_local_memory_features.pageableDeviceLocalMemory == VK_TRUE); - _gpu_extensions.m_has_pageable_device_local_memory = m_is_usable; } @@ -376,8 +330,7 @@ class VulkanEXTMeshShaderExtension final : public VulkanDeviceExtension { } void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { - m_is_usable = (m_mesh_shader_features.meshShader == VK_TRUE); - + m_is_usable = (m_mesh_shader_features.meshShader == VK_TRUE); _gpu_extensions.m_has_ext_mesh_shader = m_is_usable; _gpu_extensions.m_allow_mesh_primitive_shading = (m_mesh_shader_features.primitiveFragmentShadingRateMeshShader == VK_TRUE); @@ -402,65 +355,216 @@ class VulkanEXTMeshShaderExtension final : public VulkanDeviceExtension { VkPhysicalDeviceMeshShaderFeaturesEXT m_mesh_shader_features; }; -TVulkanDeviceExtensionArray VulkanDeviceExtension::GetMERequiredDeviceExtensions() { - // LOG_INFO("VulkanDeviceExtension: raytracing support, {}", _rhi_info.ray_tracing); +// cooperative matrix 扩展:负责 feature、property 和支持表枚举的完整生命周期。 +class VulkanKHRCooperativeMatrixExtension final : public VulkanDeviceExtension { +public: + VulkanKHRCooperativeMatrixExtension(bool _is_optional = true) : + VulkanDeviceExtension(VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME, _is_optional), + m_cooperative_matrix_features() {} - TVulkanDeviceExtensionArray extensions; + // 把 cooperative matrix feature struct 挂到 feature 查询链上。 + void PreGpuFeatures(VkPhysicalDeviceFeatures2& _gpu_features2) override { + m_cooperative_matrix_features.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR; + AddToPNext(_gpu_features2, m_cooperative_matrix_features); + } -#define ADD_EXTENSION(ext_name, optional) \ - extensions.emplace_back(std::make_shared(ext_name, optional)) + // 根据驱动返回的 feature bit 判定这个扩展在当前 GPU 上是否可用。 + void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { + m_is_usable = (m_cooperative_matrix_features.cooperativeMatrix == VK_TRUE); + _gpu_extensions.m_has_khr_cooperative_matrix = m_is_usable; + _gpu_extensions.m_has_khr_cooperative_matrix_robust_buffer_access = + m_is_usable && (m_cooperative_matrix_features.cooperativeMatrixRobustBufferAccess == VK_TRUE); + } + + // 把 cooperative matrix 的基础 property struct 挂到 property 查询链上。 + void + PreGpuProperties(const VulkanDevice* _device, VkPhysicalDeviceProperties2& _gpu_properties2) override { + auto& cooperative_matrix_props = + const_cast(_device->GetOptionalProperties()) + .cooperative_matrix_properties; + cooperative_matrix_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_PROPERTIES_KHR; + AddToPNext(_gpu_properties2, cooperative_matrix_props); + } -#define ADD_CUSTOM_EXTENSION(ext_class, optional) \ - extensions.emplace_back(std::make_shared(optional)) - // generic simple extensions - ADD_EXTENSION(VK_KHR_SWAPCHAIN_EXTENSION_NAME, VULKAN_EXTENSION_REQUIRED); - // ADD_CUSTOM_EXTENSION(VulkanEXTSwapchainMaintenance1Extension, VULKAN_EXTENSION_REQUIRED); - // ADD_EXTENSION(VK_KHR_INDEX_TYPE_UINT8_EXTENSION_NAME, VULKAN_EXTENSION_REQUIRED); + // 额外枚举驱动支持的 matrix 组合列表,这一步不能只靠 pNext property 拿到。 + void PostGpuProperties(const VulkanDevice* _device) override { + if (!m_is_usable || vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR == nullptr) { + return; + } + + auto& cooperative_matrix_supports = + const_cast(_device->GetOptionalProperties()) + .cooperative_matrix_supports; + + uint32_t property_count = 0; + VkResult result = + vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR(_device->GetGpu(), &property_count, nullptr); + if ((result != VK_SUCCESS && result != VK_INCOMPLETE) || property_count == 0) { + cooperative_matrix_supports.clear(); + return; + } -#if VULKAN_RHI_RAYTRACING - // raytracing extensions - ADD_EXTENSION(VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, VULKAN_EXTENSION_OPTIONAL); - ADD_CUSTOM_EXTENSION(VulkanKHRAccelerationStructureExtension, VULKAN_EXTENSION_OPTIONAL); - ADD_CUSTOM_EXTENSION(VulkanKHRRayTracingPipelineExtension, VULKAN_EXTENSION_OPTIONAL); - ADD_CUSTOM_EXTENSION(VulkanKHRRayQueryExtension, VULKAN_EXTENSION_OPTIONAL); -#endif - // bindless extensions - ADD_CUSTOM_EXTENSION(VulkanEXTDescriptorBufferExtension, VULKAN_EXTENSION_OPTIONAL); - ADD_CUSTOM_EXTENSION(VulkanKHRPushDescriptorExtension, VULKAN_EXTENSION_REQUIRED); - // vendor extensions + cooperative_matrix_supports.resize(property_count); + for (auto& cooperative_matrix_support : cooperative_matrix_supports) { + cooperative_matrix_support = {}; + cooperative_matrix_support.sType = VK_STRUCTURE_TYPE_COOPERATIVE_MATRIX_PROPERTIES_KHR; + } - // debug extensions + result = vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR( + _device->GetGpu(), &property_count, cooperative_matrix_supports.data() + ); + if (result != VK_SUCCESS && result != VK_INCOMPLETE) { + cooperative_matrix_supports.clear(); + return; + } - // platform specific extensions + if (property_count < cooperative_matrix_supports.size()) { + cooperative_matrix_supports.resize(property_count); + } + } - VulkanPlatform::GetDeviceExtensions(extensions); + void PreCreateDevice(VkDeviceCreateInfo& _device_create_info) override { + if (m_is_usable && m_is_enabled) { + AddToPNext(_device_create_info, m_cooperative_matrix_features); + } + } - // VulkanPlatform::GetDeviceExtensions(extensions);//MARK... - ADD_CUSTOM_EXTENSION(VulkanEXTMemoryPriorityAllocateInfoExtension, VULKAN_EXTENSION_OPTIONAL); - ADD_CUSTOM_EXTENSION(VulkanEXTPageableDeviceLocalMemoryExtension, VULKAN_EXTENSION_OPTIONAL); - // nvidia extensions - ADD_CUSTOM_EXTENSION(VulkanEXTMemoryDecompressionExtension, VULKAN_EXTENSION_OPTIONAL); - ADD_CUSTOM_EXTENSION(VulkanEXTCopyMemoryIndirectExtension, VULKAN_EXTENSION_OPTIONAL); +private: + VkPhysicalDeviceCooperativeMatrixFeaturesKHR m_cooperative_matrix_features; +}; -#undef ADD_EXTENSION -#undef ADD_CUSTOM_EXTENSION +// cooperative vector 扩展:负责 feature、property 和支持表枚举的完整生命周期。 +class VulkanNVCooperativeVectorExtension final : public VulkanDeviceExtension { +public: + VulkanNVCooperativeVectorExtension(bool _is_optional = true) : + VulkanDeviceExtension(VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME, _is_optional), + m_cooperative_vector_features() {} - return extensions; -} + // 把 cooperative vector feature struct 挂到 feature 查询链上。 + void PreGpuFeatures(VkPhysicalDeviceFeatures2& _gpu_features2) override { + m_cooperative_vector_features.sType = + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_FEATURES_NV; + AddToPNext(_gpu_features2, m_cooperative_vector_features); + } -TVulkanDeviceExtensionArray -VulkanDeviceExtension::GetMEEnabledDeviceExtensions(const Set& _gpu_extensions) { - auto extensions = GetMERequiredDeviceExtensions(); + // 根据驱动返回的 feature bit 判定这个扩展在当前 GPU 上是否可用。 + void PostGpuFeatures(VulkanOptionalDeviceExtensions& _gpu_extensions) override { + m_is_usable = (m_cooperative_vector_features.cooperativeVector == VK_TRUE); + _gpu_extensions.m_has_nv_cooperative_vector = m_is_usable; + _gpu_extensions.m_has_nv_cooperative_vector_training = + m_is_usable && (m_cooperative_vector_features.cooperativeVectorTraining == VK_TRUE); + } + + // 把 cooperative vector 的基础 property struct 挂到 property 查询链上。 + void + PreGpuProperties(const VulkanDevice* _device, VkPhysicalDeviceProperties2& _gpu_properties2) override { + auto& cooperative_vector_props = + const_cast(_device->GetOptionalProperties()) + .cooperative_vector_properties; + cooperative_vector_props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_VECTOR_PROPERTIES_NV; + AddToPNext(_gpu_properties2, cooperative_vector_props); + } - TVulkanDeviceExtensionArray extensions_enabled; + // 额外枚举驱动支持的 vector 组合列表,这一步不能只靠 pNext property 拿到。 + void PostGpuProperties(const VulkanDevice* _device) override { + if (!m_is_usable || vkGetPhysicalDeviceCooperativeVectorPropertiesNV == nullptr) { + return; + } + + auto& cooperative_vector_supports = + const_cast(_device->GetOptionalProperties()) + .cooperative_vector_supports; + + uint32_t property_count = 0; + VkResult result = + vkGetPhysicalDeviceCooperativeVectorPropertiesNV(_device->GetGpu(), &property_count, nullptr); + if ((result != VK_SUCCESS && result != VK_INCOMPLETE) || property_count == 0) { + cooperative_vector_supports.clear(); + return; + } + + cooperative_vector_supports.resize(property_count); + for (auto& cooperative_vector_support : cooperative_vector_supports) { + cooperative_vector_support = {}; + cooperative_vector_support.sType = VK_STRUCTURE_TYPE_COOPERATIVE_VECTOR_PROPERTIES_NV; + } - for (const auto& ext : extensions) { - if (_gpu_extensions.contains(ext->GetExtensionName().data())) { - ext->Enable(); - extensions_enabled.emplace_back(ext); + result = vkGetPhysicalDeviceCooperativeVectorPropertiesNV( + _device->GetGpu(), &property_count, cooperative_vector_supports.data() + ); + if (result != VK_SUCCESS && result != VK_INCOMPLETE) { + cooperative_vector_supports.clear(); + return; + } + + if (property_count < cooperative_vector_supports.size()) { + cooperative_vector_supports.resize(property_count); + } + } + + void PreCreateDevice(VkDeviceCreateInfo& _device_create_info) override { + if (m_is_usable && m_is_enabled) { + AddToPNext(_device_create_info, m_cooperative_vector_features); } } - return extensions_enabled; +private: + VkPhysicalDeviceCooperativeVectorFeaturesNV m_cooperative_vector_features; +}; + +} // namespace + +std::shared_ptr CreateVulkanEXTSwapchainMaintenance1Extension(bool _optional) { + return std::make_shared(_optional); } + +std::shared_ptr CreateVulkanKHRAccelerationStructureExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanKHRRayTracingPipelineExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanKHRRayQueryExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanEXTDescriptorBufferExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanKHRPushDescriptorExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanEXTMemoryDecompressionExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanEXTCopyMemoryIndirectExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanEXTMemoryPriorityAllocateInfoExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanEXTPageableDeviceLocalMemoryExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanEXTMeshShaderExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanKHRCooperativeMatrixExtension(bool _optional) { + return std::make_shared(_optional); +} + +std::shared_ptr CreateVulkanNVCooperativeVectorExtension(bool _optional) { + return std::make_shared(_optional); +} + } // namespace Moer::Render \ No newline at end of file diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.h b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.h new file mode 100644 index 000000000..177073cf5 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.h @@ -0,0 +1,24 @@ +#ifndef VULKAN_EXTENSION_FACTORIES_H +#define VULKAN_EXTENSION_FACTORIES_H + +#include "VulkanExtension.h" + +namespace Moer::Render { + +std::shared_ptr CreateVulkanEXTSwapchainMaintenance1Extension(bool _optional); +std::shared_ptr CreateVulkanKHRAccelerationStructureExtension(bool _optional); +std::shared_ptr CreateVulkanKHRRayTracingPipelineExtension(bool _optional); +std::shared_ptr CreateVulkanKHRRayQueryExtension(bool _optional); +std::shared_ptr CreateVulkanEXTDescriptorBufferExtension(bool _optional); +std::shared_ptr CreateVulkanKHRPushDescriptorExtension(bool _optional); +std::shared_ptr CreateVulkanEXTMemoryDecompressionExtension(bool _optional); +std::shared_ptr CreateVulkanEXTCopyMemoryIndirectExtension(bool _optional); +std::shared_ptr CreateVulkanEXTMemoryPriorityAllocateInfoExtension(bool _optional); +std::shared_ptr CreateVulkanEXTPageableDeviceLocalMemoryExtension(bool _optional); +std::shared_ptr CreateVulkanEXTMeshShaderExtension(bool _optional); +std::shared_ptr CreateVulkanKHRCooperativeMatrixExtension(bool _optional); +std::shared_ptr CreateVulkanNVCooperativeVectorExtension(bool _optional); + +} // namespace Moer::Render + +#endif // VULKAN_EXTENSION_FACTORIES_H \ No newline at end of file diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp new file mode 100644 index 000000000..f15e23a24 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp @@ -0,0 +1,162 @@ +#include "VulkanExtensionRegistry.h" +#include "VulkanExtensionFactories.h" +#include "platform/Platform.h" + +#if PLATFORM_WINDOWS +#include "../platform/windows/VulkanWindowsPlatform.h" +#endif + +namespace Moer::Render { + +static constexpr VulkanExtensionDesc vulkan_extension_descs[] = { + { + .kind = EVulkanExtensionKind::Instance, + .name = VK_KHR_SURFACE_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Instance, + .name = VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Instance, + .name = VK_EXT_DEBUG_UTILS_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_SWAPCHAIN_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + // { + // .kind = EVulkanExtensionKind::Device, + // .name = VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, + // .optional = false, + // .factory = &CreateVulkanEXTSwapchainMaintenance1Extension, + // }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_EXT_DESCRIPTOR_BUFFER_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanEXTDescriptorBufferExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME, + .optional = false, + .factory = &CreateVulkanKHRPushDescriptorExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_EXT_MEMORY_PRIORITY_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanEXTMemoryPriorityAllocateInfoExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_EXT_PAGEABLE_DEVICE_LOCAL_MEMORY_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanEXTPageableDeviceLocalMemoryExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_NV_MEMORY_DECOMPRESSION_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanEXTMemoryDecompressionExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_NV_COPY_MEMORY_INDIRECT_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanEXTCopyMemoryIndirectExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_COOPERATIVE_MATRIX_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanKHRCooperativeMatrixExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_NV_COOPERATIVE_VECTOR_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanNVCooperativeVectorExtension, + }, +#if VULKAN_RHI_RAYTRACING + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_DEFERRED_HOST_OPERATIONS_EXTENSION_NAME, + .optional = true, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanKHRAccelerationStructureExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_RAY_TRACING_PIPELINE_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanKHRRayTracingPipelineExtension, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_RAY_QUERY_EXTENSION_NAME, + .optional = true, + .factory = &CreateVulkanKHRRayQueryExtension, + }, +#endif +#if PLATFORM_WINDOWS + { + .kind = EVulkanExtensionKind::Instance, + .name = VK_KHR_WIN32_SURFACE_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Instance, + .name = VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, +#endif +#if PLATFORM_WINDOWS && WITH_CUDA + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, + { + .kind = EVulkanExtensionKind::Device, + .name = VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME, + .optional = false, + .factory = nullptr, + }, +#endif +}; + +std::span GetVulkanExtensionDescs() { + return vulkan_extension_descs; +} + +} // namespace Moer::Render \ No newline at end of file diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.h b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.h new file mode 100644 index 000000000..689ed4e5a --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.h @@ -0,0 +1,14 @@ +#ifndef VULKAN_EXTENSION_REGISTRY_H +#define VULKAN_EXTENSION_REGISTRY_H + +#include + +#include "VulkanExtension.h" + +namespace Moer::Render { + +std::span GetVulkanExtensionDescs(); + +} // namespace Moer::Render + +#endif // VULKAN_EXTENSION_REGISTRY_H \ No newline at end of file