Fix bugs in the multi-layer copies with BC formats on D3D12 and OpenGL
This patch fixes two bugs in the copy commands with BC formats and multiple array layers on D3D12 and OpenGL and adds two end2end tests as the regression tests. This patch also removes "viewArrayLayer" in the struct CopyConfig used in CompressedTextureBCFormatTest and sets the base array layer into CopyConfig.copyOrigin3D.z instead. BUG=dawn:453 TEST=dawn_end2end_tests Change-Id: I1c2e6b79fb7c44fc996655ab5a908e27ba8c4729 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/24183 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
16ca52cc16
commit
4d007f34f3
|
@ -592,7 +592,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
subresources);
|
||||
|
||||
const uint64_t bytesPerSlice =
|
||||
copy->source.bytesPerRow * copy->source.rowsPerImage;
|
||||
copy->source.bytesPerRow *
|
||||
(copy->source.rowsPerImage / texture->GetFormat().blockHeight);
|
||||
|
||||
const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width,
|
||||
copy->copySize.height, 1};
|
||||
|
@ -648,7 +649,8 @@ namespace dawn_native { namespace d3d12 {
|
|||
buffer->TrackUsageAndTransitionNow(commandContext, wgpu::BufferUsage::CopyDst);
|
||||
|
||||
const uint64_t bytesPerSlice =
|
||||
copy->destination.bytesPerRow * copy->destination.rowsPerImage;
|
||||
copy->destination.bytesPerRow *
|
||||
(copy->destination.rowsPerImage / texture->GetFormat().blockHeight);
|
||||
|
||||
const dawn_native::Extent3D copyOneLayerSize = {copy->copySize.width,
|
||||
copy->copySize.height, 1};
|
||||
|
|
|
@ -542,7 +542,7 @@ namespace dawn_native { namespace opengl {
|
|||
ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
|
||||
uint64_t copyDataSize = (copySize.width / formatInfo.blockWidth) *
|
||||
(copySize.height / formatInfo.blockHeight) *
|
||||
formatInfo.blockByteSize;
|
||||
formatInfo.blockByteSize * copySize.depth;
|
||||
Extent3D copyExtent = ComputeTextureCopyExtent(dst, copySize);
|
||||
|
||||
if (texture->GetArrayLayers() > 1) {
|
||||
|
|
|
@ -27,7 +27,6 @@ struct CopyConfig {
|
|||
wgpu::Extent3D copyExtent3D;
|
||||
wgpu::Origin3D copyOrigin3D = {0, 0, 0};
|
||||
uint32_t viewMipmapLevel = 0;
|
||||
uint32_t viewArrayLayer = 0;
|
||||
uint32_t bufferOffset = 0;
|
||||
uint32_t bytesPerRowAlignment = kTextureBytesPerRowAlignment;
|
||||
uint32_t rowsPerImage = 0;
|
||||
|
@ -69,19 +68,24 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
copyWidthInBlockAtLevel *
|
||||
utils::GetTexelBlockSizeInBytes(copyConfig.textureDescriptor.format);
|
||||
}
|
||||
uint32_t copyBytesPerImage = bufferRowPitchInBytes * copyHeightInBlockAtLevel;
|
||||
uint32_t uploadBufferSize =
|
||||
copyConfig.bufferOffset + bufferRowPitchInBytes * copyHeightInBlockAtLevel;
|
||||
copyConfig.bufferOffset + copyBytesPerImage * copyConfig.copyExtent3D.depth;
|
||||
|
||||
// Fill uploadData with the pre-prepared one-block compressed texture data.
|
||||
std::vector<uint8_t> uploadData(uploadBufferSize, 0);
|
||||
std::vector<uint8_t> oneBlockCompressedTextureData =
|
||||
GetOneBlockBCFormatTextureData(copyConfig.textureDescriptor.format);
|
||||
for (uint32_t h = 0; h < copyHeightInBlockAtLevel; ++h) {
|
||||
for (uint32_t w = 0; w < copyWidthInBlockAtLevel; ++w) {
|
||||
uint32_t uploadBufferOffset = copyConfig.bufferOffset + bufferRowPitchInBytes * h +
|
||||
oneBlockCompressedTextureData.size() * w;
|
||||
std::memcpy(&uploadData[uploadBufferOffset], oneBlockCompressedTextureData.data(),
|
||||
oneBlockCompressedTextureData.size() * sizeof(uint8_t));
|
||||
for (uint32_t layer = 0; layer < copyConfig.copyExtent3D.depth; ++layer) {
|
||||
for (uint32_t h = 0; h < copyHeightInBlockAtLevel; ++h) {
|
||||
for (uint32_t w = 0; w < copyWidthInBlockAtLevel; ++w) {
|
||||
uint32_t uploadBufferOffset =
|
||||
copyConfig.bufferOffset + copyBytesPerImage * layer +
|
||||
bufferRowPitchInBytes * h + oneBlockCompressedTextureData.size() * w;
|
||||
std::memcpy(&uploadData[uploadBufferOffset],
|
||||
oneBlockCompressedTextureData.data(),
|
||||
oneBlockCompressedTextureData.size() * sizeof(uint8_t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,11 +96,8 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
utils::CreateBufferCopyView(stagingBuffer, copyConfig.bufferOffset,
|
||||
copyConfig.bytesPerRowAlignment, copyConfig.rowsPerImage);
|
||||
|
||||
ASSERT(copyConfig.copyOrigin3D.z == 0);
|
||||
wgpu::Origin3D copyOrigin = copyConfig.copyOrigin3D;
|
||||
copyOrigin.z = copyConfig.viewArrayLayer;
|
||||
wgpu::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
bcCompressedTexture, copyConfig.viewMipmapLevel, copyOrigin);
|
||||
bcCompressedTexture, copyConfig.viewMipmapLevel, copyConfig.copyOrigin3D);
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Config.copyExtent3D);
|
||||
|
@ -204,9 +205,6 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
wgpu::Texture bcTexture = CreateTextureWithCompressedData(config);
|
||||
|
||||
wgpu::RenderPipeline renderPipeline = CreateRenderPipelineForTest();
|
||||
wgpu::BindGroup bindGroup = CreateBindGroupForTest(
|
||||
renderPipeline.GetBindGroupLayout(0), bcTexture, config.textureDescriptor.format,
|
||||
config.viewArrayLayer, config.viewMipmapLevel);
|
||||
|
||||
wgpu::Extent3D virtualSizeAtLevel = GetVirtualSizeAtLevel(config);
|
||||
|
||||
|
@ -220,11 +218,21 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
if (config.copyOrigin3D.y + config.copyExtent3D.height > virtualSizeAtLevel.height) {
|
||||
noPaddingExtent3D.height = virtualSizeAtLevel.height - config.copyOrigin3D.y;
|
||||
}
|
||||
noPaddingExtent3D.depth = 1u;
|
||||
|
||||
std::vector<RGBA8> expectedData =
|
||||
GetExpectedData(config.textureDescriptor.format, virtualSizeAtLevel);
|
||||
VerifyCompressedTexturePixelValues(renderPipeline, bindGroup, virtualSizeAtLevel,
|
||||
config.copyOrigin3D, noPaddingExtent3D, expectedData);
|
||||
|
||||
wgpu::Origin3D firstLayerCopyOrigin = {config.copyOrigin3D.x, config.copyOrigin3D.y, 0};
|
||||
for (uint32_t layer = config.copyOrigin3D.z;
|
||||
layer < config.copyOrigin3D.z + config.copyExtent3D.depth; ++layer) {
|
||||
wgpu::BindGroup bindGroup = CreateBindGroupForTest(
|
||||
renderPipeline.GetBindGroupLayout(0), bcTexture, config.textureDescriptor.format,
|
||||
layer, config.viewMipmapLevel);
|
||||
VerifyCompressedTexturePixelValues(renderPipeline, bindGroup, virtualSizeAtLevel,
|
||||
firstLayerCopyOrigin, noPaddingExtent3D,
|
||||
expectedData);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a texture and initialize it with the pre-prepared compressed texture data.
|
||||
|
@ -240,17 +248,10 @@ class CompressedTextureBCFormatTest : public DawnTest {
|
|||
wgpu::Texture dstTexture,
|
||||
CopyConfig srcConfig,
|
||||
CopyConfig dstConfig) {
|
||||
ASSERT(srcConfig.copyOrigin3D.z == 0);
|
||||
wgpu::Origin3D srcCopyOrigin = srcConfig.copyOrigin3D;
|
||||
srcCopyOrigin.z = srcConfig.viewArrayLayer;
|
||||
wgpu::TextureCopyView textureCopyViewSrc =
|
||||
utils::CreateTextureCopyView(srcTexture, srcConfig.viewMipmapLevel, srcCopyOrigin);
|
||||
|
||||
ASSERT(dstConfig.copyOrigin3D.z == 0);
|
||||
wgpu::Origin3D dstCopyOrigin = dstConfig.copyOrigin3D;
|
||||
dstCopyOrigin.z = dstConfig.viewArrayLayer;
|
||||
wgpu::TextureCopyView textureCopyViewDst =
|
||||
utils::CreateTextureCopyView(dstTexture, dstConfig.viewMipmapLevel, dstCopyOrigin);
|
||||
wgpu::TextureCopyView textureCopyViewSrc = utils::CreateTextureCopyView(
|
||||
srcTexture, srcConfig.viewMipmapLevel, srcConfig.copyOrigin3D);
|
||||
wgpu::TextureCopyView textureCopyViewDst = utils::CreateTextureCopyView(
|
||||
dstTexture, dstConfig.viewMipmapLevel, dstConfig.copyOrigin3D);
|
||||
encoder.CopyTextureToTexture(&textureCopyViewSrc, &textureCopyViewDst,
|
||||
&dstConfig.copyExtent3D);
|
||||
}
|
||||
|
@ -490,7 +491,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyIntoNonZeroArrayLayer) {
|
|||
|
||||
constexpr uint32_t kArrayLayerCount = 3;
|
||||
config.textureDescriptor.size.depth = kArrayLayerCount;
|
||||
config.viewArrayLayer = kArrayLayerCount - 1;
|
||||
config.copyOrigin3D.z = kArrayLayerCount - 1;
|
||||
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
config.textureDescriptor.format = format;
|
||||
|
@ -587,7 +588,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyWholeTextureSubResourceIntoNonZeroMipm
|
|||
wgpu::RenderPipeline renderPipeline = CreateRenderPipelineForTest();
|
||||
wgpu::BindGroup bindGroup =
|
||||
CreateBindGroupForTest(renderPipeline.GetBindGroupLayout(0), bcTextureDst, format,
|
||||
config.viewArrayLayer, config.viewMipmapLevel);
|
||||
config.copyOrigin3D.z, config.viewMipmapLevel);
|
||||
|
||||
std::vector<RGBA8> expectedData = GetExpectedData(format, kVirtualSize);
|
||||
VerifyCompressedTexturePixelValues(renderPipeline, bindGroup, kVirtualSize,
|
||||
|
@ -651,7 +652,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyIntoSubresourceWithPhysicalSizeNotEqua
|
|||
wgpu::RenderPipeline renderPipeline = CreateRenderPipelineForTest();
|
||||
wgpu::BindGroup bindGroup =
|
||||
CreateBindGroupForTest(renderPipeline.GetBindGroupLayout(0), bcTextureDst, format,
|
||||
dstConfig.viewArrayLayer, dstConfig.viewMipmapLevel);
|
||||
dstConfig.copyOrigin3D.z, dstConfig.viewMipmapLevel);
|
||||
|
||||
std::vector<RGBA8> expectedData = GetExpectedData(format, kDstVirtualSize);
|
||||
VerifyCompressedTexturePixelValues(renderPipeline, bindGroup, kDstVirtualSize,
|
||||
|
@ -711,7 +712,7 @@ TEST_P(CompressedTextureBCFormatTest, CopyFromSubresourceWithPhysicalSizeNotEqua
|
|||
wgpu::RenderPipeline renderPipeline = CreateRenderPipelineForTest();
|
||||
wgpu::BindGroup bindGroup =
|
||||
CreateBindGroupForTest(renderPipeline.GetBindGroupLayout(0), bcTextureDst, format,
|
||||
dstConfig.viewArrayLayer, dstConfig.viewMipmapLevel);
|
||||
dstConfig.copyOrigin3D.z, dstConfig.viewMipmapLevel);
|
||||
|
||||
std::vector<RGBA8> expectedData = GetExpectedData(format, kDstVirtualSize);
|
||||
VerifyCompressedTexturePixelValues(renderPipeline, bindGroup, kDstVirtualSize,
|
||||
|
@ -792,7 +793,7 @@ TEST_P(CompressedTextureBCFormatTest, MultipleCopiesWithPhysicalSizeNotEqualToVi
|
|||
// Verify if we can use bcDstTextures as sampled textures correctly.
|
||||
wgpu::BindGroup bindGroup0 = CreateBindGroupForTest(
|
||||
renderPipeline.GetBindGroupLayout(0), bcDstTextures[i], format,
|
||||
dstConfigs[i].viewArrayLayer, dstConfigs[i].viewMipmapLevel);
|
||||
dstConfigs[i].copyOrigin3D.z, dstConfigs[i].viewMipmapLevel);
|
||||
|
||||
std::vector<RGBA8> expectedData = GetExpectedData(format, dstVirtualSizes[i]);
|
||||
VerifyCompressedTexturePixelValues(renderPipeline, bindGroup0, dstVirtualSizes[i],
|
||||
|
@ -1003,6 +1004,62 @@ TEST_P(CompressedTextureBCFormatTest, LargeImageHeightAndClampedCopyExtent) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test copying a whole 2D array texture with array layer count > 1 in one copy command works with
|
||||
// BC formats.
|
||||
TEST_P(CompressedTextureBCFormatTest, CopyWhole2DArrayTexture) {
|
||||
// TODO(jiawei.shao@intel.com): find out why this test is flaky on Windows Intel Vulkan
|
||||
// bots.
|
||||
DAWN_SKIP_TEST_IF(IsIntel() && IsVulkan() && IsWindows());
|
||||
|
||||
// TODO(jiawei.shao@intel.com): find out why this test fails on Windows Intel OpenGL drivers.
|
||||
DAWN_SKIP_TEST_IF(IsIntel() && IsOpenGL() && IsWindows());
|
||||
|
||||
DAWN_SKIP_TEST_IF(!IsBCFormatSupported());
|
||||
|
||||
constexpr uint32_t kArrayLayerCount = 3;
|
||||
|
||||
CopyConfig config;
|
||||
config.textureDescriptor.usage = kDefaultBCFormatTextureUsage;
|
||||
config.textureDescriptor.size = {8, 8, kArrayLayerCount};
|
||||
|
||||
config.copyExtent3D = config.textureDescriptor.size;
|
||||
config.copyExtent3D.depth = kArrayLayerCount;
|
||||
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
config.textureDescriptor.format = format;
|
||||
TestCopyRegionIntoBCFormatTextures(config);
|
||||
}
|
||||
}
|
||||
|
||||
// Test copying a multiple 2D texture array layers in one copy command works with BC formats.
|
||||
TEST_P(CompressedTextureBCFormatTest, CopyMultiple2DArrayLayers) {
|
||||
// TODO(jiawei.shao@intel.com): find out why this test is flaky on Windows Intel Vulkan
|
||||
// bots.
|
||||
DAWN_SKIP_TEST_IF(IsIntel() && IsVulkan() && IsWindows());
|
||||
|
||||
// TODO(jiawei.shao@intel.com): find out why this test fails on Windows Intel OpenGL drivers.
|
||||
DAWN_SKIP_TEST_IF(IsIntel() && IsOpenGL() && IsWindows());
|
||||
|
||||
DAWN_SKIP_TEST_IF(!IsBCFormatSupported());
|
||||
|
||||
constexpr uint32_t kArrayLayerCount = 3;
|
||||
|
||||
CopyConfig config;
|
||||
config.textureDescriptor.usage = kDefaultBCFormatTextureUsage;
|
||||
config.textureDescriptor.size = {8, 8, kArrayLayerCount};
|
||||
|
||||
constexpr uint32_t kCopyBaseArrayLayer = 1;
|
||||
constexpr uint32_t kCopyLayerCount = 2;
|
||||
config.copyOrigin3D = {0, 0, kCopyBaseArrayLayer};
|
||||
config.copyExtent3D = config.textureDescriptor.size;
|
||||
config.copyExtent3D.depth = kCopyLayerCount;
|
||||
|
||||
for (wgpu::TextureFormat format : kBCFormats) {
|
||||
config.textureDescriptor.format = format;
|
||||
TestCopyRegionIntoBCFormatTextures(config);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(jiawei.shao@intel.com): support BC formats on OpenGL backend
|
||||
DAWN_INSTANTIATE_TEST(CompressedTextureBCFormatTest,
|
||||
D3D12Backend(),
|
||||
|
|
Loading…
Reference in New Issue