Implement 3D texture copies on OpenGL/ES

Bug: dawn:783
Change-Id: I3c7f0ffc3f45a0d67b411a39342e89c710604d54
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/50244
Commit-Queue: Austin Eng <enga@chromium.org>
Reviewed-by: Yunchao He <yunchao.he@intel.com>
Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
Austin Eng 2021-05-11 00:50:53 +00:00 committed by Commit Bot service account
parent 5230c6bd93
commit 2a7d0ac828
3 changed files with 22 additions and 33 deletions

View File

@ -492,7 +492,8 @@ namespace dawn_native { namespace opengl {
case Aspect::Plane1:
UNREACHABLE();
}
if (srcTexture->GetArrayLayers() == 1) {
if (srcTexture->GetArrayLayers() == 1 &&
srcTexture->GetDimension() == wgpu::TextureDimension::e2D) {
gl.FramebufferTexture2D(GL_READ_FRAMEBUFFER, glAttachment,
srcTexture->GetGLTarget(), srcTexture->GetHandle(),
src.mipLevel);
@ -502,7 +503,8 @@ namespace dawn_native { namespace opengl {
static_cast<GLint>(src.mipLevel),
static_cast<GLint>(src.origin.z + layer));
}
if (dstTexture->GetArrayLayers() == 1) {
if (dstTexture->GetArrayLayers() == 1 &&
dstTexture->GetDimension() == wgpu::TextureDimension::e2D) {
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, glAttachment,
dstTexture->GetGLTarget(), dstTexture->GetHandle(),
dst.mipLevel);
@ -651,7 +653,7 @@ namespace dawn_native { namespace opengl {
buffer->EnsureDataInitializedAsDestination(copy);
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(texture->GetDimension() != wgpu::TextureDimension::e1D);
SubresourceRange subresources =
GetSubresourcesAffectedByCopy(src, copy->copySize);
texture->EnsureSubresourceContentInitialized(subresources);
@ -706,23 +708,25 @@ namespace dawn_native { namespace opengl {
copySize.height, glFormat, glType, offset);
break;
}
// Implementation for 2D array is the same as 3D.
DAWN_FALLTHROUGH;
}
case wgpu::TextureDimension::e3D: {
const uint64_t bytesPerImage = dst.bytesPerRow * dst.rowsPerImage;
for (uint32_t layer = 0; layer < copySize.depthOrArrayLayers; ++layer) {
for (uint32_t z = 0; z < copySize.depthOrArrayLayers; ++z) {
gl.FramebufferTextureLayer(GL_READ_FRAMEBUFFER, glAttachment,
texture->GetHandle(), src.mipLevel,
src.origin.z + layer);
src.origin.z + z);
gl.ReadPixels(src.origin.x, src.origin.y, copySize.width,
copySize.height, glFormat, glType, offset);
offset += bytesPerImage;
}
break;
}
case wgpu::TextureDimension::e1D:
case wgpu::TextureDimension::e3D:
UNREACHABLE();
}
@ -1269,7 +1273,7 @@ namespace dawn_native { namespace opengl {
const TextureDataLayout& dataLayout,
const Extent3D& copySize) {
Texture* texture = ToBackend(destination.texture.Get());
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(texture->GetDimension() != wgpu::TextureDimension::e1D);
SubresourceRange range = GetSubresourcesAffectedByCopy(destination, copySize);
if (IsCompleteSubresourceCopiedTo(texture, copySize, destination.mipLevel)) {
texture->SetIsSubresourceContentInitialized(true, range);
@ -1312,7 +1316,8 @@ namespace dawn_native { namespace opengl {
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, blockInfo.height);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 1);
if (texture->GetArrayLayers() == 1) {
if (texture->GetArrayLayers() == 1 &&
texture->GetDimension() == wgpu::TextureDimension::e2D) {
gl.CompressedTexSubImage2D(target, destination.mipLevel, x, y, width, height,
format.internalFormat, imageSize, data);
} else {
@ -1330,7 +1335,8 @@ namespace dawn_native { namespace opengl {
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_HEIGHT, 0);
gl.PixelStorei(GL_UNPACK_COMPRESSED_BLOCK_DEPTH, 0);
} else {
if (texture->GetArrayLayers() == 1) {
if (texture->GetArrayLayers() == 1 &&
texture->GetDimension() == wgpu::TextureDimension::e2D) {
const uint8_t* d = static_cast<const uint8_t*>(data);
for (; y < destination.origin.y + copySize.height; y += blockInfo.height) {
@ -1364,7 +1370,8 @@ namespace dawn_native { namespace opengl {
if (dataLayout.bytesPerRow % blockInfo.byteSize == 0) {
gl.PixelStorei(GL_UNPACK_ROW_LENGTH,
dataLayout.bytesPerRow / blockInfo.byteSize * blockInfo.width);
if (texture->GetArrayLayers() == 1) {
if (texture->GetArrayLayers() == 1 &&
texture->GetDimension() == wgpu::TextureDimension::e2D) {
gl.TexSubImage2D(target, destination.mipLevel, x, y, width, height,
format.format, format.type, data);
} else {
@ -1376,7 +1383,8 @@ namespace dawn_native { namespace opengl {
}
gl.PixelStorei(GL_UNPACK_ROW_LENGTH, 0);
} else {
if (texture->GetArrayLayers() == 1) {
if (texture->GetArrayLayers() == 1 &&
texture->GetDimension() == wgpu::TextureDimension::e2D) {
const uint8_t* d = static_cast<const uint8_t*>(data);
for (; y < destination.origin.y + height; ++y) {
gl.TexSubImage2D(target, destination.mipLevel, x, y, width, 1,

View File

@ -339,7 +339,8 @@ namespace dawn_native { namespace opengl {
GLuint framebuffer = 0;
gl.GenFramebuffers(1, &framebuffer);
gl.BindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
if (GetArrayLayers() == 1) {
if (GetArrayLayers() == 1 &&
GetDimension() == wgpu::TextureDimension::e2D) {
gl.FramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GetGLTarget(), GetHandle(), level);
} else {

View File

@ -968,10 +968,6 @@ TEST_P(CopyTests_T2B, Texture2DArrayRegionWithOffsetEvenRowsPerImage) {
// Test that copying whole 3D texture in one texture-to-buffer-copy works.
TEST_P(CopyTests_T2B, Texture3DFull) {
// TODO(yunchao.he@intel.com): implement 3D texture copy on OpenGL and OpenGLES
// backend.
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kDepth = 6u;
@ -985,10 +981,6 @@ TEST_P(CopyTests_T2B, Texture3DFull) {
// Test that copying a range of texture 3D depths in one texture-to-buffer-copy works.
TEST_P(CopyTests_T2B, Texture3DSubRegion) {
// TODO(yunchao.he@intel.com): implement 3D texture copy on OpenGL and OpenGLES
// backend.
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kDepth = 6u;
@ -1445,10 +1437,6 @@ TEST_P(CopyTests_B2T, Texture2DArrayRegionWithOffsetEvenRowsPerImage) {
// Test that copying whole texture 3D in one buffer-to-texture-copy works.
TEST_P(CopyTests_B2T, Texture3DFull) {
// TODO(yunchao.he@intel.com): implement 3D texture copy on OpenGL and OpenGLES
// backend.
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kDepth = 6u;
@ -1462,10 +1450,6 @@ TEST_P(CopyTests_B2T, Texture3DFull) {
// Test that copying a range of texture 3D Depths in one texture-to-buffer-copy works.
TEST_P(CopyTests_B2T, Texture3DSubRegion) {
// TODO(yunchao.he@intel.com): implement 3D texture copy on OpenGL and OpenGLES
// backend.
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kDepth = 6u;
@ -1799,10 +1783,6 @@ TEST_P(CopyTests_T2T, CopyFromNonZeroMipLevelWithTexelBlockSizeLessThan4Bytes) {
// Test that copying whole 3D texture in one texture-to-texture-copy works.
TEST_P(CopyTests_T2T, Texture3DFull) {
// TODO(yunchao.he@intel.com): implement 3D texture copy on OpenGL and OpenGLES
// backend.
DAWN_SKIP_TEST_IF(IsOpenGL() || IsOpenGLES());
constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kDepth = 6u;