mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 04:08:32 +09:00
[Feat] (Diligent, EGL): wire EGL window swapchain creation via Diligent ISwapChain
- Add CreateSwapChain to renderer using IEngineFactoryVk::CreateSwapChainVk - InitWindowSurface creates the swapchain for native window surfaces - Present now presents the active swapchain; ReleaseEGLResources releases it - InitPbufferSurface keeps offscreen target for pbuffer EGL surfaces - Update handoff; 16 Diligent tests pass
This commit is contained in:
+2
-1
@@ -117,6 +117,7 @@ Working tree is clean.
|
||||
Verified locally on Turnip Adreno 750:
|
||||
|
||||
- Diligent device/context creation
|
||||
- EGL window-surface swapchain creation path through Diligent `ISwapChain` (offscreen tests still use the offscreen target)
|
||||
- GL 3.2 / GLSL 1.50 capability advertisement
|
||||
- Offscreen color + depth rendering
|
||||
- Clear color and depth
|
||||
@@ -219,7 +220,7 @@ Notes:
|
||||
- User framebuffers now support texture color attachments, renderbuffer color readback, multiple simultaneous color targets, and depth/stencil texture or renderbuffer attachments.
|
||||
- Textures auto-sync `ITextureObject` → Diligent resources, including mip levels and sampler state; compressed textures and integer/3-channel formats that Diligent lacks are still skipped.
|
||||
- Global UBO (default-block `glUniform*`) and named application UBO blocks (through `glBindBufferBase`/`glUniformBlockBinding`) now upload and bind; SSBOs are still not fed from frontend buffer bindings.
|
||||
- No swapchain / EGL window surface presentation yet; `Present()` only flushes and `SetSwapInterval` is a no-op.
|
||||
- Swapchain creation is now wired for native EGL window surfaces via `Diligent::ISwapChain`; `Present()` presents the active swap chain when present and otherwise flushes the offscreen target. Actual on-screen EGL presentation is still untested in this headless environment, and the X11 display/connection fields are not yet plumbed through `WindowHandle`. `SetSwapInterval` remains a no-op.
|
||||
- No transform feedback / GPU-accelerated queries / non-color readback; fence sync and timer queries use CPU fallbacks.
|
||||
- Draw range, multi-draw, instanced-draw wrappers, clear-buffer, blit, read-pixels, CopyTexImage*, CopyImageSubData, GenerateMipmap, GetTexImage/GetTextureImage and indirect draws are now wired; buffer subdata paths still remain.
|
||||
- A last-PSO cache now avoids recreating the pipeline when program/render-state/topology/VAO layout is unchanged; texture/UBO resources are still rebound dynamically per draw.
|
||||
|
||||
@@ -813,8 +813,32 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
}
|
||||
|
||||
Bool BackendObject_Diligent::InitWindowSurface() {
|
||||
// Skeleton: no native swapchain creation yet.
|
||||
return true;
|
||||
if (!m_windowHandle.Handle) {
|
||||
MGLOG_E("BackendObject_Diligent::InitWindowSurface failed: native window handle is null");
|
||||
return false;
|
||||
}
|
||||
if (m_pRenderer == nullptr || m_pFactoryVk == nullptr) {
|
||||
MGLOG_E("BackendObject_Diligent::InitWindowSurface failed: renderer/factory is not ready");
|
||||
return false;
|
||||
}
|
||||
return m_pRenderer->CreateSwapChain(m_pFactoryVk, m_windowHandle,
|
||||
m_windowHandle.Width, m_windowHandle.Height);
|
||||
}
|
||||
|
||||
Bool BackendObject_Diligent::InitPbufferSurface(EGLint width, EGLint height) {
|
||||
// The Diligent backend keeps its offscreen target for pbuffer EGL surfaces.
|
||||
// A future enhancement can resize/recreate the offscreen target to match the
|
||||
// pbuffer dimensions.
|
||||
(void)width;
|
||||
(void)height;
|
||||
return m_pRenderer != nullptr;
|
||||
}
|
||||
|
||||
void BackendObject_Diligent::ReleaseEGLResources() {
|
||||
if (m_pRenderer != nullptr) {
|
||||
m_pRenderer->ReleaseSwapChain();
|
||||
}
|
||||
BackendObject::ReleaseEGLResources();
|
||||
}
|
||||
|
||||
const RendererInfo& BackendObject_Diligent::GetRendererInfo() const {
|
||||
|
||||
@@ -42,12 +42,14 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
void Initialize() override;
|
||||
Bool InitCapabilities() override;
|
||||
Bool InitWindowSurface() override;
|
||||
Bool InitPbufferSurface(EGLint width, EGLint height) override;
|
||||
|
||||
const RendererInfo& GetRendererInfo() const override;
|
||||
String GetBackendAPIVersionString() const override;
|
||||
const GlobalBackendFunctionsTable& GetBackendFunctions() const override;
|
||||
const DynamicBackendParameters& GetDynamicParameters() const override;
|
||||
BackendType GetBackendType() const override;
|
||||
void ReleaseEGLResources() override;
|
||||
|
||||
DiligentRenderer* GetRenderer();
|
||||
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
#include <PipelineState.h>
|
||||
#include <InputLayout.h>
|
||||
#include <Sampler.h>
|
||||
#include <SwapChain.h>
|
||||
#include <NativeWindow.h>
|
||||
#include <ShaderResourceBinding.h>
|
||||
#include <ShaderResourceVariable.h>
|
||||
#include <EngineFactoryVk.h>
|
||||
|
||||
#include <MG_State/GLState/Core.h>
|
||||
#include <MG_State/GLState/ProgramState/ProgramObject.h>
|
||||
@@ -378,6 +381,45 @@ void main()
|
||||
return true;
|
||||
}
|
||||
|
||||
Bool DiligentRenderer::CreateSwapChain(::Diligent::IEngineFactoryVk* factory, const WindowHandle& handle,
|
||||
Uint32 width, Uint32 height) {
|
||||
if (factory == nullptr || m_pDevice == nullptr || m_pContext == nullptr || handle.Handle == nullptr) {
|
||||
MGLOG_E("DiligentRenderer::CreateSwapChain: invalid factory/device/context/window");
|
||||
return false;
|
||||
}
|
||||
|
||||
::Diligent::SwapChainDesc desc;
|
||||
desc.Width = width > 0 ? width : std::max<Uint32>(handle.Width, 1);
|
||||
desc.Height = height > 0 ? height : std::max<Uint32>(handle.Height, 1);
|
||||
desc.ColorBufferFormat = ::Diligent::TEX_FORMAT_RGBA8_UNORM_SRGB;
|
||||
desc.DepthBufferFormat = ::Diligent::TEX_FORMAT_D24_UNORM_S8_UINT;
|
||||
desc.BufferCount = 2;
|
||||
|
||||
::Diligent::NativeWindow nativeWindow{};
|
||||
#if PLATFORM_ANDROID
|
||||
nativeWindow.pAWindow = handle.Handle;
|
||||
#elif PLATFORM_LINUX
|
||||
// X11 Window IDs are integers that the frontend stores as a void* handle.
|
||||
// The X11 display/connection could not be plumbed through WindowHandle yet;
|
||||
// swapchain creation on X11 may need those fields filled by a future change.
|
||||
nativeWindow.WindowId = static_cast<::Diligent::Uint32>(
|
||||
reinterpret_cast<uintptr_t>(handle.Handle));
|
||||
#else
|
||||
(void)nativeWindow;
|
||||
#endif
|
||||
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ISwapChain> pSwapChain;
|
||||
factory->CreateSwapChainVk(m_pDevice, m_pContext, desc, nativeWindow, &pSwapChain);
|
||||
if (!pSwapChain) {
|
||||
MGLOG_E("DiligentRenderer::CreateSwapChain: failed to create swap chain");
|
||||
return false;
|
||||
}
|
||||
m_pSwapChain = pSwapChain;
|
||||
m_width = desc.Width;
|
||||
m_height = desc.Height;
|
||||
return true;
|
||||
}
|
||||
|
||||
Bool DiligentRenderer::CreateOffscreenTargets() {
|
||||
::Diligent::TextureDesc texDesc;
|
||||
texDesc.Name = "MobileGL Diligent offscreen color target";
|
||||
@@ -867,7 +909,19 @@ void main()
|
||||
return false;
|
||||
}
|
||||
|
||||
auto useSwapChainTargets = [&]() -> Bool {
|
||||
if (m_pSwapChain && m_pSwapChain->GetCurrentBackBufferRTV()) {
|
||||
rtvs.push_back(m_pSwapChain->GetCurrentBackBufferRTV());
|
||||
dsv = m_pSwapChain->GetDepthBufferDSV();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if (MG_State::pGLContext == nullptr) {
|
||||
if (useSwapChainTargets()) {
|
||||
return true;
|
||||
}
|
||||
if (m_pColorRTV) {
|
||||
rtvs.push_back(m_pColorRTV.RawPtr());
|
||||
}
|
||||
@@ -877,6 +931,9 @@ void main()
|
||||
|
||||
auto drawFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Draw).GetBoundObject();
|
||||
if (!drawFbo || drawFbo->IsDefaultFramebuffer()) {
|
||||
if (useSwapChainTargets()) {
|
||||
return true;
|
||||
}
|
||||
if (m_pColorRTV) {
|
||||
rtvs.push_back(m_pColorRTV.RawPtr());
|
||||
}
|
||||
@@ -1641,6 +1698,9 @@ void main()
|
||||
}
|
||||
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITexture> pSrcTexture = m_pColorTarget;
|
||||
if (m_pSwapChain && m_pSwapChain->GetCurrentBackBufferRTV()) {
|
||||
pSrcTexture = m_pSwapChain->GetCurrentBackBufferRTV()->GetTexture();
|
||||
}
|
||||
if (MG_State::pGLContext != nullptr) {
|
||||
auto readFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
|
||||
if (readFbo && !readFbo->IsDefaultFramebuffer()) {
|
||||
@@ -1970,9 +2030,15 @@ void main()
|
||||
return true;
|
||||
}
|
||||
|
||||
void DiligentRenderer::ReleaseSwapChain() {
|
||||
m_pSwapChain.Release();
|
||||
}
|
||||
|
||||
void DiligentRenderer::Present() {
|
||||
// Offscreen renderer: nothing to present yet.
|
||||
if (m_pContext) {
|
||||
if (m_pSwapChain) {
|
||||
m_pSwapChain->Present(0);
|
||||
} else if (m_pContext) {
|
||||
// Offscreen renderer: nothing to present yet.
|
||||
m_pContext->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
|
||||
#include <RefCntAutoPtr.hpp>
|
||||
|
||||
namespace MobileGL::MG_Backend {
|
||||
struct WindowHandle;
|
||||
}
|
||||
|
||||
namespace Diligent {
|
||||
struct IRenderDevice;
|
||||
struct IDeviceContext;
|
||||
@@ -29,6 +33,8 @@ namespace Diligent {
|
||||
struct IBuffer;
|
||||
struct ISampler;
|
||||
struct IShaderResourceBinding;
|
||||
struct ISwapChain;
|
||||
struct IEngineFactoryVk;
|
||||
}
|
||||
|
||||
namespace MobileGL::MG_State::GLState {
|
||||
@@ -55,6 +61,9 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
void ClearStencil(Uint32 stencil);
|
||||
void DrawTriangle();
|
||||
void DrawVertices(const Float* vertices, Uint32 vertexCount);
|
||||
// Creates a real Diligent swap chain for a native EGL window surface.
|
||||
Bool CreateSwapChain(::Diligent::IEngineFactoryVk* factory, const WindowHandle& handle,
|
||||
Uint32 width, Uint32 height);
|
||||
// Creates a simple 2D RGBA8 texture from CPU data and makes it available
|
||||
// to state PSOs under the shader variable name "g_Texture".
|
||||
Bool CreateTestTexture(const void* data, Uint32 width, Uint32 height);
|
||||
@@ -73,6 +82,7 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
void CopyTextureSubData(MG_State::GLState::ITextureObject& src, MG_State::GLState::ITextureObject& dst);
|
||||
void GenerateMipmap(MG_State::GLState::ITextureObject& texture);
|
||||
Bool ReadTextureImage(MG_State::GLState::ITextureObject& texture, Uint32 level, void* pixels);
|
||||
void ReleaseSwapChain();
|
||||
void Present();
|
||||
|
||||
::Diligent::IRenderDevice* GetDevice() const { return m_pDevice; }
|
||||
@@ -115,6 +125,7 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITextureView> m_pColorRTV;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITexture> m_pDepthTarget;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITextureView> m_pDepthDSV;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ISwapChain> m_pSwapChain;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITexture> m_pTestTexture;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ITextureView> m_pTestSRV;
|
||||
::Diligent::RefCntAutoPtr<::Diligent::ISampler> m_pTestSampler;
|
||||
|
||||
Reference in New Issue
Block a user