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 <cwallez@chromium.org>
Reviewed-by: Stephen White <senorblanco@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp
index c88aef4..be6b58d 100644
--- a/src/dawn_native/opengl/CommandBufferGL.cpp
+++ b/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -445,7 +445,7 @@
: CommandBufferBase(encoder, descriptor) {
}
- void CommandBuffer::Execute() {
+ MaybeError CommandBuffer::Execute() {
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
auto TransitionForPass = [](const PassResourceUsage& usages) {
@@ -518,6 +518,12 @@
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 @@
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 @@
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<uint8_t*>(static_cast<uintptr_t>(dst.offset));
@@ -650,8 +669,7 @@
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 @@
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 @@
}
}
}
+
+ return {};
}
void CommandBuffer::ExecuteComputePass() {
diff --git a/src/dawn_native/opengl/CommandBufferGL.h b/src/dawn_native/opengl/CommandBufferGL.h
index eceb533..b860be8 100644
--- a/src/dawn_native/opengl/CommandBufferGL.h
+++ b/src/dawn_native/opengl/CommandBufferGL.h
@@ -29,7 +29,7 @@
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 88d1575..340ec25 100644
--- a/src/dawn_native/opengl/QueueGL.cpp
+++ b/src/dawn_native/opengl/QueueGL.cpp
@@ -30,7 +30,7 @@
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 22e3e63..55cb721 100644
--- a/src/tests/end2end/DepthStencilCopyTests.cpp
+++ b/src/tests/end2end/DepthStencilCopyTests.cpp
@@ -153,6 +153,9 @@
// 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 @@
}
}
-DAWN_INSTANTIATE_TEST(DepthStencilCopyTests, D3D12Backend(), MetalBackend(), VulkanBackend());
+DAWN_INSTANTIATE_TEST(DepthStencilCopyTests,
+ D3D12Backend(),
+ MetalBackend(),
+ OpenGLBackend(),
+ VulkanBackend());