chromium/third_party/dawn/src/dawn/tests/end2end/CopyTests.cpp

// Copyright 2017 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <algorithm>
#include <array>
#include <sstream>
#include <vector>

#include "dawn/common/Constants.h"
#include "dawn/common/Math.h"
#include "dawn/tests/DawnTest.h"
#include "dawn/utils/TestUtils.h"
#include "dawn/utils/TextureUtils.h"
#include "dawn/utils/WGPUHelpers.h"

namespace dawn {
namespace {

// For MinimumBufferSpec bytesPerRow and rowsPerImage, compute a default from the copy extent.
constexpr uint32_t kStrideComputeDefault =;

constexpr wgpu::TextureFormat kDefaultFormat =;

bool IsSnorm(wgpu::TextureFormat format) {}

class CopyTests {};

namespace {
TextureFormat;
DAWN_TEST_PARAM_STRUCT();
}  // namespace

class CopyTests_T2B : public CopyTests, public DawnTestWithParams<CopyTextureFormatParams> {};

class CopyTests_B2T : public CopyTests, public DawnTest {};

template <typename Parent>
class CopyTests_T2TBase : public CopyTests, public Parent {};

class CopyTests_T2T : public CopyTests_T2TBase<DawnTestWithParams<CopyTextureFormatParams>> {};

class CopyTests_T2T_Srgb : public CopyTests_T2TBase<DawnTestWithParams<CopyTextureFormatParams>> {};

class CopyTests_B2B : public DawnTest {};

class ClearBufferTests : public DawnTest {};

// Test that copying an entire texture with 256-byte aligned dimensions works
TEST_P(CopyTests_T2B, FullTextureAligned) {}

// Test noop copies
TEST_P(CopyTests_T2B, ZeroSizedCopy) {}

// Test that copying an entire texture without 256-byte aligned dimensions works
TEST_P(CopyTests_T2B, FullTextureUnaligned) {}

// Test that reading pixels from a 256-byte aligned texture works
TEST_P(CopyTests_T2B, PixelReadAligned) {}

// Test that copying pixels from a texture that is not 256-byte aligned works
TEST_P(CopyTests_T2B, PixelReadUnaligned) {}

// Test that copying regions with 256-byte aligned sizes works
TEST_P(CopyTests_T2B, TextureRegionAligned) {}

// Test that copying regions without 256-byte aligned sizes works
TEST_P(CopyTests_T2B, TextureRegionUnaligned) {}

// Test that copying mips with 256-byte aligned sizes works
TEST_P(CopyTests_T2B, TextureMipAligned) {}

// Test that copying mips when one dimension is 256-byte aligned and another dimension reach one
// works
TEST_P(CopyTests_T2B, TextureMipDimensionReachOne) {}

// Test that copying mips without 256-byte aligned sizes works
TEST_P(CopyTests_T2B, TextureMipUnaligned) {}

// Test that copying with a 512-byte aligned buffer offset works
TEST_P(CopyTests_T2B, OffsetBufferAligned) {}

// Test that copying without a 512-byte aligned buffer offset works
TEST_P(CopyTests_T2B, OffsetBufferUnaligned) {}

// Test that copying without a 512-byte aligned buffer offset works. Note: the buffer is mappable.
TEST_P(CopyTests_T2B, MappableBufferWithOffsetUnaligned) {}

// Test that copying from a texture to a mappable buffer won't overwrite the buffer's bytes
// before and after the copied region.
TEST_P(CopyTests_T2B, MappableBufferBeforeAndAfterBytesNotOverwritten) {}

// Test that copying without a 512-byte aligned buffer offset that is greater than the bytes per row
// works
TEST_P(CopyTests_T2B, OffsetBufferUnalignedSmallBytesPerRow) {}

// Test that copying with a greater bytes per row than needed on a 256-byte aligned texture works
TEST_P(CopyTests_T2B, BytesPerRowAligned) {}

// Test that copying with a greater bytes per row than needed on a texture that is not 256-byte
// aligned works
TEST_P(CopyTests_T2B, BytesPerRowUnaligned) {}

// Test that copying with bytesPerRow = 0 and bytesPerRow < bytesInACompleteRow works
// when we're copying one row only
TEST_P(CopyTests_T2B, BytesPerRowWithOneRowCopy) {}

TEST_P(CopyTests_T2B, StrideSpecialCases) {}

// Test copying a single slice with rowsPerImage larger than copy height and rowsPerImage will not
// take effect. If rowsPerImage takes effect, it looks like the copy may go past the end of the
// buffer.
TEST_P(CopyTests_T2B, RowsPerImageShouldNotCauseBufferOOBIfDepthOrArrayLayersIsOne) {}

// Test copying a single row with bytesPerRow larger than copy width and bytesPerRow will not
// take effect. If bytesPerRow takes effect, it looks like the copy may go past the end of the
// buffer.
TEST_P(CopyTests_T2B, BytesPerRowShouldNotCauseBufferOOBIfCopyHeightIsOne) {}

// Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_T2B, Texture2DArrayFull) {}

// Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_T2B, Texture2DArraySubRegion) {}

// Test that copying texture 2D array mips with 256-byte aligned sizes works
TEST_P(CopyTests_T2B, Texture2DArrayMip) {}

// Test that copying from a range of texture 2D array layers in one texture-to-buffer-copy when
// RowsPerImage is not equal to the height of the texture works.
TEST_P(CopyTests_T2B, Texture2DArrayRegionNonzeroRowsPerImage) {}

// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is not a
// multiple of 512.
TEST_P(CopyTests_T2B, Texture2DArrayRegionWithOffsetOddRowsPerImage) {}

// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is a multiple
// of 512.
TEST_P(CopyTests_T2B, Texture2DArrayRegionWithOffsetEvenRowsPerImage) {}

// Testing a series of params for 1D texture texture-to-buffer-copy.
TEST_P(CopyTests_T2B, Texture1D) {}

// Test that copying whole 3D texture in one texture-to-buffer-copy works.
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) {}

TEST_P(CopyTests_T2B, Texture3DNoSplitRowDataWithEmptyFirstRow) {}

TEST_P(CopyTests_T2B, Texture3DSplitRowDataWithoutEmptyFirstRow) {}

TEST_P(CopyTests_T2B, Texture3DSplitRowDataWithEmptyFirstRow) {}

TEST_P(CopyTests_T2B, Texture3DCopyHeightIsOneCopyWidthIsTiny) {}

TEST_P(CopyTests_T2B, Texture3DCopyHeightIsOneCopyWidthIsSmall) {}

// Test that copying texture 3D array mips with 256-byte aligned sizes works
TEST_P(CopyTests_T2B, Texture3DMipAligned) {}

// Test that copying texture 3D array mips with 256-byte unaligned sizes works
TEST_P(CopyTests_T2B, Texture3DMipUnaligned) {}

DAWN_INSTANTIATE_TEST_P();

class CopyTests_T2B_No_Format_Param : public CopyTests, public DawnTest {};

// A regression test for a bug on D3D12 backend that causes crash when doing texture-to-texture
// copy one row with the texture format Depth32Float.
TEST_P(CopyTests_T2B_No_Format_Param, CopyOneRowWithDepth32Float) {}

DAWN_INSTANTIATE_TEST();

class CopyTests_T2B_Compat : public CopyTests_T2B {};

// Test that copying 2d texture array with binding view dimension set to cube.
TEST_P(CopyTests_T2B_Compat, TextureCubeFull) {}

// Test that copying a range of cube texture layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_T2B_Compat, TextureCubeSubRegion) {}

// Test that copying texture 2D array mips with 256-byte aligned sizes works
TEST_P(CopyTests_T2B_Compat, TextureCubeMip) {}

// Test that copying from a range of texture 2D array layers in one texture-to-buffer-copy when
// RowsPerImage is not equal to the height of the texture works.
TEST_P(CopyTests_T2B_Compat, TextureCubeRegionNonzeroRowsPerImage) {}

DAWN_INSTANTIATE_TEST_P();

// Test that copying an entire texture with 256-byte aligned dimensions works
TEST_P(CopyTests_B2T, FullTextureAligned) {}

// Test noop copies.
TEST_P(CopyTests_B2T, ZeroSizedCopy) {}

// Test that copying an entire texture without 256-byte aligned dimensions works
TEST_P(CopyTests_B2T, FullTextureUnaligned) {}

// Test that reading pixels from a 256-byte aligned texture works
TEST_P(CopyTests_B2T, PixelReadAligned) {}

// Test that copying pixels from a texture that is not 256-byte aligned works
TEST_P(CopyTests_B2T, PixelReadUnaligned) {}

// Test that copying regions with 256-byte aligned sizes works
TEST_P(CopyTests_B2T, TextureRegionAligned) {}

// Test that copying regions without 256-byte aligned sizes works
TEST_P(CopyTests_B2T, TextureRegionUnaligned) {}

// Test that copying mips with 256-byte aligned sizes works
TEST_P(CopyTests_B2T, TextureMipAligned) {}

// Test that copying mips without 256-byte aligned sizes works
TEST_P(CopyTests_B2T, TextureMipUnaligned) {}

// Test that copying with a 512-byte aligned buffer offset works
TEST_P(CopyTests_B2T, OffsetBufferAligned) {}

// Test that copying without a 512-byte aligned buffer offset works
TEST_P(CopyTests_B2T, OffsetBufferUnaligned) {}

// Test that copying without a 512-byte aligned buffer offset that is greater than the bytes per row
// works
TEST_P(CopyTests_B2T, OffsetBufferUnalignedSmallBytesPerRow) {}

// Test that copying with a greater bytes per row than needed on a 256-byte aligned texture works
TEST_P(CopyTests_B2T, BytesPerRowAligned) {}

// Test that copying with a greater bytes per row than needed on a texture that is not 256-byte
// aligned works
TEST_P(CopyTests_B2T, BytesPerRowUnaligned) {}

// Test that copying with bytesPerRow = 0 and bytesPerRow < bytesInACompleteRow works
// when we're copying one row only
TEST_P(CopyTests_B2T, BytesPerRowWithOneRowCopy) {}

TEST_P(CopyTests_B2T, StrideSpecialCases) {}

// Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_B2T, Texture2DArrayFull) {}

// Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
TEST_P(CopyTests_B2T, Texture2DArraySubRegion) {}

// Test that copying into a range of texture 2D array layers in one texture-to-buffer-copy when
// RowsPerImage is not equal to the height of the texture works.
TEST_P(CopyTests_B2T, Texture2DArrayRegionNonzeroRowsPerImage) {}

// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is not a
// multiple of 512.
TEST_P(CopyTests_B2T, Texture2DArrayRegionWithOffsetOddRowsPerImage) {}

// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is a multiple
// of 512.
TEST_P(CopyTests_B2T, Texture2DArrayRegionWithOffsetEvenRowsPerImage) {}

// Test that copying whole texture 3D in one buffer-to-texture-copy works.
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) {}

TEST_P(CopyTests_B2T, Texture3DNoSplitRowDataWithEmptyFirstRow) {}

TEST_P(CopyTests_B2T, Texture3DSplitRowDataWithoutEmptyFirstRow) {}

TEST_P(CopyTests_B2T, Texture3DSplitRowDataWithEmptyFirstRow) {}

TEST_P(CopyTests_B2T, Texture3DCopyHeightIsOneCopyWidthIsTiny) {}

TEST_P(CopyTests_B2T, Texture3DCopyHeightIsOneCopyWidthIsSmall) {}

// Test that copying texture 3D array mips with 256-byte aligned sizes works
TEST_P(CopyTests_B2T, Texture3DMipAligned) {}

// Test that copying texture 3D array mips with 256-byte unaligned sizes works
TEST_P(CopyTests_B2T, Texture3DMipUnaligned) {}

DAWN_INSTANTIATE_TEST(CopyTests_B2T,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend());

TEST_P(CopyTests_T2T, Texture) {}

// Test noop copies.
TEST_P(CopyTests_T2T, ZeroSizedCopy) {}

TEST_P(CopyTests_T2T, TextureRegion) {}

TEST_P(CopyTests_T2T, TextureMip) {}

TEST_P(CopyTests_T2T, SingleMipSrcMultipleMipDst) {}

TEST_P(CopyTests_T2T, MultipleMipSrcSingleMipDst) {}

// Test that copying from one mip level to another mip level within the same 2D texture works.
TEST_P(CopyTests_T2T, Texture2DSameTextureDifferentMipLevels) {}

// Test copying the whole 2D array texture.
TEST_P(CopyTests_T2T, Texture2DArrayFull) {}

// Test copying a subresource region of the 2D array texture.
TEST_P(CopyTests_T2T, Texture2DArrayRegion) {}

// Test copying one slice of a 2D array texture.
TEST_P(CopyTests_T2T, Texture2DArrayCopyOneSlice) {}

// Test copying multiple contiguous slices of a 2D array texture.
TEST_P(CopyTests_T2T, Texture2DArrayCopyMultipleSlices) {}

// Test copying one texture slice within the same texture.
TEST_P(CopyTests_T2T, CopyWithinSameTextureOneSlice) {}

// Test copying multiple contiguous texture slices within the same texture with non-overlapped
// slices.
TEST_P(CopyTests_T2T, CopyWithinSameTextureNonOverlappedSlices) {}

// A regression test (from WebGPU CTS) for an Intel D3D12 driver bug about T2T copy with specific
// texture formats. See http://crbug.com/1161355 for more details.
TEST_P(CopyTests_T2T, CopyFromNonZeroMipLevelWithTexelBlockSizeLessThan4Bytes) {}

// Test that copying from one mip level to another mip level within the same 2D array texture works.
TEST_P(CopyTests_T2T, Texture2DArraySameTextureDifferentMipLevels) {}

// Test that copying whole 3D texture in one texture-to-texture-copy works.
TEST_P(CopyTests_T2T, Texture3DFull) {}

// Test that copying from one mip level to another mip level within the same 3D texture works.
TEST_P(CopyTests_T2T, Texture3DSameTextureDifferentMipLevels) {}

// Test that copying whole 3D texture to a 2D array in one texture-to-texture-copy works.
TEST_P(CopyTests_T2T, Texture3DTo2DArrayFull) {}

// Test that copying between 3D texture and 2D array textures works. It includes partial copy
// for src and/or dst texture, non-zero offset (copy origin), non-zero mip level.
TEST_P(CopyTests_T2T, Texture3DAnd2DArraySubRegion) {}

// Test that copying whole 2D array to a 3D texture in one texture-to-texture-copy works.
TEST_P(CopyTests_T2T, Texture2DArrayTo3DFull) {}

// Test that copying subregion of a 3D texture in one texture-to-texture-copy works.
TEST_P(CopyTests_T2T, Texture3DSubRegion) {}

// Test that copying subregion of a 3D texture to a 2D array in one texture-to-texture-copy works.
TEST_P(CopyTests_T2T, Texture3DTo2DArraySubRegion) {}

// Test that copying subregion of a 2D array to a 3D texture to in one texture-to-texture-copy
// works.
TEST_P(CopyTests_T2T, Texture2DArrayTo3DSubRegion) {}

// Test that copying texture 3D array mips in one texture-to-texture-copy works
TEST_P(CopyTests_T2T, Texture3DMipAligned) {}

// Test that copying texture 3D array mips in one texture-to-texture-copy works
TEST_P(CopyTests_T2T, Texture3DMipUnaligned) {}

// TODO(dawn:1705): enable this test for D3D11
DAWN_INSTANTIATE_TEST_P();

// Test copying between textures that have srgb compatible texture formats;
TEST_P(CopyTests_T2T_Srgb, FullCopy) {}

DAWN_INSTANTIATE_TEST_P();

static constexpr uint64_t kSmallBufferSize =;
static constexpr uint64_t kLargeBufferSize =;

// Test copying full buffers
TEST_P(CopyTests_B2B, FullCopy) {}

// Test copying small pieces of a buffer at different corner case offsets
TEST_P(CopyTests_B2B, SmallCopyInBigBuffer) {}

// Test zero-size copies
TEST_P(CopyTests_B2B, ZeroSizedCopy) {}

DAWN_INSTANTIATE_TEST(CopyTests_B2B,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend());

// Test clearing full buffers
TEST_P(ClearBufferTests, FullClear) {}

// Test clearing small pieces of a buffer at different corner case offsets
TEST_P(ClearBufferTests, SmallClearInBigBuffer) {}

// Test zero-size clears
TEST_P(ClearBufferTests, ZeroSizedClear) {}

DAWN_INSTANTIATE_TEST(ClearBufferTests,
                      D3D11Backend(),
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend());

// Regression tests to reproduce a flaky failure when running whole WebGPU CTS on Intel GPUs.
// See crbug.com/dawn/1487 for more details.
namespace {
TextureFormat;

enum class InitializationMethod {};

std::ostream& operator<<(std::ostream& o, InitializationMethod method) {}

AddRenderAttachmentUsage;

DAWN_TEST_PARAM_STRUCT(CopyToDepthStencilTextureAfterDestroyingBigBufferTestsParams,
                       TextureFormat,
                       InitializationMethod,
                       AddRenderAttachmentUsage);

}  // anonymous namespace

class CopyToDepthStencilTextureAfterDestroyingBigBufferTests
    : public DawnTestWithParams<CopyToDepthStencilTextureAfterDestroyingBigBufferTestsParams> {};

TEST_P(CopyToDepthStencilTextureAfterDestroyingBigBufferTests, DoTest) {}

DAWN_INSTANTIATE_TEST_P();

// A series of regression tests for an Intel D3D12 driver issue about creating textures with
// CreatePlacedResource(). See crbug.com/1237175 for more details.
class T2TCopyFromDirtyHeapTests : public DawnTest {};

TEST_P(T2TCopyFromDirtyHeapTests, From2DArrayTexture) {}

TEST_P(T2TCopyFromDirtyHeapTests, From2DMultiMipmapLevelTexture) {}

DAWN_INSTANTIATE_TEST(T2TCopyFromDirtyHeapTests,
                      D3D12Backend(),
                      MetalBackend(),
                      OpenGLBackend(),
                      OpenGLESBackend(),
                      VulkanBackend());

}  // anonymous namespace
}  // namespace dawn