From d03a6a24c7d86d8ab929605ddb62fa044556ed92 Mon Sep 17 00:00:00 2001 From: YXHXianYu <2943003@qq.com> Date: Sun, 12 Apr 2026 15:55:34 +0800 Subject: [PATCH 1/4] =?UTF-8?q?refactor(rhi):=20=E5=B0=86=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E7=B3=BB=E7=BB=9F=E7=94=B1DeviceExtension=E9=87=8D?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E4=B8=BARuntimePlugin=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E5=92=8CVulkanApiExtension=E6=B7=B7=E6=B7=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../raytracing/RaytracingRenderer.cpp | 6 ++-- source/runtime/render/rhi/RHI.h | 10 ++++--- source/runtime/render/rhi/RHIImpl.cpp | 8 ++--- source/runtime/render/rhi/RHIImpl.h | 2 +- .../extension/{NrdExtension.h => NrdPlugin.h} | 10 +++---- .../render/rhi/vulkan/VulkanDevice.cpp | 14 ++++----- .../runtime/render/rhi/vulkan/VulkanDevice.h | 18 ++++++------ .../{NrdExtension.cpp => NrdPlugin.cpp} | 2 +- .../rhi/vulkan/extension/VulkanNrdExtension.h | 25 ---------------- ...anNrdExtension.cpp => VulkanNrdPlugin.cpp} | 6 ++-- .../rhi/vulkan/extension/VulkanNrdPlugin.h | 29 +++++++++++++++++++ 11 files changed, 68 insertions(+), 62 deletions(-) rename source/runtime/render/rhi/extension/{NrdExtension.h => NrdPlugin.h} (95%) rename source/runtime/render/rhi/vulkan/extension/{NrdExtension.cpp => NrdPlugin.cpp} (99%) delete mode 100644 source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.h rename source/runtime/render/rhi/vulkan/extension/{VulkanNrdExtension.cpp => VulkanNrdPlugin.cpp} (99%) create mode 100644 source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.h diff --git a/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp b/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp index eeccef458..576827fe6 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/extension/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..ea0b388d7 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,7 @@ class RenderDevice { } template - RENDER_API Ext* LoadExtension() const; + RENDER_API Ext* LoadPlugin() 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..eab99022d 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/extension/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,8 @@ 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)); } void RenderDevice::FlushDebugMessages() const { @@ -135,6 +135,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..ce2cea3a9 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; } diff --git a/source/runtime/render/rhi/extension/NrdExtension.h b/source/runtime/render/rhi/extension/NrdPlugin.h similarity index 95% rename from source/runtime/render/rhi/extension/NrdExtension.h rename to source/runtime/render/rhi/extension/NrdPlugin.h index a8888fa7e..12bf42342 100644 --- a/source/runtime/render/rhi/extension/NrdExtension.h +++ b/source/runtime/render/rhi/extension/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/VulkanDevice.cpp b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp index af354635a..8a3142a31 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDevice.cpp +++ b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp @@ -12,7 +12,7 @@ #include "VulkanQueue.h" #include "VulkanRHIResource.h" #include "VulkanUtil.h" -#include "extension/VulkanNrdExtension.h" +#include "extension/VulkanNrdPlugin.h" #include #include "log/LogSystem.h" @@ -1696,7 +1696,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 +1727,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..959058806 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDevice.h +++ b/source/runtime/render/rhi/vulkan/VulkanDevice.h @@ -143,12 +143,12 @@ 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; + 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} {} @@ -246,11 +246,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; diff --git a/source/runtime/render/rhi/vulkan/extension/NrdExtension.cpp b/source/runtime/render/rhi/vulkan/extension/NrdPlugin.cpp similarity index 99% rename from source/runtime/render/rhi/vulkan/extension/NrdExtension.cpp rename to source/runtime/render/rhi/vulkan/extension/NrdPlugin.cpp index aaeedce45..39b070e6f 100644 --- a/source/runtime/render/rhi/vulkan/extension/NrdExtension.cpp +++ b/source/runtime/render/rhi/vulkan/extension/NrdPlugin.cpp @@ -1,4 +1,4 @@ -#include "rhi/extension/NrdExtension.h" +#include "rhi/extension/NrdPlugin.h" #if WITH_NRD 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/extension/VulkanNrdExtension.cpp b/source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.cpp similarity index 99% rename from source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.cpp rename to source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.cpp index 1c1e53211..4881c4435 100644 --- a/source/runtime/render/rhi/vulkan/extension/VulkanNrdExtension.cpp +++ b/source/runtime/render/rhi/vulkan/extension/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/extension/VulkanNrdPlugin.h b/source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.h new file mode 100644 index 000000000..118f99177 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.h @@ -0,0 +1,29 @@ +#ifndef VULKAN_NRD_PLUGIN_H +#define VULKAN_NRD_PLUGIN_H + +#include "rhi/extension/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 From 8afc70a3027ad7b4e6192dafc968f762b349c2f7 Mon Sep 17 00:00:00 2001 From: YXHXianYu <2943003@qq.com> Date: Sun, 12 Apr 2026 20:39:48 +0800 Subject: [PATCH 2/4] =?UTF-8?q?refactor(rhi):=20=E9=87=8D=E6=9E=84VulkanEx?= =?UTF-8?q?tension=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=BA=86=E4=B8=93=E7=94=A8Ex?= =?UTF-8?q?tensionRegistry=EF=BC=8C=E4=BE=BF=E4=BA=8E=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=92=8C=E7=AE=A1=E7=90=86extension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 实现里补齐对应逻辑。 --- .../render/rhi/vulkan/VulkanDevice.cpp | 2 +- .../runtime/render/rhi/vulkan/VulkanDevice.h | 2 +- .../vulkan/platform/VulkanGenericPlatform.h | 4 - .../windows/VulkanWindowsPlatform.cpp | 32 ---- .../platform/windows/VulkanWindowsPlatform.h | 3 - .../vulkanextension/VulkanExtension.cpp | 59 +++++++ .../{ => vulkanextension}/VulkanExtension.h | 41 ++++- .../VulkanExtensionFactories.cpp} | 140 +++++----------- .../VulkanExtensionFactories.h | 22 +++ .../VulkanExtensionRegistry.cpp | 150 ++++++++++++++++++ .../vulkanextension/VulkanExtensionRegistry.h | 14 ++ 11 files changed, 320 insertions(+), 149 deletions(-) create mode 100644 source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.cpp rename source/runtime/render/rhi/vulkan/{ => vulkanextension}/VulkanExtension.h (66%) rename source/runtime/render/rhi/vulkan/{VulkanExtension.cpp => vulkanextension/VulkanExtensionFactories.cpp} (79%) create mode 100644 source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.h create mode 100644 source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp create mode 100644 source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.h diff --git a/source/runtime/render/rhi/vulkan/VulkanDevice.cpp b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp index 8a3142a31..da4e4ef3b 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDevice.cpp +++ b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp @@ -6,7 +6,7 @@ #include "PixelFormat.h" #include "VulkanCommand.h" #include "VulkanDebugCallback.h" -#include "VulkanExtension.h" +#include "vulkanextension/VulkanExtension.h" #include "VulkanMacroUtils.h" #include "VulkanPlatform.h" #include "VulkanQueue.h" diff --git a/source/runtime/render/rhi/vulkan/VulkanDevice.h b/source/runtime/render/rhi/vulkan/VulkanDevice.h index 959058806..e8f4cee67 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDevice.h +++ b/source/runtime/render/rhi/vulkan/VulkanDevice.h @@ -15,7 +15,7 @@ #include "VulkanDescriptor.h" #include "VulkanDeviceFeature.h" #include "VulkanDeviceProperty.h" -#include "VulkanExtension.h" +#include "vulkanextension/VulkanExtension.h" #include "VulkanPlatform.h" #include "VulkanQueue.h" #include "VulkanTypeDefs.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/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.h b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h similarity index 66% rename from source/runtime/render/rhi/vulkan/VulkanExtension.h rename to source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h index 6ad45e4b7..2871bff1e 100644 --- a/source/runtime/render/rhi/vulkan/VulkanExtension.h +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h @@ -1,22 +1,49 @@ -// -// Created by 74535 on 2023/10/11. -// +/* +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 -#define VULKAN_EXTENSION_OPTIONAL 1 -#define VULKAN_EXTENSION_REQUIRED 0 -#include "VulkanTypeDefs.h" -#include "log/LogSystem.h" +#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: diff --git a/source/runtime/render/rhi/vulkan/VulkanExtension.cpp b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp similarity index 79% rename from source/runtime/render/rhi/vulkan/VulkanExtension.cpp rename to source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp index dd2efd87d..42b972e7f 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,50 @@ class VulkanEXTMeshShaderExtension final : public VulkanDeviceExtension { VkPhysicalDeviceMeshShaderFeaturesEXT m_mesh_shader_features; }; -TVulkanDeviceExtensionArray VulkanDeviceExtension::GetMERequiredDeviceExtensions() { - // LOG_INFO("VulkanDeviceExtension: raytracing support, {}", _rhi_info.ray_tracing); - - TVulkanDeviceExtensionArray extensions; - -#define ADD_EXTENSION(ext_name, optional) \ - extensions.emplace_back(std::make_shared(ext_name, optional)) +} // namespace -#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); - -#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 +std::shared_ptr CreateVulkanEXTSwapchainMaintenance1Extension(bool _optional) { + return std::make_shared(_optional); +} - // debug extensions +std::shared_ptr CreateVulkanKHRAccelerationStructureExtension(bool _optional) { + return std::make_shared(_optional); +} - // platform specific extensions +std::shared_ptr CreateVulkanKHRRayTracingPipelineExtension(bool _optional) { + return std::make_shared(_optional); +} - VulkanPlatform::GetDeviceExtensions(extensions); +std::shared_ptr CreateVulkanKHRRayQueryExtension(bool _optional) { + return std::make_shared(_optional); +} - // 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); +std::shared_ptr CreateVulkanEXTDescriptorBufferExtension(bool _optional) { + return std::make_shared(_optional); +} -#undef ADD_EXTENSION -#undef ADD_CUSTOM_EXTENSION +std::shared_ptr CreateVulkanKHRPushDescriptorExtension(bool _optional) { + return std::make_shared(_optional); +} - return extensions; +std::shared_ptr CreateVulkanEXTMemoryDecompressionExtension(bool _optional) { + return std::make_shared(_optional); } -TVulkanDeviceExtensionArray -VulkanDeviceExtension::GetMEEnabledDeviceExtensions(const Set& _gpu_extensions) { - auto extensions = GetMERequiredDeviceExtensions(); +std::shared_ptr CreateVulkanEXTCopyMemoryIndirectExtension(bool _optional) { + return std::make_shared(_optional); +} - TVulkanDeviceExtensionArray extensions_enabled; +std::shared_ptr CreateVulkanEXTMemoryPriorityAllocateInfoExtension(bool _optional) { + return std::make_shared(_optional); +} - for (const auto& ext : extensions) { - if (_gpu_extensions.contains(ext->GetExtensionName().data())) { - ext->Enable(); - extensions_enabled.emplace_back(ext); - } - } +std::shared_ptr CreateVulkanEXTPageableDeviceLocalMemoryExtension(bool _optional) { + return std::make_shared(_optional); +} - return extensions_enabled; +std::shared_ptr CreateVulkanEXTMeshShaderExtension(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..697e5b323 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.h @@ -0,0 +1,22 @@ +#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); + +} // 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..773cb6711 --- /dev/null +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp @@ -0,0 +1,150 @@ +#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, + }, +#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 From 1fde85fbdf7884c593dffbcf627972614374293a Mon Sep 17 00:00:00 2001 From: YXHXianYu <2943003@qq.com> Date: Sun, 12 Apr 2026 20:43:59 +0800 Subject: [PATCH 3/4] =?UTF-8?q?refactor(rhi):=20=E5=B0=86nrd=20extension?= =?UTF-8?q?=E7=9A=84extension=E6=96=87=E4=BB=B6=E5=A4=B9=E9=87=8D=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E4=B8=BAplugin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runtime/render/renderer/raytracing/RaytracingRenderer.cpp | 2 +- source/runtime/render/rhi/RHIImpl.cpp | 2 +- source/runtime/render/rhi/{extension => plugin}/NrdPlugin.h | 0 source/runtime/render/rhi/vulkan/VulkanDevice.cpp | 2 +- .../render/rhi/vulkan/{extension => plugin}/NrdIntegration.cpp | 0 .../render/rhi/vulkan/{extension => plugin}/NrdPlugin.cpp | 2 +- .../render/rhi/vulkan/{extension => plugin}/VulkanNrdPlugin.cpp | 0 .../render/rhi/vulkan/{extension => plugin}/VulkanNrdPlugin.h | 2 +- 8 files changed, 5 insertions(+), 5 deletions(-) rename source/runtime/render/rhi/{extension => plugin}/NrdPlugin.h (100%) rename source/runtime/render/rhi/vulkan/{extension => plugin}/NrdIntegration.cpp (100%) rename source/runtime/render/rhi/vulkan/{extension => plugin}/NrdPlugin.cpp (99%) rename source/runtime/render/rhi/vulkan/{extension => plugin}/VulkanNrdPlugin.cpp (100%) rename source/runtime/render/rhi/vulkan/{extension => plugin}/VulkanNrdPlugin.h (95%) diff --git a/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp b/source/runtime/render/renderer/raytracing/RaytracingRenderer.cpp index 576827fe6..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/NrdPlugin.h" +#include "rhi/plugin/NrdPlugin.h" #include "scene/GpuScene.h" #include "scene/loader/LoaderInterface.h" #include "shader/ShaderResourceManager.h" diff --git a/source/runtime/render/rhi/RHIImpl.cpp b/source/runtime/render/rhi/RHIImpl.cpp index eab99022d..c0c400fa8 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/NrdPlugin.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)); diff --git a/source/runtime/render/rhi/extension/NrdPlugin.h b/source/runtime/render/rhi/plugin/NrdPlugin.h similarity index 100% rename from source/runtime/render/rhi/extension/NrdPlugin.h rename to source/runtime/render/rhi/plugin/NrdPlugin.h diff --git a/source/runtime/render/rhi/vulkan/VulkanDevice.cpp b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp index da4e4ef3b..82bdb755a 100644 --- a/source/runtime/render/rhi/vulkan/VulkanDevice.cpp +++ b/source/runtime/render/rhi/vulkan/VulkanDevice.cpp @@ -12,7 +12,7 @@ #include "VulkanQueue.h" #include "VulkanRHIResource.h" #include "VulkanUtil.h" -#include "extension/VulkanNrdPlugin.h" +#include "plugin/VulkanNrdPlugin.h" #include #include "log/LogSystem.h" 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/NrdPlugin.cpp b/source/runtime/render/rhi/vulkan/plugin/NrdPlugin.cpp similarity index 99% rename from source/runtime/render/rhi/vulkan/extension/NrdPlugin.cpp rename to source/runtime/render/rhi/vulkan/plugin/NrdPlugin.cpp index 39b070e6f..e06720da9 100644 --- a/source/runtime/render/rhi/vulkan/extension/NrdPlugin.cpp +++ b/source/runtime/render/rhi/vulkan/plugin/NrdPlugin.cpp @@ -1,4 +1,4 @@ -#include "rhi/extension/NrdPlugin.h" +#include "rhi/plugin/NrdPlugin.h" #if WITH_NRD diff --git a/source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.cpp b/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.cpp similarity index 100% rename from source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.cpp rename to source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.cpp diff --git a/source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.h b/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.h similarity index 95% rename from source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.h rename to source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.h index 118f99177..2fb0bf8c3 100644 --- a/source/runtime/render/rhi/vulkan/extension/VulkanNrdPlugin.h +++ b/source/runtime/render/rhi/vulkan/plugin/VulkanNrdPlugin.h @@ -1,7 +1,7 @@ #ifndef VULKAN_NRD_PLUGIN_H #define VULKAN_NRD_PLUGIN_H -#include "rhi/extension/NrdPlugin.h" +#include "rhi/plugin/NrdPlugin.h" #include "../VulkanRHIResource.h" From 3854e4167428365b9999237e1b06d9bd80c958ab Mon Sep 17 00:00:00 2001 From: YXHXianYu <2943003@qq.com> Date: Mon, 13 Apr 2026 00:32:56 +0800 Subject: [PATCH 4/4] =?UTF-8?q?feat(rhi):=20=E6=B7=BB=E5=8A=A0Cooperative?= =?UTF-8?q?=E6=8B=93=E5=B1=95=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=EF=BC=8C?= =?UTF-8?q?=E9=9C=80=E8=A6=81vulkan=20runtime=20>=3D=201.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../render/renderer/raster/RasterRenderer.cpp | 5 + source/runtime/render/rhi/RHI.h | 2 + source/runtime/render/rhi/RHIImpl.cpp | 4 + source/runtime/render/rhi/RHIImpl.h | 4 + .../render/rhi/vulkan/VulkanDebugCallback.cpp | 74 +++++++- .../render/rhi/vulkan/VulkanDevice.cpp | 40 ++++- .../runtime/render/rhi/vulkan/VulkanDevice.h | 9 +- .../render/rhi/vulkan/VulkanDeviceFeature.h | 8 + .../render/rhi/vulkan/VulkanDeviceProperty.h | 22 ++- .../VulkanCooperativeSupport.cpp | 84 +++++++++ .../VulkanCooperativeSupport.h | 31 ++++ .../vulkan/vulkanextension/VulkanExtension.h | 96 ++++++++-- .../VulkanExtensionFactories.cpp | 166 ++++++++++++++++++ .../VulkanExtensionFactories.h | 2 + .../VulkanExtensionRegistry.cpp | 12 ++ 15 files changed, 526 insertions(+), 33 deletions(-) create mode 100644 source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.cpp create mode 100644 source/runtime/render/rhi/vulkan/vulkanextension/VulkanCooperativeSupport.h 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/rhi/RHI.h b/source/runtime/render/rhi/RHI.h index ea0b388d7..912984b26 100644 --- a/source/runtime/render/rhi/RHI.h +++ b/source/runtime/render/rhi/RHI.h @@ -200,6 +200,8 @@ class RenderDevice { template 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 c0c400fa8..4414d7267 100644 --- a/source/runtime/render/rhi/RHIImpl.cpp +++ b/source/runtime/render/rhi/RHIImpl.cpp @@ -127,6 +127,10 @@ Ext* RenderDevice::LoadPlugin() const { return static_cast(impl->LoadPlugin(Ext::name)); } +bool RenderDevice::IsExtensionCooperativeEnabled() const { + return impl && impl->IsExtensionCooperativeEnabled(); +} + void RenderDevice::FlushDebugMessages() const { impl->FlushDebugMessages(); } diff --git a/source/runtime/render/rhi/RHIImpl.h b/source/runtime/render/rhi/RHIImpl.h index ce2cea3a9..dc688c67b 100644 --- a/source/runtime/render/rhi/RHIImpl.h +++ b/source/runtime/render/rhi/RHIImpl.h @@ -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/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 82bdb755a..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/VulkanExtension.h" #include "VulkanMacroUtils.h" #include "VulkanPlatform.h" #include "VulkanQueue.h" #include "VulkanRHIResource.h" #include "VulkanUtil.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); diff --git a/source/runtime/render/rhi/vulkan/VulkanDevice.h b/source/runtime/render/rhi/vulkan/VulkanDevice.h index e8f4cee67..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/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) @@ -149,8 +150,8 @@ class VulkanDevice : public RenderDevice::Impl { using Ctor = std::function; using Dtor = std::function; RuntimePlugin* ext; - Ctor ctor; - Dtor dtor; + 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} { @@ -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/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.h b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h index 2871bff1e..61c63a813 100644 --- a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtension.h @@ -91,10 +91,18 @@ class VulkanDeviceExtension : public VulkanExtensionBase { 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: @@ -108,19 +116,85 @@ class VulkanOptionalDeviceExtensions final { 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; - 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; + 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; - bool m_has_nv_copy_memory_indirect; + 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 diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp index 42b972e7f..915ba102a 100644 --- a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.cpp @@ -355,6 +355,164 @@ class VulkanEXTMeshShaderExtension final : public VulkanDeviceExtension { VkPhysicalDeviceMeshShaderFeaturesEXT m_mesh_shader_features; }; +// 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() {} + + // 把 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); + } + + // 根据驱动返回的 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); + } + + // 额外枚举驱动支持的 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; + } + + 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; + } + + result = vkGetPhysicalDeviceCooperativeMatrixPropertiesKHR( + _device->GetGpu(), &property_count, cooperative_matrix_supports.data() + ); + if (result != VK_SUCCESS && result != VK_INCOMPLETE) { + cooperative_matrix_supports.clear(); + return; + } + + if (property_count < cooperative_matrix_supports.size()) { + cooperative_matrix_supports.resize(property_count); + } + } + + void PreCreateDevice(VkDeviceCreateInfo& _device_create_info) override { + if (m_is_usable && m_is_enabled) { + AddToPNext(_device_create_info, m_cooperative_matrix_features); + } + } + +private: + VkPhysicalDeviceCooperativeMatrixFeaturesKHR m_cooperative_matrix_features; +}; + +// 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() {} + + // 把 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); + } + + // 根据驱动返回的 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); + } + + // 额外枚举驱动支持的 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; + } + + 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); + } + } + +private: + VkPhysicalDeviceCooperativeVectorFeaturesNV m_cooperative_vector_features; +}; + } // namespace std::shared_ptr CreateVulkanEXTSwapchainMaintenance1Extension(bool _optional) { @@ -401,4 +559,12 @@ std::shared_ptr CreateVulkanEXTMeshShaderExtension(bool _ 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 index 697e5b323..177073cf5 100644 --- a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.h +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionFactories.h @@ -16,6 +16,8 @@ std::shared_ptr CreateVulkanEXTCopyMemoryIndirectExtensio 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 diff --git a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp index 773cb6711..f15e23a24 100644 --- a/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp +++ b/source/runtime/render/rhi/vulkan/vulkanextension/VulkanExtensionRegistry.cpp @@ -75,6 +75,18 @@ static constexpr VulkanExtensionDesc vulkan_extension_descs[] = { .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,