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>
This commit is contained in:
Austin Eng 2020-08-18 18:53:26 +00:00 committed by Commit Bot service account
parent caec4ab04a
commit b54c82ed39
4 changed files with 50 additions and 24 deletions

View File

@ -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<uint8_t*>(static_cast<uintptr_t>(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() {

View File

@ -29,7 +29,7 @@ namespace dawn_native { namespace opengl {
public:
CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor);
void Execute();
MaybeError Execute();
private:
void ExecuteComputePass();

View File

@ -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");

View File

@ -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());