Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions source/runtime/render/renderer/raster/RasterRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -145,8 +145,8 @@ void RaytracingRenderer::Run(const SharedPtr<EditorConfig> editor_config, const
//////////////////////////////////////////////////////////////////////////
#if WITH_NRD
uint64 nrd_time = 0ull;
auto* nrd_ext = device.LoadExtension<Ext::NRDExtension>();
auto nrd_interface = nrd_ext->CreateInterface(max_frame_in_flight, resolution.x, resolution.y);
auto* nrd_plugin = device.LoadPlugin<Ext::NRDPlugin>();
auto nrd_interface = nrd_plugin->CreateInterface(max_frame_in_flight, resolution.x, resolution.y);
#endif

VisualizeConfig visualize_config{};
Expand Down
12 changes: 8 additions & 4 deletions source/runtime/render/rhi/RHI.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<typename T>
concept DeviceExt =
std::is_base_of_v<DeviceExtension, T> && std::is_same_v<const std::string_view, decltype(T::name)>;
std::is_base_of_v<RuntimePlugin, T> && std::is_same_v<const std::string_view, decltype(T::name)>;

class RenderDevice {
public:
Expand Down Expand Up @@ -196,7 +198,9 @@ class RenderDevice {
}

template<DeviceExt Ext>
RENDER_API Ext* LoadExtension() const;
RENDER_API Ext* LoadPlugin() const;

RENDER_API bool IsExtensionCooperativeEnabled() const;

RENDER_API void FlushDebugMessages() const;
RENDER_API void WaitIdle();
Expand Down
12 changes: 8 additions & 4 deletions source/runtime/render/rhi/RHIImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -123,8 +123,12 @@ RaytracingSceneRef RenderDevice::CreateRaytracingScene() {
}

template<DeviceExt Ext>
Ext* RenderDevice::LoadExtension() const {
return static_cast<Ext*>(impl->LoadExtension(Ext::name));
Ext* RenderDevice::LoadPlugin() const {
return static_cast<Ext*>(impl->LoadPlugin(Ext::name));
}

bool RenderDevice::IsExtensionCooperativeEnabled() const {
return impl && impl->IsExtensionCooperativeEnabled();
}

void RenderDevice::FlushDebugMessages() const {
Expand All @@ -135,6 +139,6 @@ void RenderDevice::WaitIdle() {
impl->WaitIdle();
}

template RENDER_API Ext::NRDExtension* RenderDevice::LoadExtension<Ext::NRDExtension>() const;
template RENDER_API Ext::NRDPlugin* RenderDevice::LoadPlugin<Ext::NRDPlugin>() const;

} // namespace Moer::Render
6 changes: 5 additions & 1 deletion source/runtime/render/rhi/RHIImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -1718,6 +1718,10 @@ class RenderDevice::Impl {
; // do nothing by default
}

virtual bool IsExtensionCooperativeEnabled() const {
return false;
}

virtual void WaitIdle() {};
};

Expand Down
Original file line number Diff line number Diff line change
@@ -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支持。
Expand Down Expand Up @@ -172,10 +172,10 @@ class NRDInterface {
UnorderedMap<uint64, nri::CommandBuffer*> 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<NRDInterface>
CreateInterface(uint8 _max_frame_in_flight = 0, uint16 _frame_width = 0, uint16 _frame_height = 0) = 0;
Expand Down
74 changes: 71 additions & 3 deletions source/runtime/render/rhi/vulkan/VulkanDebugCallback.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@

#include "log/LogSystem.h"
#include "vulkan/vulkan_core.h"
#include <cctype>
#include <atomic>
#include <chrono>
#include <mutex>
#include <sstream>
#include <string>
#include <string_view>
#include <unordered_map>

namespace Moer::Render {
Expand All @@ -22,6 +23,69 @@ struct BufEntry {
};
static std::mutex s_debugbuf_mutex;
static std::unordered_map<std::string, BufEntry> 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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 : "");
Expand All @@ -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');
Expand Down
54 changes: 39 additions & 15 deletions source/runtime/render/rhi/vulkan/VulkanDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <string_view>

#include "log/LogSystem.h"
Expand Down Expand Up @@ -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{};
Expand All @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -428,6 +437,10 @@ void VulkanDevice::CreateDevice(uint32 _api_version) {
// setup extension and feature info
Moer::Array<const char*> 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());
Expand Down Expand Up @@ -638,12 +651,19 @@ void VulkanDevice::Destroy() {
// Assertion failed: m_pMetadata->IsEmpty() && "Some allocations were not freed before destruction of this memory block!"
}

Set<std::string> VulkanDevice::GetGpuExtensions(VkPhysicalDevice _gpu) {
uint32 gpu_extension_count;
// check extensions
vkEnumerateDeviceExtensionProperties(_gpu, nullptr, &gpu_extension_count, nullptr);
Set<std::string> 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<VkExtensionProperties> 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<std::string> ret;
for (const auto& extension : gpu_extensions)
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<Moer::Render::Ext::VkNRDExtension*>(_ext));
[](RuntimePlugin* _ext) {
MoerDelete(static_cast<Moer::Render::Ext::VkNRDPlugin*>(_ext));
}
);
#endif
Expand Down
Loading