From 57b7db9c7425cb4de5c7533c200e96d56fe2011b Mon Sep 17 00:00:00 2001 From: Stephen White Date: Fri, 25 Mar 2022 17:29:57 +0000 Subject: [PATCH] OpenGL: refactor texture-to-texture copies into UtilsGL. Change-Id: I6210b192c0676dacecc0d0b1026905b31e869d72 Bug: dawn:593 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/84440 Reviewed-by: Austin Eng Commit-Queue: Stephen White --- src/dawn/native/opengl/CommandBufferGL.cpp | 93 +-------------------- src/dawn/native/opengl/UtilsGL.cpp | 95 ++++++++++++++++++++++ src/dawn/native/opengl/UtilsGL.h | 14 ++++ 3 files changed, 113 insertions(+), 89 deletions(-) diff --git a/src/dawn/native/opengl/CommandBufferGL.cpp b/src/dawn/native/opengl/CommandBufferGL.cpp index c71d8f6d3e..a549c82296 100644 --- a/src/dawn/native/opengl/CommandBufferGL.cpp +++ b/src/dawn/native/opengl/CommandBufferGL.cpp @@ -452,85 +452,6 @@ namespace dawn::native::opengl { return validTextureCopyExtent; } - void CopyTextureToTextureWithBlit(const OpenGLFunctions& gl, - const TextureCopy& src, - const TextureCopy& dst, - const Extent3D& copySize) { - Texture* srcTexture = ToBackend(src.texture.Get()); - Texture* dstTexture = ToBackend(dst.texture.Get()); - - // Generate temporary framebuffers for the blits. - GLuint readFBO = 0, drawFBO = 0; - gl.GenFramebuffers(1, &readFBO); - gl.GenFramebuffers(1, &drawFBO); - gl.BindFramebuffer(GL_READ_FRAMEBUFFER, readFBO); - gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO); - - // Reset state that may affect glBlitFramebuffer(). - gl.Disable(GL_SCISSOR_TEST); - GLenum blitMask = 0; - if (src.aspect & Aspect::Color) { - blitMask |= GL_COLOR_BUFFER_BIT; - } - if (src.aspect & Aspect::Depth) { - blitMask |= GL_DEPTH_BUFFER_BIT; - } - if (src.aspect & Aspect::Stencil) { - blitMask |= GL_STENCIL_BUFFER_BIT; - } - // Iterate over all layers, doing a single blit for each. - for (uint32_t layer = 0; layer < copySize.depthOrArrayLayers; ++layer) { - // Bind all required aspects for this layer. - for (Aspect aspect : IterateEnumMask(src.aspect)) { - GLenum glAttachment; - switch (aspect) { - case Aspect::Color: - glAttachment = GL_COLOR_ATTACHMENT0; - break; - case Aspect::Depth: - glAttachment = GL_DEPTH_ATTACHMENT; - break; - case Aspect::Stencil: - glAttachment = GL_STENCIL_ATTACHMENT; - break; - case Aspect::CombinedDepthStencil: - case Aspect::None: - case Aspect::Plane0: - case Aspect::Plane1: - UNREACHABLE(); - } - if (srcTexture->GetArrayLayers() == 1 && - srcTexture->GetDimension() == wgpu::TextureDimension::e2D) { - gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, - srcTexture->GetGLTarget(), srcTexture->GetHandle(), - src.mipLevel); - } else { - gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment, - srcTexture->GetHandle(), - static_cast(src.mipLevel), - static_cast(src.origin.z + layer)); - } - if (dstTexture->GetArrayLayers() == 1 && - dstTexture->GetDimension() == wgpu::TextureDimension::e2D) { - gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, - dstTexture->GetGLTarget(), dstTexture->GetHandle(), - dst.mipLevel); - } else { - gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, glAttachment, - dstTexture->GetHandle(), - static_cast(dst.mipLevel), - static_cast(dst.origin.z + layer)); - } - } - gl.BlitFramebuffer(src.origin.x, src.origin.y, src.origin.x + copySize.width, - src.origin.y + copySize.height, dst.origin.x, dst.origin.y, - dst.origin.x + copySize.width, dst.origin.y + copySize.height, - blitMask, GL_NEAREST); - } - gl.Enable(GL_SCISSOR_TEST); - gl.DeleteFramebuffers(1, &readFBO); - gl.DeleteFramebuffers(1, &drawFBO); - } bool TextureFormatIsSnorm(wgpu::TextureFormat format) { return format == wgpu::TextureFormat::RGBA8Snorm || format == wgpu::TextureFormat::RG8Snorm || @@ -793,16 +714,10 @@ namespace dawn::native::opengl { } else { dstTexture->EnsureSubresourceContentInitialized(dstRange); } - if (gl.IsAtLeastGL(4, 3) || gl.IsAtLeastGLES(3, 2)) { - gl.CopyImageSubData(srcTexture->GetHandle(), srcTexture->GetGLTarget(), - src.mipLevel, src.origin.x, src.origin.y, src.origin.z, - dstTexture->GetHandle(), dstTexture->GetGLTarget(), - dst.mipLevel, dst.origin.x, dst.origin.y, dst.origin.z, - copySize.width, copySize.height, - copy->copySize.depthOrArrayLayers); - } else { - CopyTextureToTextureWithBlit(gl, src, dst, copySize); - } + CopyImageSubData(gl, src.aspect, srcTexture->GetHandle(), + srcTexture->GetGLTarget(), src.mipLevel, src.origin, + dstTexture->GetHandle(), dstTexture->GetGLTarget(), + dst.mipLevel, dst.origin, copySize); break; } diff --git a/src/dawn/native/opengl/UtilsGL.cpp b/src/dawn/native/opengl/UtilsGL.cpp index 616110eefd..f0dcdbe0d8 100644 --- a/src/dawn/native/opengl/UtilsGL.cpp +++ b/src/dawn/native/opengl/UtilsGL.cpp @@ -15,6 +15,8 @@ #include "dawn/native/opengl/UtilsGL.h" #include "dawn/common/Assert.h" +#include "dawn/native/EnumMaskIterator.h" +#include "dawn/native/opengl/OpenGLFunctions.h" namespace dawn::native::opengl { @@ -55,4 +57,97 @@ namespace dawn::native::opengl { UNREACHABLE(); } } + + void CopyImageSubData(const OpenGLFunctions& gl, + Aspect srcAspects, + GLuint srcHandle, + GLenum srcTarget, + GLint srcLevel, + const Origin3D& src, + GLuint dstHandle, + GLenum dstTarget, + GLint dstLevel, + const Origin3D& dst, + const Extent3D& size) { + if (gl.IsAtLeastGL(4, 3) || gl.IsAtLeastGLES(3, 2)) { + gl.CopyImageSubData(srcHandle, srcTarget, srcLevel, src.x, src.y, src.z, dstHandle, + dstTarget, dstLevel, dst.x, dst.y, dst.z, size.width, size.height, + size.depthOrArrayLayers); + return; + } + + GLint prevReadFBO = 0, prevDrawFBO = 0; + gl.GetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &prevReadFBO); + gl.GetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &prevDrawFBO); + + // Generate temporary framebuffers for the blits. + GLuint readFBO = 0, drawFBO = 0; + gl.GenFramebuffers(1, &readFBO); + gl.GenFramebuffers(1, &drawFBO); + gl.BindFramebuffer(GL_READ_FRAMEBUFFER, readFBO); + gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO); + + // Reset state that may affect glBlitFramebuffer(). + gl.Disable(GL_SCISSOR_TEST); + GLenum blitMask = 0; + if (srcAspects & Aspect::Color) { + blitMask |= GL_COLOR_BUFFER_BIT; + } + if (srcAspects & Aspect::Depth) { + blitMask |= GL_DEPTH_BUFFER_BIT; + } + if (srcAspects & Aspect::Stencil) { + blitMask |= GL_STENCIL_BUFFER_BIT; + } + + // Iterate over all layers, doing a single blit for each. + for (uint32_t layer = 0; layer < size.depthOrArrayLayers; ++layer) { + // Set attachments for all aspects. + for (Aspect aspect : IterateEnumMask(srcAspects)) { + GLenum glAttachment; + switch (aspect) { + case Aspect::Color: + glAttachment = GL_COLOR_ATTACHMENT0; + break; + case Aspect::Depth: + glAttachment = GL_DEPTH_ATTACHMENT; + break; + case Aspect::Stencil: + glAttachment = GL_STENCIL_ATTACHMENT; + break; + case Aspect::CombinedDepthStencil: + case Aspect::None: + case Aspect::Plane0: + case Aspect::Plane1: + UNREACHABLE(); + } + if (srcTarget == GL_TEXTURE_2D) { + gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, srcTarget, srcHandle, + srcLevel); + } else { + gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment, srcHandle, + srcLevel, src.z + layer); + } + if (dstTarget == GL_TEXTURE_2D) { + gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, dstTarget, dstHandle, + dstLevel); + } else if (dstTarget == GL_TEXTURE_CUBE_MAP) { + GLenum target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + layer; + gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment, target, dstHandle, + dstLevel); + } else { + gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, glAttachment, dstHandle, + dstLevel, dst.z + layer); + } + } + gl.BlitFramebuffer(src.x, src.y, size.width, size.height, dst.x, dst.y, size.width, + size.height, blitMask, GL_NEAREST); + } + gl.Enable(GL_SCISSOR_TEST); + gl.DeleteFramebuffers(1, &readFBO); + gl.DeleteFramebuffers(1, &drawFBO); + gl.BindFramebuffer(GL_READ_FRAMEBUFFER, prevReadFBO); + gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, prevDrawFBO); + } + } // namespace dawn::native::opengl diff --git a/src/dawn/native/opengl/UtilsGL.h b/src/dawn/native/opengl/UtilsGL.h index 90869800ef..0abaff793d 100644 --- a/src/dawn/native/opengl/UtilsGL.h +++ b/src/dawn/native/opengl/UtilsGL.h @@ -15,13 +15,27 @@ #ifndef DAWNNATIVE_OPENGL_UTILSGL_H_ #define DAWNNATIVE_OPENGL_UTILSGL_H_ +#include "dawn/native/Format.h" #include "dawn/native/dawn_platform.h" #include "dawn/native/opengl/opengl_platform.h" namespace dawn::native::opengl { + struct OpenGLFunctions; GLuint ToOpenGLCompareFunction(wgpu::CompareFunction compareFunction); GLint GetStencilMaskFromStencilFormat(wgpu::TextureFormat depthStencilFormat); + void CopyImageSubData(const OpenGLFunctions& gl, + Aspect srcAspects, + GLuint srcHandle, + GLenum srcTarget, + GLint srcLevel, + const Origin3D& src, + GLuint dstHandle, + GLenum dstTarget, + GLint dstLevel, + const Origin3D& dst, + const Extent3D& size); + } // namespace dawn::native::opengl #endif // DAWNNATIVE_OPENGL_UTILSGL_H_