[Feat] (Diligent, CMake): enable DiligentCore and add initial Diligent/Vulkan backend skeleton

- Add MOBILEGL_ENABLE_DILIGENT option; build DiligentCore Vulkan-only after
  MobileGL's existing 3rdparty targets so shared glslang/SPIRV-Cross/xxHash
  targets are reused instead of duplicated.
- Add BackendType::DiligentVulkan, config parsing, and backend-object switch.
- Add DiligentBackend::BackendObject_Diligent skeleton: creates a Diligent
  Vulkan device/context when an adapter is available, advertises GL 3.2 core,
  and returns an empty GL function table for now.
- Add local DiligentVulkanSanityTest that compiles/runs on the host (skips
  device creation gracefully when no Vulkan adapter is present).
- Fix GLXImpl EGLDisplay member shadowing the X11 Display typedef, exposed by
  GCC 16 + Diligent header include order.
This commit is contained in:
BZLZHH
2026-08-18 12:42:17 +08:00
parent 7769156cfc
commit e62f158c22
13 changed files with 341 additions and 12 deletions
+4 -1
View File
@@ -1,4 +1,4 @@
################################################################################
################################################################################
# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。
################################################################################
@@ -16,6 +16,9 @@ MobileGLCodeManager
MobileGL/MG_Test/build
/build_*
/cmake-build*
/build-*/
/local.properties
/.jspace/
.idea
MobileGL/MG*/build*
MobileGL/MG*/cmake-build*
+41 -1
View File
@@ -199,7 +199,6 @@ set(SPIRV_REFLECT_ENABLE_ASSERTS OFF CACHE BOOL "Enable asserts for debugging"
set(SPIRV_REFLECT_ENABLE_ASAN OFF CACHE BOOL "Use address sanitization" FORCE)
set(SPIRV_REFLECT_INSTALL OFF CACHE BOOL "Whether to install" FORCE)
# add_subdirectory(3rdparty/DiligentCore)
add_subdirectory(3rdparty/glslang)
add_subdirectory(3rdparty/SPIRV-Cross)
add_subdirectory(3rdparty/VulkanMemoryAllocator)
@@ -211,6 +210,23 @@ set(XXHASH_BUILD_XXHSUM OFF)
option(BUILD_SHARED_LIBS OFF)
add_subdirectory(3rdparty/xxHash/build/cmake xxhash_build EXCLUDE_FROM_ALL)
# Diligent-based backend. Enabled by default on local builds; only the Vulkan
# engine from DiligentCore is built. Added after the other 3rdparty projects so
# DiligentCore reuses the glslang / SPIRV-Cross / SPIRV-Tools / xxHash targets
# already defined by MobileGL instead of building its bundled copies.
option(MOBILEGL_ENABLE_DILIGENT "Enable the Diligent/Vulkan backend" ON)
if(MOBILEGL_ENABLE_DILIGENT)
set(DILIGENT_NO_DIRECT3D11 ON CACHE BOOL "Disable Direct3D11 backend" FORCE)
set(DILIGENT_NO_DIRECT3D12 ON CACHE BOOL "Disable Direct3D12 backend" FORCE)
set(DILIGENT_NO_OPENGL ON CACHE BOOL "Disable OpenGL backend" FORCE)
set(DILIGENT_NO_METAL ON CACHE BOOL "Disable Metal backend" FORCE)
set(DILIGENT_NO_WEBGPU ON CACHE BOOL "Disable WebGPU backend" FORCE)
set(DILIGENT_NO_ARCHIVER ON CACHE BOOL "Disable Archiver" FORCE)
set(DILIGENT_BUILD_TESTS OFF CACHE BOOL "Build Diligent tests" FORCE)
set(DILIGENT_INSTALL_CORE OFF CACHE BOOL "Install DiligentCore" FORCE)
add_subdirectory(3rdparty/DiligentCore)
endif()
set(TRACY_ENABLE ${MOBILEGL_ENABLE_TRACY} CACHE BOOL "Enable Tracy, this is an internal variable" FORCE)
if (TRACY_ENABLE)
@@ -396,6 +412,13 @@ set(SOURCE_FILES
MobileGL/MG_State/GLState/RenderbufferState/RenderbufferState.cpp
)
if(MOBILEGL_ENABLE_DILIGENT)
list(APPEND SOURCE_FILES
MobileGL/MG_Backend/Diligent/BackendObject_Diligent.cpp
MobileGL/MG_Backend/Diligent/DiligentVulkan.cpp
)
endif()
if (APPLE AND NOT MOBILEGL_IOS)
list(APPEND SOURCE_FILES
MobileGL/MG_Impl/CGLImpl/CGLImpl.cpp
@@ -436,6 +459,21 @@ set(MOBILEGL_LINK_LIBRARIES
Threads::Threads
)
if(MOBILEGL_ENABLE_DILIGENT)
list(APPEND MOBILEGL_LINK_LIBRARIES
Diligent-GraphicsEngineVk-static
Diligent-GraphicsEngine
Diligent-GraphicsEngineNextGenBase
Diligent-GraphicsAccessories
Diligent-ShaderTools
Diligent-GraphicsTools
Diligent-Common
Diligent-Primitives
Diligent-TargetPlatform
Vulkan::Headers
)
endif()
set(MOBILEGL_COMPILE_DEF
-DVMA_STATIC_VULKAN_FUNCTIONS=0
-DVMA_DYNAMIC_VULKAN_FUNCTIONS=1
@@ -501,6 +539,7 @@ target_compile_definitions(${CMAKE_PROJECT_NAME}
${MOBILEGL_COMPILE_DEF}
MOBILEGL_LOG_ACTIVE_LEVEL=${MOBILEGL_LOG_ACTIVE_LEVEL}
$<$<BOOL:${MOBILEGL_TRACE_ANGLE_VARIANTS}>:MOBILEGL_TRACE_ANGLE_VARIANTS=1>
$<$<BOOL:${MOBILEGL_ENABLE_DILIGENT}>:MOBILEGL_ENABLE_DILIGENT=1>
)
if(UNIX AND NOT APPLE AND NOT ANDROID)
@@ -559,6 +598,7 @@ if(NOT ANDROID)
PUBLIC
${MOBILEGL_COMPILE_DEF}
MOBILEGL_LOG_ACTIVE_LEVEL=${MOBILEGL_LOG_ACTIVE_LEVEL}
$<$<BOOL:${MOBILEGL_ENABLE_DILIGENT}>:MOBILEGL_ENABLE_DILIGENT=1>
)
endif()
+1
View File
@@ -202,6 +202,7 @@ namespace MobileGL::MG_ConfigLoader {
}
ENTRY(DirectGLES)
ENTRY(DirectVulkan)
ENTRY(DiligentVulkan)
ENTRY(Unknown)
MG_Config::ActiveBackendType = BackendType::Unknown;
#undef ENTRY
+1
View File
@@ -19,6 +19,7 @@ namespace MobileGL {
enum class BackendType {
DirectGLES,
DirectVulkan,
DiligentVulkan,
BackendTypeCount,
Unknown = -1
};
@@ -0,0 +1,134 @@
// MobileGL - MobileGL/MG_Backend/Diligent/BackendObject_Diligent.cpp
// Copyright (c) 2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
#include "BackendObject_Diligent.h"
#include "DiligentVulkan.h"
#include <MG_Backend/BackendObject.h>
#include <EngineFactoryVk.h>
#include <RenderDevice.h>
#include <DeviceContext.h>
#include <exception>
namespace MobileGL::MG_Backend::DiligentBackend {
namespace {
const RendererInfo BuildInitialRendererInfo() {
RendererInfo info;
info.RendererName = "MobileGL (Diligent/Vulkan)";
info.BackendName = "Diligent Vulkan";
info.RendererGLInfo.TargetGLVersion = {3, 2, 0};
info.RendererGLInfo.TargetGLSLVersion = {1, 50, 0};
info.RendererGLInfo.IsCompatibilityProfile = false;
return info;
}
} // namespace
BackendObject_Diligent::BackendObject_Diligent()
: m_rendererInfo(BuildInitialRendererInfo()) {}
BackendObject_Diligent::~BackendObject_Diligent() {
m_pContext.Release();
m_pDevice.Release();
m_pFactoryVk = nullptr;
}
Bool BackendObject_Diligent::CreateDiligentDevice() {
if (m_pDevice && m_pContext) {
return true;
}
try {
if (m_pFactoryVk == nullptr) {
m_pFactoryVk = ::Diligent::GetEngineFactoryVk();
if (m_pFactoryVk == nullptr) {
MGLOG_E("Diligent: failed to load Vulkan engine factory");
return false;
}
m_pFactoryVk->SetBreakOnError(false);
}
::Diligent::Uint32 numAdapters = 0;
m_pFactoryVk->EnumerateAdapters(::Diligent::Version{}, numAdapters, nullptr);
if (numAdapters == 0) {
MGLOG_W("Diligent: no Vulkan adapters available; skipping device creation");
return false;
}
::Diligent::EngineVkCreateInfo engineCI;
::Diligent::ImmediateContextCreateInfo ctxCI;
ctxCI.Name = "MobileGL Diligent Main Context";
ctxCI.QueueId = 0;
ctxCI.Priority = ::Diligent::QUEUE_PRIORITY_MEDIUM;
engineCI.NumImmediateContexts = 1;
engineCI.pImmediateContextInfo = &ctxCI;
::Diligent::IRenderDevice* pDevice = nullptr;
::Diligent::IDeviceContext* pContext = nullptr;
m_pFactoryVk->CreateDeviceAndContextsVk(engineCI, &pDevice, &pContext);
if (pDevice == nullptr || pContext == nullptr) {
MGLOG_E("Diligent: failed to create Vulkan device/context");
return false;
}
m_pDevice.Attach(pDevice);
m_pContext.Attach(pContext);
MGLOG_I("Diligent: Vulkan device created");
return true;
} catch (const std::exception& e) {
MGLOG_W("Diligent: Vulkan device creation failed: %s", e.what());
return false;
} catch (...) {
MGLOG_W("Diligent: Vulkan device creation failed");
return false;
}
}
void BackendObject_Diligent::Initialize() {
if (m_initialized) {
return;
}
if (!CreateDiligentDevice()) {
MGLOG_W("Diligent: backend initialization failed");
return;
}
m_initialized = true;
}
Bool BackendObject_Diligent::InitCapabilities() {
// Skeleton: no format probing yet. The backend advertises GL 3.2 core
// capability, and the capability tables will be filled as resource
// creation paths are ported.
m_backendCapabilitiesInitialized = true;
return true;
}
Bool BackendObject_Diligent::InitWindowSurface() {
// Skeleton: no native swapchain creation yet.
return true;
}
const RendererInfo& BackendObject_Diligent::GetRendererInfo() const {
return m_rendererInfo;
}
String BackendObject_Diligent::GetBackendAPIVersionString() const {
return "Diligent Vulkan 0.1 (GL 3.2 skeleton)";
}
const GlobalBackendFunctionsTable& BackendObject_Diligent::GetBackendFunctions() const {
return m_functions;
}
const DynamicBackendParameters& BackendObject_Diligent::GetDynamicParameters() const {
return m_dynamicParameters;
}
BackendType BackendObject_Diligent::GetBackendType() const {
return BackendType::DiligentVulkan;
}
} // namespace MobileGL::MG_Backend::DiligentBackend
@@ -0,0 +1,61 @@
// MobileGL - MobileGL/MG_Backend/Diligent/BackendObject_Diligent.h
// Copyright (c) 2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
#pragma once
#include <Includes.h>
#include "../BackendObject.h"
// X11 (pulled in by Includes.h through Vulkan-Headers) defines True/False as
// macros, which collide with Diligent's Bool constants in BasicTypes.h.
#if defined(True)
#undef True
#endif
#if defined(False)
#undef False
#endif
#include <RefCntAutoPtr.hpp>
namespace Diligent {
struct IEngineFactoryVk;
struct IRenderDevice;
struct IDeviceContext;
}
namespace MobileGL::MG_Backend::DiligentBackend {
// New Diligent/Vulkan backend, implemented from scratch on top of
// DiligentCore. The backend object owns the Diligent device/context and
// currently advertises OpenGL 3.2 core capability; the GL function table
// is intentionally empty until drawing/resource paths are ported.
class BackendObject_Diligent : public BackendObject {
public:
BackendObject_Diligent();
~BackendObject_Diligent() override;
void Initialize() override;
Bool InitCapabilities() override;
Bool InitWindowSurface() override;
const RendererInfo& GetRendererInfo() const override;
String GetBackendAPIVersionString() const override;
const GlobalBackendFunctionsTable& GetBackendFunctions() const override;
const DynamicBackendParameters& GetDynamicParameters() const override;
BackendType GetBackendType() const override;
private:
Bool CreateDiligentDevice();
RendererInfo m_rendererInfo;
DynamicBackendParameters m_dynamicParameters;
GlobalBackendFunctionsTable m_functions{};
::Diligent::IEngineFactoryVk* m_pFactoryVk = nullptr;
::Diligent::RefCntAutoPtr<::Diligent::IRenderDevice> m_pDevice;
::Diligent::RefCntAutoPtr<::Diligent::IDeviceContext> m_pContext;
Bool m_initialized = false;
};
} // namespace MobileGL::MG_Backend::DiligentBackend
@@ -0,0 +1,8 @@
// MobileGL - MobileGL/MG_Backend/Diligent/DiligentVulkan.cpp
// Copyright (c) 2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
#include "DiligentVulkan.h"
@@ -0,0 +1,17 @@
// MobileGL - MobileGL/MG_Backend/Diligent/DiligentVulkan.h
// Copyright (c) 2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
#pragma once
#include <Includes.h>
namespace MobileGL::MG_Backend::DiligentBackend {
// Backend identity string used by the backend object and local smoke tests.
inline String GetDiligentVulkanBackendName() {
return "DiligentVulkan";
}
} // namespace MobileGL::MG_Backend::DiligentBackend
+8
View File
@@ -10,6 +10,9 @@
#include <Config.h>
#include <MG_Util/BackendLoaders/OpenGL/Loader.h>
#include <MG_Util/Converters/MGToStr/GLExtensionConverter.h>
#if defined(MOBILEGL_ENABLE_DILIGENT)
#include <MG_Backend/Diligent/BackendObject_Diligent.h>
#endif
namespace MobileGL::MG_Backend {
void LogBackendInfo() {
@@ -55,6 +58,11 @@ namespace MobileGL::MG_Backend {
case BackendType::DirectVulkan:
pActiveBackendObject = MakeUnique<DirectVulkan::BackendObject_DirectVulkan>();
break;
#if defined(MOBILEGL_ENABLE_DILIGENT)
case BackendType::DiligentVulkan:
pActiveBackendObject = MakeUnique<DiligentBackend::BackendObject_Diligent>();
break;
#endif
case BackendType::Unknown:
default:
MGLOG_W("Unknown backend type, defaulting to unknown backend");
+10 -10
View File
@@ -175,14 +175,14 @@ namespace MobileGL::MG_Impl::GLXImpl {
struct ContextObject {
Display* XDisplay = nullptr;
EGLDisplay Display = EGL_NO_DISPLAY;
EGLDisplay Dpy = EGL_NO_DISPLAY;
EGLConfig Config = nullptr;
EGLContext Context = EGL_NO_CONTEXT;
const FBConfigInfo* FBConfig = nullptr;
};
struct DrawableSurface {
EGLDisplay Display = EGL_NO_DISPLAY;
EGLDisplay Dpy = EGL_NO_DISPLAY;
EGLSurface Surface = EGL_NO_SURFACE;
Uint32 Width = 0;
Uint32 Height = 0;
@@ -294,7 +294,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
if (width == surface.Width && height == surface.Height) {
return;
}
if (EGLImpl::ResizePlatformWindowSurface(surface.Display, surface.Surface,
if (EGLImpl::ResizePlatformWindowSurface(surface.Dpy, surface.Surface,
static_cast<EGLint>(width),
static_cast<EGLint>(height))) {
surface.Width = width;
@@ -324,7 +324,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
EGL_NONE,
};
EGLSurface surface = EGLImpl::CreatePlatformWindowSurface(
context.Display, context.Config, reinterpret_cast<void*>(drawable), attribs);
context.Dpy, context.Config, reinterpret_cast<void*>(drawable), attribs);
if (surface == EGL_NO_SURFACE) {
MGLOG_E_ONCE("glx: failed to create window surface for drawable 0x%lx (%ux%u)", drawable,
width, height);
@@ -332,7 +332,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
}
DrawableSurface record;
record.Display = context.Display;
record.Dpy = context.Dpy;
record.Surface = surface;
record.Width = width;
record.Height = height;
@@ -388,7 +388,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
ContextObject object;
object.XDisplay = dpy;
object.Display = display;
object.Dpy = display;
object.Config = config;
object.Context = eglContext;
object.FBConfig = fbconfig;
@@ -895,7 +895,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
return;
}
if (object->Context != EGL_NO_CONTEXT) {
EGLImpl::DestroyContext(object->Display, object->Context);
EGLImpl::DestroyContext(object->Dpy, object->Context);
}
Contexts().erase(context);
}
@@ -929,7 +929,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
return 0;
}
if (!EGLImpl::MakeCurrent(object->Display, surface->Surface, surface->Surface,
if (!EGLImpl::MakeCurrent(object->Dpy, surface->Surface, surface->Surface,
object->Context)) {
MGLOG_E_ONCE("glx: eglMakeCurrent failed (drawable=0x%lx, ctx=%p)", drawable, context);
return 0;
@@ -962,7 +962,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
return;
}
SyncSurfaceSize(dpy, drawable, it->second);
EGLImpl::SwapBuffers(it->second.Display, it->second.Surface);
EGLImpl::SwapBuffers(it->second.Dpy, it->second.Surface);
}
GLXDrawableHandle CreateWindow(Display*, GLXFBConfigHandle config, GLXDrawableHandle window,
@@ -988,7 +988,7 @@ namespace MobileGL::MG_Impl::GLXImpl {
if (it == surfaces.end()) {
return;
}
EGLImpl::DestroySurface(it->second.Display, it->second.Surface);
EGLImpl::DestroySurface(it->second.Dpy, it->second.Surface);
surfaces.erase(it);
}
@@ -0,0 +1,22 @@
cmake_minimum_required(VERSION 3.14)
message(STATUS "Generating build files for MobileGL Diligent Backend Test...")
add_executable(
DiligentVulkanSanityTest
SanityTest.cpp
)
target_include_directories(DiligentVulkanSanityTest PRIVATE
${MGL_ROOT}/include
${MGL_ROOT}/MobileGL
)
target_link_libraries(
DiligentVulkanSanityTest PRIVATE
GTest::gtest_main
${LINK_LIBRARIES}
)
include(GoogleTest)
gtest_discover_tests(DiligentVulkanSanityTest DISCOVERY_TIMEOUT 30 PROPERTIES LABELS integration)
@@ -0,0 +1,31 @@
// MobileGL - MobileGL/MG_Test/Backend/Diligent/SanityTest.cpp
// Copyright (c) 2026 MobileGL-Dev
// Licensed under the GNU Lesser General Public License v3.0:
// https://www.gnu.org/licenses/gpl-3.0.txt
// https://www.gnu.org/licenses/lgpl-3.0.txt
// SPDX-License-Identifier: LGPL-3.0-only
#include <gtest/gtest.h>
#include <MG_Backend/BackendObject.h>
#include <MG_Backend/Diligent/BackendObject_Diligent.h>
#include <MG_Backend/BackendObjects.h>
using namespace MobileGL;
using namespace MobileGL::MG_Backend;
TEST(DiligentVulkanBackend, CreatesDiligentDeviceAndAdvertisesGL32) {
DiligentBackend::BackendObject_Diligent backend;
backend.Initialize();
EXPECT_EQ(backend.GetBackendType(), BackendType::DiligentVulkan);
const RendererInfo& info = backend.GetRendererInfo();
EXPECT_GE(info.RendererGLInfo.TargetGLVersion.Major, 3);
if (info.RendererGLInfo.TargetGLVersion.Major == 3) {
EXPECT_GE(info.RendererGLInfo.TargetGLVersion.Minor, 2);
}
EXPECT_FALSE(backend.GetBackendAPIVersionString().empty());
EXPECT_FALSE(backend.GetRendererInfo().BackendName.empty());
}
+3
View File
@@ -84,3 +84,6 @@ add_subdirectory(Backend/DirectGLES)
if (ENABLE_INTEGRATION_TESTS)
add_subdirectory(Backend/DirectVulkan)
endif()
if (MOBILEGL_ENABLE_DILIGENT)
add_subdirectory(Backend/Diligent)
endif()