// Copyright 2022 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 <vector> #include "dawn/common/Platform.h" #include "dawn/tests/DawnTest.h" #include "dawn/utils/TestUtils.h" #include "dawn/utils/WGPUHelpers.h" namespace dawn { namespace { constexpr static wgpu::Extent3D kCopySize = …; constexpr static uint64_t kOffset = …; constexpr static uint64_t kBytesPerRow = …; constexpr static wgpu::TextureFormat kFormat = …; constexpr static uint32_t kBytesPerBlock = …; enum class Type { … }; std::ostream& operator<<(std::ostream& o, Type copyType) { … } TextureDimension; CopyDepth; ExtraRowsPerImage; DAWN_TEST_PARAM_STRUCT(RequiredBufferSizeInCopyTestsParams, Type, TextureDimension, CopyDepth, ExtraRowsPerImage); // Tests in this file are used to expose an error on D3D12 about required minimum buffer size. // See detailed bug reports at crbug.com/dawn/1278, 1288, 1289. // When we do B2T or T2B copy from/to a buffer with paddings, it may wrongly calculate // the required buffer size on D3D12. // Using the data in this test as an example, in which copySize = {1, 1, 2}, offset = 0, bytesPerRow // = 256, and rowsPerImage = 2 (there is 1-row padding for every image), and assuming we are copying // a non-compressed format like rgba8unorm, the required minimum buffer size should be: // offset + bytesPerRow * rowsPerImage * (copySize.depthOrArrayLayers - 1) // + bytesPerRow * (copySize.height - 1) + bytesPerBlock * copySize.width. // It is 0 + 256 * 2 * (2 - 1) + 256 * (1 - 1) + 4 * 1 = 516. // However, the required minimum buffer size on D3D12 (including WARP) is: // offset + bytesPerRow * rowsPerImage * (copySize.depthOrArrayLayers - 1) // + bytesPerRow * (rowsPerImage - 1) + bytesPerBlock * copySize.width. // Or // offset + bytesPerRow * rowsPerImage * copySize.depthOrArrayLayers // + bytesPerBlock * copySize.width - bytesPerRow. // It is 0 + 256 * 2 * (2 - 1) + 256 * (2 - 1) + 4 * 1 = 772. // It looks like D3D12 requires unnecessary buffer storage for rowsPerImagePadding in the last // image. It does respect bytesPerRowPadding in the last row and doesn't require storage for // that part, though. // // Further tests reveal that this incorrect calculation exist only when the texture dimension // is 3D, and there are rowsPerImage paddings, and there are multiple depth images. class RequiredBufferSizeInCopyTests : public DawnTestWithParams<RequiredBufferSizeInCopyTestsParams> { … }; // The buffer contains full data on the last image and has storage for all kinds of paddings. TEST_P(RequiredBufferSizeInCopyTests, AbundantBufferSize) { … } // The buffer has storage for rowsPerImage paddings on the last image but not bytesPerRow // paddings on the last row, which is exactly what D3D12 requires. See the comments at the // beginning of class RequiredBufferSizeInCopyTests for details. TEST_P(RequiredBufferSizeInCopyTests, BufferSizeOnBoundary) { … } // The buffer doesn't have storage for any paddings on the last image. WebGPU spec doesn't require // storage for these paddings, and the copy operation will never access to these paddings. So it // should work. TEST_P(RequiredBufferSizeInCopyTests, MinimumBufferSize) { … } DAWN_INSTANTIATE_TEST_P(…); } // anonymous namespace } // namespace dawn