diff --git a/HANDOFF_DILIGENT.md b/HANDOFF_DILIGENT.md index b7577685..2170ee4e 100644 --- a/HANDOFF_DILIGENT.md +++ b/HANDOFF_DILIGENT.md @@ -155,7 +155,7 @@ Verified locally on Turnip Adreno 750: - `DrawArraysInstanced` / `DrawElementsInstanced` family - Indirect draw CPU fallback: `DrawArraysIndirect`, `DrawElementsIndirect`, `MultiDraw*Indirect`, `*IndirectCount` - `ClearBufferfv` / `ClearBufferfi` / `ClearBufferiv` / `ClearBufferuiv` (incl. stencil clear) - - `BlitFramebuffer` (same-size color copy between current read/draw FBOs) + - `BlitFramebuffer` / `BlitNamedFramebuffer` (same-size color copy between read/draw FBOs) - `CopyTexImage2D` / `CopyTexSubImage2D` (whole-color copy fallback) - `CopyImageSubData` (whole-texture copy between two texture objects) - `GenerateMipmap` (Diligent GPU mip generation on state textures) diff --git a/MobileGL/MG_Backend/Diligent/BackendObject_Diligent.cpp b/MobileGL/MG_Backend/Diligent/BackendObject_Diligent.cpp index 4e107cf7..c2316d33 100644 --- a/MobileGL/MG_Backend/Diligent/BackendObject_Diligent.cpp +++ b/MobileGL/MG_Backend/Diligent/BackendObject_Diligent.cpp @@ -449,6 +449,26 @@ namespace MobileGL::MG_Backend::DiligentBackend { } } + void BlitNamedFramebuffer(const SharedPtr& readFramebuffer, + const SharedPtr& drawFramebuffer, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) { + (void)srcX0; + (void)srcY0; + (void)srcX1; + (void)srcY1; + (void)dstX0; + (void)dstY0; + (void)dstX1; + (void)dstY1; + (void)filter; + auto* renderer = GetActiveRenderer(); + if (renderer != nullptr) { + renderer->BlitNamedFramebuffer(readFramebuffer, drawFramebuffer, mask); + } + } + void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { (void)level; @@ -662,6 +682,7 @@ namespace MobileGL::MG_Backend::DiligentBackend { m_functions.GL.ClearBufferiv = ClearBufferiv; m_functions.GL.ClearBufferuiv = ClearBufferuiv; m_functions.GL.BlitFramebuffer = BlitFramebuffer; + m_functions.GL.BlitNamedFramebuffer = BlitNamedFramebuffer; m_functions.GL.CopyTexImage2D = CopyTexImage2D; m_functions.GL.CopyTexSubImage2D = CopyTexSubImage2D; m_functions.GL.CopyImageSubData = CopyImageSubData; diff --git a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp index 511b2380..b696ec52 100644 --- a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp +++ b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.cpp @@ -1712,6 +1712,63 @@ void main() m_pContext->UnmapTextureSubresource(pStaging, 0, 0); } + void DiligentRenderer::BlitNamedFramebuffer( + const SharedPtr& readFbo, + const SharedPtr& drawFbo, + GLbitfield mask) { + if (!m_initialized || !m_pContext || (mask & GL_COLOR_BUFFER_BIT) == 0) { + return; + } + + ::Diligent::RefCntAutoPtr<::Diligent::ITexture> pSrcTexture = m_pColorTarget; + ::Diligent::RefCntAutoPtr<::Diligent::ITexture> pDstTexture = m_pColorTarget; + if (readFbo && !readFbo->IsDefaultFramebuffer()) { + auto readBuffer = readFbo->GetReadBuffer(); + if (readBuffer == FramebufferAttachmentType::None) { + readBuffer = FramebufferAttachmentType::Color0; + } + const auto& att = readFbo->GetAttachment(readBuffer); + if (att.IsTexture() && SyncTexture(*att.GetTexture()) != nullptr) { + auto it = m_textureCache.find(att.GetTexture()->GetLifetimeId()); + if (it != m_textureCache.end() && it->second.Texture) { + pSrcTexture = it->second.Texture; + } + } else if (att.IsRenderbuffer() && SyncRenderbuffer(*att.GetRenderbuffer()) != nullptr) { + auto it = m_renderbufferCache.find(att.GetRenderbuffer()->GetExternalIndex()); + if (it != m_renderbufferCache.end() && it->second.Texture) { + pSrcTexture = it->second.Texture; + } + } + } + if (drawFbo && !drawFbo->IsDefaultFramebuffer()) { + for (const auto candidate : drawFbo->GetDrawBuffers()) { + if (candidate == FramebufferAttachmentType::None) { + continue; + } + const auto& att = drawFbo->GetAttachment(candidate); + if (att.IsTexture() && SyncTexture(*att.GetTexture()) != nullptr) { + auto it = m_textureCache.find(att.GetTexture()->GetLifetimeId()); + if (it != m_textureCache.end() && it->second.Texture) { + pDstTexture = it->second.Texture; + } + } else if (att.IsRenderbuffer() && SyncRenderbuffer(*att.GetRenderbuffer()) != nullptr) { + auto it = m_renderbufferCache.find(att.GetRenderbuffer()->GetExternalIndex()); + if (it != m_renderbufferCache.end() && it->second.Texture) { + pDstTexture = it->second.Texture; + } + } + break; + } + } + if (!pSrcTexture || !pDstTexture || pSrcTexture == pDstTexture) { + return; + } + ::Diligent::CopyTextureAttribs copyAttribs( + pSrcTexture, ::Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION, + pDstTexture, ::Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + m_pContext->CopyTexture(copyAttribs); + } + void DiligentRenderer::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { diff --git a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h index 8ea301d6..1eae53be 100644 --- a/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h +++ b/MobileGL/MG_Backend/Diligent/Renderer/DiligentRenderer.h @@ -36,6 +36,7 @@ namespace MobileGL::MG_State::GLState { class SamplerObject; class ProgramObject; class RenderbufferObject; + class FramebufferObject; } namespace MobileGL::MG_Backend::DiligentBackend { @@ -65,6 +66,9 @@ namespace MobileGL::MG_Backend::DiligentBackend { void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void BlitNamedFramebuffer(const SharedPtr& readFbo, + const SharedPtr& drawFbo, + GLbitfield mask); void CopyReadFramebufferToTexture(MG_State::GLState::ITextureObject& dst); void CopyTextureSubData(MG_State::GLState::ITextureObject& src, MG_State::GLState::ITextureObject& dst); void GenerateMipmap(MG_State::GLState::ITextureObject& texture);