From b54c82ed3948e6aad955607772402d55c2113e46 Mon Sep 17 00:00:00 2001 From: Austin Eng Date: Tue, 18 Aug 2020 18:53:26 +0000 Subject: [PATCH] Support depth-only/stencil-only COPY_SRC on OpenGL Bug: dawn:439 Change-Id: I09d33d3115d54c03e3ba5a32f34843065edb8020 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24961 Reviewed-by: Corentin Wallez Reviewed-by: Stephen White Commit-Queue: Austin Eng --- src/dawn_native/opengl/CommandBufferGL.cpp | 61 ++++++++++++++------- src/dawn_native/opengl/CommandBufferGL.h | 2 +- src/dawn_native/opengl/QueueGL.cpp | 2 +- src/tests/end2end/DepthStencilCopyTests.cpp | 9 ++- 4 files changed, 50 insertions(+), 24 deletions(-) diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp index c88aef412c..be6b58d9d8 100644 --- a/src/dawn_native/opengl/CommandBufferGL.cpp +++ b/src/dawn_native/opengl/CommandBufferGL.cpp @@ -445,7 +445,7 @@ namespace dawn_native { namespace opengl { : CommandBufferBase(encoder, descriptor) { } - void CommandBuffer::Execute() { + MaybeError CommandBuffer::Execute() { const OpenGLFunctions& gl = ToBackend(GetDevice())->gl; auto TransitionForPass = [](const PassResourceUsage& usages) { @@ -518,6 +518,12 @@ namespace dawn_native { namespace opengl { GLenum target = texture->GetGLTarget(); const GLFormat& format = texture->GetGLFormat(); + if (dst.aspect == Aspect::Stencil) { + return DAWN_VALIDATION_ERROR( + "Copies to stencil textures unsupported on OpenGL"); + } + ASSERT(dst.aspect == Aspect::Color); + buffer->EnsureDataInitialized(); ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D); @@ -601,13 +607,13 @@ namespace dawn_native { namespace opengl { auto& copySize = copy->copySize; Texture* texture = ToBackend(src.texture.Get()); Buffer* buffer = ToBackend(dst.buffer.Get()); - const Format& format = texture->GetFormat(); - const GLFormat& glFormat = texture->GetGLFormat(); + const Format& formatInfo = texture->GetFormat(); + const GLFormat& format = texture->GetGLFormat(); GLenum target = texture->GetGLTarget(); // TODO(jiawei.shao@intel.com): support texture-to-buffer copy with compressed // texture formats. - if (format.isCompressed) { + if (formatInfo.isCompressed) { UNREACHABLE(); } @@ -625,22 +631,35 @@ namespace dawn_native { namespace opengl { gl.GenFramebuffers(1, &readFBO); gl.BindFramebuffer(GL_READ_FRAMEBUFFER, readFBO); - GLenum glAttachment = 0; - if (format.aspects == (Aspect::Depth | Aspect::Stencil)) { - glAttachment = GL_DEPTH_STENCIL_ATTACHMENT; - } else if (format.aspects == Aspect::Depth) { - glAttachment = GL_DEPTH_ATTACHMENT; - } else if (format.aspects == Aspect::Stencil) { - glAttachment = GL_STENCIL_ATTACHMENT; - } else if (format.aspects == Aspect::Color) { - glAttachment = GL_COLOR_ATTACHMENT0; - } else { - UNREACHABLE(); - } + const TexelBlockInfo& blockInfo = formatInfo.GetTexelBlockInfo(src.aspect); gl.BindBuffer(GL_PIXEL_PACK_BUFFER, buffer->GetHandle()); - gl.PixelStorei(GL_PACK_ROW_LENGTH, dst.bytesPerRow / format.blockByteSize); gl.PixelStorei(GL_PACK_IMAGE_HEIGHT, dst.rowsPerImage); + gl.PixelStorei(GL_PACK_ROW_LENGTH, dst.bytesPerRow / blockInfo.blockByteSize); + + GLenum glAttachment; + GLenum glFormat; + GLenum glType; + switch (src.aspect) { + case Aspect::Color: + glAttachment = GL_COLOR_ATTACHMENT0; + glFormat = format.format; + glType = format.type; + break; + case Aspect::Depth: + glAttachment = GL_DEPTH_ATTACHMENT; + glFormat = GL_DEPTH_COMPONENT; + glType = GL_FLOAT; + break; + case Aspect::Stencil: + glAttachment = GL_STENCIL_ATTACHMENT; + glFormat = GL_STENCIL_INDEX; + glType = GL_UNSIGNED_BYTE; + break; + default: + UNREACHABLE(); + break; + } uint8_t* offset = reinterpret_cast(static_cast(dst.offset)); @@ -650,8 +669,7 @@ namespace dawn_native { namespace opengl { gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment, target, texture->GetHandle(), src.mipLevel); gl.ReadPixels(src.origin.x, src.origin.y, copySize.width, - copySize.height, glFormat.format, glFormat.type, - offset); + copySize.height, glFormat, glType, offset); break; } @@ -661,8 +679,7 @@ namespace dawn_native { namespace opengl { texture->GetHandle(), src.mipLevel, src.origin.z + layer); gl.ReadPixels(src.origin.x, src.origin.y, copySize.width, - copySize.height, glFormat.format, glFormat.type, - offset); + copySize.height, glFormat, glType, offset); offset += bytesPerImage; } @@ -731,6 +748,8 @@ namespace dawn_native { namespace opengl { } } } + + return {}; } void CommandBuffer::ExecuteComputePass() { diff --git a/src/dawn_native/opengl/CommandBufferGL.h b/src/dawn_native/opengl/CommandBufferGL.h index eceb5335e9..b860be8c84 100644 --- a/src/dawn_native/opengl/CommandBufferGL.h +++ b/src/dawn_native/opengl/CommandBufferGL.h @@ -29,7 +29,7 @@ namespace dawn_native { namespace opengl { public: CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor); - void Execute(); + MaybeError Execute(); private: void ExecuteComputePass(); diff --git a/src/dawn_native/opengl/QueueGL.cpp b/src/dawn_native/opengl/QueueGL.cpp index 88d1575cf4..340ec250c7 100644 --- a/src/dawn_native/opengl/QueueGL.cpp +++ b/src/dawn_native/opengl/QueueGL.cpp @@ -30,7 +30,7 @@ namespace dawn_native { namespace opengl { TRACE_EVENT_BEGIN0(GetDevice()->GetPlatform(), Recording, "CommandBufferGL::Execute"); for (uint32_t i = 0; i < commandCount; ++i) { - ToBackend(commands[i])->Execute(); + DAWN_TRY(ToBackend(commands[i])->Execute()); } TRACE_EVENT_END0(GetDevice()->GetPlatform(), Recording, "CommandBufferGL::Execute"); diff --git a/src/tests/end2end/DepthStencilCopyTests.cpp b/src/tests/end2end/DepthStencilCopyTests.cpp index 22e3e6385e..55cb721bd0 100644 --- a/src/tests/end2end/DepthStencilCopyTests.cpp +++ b/src/tests/end2end/DepthStencilCopyTests.cpp @@ -153,6 +153,9 @@ TEST_P(DepthStencilCopyTests, FromStencilAspect) { // Test copying to the stencil-aspect of a buffer TEST_P(DepthStencilCopyTests, ToStencilAspect) { + // Copies to a single aspect are unsupported on OpenGL. + DAWN_SKIP_TEST_IF(IsOpenGL()); + // TODO(enga): Figure out why this fails on Vulkan Intel // Results are shifted by 1 byte on Windows, and crash/hang on Linux. DAWN_SKIP_TEST_IF(IsVulkan() && IsIntel()); @@ -320,4 +323,8 @@ TEST_P(DepthStencilCopyTests, ToStencilAspect) { } } -DAWN_INSTANTIATE_TEST(DepthStencilCopyTests, D3D12Backend(), MetalBackend(), VulkanBackend()); +DAWN_INSTANTIATE_TEST(DepthStencilCopyTests, + D3D12Backend(), + MetalBackend(), + OpenGLBackend(), + VulkanBackend());