[Feat] (Diligent, MG_Impl): wire CopyImageSubData whole-texture copy

- CopyImageSubData syncs both texture objects and issues a Diligent CopyTexture
- Update handoff; 16 Diligent tests pass
This commit is contained in:
BZLZHH
2026-08-23 10:05:50 +08:00
parent a223499143
commit b9d1504cc5
4 changed files with 51 additions and 1 deletions
+2 -1
View File
@@ -157,6 +157,7 @@ Verified locally on Turnip Adreno 750:
- `ClearBufferfv` / `ClearBufferfi` / `ClearBufferiv` / `ClearBufferuiv` (incl. stencil clear)
- `BlitFramebuffer` (same-size color copy between current read/draw FBOs)
- `CopyTexImage2D` / `CopyTexSubImage2D` (whole-color copy fallback)
- `CopyImageSubData` (whole-texture copy between two texture objects)
- `GetTexImage` / `GetTextureImage` (RGBA8 readback)
- `ReadPixels` from default and user color attachments
- Primitive expansion:
@@ -250,7 +251,7 @@ Notes:
- [x] `MultiDraw*`
- [x] `BlitFramebuffer` (same-size color copy)
- [x] `ReadPixels` from non-default framebuffer
- [x] `CopyTexImage*` wired as whole-color copy
- [x] `CopyTexImage*` / `CopyImageSubData` wired as whole-resource copies
- [x] `GetTexImage` / `GetTextureImage` (RGBA8)
- [x] Indirect draws (CPU fallback)
@@ -515,6 +515,30 @@ namespace MobileGL::MG_Backend::DiligentBackend {
renderer->ReadTextureImage(*texture, static_cast<Uint32>(level), pixels);
}
void CopyImageSubData(const SharedPtr<MG_State::GLState::ITextureObject>& srcTexture,
GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ,
const SharedPtr<MG_State::GLState::ITextureObject>& dstTexture,
GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ,
GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) {
(void)srcTarget;
(void)srcLevel;
(void)srcX;
(void)srcY;
(void)srcZ;
(void)dstTarget;
(void)dstLevel;
(void)dstX;
(void)dstY;
(void)dstZ;
(void)srcWidth;
(void)srcHeight;
(void)srcDepth;
auto* renderer = GetActiveRenderer();
if (renderer != nullptr && srcTexture && dstTexture) {
renderer->CopyTextureSubData(*srcTexture, *dstTexture);
}
}
void Present() {
auto* renderer = GetActiveRenderer();
if (renderer != nullptr) {
@@ -628,6 +652,7 @@ namespace MobileGL::MG_Backend::DiligentBackend {
m_functions.GL.BlitFramebuffer = BlitFramebuffer;
m_functions.GL.CopyTexImage2D = CopyTexImage2D;
m_functions.GL.CopyTexSubImage2D = CopyTexSubImage2D;
m_functions.GL.CopyImageSubData = CopyImageSubData;
m_functions.GL.GetTexImage = GetTexImage;
m_functions.GL.GetTextureImage = GetTextureImage;
m_functions.GL.ReadPixels = ReadPixels;
@@ -1816,6 +1816,29 @@ void main()
m_pContext->CopyTexture(copyAttribs);
}
void DiligentRenderer::CopyTextureSubData(MG_State::GLState::ITextureObject& src,
MG_State::GLState::ITextureObject& dst) {
if (!m_initialized || !m_pContext) {
return;
}
if (SyncTexture(src) == nullptr || SyncTexture(dst) == nullptr) {
return;
}
auto srcIt = m_textureCache.find(src.GetLifetimeId());
auto dstIt = m_textureCache.find(dst.GetLifetimeId());
if (srcIt == m_textureCache.end() || dstIt == m_textureCache.end() ||
!srcIt->second.Texture || !dstIt->second.Texture) {
return;
}
if (srcIt->second.Texture == dstIt->second.Texture) {
return;
}
::Diligent::CopyTextureAttribs copyAttribs(
srcIt->second.Texture, ::Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION,
dstIt->second.Texture, ::Diligent::RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
m_pContext->CopyTexture(copyAttribs);
}
Bool DiligentRenderer::ReadTextureImage(MG_State::GLState::ITextureObject& texture, Uint32 level,
void* pixels) {
if (!m_initialized || !m_pContext || pixels == nullptr) {
@@ -66,6 +66,7 @@ namespace MobileGL::MG_Backend::DiligentBackend {
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
void CopyReadFramebufferToTexture(MG_State::GLState::ITextureObject& dst);
void CopyTextureSubData(MG_State::GLState::ITextureObject& src, MG_State::GLState::ITextureObject& dst);
Bool ReadTextureImage(MG_State::GLState::ITextureObject& texture, Uint32 level, void* pixels);
void Present();