Implement depth/stencil texture-to-texture copies for OpenGL ES 3.1.
Bug: dawn:634 Change-Id: I30f0c1496e5443bda9bee1905162eae39ce2461c Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/38940 Commit-Queue: Stephen White <senorblanco@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
78440d66f3
commit
a194a48ba2
|
@ -440,6 +440,81 @@ namespace dawn_native { namespace opengl {
|
||||||
return validTextureCopyExtent;
|
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.depth; ++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:
|
||||||
|
UNREACHABLE();
|
||||||
|
}
|
||||||
|
if (srcTexture->GetArrayLayers() == 1) {
|
||||||
|
gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment,
|
||||||
|
srcTexture->GetGLTarget(), srcTexture->GetHandle(),
|
||||||
|
src.mipLevel);
|
||||||
|
} else {
|
||||||
|
gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment,
|
||||||
|
srcTexture->GetHandle(),
|
||||||
|
static_cast<GLint>(src.mipLevel),
|
||||||
|
static_cast<GLint>(src.origin.z + layer));
|
||||||
|
}
|
||||||
|
if (dstTexture->GetArrayLayers() == 1) {
|
||||||
|
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment,
|
||||||
|
dstTexture->GetGLTarget(), dstTexture->GetHandle(),
|
||||||
|
dst.mipLevel);
|
||||||
|
} else {
|
||||||
|
gl.FramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, glAttachment,
|
||||||
|
dstTexture->GetHandle(),
|
||||||
|
static_cast<GLint>(dst.mipLevel),
|
||||||
|
static_cast<GLint>(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);
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
CommandBuffer::CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor)
|
CommandBuffer::CommandBuffer(CommandEncoder* encoder, const CommandBufferDescriptor* descriptor)
|
||||||
|
@ -793,42 +868,7 @@ namespace dawn_native { namespace opengl {
|
||||||
dst.mipLevel, dst.origin.x, dst.origin.y, dst.origin.z,
|
dst.mipLevel, dst.origin.x, dst.origin.y, dst.origin.z,
|
||||||
copySize.width, copySize.height, copy->copySize.depth);
|
copySize.width, copySize.height, copy->copySize.depth);
|
||||||
} else {
|
} else {
|
||||||
GLuint readFBO = 0, drawFBO = 0;
|
CopyTextureToTextureWithBlit(gl, src, dst, copySize);
|
||||||
gl.GenFramebuffers(1, &readFBO);
|
|
||||||
gl.GenFramebuffers(1, &drawFBO);
|
|
||||||
gl.BindFramebuffer(GL_READ_FRAMEBUFFER, readFBO);
|
|
||||||
gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, drawFBO);
|
|
||||||
gl.Disable(GL_SCISSOR_TEST);
|
|
||||||
for (uint32_t layer = 0; layer < copy->copySize.depth; ++layer) {
|
|
||||||
if (srcTexture->GetArrayLayers() == 1) {
|
|
||||||
gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
srcTexture->GetGLTarget(),
|
|
||||||
srcTexture->GetHandle(), src.mipLevel);
|
|
||||||
} else {
|
|
||||||
gl.FramebufferTextureLayer(
|
|
||||||
GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
srcTexture->GetHandle(), static_cast<GLint>(src.mipLevel),
|
|
||||||
static_cast<GLint>(src.origin.z + layer));
|
|
||||||
}
|
|
||||||
if (dstTexture->GetArrayLayers() == 1) {
|
|
||||||
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
dstTexture->GetGLTarget(),
|
|
||||||
dstTexture->GetHandle(), dst.mipLevel);
|
|
||||||
} else {
|
|
||||||
gl.FramebufferTextureLayer(
|
|
||||||
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
|
||||||
dstTexture->GetHandle(), static_cast<GLint>(dst.mipLevel),
|
|
||||||
static_cast<GLint>(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,
|
|
||||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
|
||||||
}
|
|
||||||
gl.Enable(GL_SCISSOR_TEST);
|
|
||||||
gl.DeleteFramebuffers(1, &readFBO);
|
|
||||||
gl.DeleteFramebuffers(1, &drawFBO);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace dawn_native {
|
||||||
namespace dawn_native { namespace opengl {
|
namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
class Device;
|
class Device;
|
||||||
|
struct OpenGLFunctions;
|
||||||
|
|
||||||
class CommandBuffer final : public CommandBufferBase {
|
class CommandBuffer final : public CommandBufferBase {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -475,9 +475,6 @@ TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonRenderableNonZeroMipStenc
|
||||||
|
|
||||||
// Test copying both aspects in a T2T copy, then copying only depth.
|
// Test copying both aspects in a T2T copy, then copying only depth.
|
||||||
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepth) {
|
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepth) {
|
||||||
// TODO(crbug.com/dawn/634): Diagnose and fix ANGLE failure.
|
|
||||||
DAWN_SKIP_TEST_IF(IsANGLE());
|
|
||||||
|
|
||||||
constexpr uint32_t kWidth = 4;
|
constexpr uint32_t kWidth = 4;
|
||||||
constexpr uint32_t kHeight = 4;
|
constexpr uint32_t kHeight = 4;
|
||||||
|
|
||||||
|
@ -496,9 +493,6 @@ TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyDepth) {
|
||||||
|
|
||||||
// Test copying both aspects in a T2T copy, then copying only depth at a nonzero mip.
|
// Test copying both aspects in a T2T copy, then copying only depth at a nonzero mip.
|
||||||
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonZeroMipDepth) {
|
TEST_P(DepthStencilCopyTests, T2TBothAspectsThenCopyNonZeroMipDepth) {
|
||||||
// TODO(crbug.com/dawn/634): Diagnose and fix ANGLE failure.
|
|
||||||
DAWN_SKIP_TEST_IF(IsANGLE());
|
|
||||||
|
|
||||||
wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
|
wgpu::Texture texture = CreateInitializeDepthStencilTextureAndCopyT2T(
|
||||||
0.1f, 0.3f, 1u, 3u, 8, 8, wgpu::TextureUsage::RenderAttachment, 1);
|
0.1f, 0.3f, 1u, 3u, 8, 8, wgpu::TextureUsage::RenderAttachment, 1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue