// 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