mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-11 21:58:31 +09:00
[Feat] (Diligent, MG_Impl): wire CopyTexImage2D/CopyTexSubImage2D readback copy
- Copy current read-FBO color attachment into the bound GL_TEXTURE_2D - Uses whole-color CopyTexture fallback for now; 13 Diligent tests pass
This commit is contained in:
+3
-2
@@ -151,6 +151,7 @@ Verified locally on Turnip Adreno 750:
|
|||||||
- `DrawArraysInstanced` / `DrawElementsInstanced` family
|
- `DrawArraysInstanced` / `DrawElementsInstanced` family
|
||||||
- `ClearBufferfv` / `ClearBufferiv` / `ClearBufferuiv`
|
- `ClearBufferfv` / `ClearBufferiv` / `ClearBufferuiv`
|
||||||
- `BlitFramebuffer` (same-size color copy between current read/draw FBOs)
|
- `BlitFramebuffer` (same-size color copy between current read/draw FBOs)
|
||||||
|
- `CopyTexImage2D` / `CopyTexSubImage2D` (whole-color copy fallback)
|
||||||
- `ReadPixels` from default and user color attachments
|
- `ReadPixels` from default and user color attachments
|
||||||
- Primitive expansion:
|
- Primitive expansion:
|
||||||
- `GL_TRIANGLE_FAN` expanded to triangle list
|
- `GL_TRIANGLE_FAN` expanded to triangle list
|
||||||
@@ -210,7 +211,7 @@ Notes:
|
|||||||
- 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.
|
- 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.
|
- No swapchain / EGL window surface presentation yet; `Present()` only flushes.
|
||||||
- No transform feedback / queries / sync / readback of non-color resources.
|
- No transform feedback / queries / sync / readback of non-color resources.
|
||||||
- Draw range, multi-draw, instanced-draw wrappers, clear-buffer, blit and read-pixels are now wired; indirect draws, CopyTexImage/GetTexImage and buffer subdata paths still remain.
|
- Draw range, multi-draw, instanced-draw wrappers, clear-buffer, blit, read-pixels and CopyTexImage* are now wired; indirect draws, GetTexImage and 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.
|
- 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.
|
||||||
- The `GLFunctionsTable` is only partially populated.
|
- The `GLFunctionsTable` is only partially populated.
|
||||||
|
|
||||||
@@ -242,7 +243,7 @@ Notes:
|
|||||||
- [x] `MultiDraw*`
|
- [x] `MultiDraw*`
|
||||||
- [x] `BlitFramebuffer` (same-size color copy)
|
- [x] `BlitFramebuffer` (same-size color copy)
|
||||||
- [x] `ReadPixels` from non-default framebuffer
|
- [x] `ReadPixels` from non-default framebuffer
|
||||||
- [ ] `GetTexImage` / `CopyTexImage*` / indirect draws
|
- [~] `CopyTexImage*` wired as whole-color copy; `GetTexImage` / indirect draws remain
|
||||||
|
|
||||||
6. **Expand local test suite**
|
6. **Expand local test suite**
|
||||||
- [x] Scissor test
|
- [x] Scissor test
|
||||||
|
|||||||
@@ -238,6 +238,46 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height, GLint border) {
|
||||||
|
(void)level;
|
||||||
|
(void)internalformat;
|
||||||
|
(void)x;
|
||||||
|
(void)y;
|
||||||
|
(void)width;
|
||||||
|
(void)height;
|
||||||
|
(void)border;
|
||||||
|
auto* renderer = GetActiveRenderer();
|
||||||
|
if (renderer == nullptr || MG_State::pGLContext == nullptr || target != GL_TEXTURE_2D) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& unit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
|
||||||
|
auto texture = unit.GetBindingSlot(TextureTarget::Texture2D).GetBoundObject();
|
||||||
|
if (texture) {
|
||||||
|
renderer->CopyReadFramebufferToTexture(*texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
|
||||||
|
GLsizei width, GLsizei height) {
|
||||||
|
(void)level;
|
||||||
|
(void)xoffset;
|
||||||
|
(void)yoffset;
|
||||||
|
(void)x;
|
||||||
|
(void)y;
|
||||||
|
(void)width;
|
||||||
|
(void)height;
|
||||||
|
auto* renderer = GetActiveRenderer();
|
||||||
|
if (renderer == nullptr || MG_State::pGLContext == nullptr || target != GL_TEXTURE_2D) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& unit = MG_State::pGLContext->GetTextureUnitObject(MG_State::pGLContext->GetActiveTextureUnit());
|
||||||
|
auto texture = unit.GetBindingSlot(TextureTarget::Texture2D).GetBoundObject();
|
||||||
|
if (texture) {
|
||||||
|
renderer->CopyReadFramebufferToTexture(*texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Present() {
|
void Present() {
|
||||||
auto* renderer = GetActiveRenderer();
|
auto* renderer = GetActiveRenderer();
|
||||||
if (renderer != nullptr) {
|
if (renderer != nullptr) {
|
||||||
@@ -342,6 +382,8 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
|||||||
m_functions.GL.ClearBufferiv = ClearBufferiv;
|
m_functions.GL.ClearBufferiv = ClearBufferiv;
|
||||||
m_functions.GL.ClearBufferuiv = ClearBufferuiv;
|
m_functions.GL.ClearBufferuiv = ClearBufferuiv;
|
||||||
m_functions.GL.BlitFramebuffer = BlitFramebuffer;
|
m_functions.GL.BlitFramebuffer = BlitFramebuffer;
|
||||||
|
m_functions.GL.CopyTexImage2D = CopyTexImage2D;
|
||||||
|
m_functions.GL.CopyTexSubImage2D = CopyTexSubImage2D;
|
||||||
m_functions.GL.ReadPixels = ReadPixels;
|
m_functions.GL.ReadPixels = ReadPixels;
|
||||||
m_functions.Present = Present;
|
m_functions.Present = Present;
|
||||||
|
|
||||||
|
|||||||
@@ -1701,6 +1701,46 @@ void main()
|
|||||||
m_pContext->CopyTexture(copyAttribs);
|
m_pContext->CopyTexture(copyAttribs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DiligentRenderer::CopyReadFramebufferToTexture(MG_State::GLState::ITextureObject& dst) {
|
||||||
|
if (!m_initialized || !m_pContext || !m_pColorTarget) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
::Diligent::RefCntAutoPtr<::Diligent::ITexture> pSrcTexture = m_pColorTarget;
|
||||||
|
if (MG_State::pGLContext != nullptr) {
|
||||||
|
auto readFbo = MG_State::pGLContext->GetFramebufferBindingSlot(FramebufferTarget::Read).GetBoundObject();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SyncTexture(dst) == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto it = m_textureCache.find(dst.GetLifetimeId());
|
||||||
|
if (it == m_textureCache.end() || !it->second.Texture) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto pDstTexture = it->second.Texture;
|
||||||
|
if (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::Present() {
|
void DiligentRenderer::Present() {
|
||||||
// Offscreen renderer: nothing to present yet.
|
// Offscreen renderer: nothing to present yet.
|
||||||
if (m_pContext) {
|
if (m_pContext) {
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ namespace MobileGL::MG_Backend::DiligentBackend {
|
|||||||
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||||
GLbitfield mask, GLenum filter);
|
GLbitfield mask, GLenum filter);
|
||||||
|
void CopyReadFramebufferToTexture(MG_State::GLState::ITextureObject& dst);
|
||||||
void Present();
|
void Present();
|
||||||
|
|
||||||
::Diligent::IRenderDevice* GetDevice() const { return m_pDevice; }
|
::Diligent::IRenderDevice* GetDevice() const { return m_pDevice; }
|
||||||
|
|||||||
Reference in New Issue
Block a user