blob: 20cacaa2cd27aa2022ef15955a5495bf97838adf [file] [log] [blame]
Corentin Wallez4a9ef4e2018-07-18 11:40:26 +02001// Copyright 2017 The Dawn Authors
Austin Engb343e8d2017-07-17 09:38:30 -04002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Corentin Walleza4da0322018-07-18 15:18:25 +020015#include "tests/DawnTest.h"
Austin Engb343e8d2017-07-17 09:38:30 -040016
17#include <array>
18#include "common/Constants.h"
19#include "common/Math.h"
Tomek Ponitka7f265d12020-08-20 11:25:49 +000020#include "utils/TestUtils.h"
Yunchao He9749f5a2021-07-09 02:47:49 +000021#include "utils/TextureUtils.h"
Corentin Wallez04863c42019-10-25 11:36:47 +000022#include "utils/WGPUHelpers.h"
Austin Engb343e8d2017-07-17 09:38:30 -040023
Kai Ninomiya16036cf2020-11-06 13:41:50 +000024// For MinimumBufferSpec bytesPerRow and rowsPerImage, compute a default from the copy extent.
25constexpr uint32_t kStrideComputeDefault = 0xFFFF'FFFEul;
26
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000027constexpr wgpu::TextureFormat kDefaultFormat = wgpu::TextureFormat::RGBA8Unorm;
28
Juanmif00c68a2021-08-05 22:55:09 +000029class CopyTests {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000030 protected:
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000031 struct TextureSpec {
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000032 wgpu::TextureFormat format = kDefaultFormat;
33 wgpu::Origin3D copyOrigin = {0, 0, 0};
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000034 wgpu::Extent3D textureSize;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000035 uint32_t copyLevel = 0;
36 uint32_t levelCount = 1;
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000037 };
Austin Engb343e8d2017-07-17 09:38:30 -040038
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000039 struct BufferSpec {
40 uint64_t size;
41 uint64_t offset;
42 uint32_t bytesPerRow;
43 uint32_t rowsPerImage;
44 };
Austin Engb343e8d2017-07-17 09:38:30 -040045
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000046 static std::vector<uint8_t> GetExpectedTextureData(const utils::TextureDataCopyLayout& layout) {
47 uint32_t bytesPerTexelBlock = layout.bytesPerRow / layout.texelBlocksPerRow;
48 std::vector<uint8_t> textureData(layout.byteLength);
shrekshaob00de7f2021-03-22 21:12:36 +000049 for (uint32_t layer = 0; layer < layout.mipSize.depthOrArrayLayers; ++layer) {
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000050 const uint32_t byteOffsetPerSlice = layout.bytesPerImage * layer;
51 for (uint32_t y = 0; y < layout.mipSize.height; ++y) {
52 for (uint32_t x = 0; x < layout.mipSize.width * bytesPerTexelBlock; ++x) {
Jiawei Shao8ce15b32021-11-17 00:31:38 +000053 uint32_t i = x + y * layout.bytesPerRow;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000054 textureData[byteOffsetPerSlice + i] =
55 static_cast<uint8_t>((x + 1 + (layer + 1) * y) % 256);
56 }
57 }
58 }
59 return textureData;
60 }
61
Austin Enged8a8c02021-06-04 22:23:56 +000062 // TODO(crbug.com/dawn/818): remove this function when all the tests in this file support
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000063 // testing arbitrary formats.
64 static std::vector<RGBA8> GetExpectedTextureDataRGBA8(
65 const utils::TextureDataCopyLayout& layout) {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000066 std::vector<RGBA8> textureData(layout.texelBlockCount);
shrekshaob00de7f2021-03-22 21:12:36 +000067 for (uint32_t layer = 0; layer < layout.mipSize.depthOrArrayLayers; ++layer) {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000068 const uint32_t texelIndexOffsetPerSlice = layout.texelBlocksPerImage * layer;
69 for (uint32_t y = 0; y < layout.mipSize.height; ++y) {
70 for (uint32_t x = 0; x < layout.mipSize.width; ++x) {
71 uint32_t i = x + y * layout.texelBlocksPerRow;
72 textureData[texelIndexOffsetPerSlice + i] =
73 RGBA8(static_cast<uint8_t>((x + layer * x) % 256),
74 static_cast<uint8_t>((y + layer * y) % 256),
75 static_cast<uint8_t>(x / 256), static_cast<uint8_t>(y / 256));
Austin Engb343e8d2017-07-17 09:38:30 -040076 }
77 }
78 }
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000079
80 return textureData;
81 }
82
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000083 static BufferSpec MinimumBufferSpec(uint32_t width,
84 uint32_t height,
85 uint32_t depth = 1,
86 wgpu::TextureFormat format = kDefaultFormat) {
Kai Ninomiya16036cf2020-11-06 13:41:50 +000087 return MinimumBufferSpec({width, height, depth}, kStrideComputeDefault,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000088 depth == 1 ? wgpu::kCopyStrideUndefined : kStrideComputeDefault,
89 format);
Kai Ninomiya2afea0c2020-07-10 20:33:08 +000090 }
91
Kai Ninomiya16036cf2020-11-06 13:41:50 +000092 static BufferSpec MinimumBufferSpec(wgpu::Extent3D copyExtent,
93 uint32_t overrideBytesPerRow = kStrideComputeDefault,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +000094 uint32_t overrideRowsPerImage = kStrideComputeDefault,
95 wgpu::TextureFormat format = kDefaultFormat) {
96 uint32_t bytesPerRow = utils::GetMinimumBytesPerRow(format, copyExtent.width);
Kai Ninomiya16036cf2020-11-06 13:41:50 +000097 if (overrideBytesPerRow != kStrideComputeDefault) {
98 bytesPerRow = overrideBytesPerRow;
99 }
100 uint32_t rowsPerImage = copyExtent.height;
101 if (overrideRowsPerImage != kStrideComputeDefault) {
102 rowsPerImage = overrideRowsPerImage;
103 }
104
105 uint32_t totalDataSize =
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000106 utils::RequiredBytesInCopy(bytesPerRow, rowsPerImage, copyExtent, format);
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000107 return {totalDataSize, 0, bytesPerRow, rowsPerImage};
108 }
Yunchao He9df00a32021-06-07 17:32:43 +0000109 static void CopyTextureData(uint32_t bytesPerTexelBlock,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000110 const void* srcData,
111 uint32_t widthInBlocks,
112 uint32_t heightInBlocks,
Yunchao He3e8f3f92021-04-01 22:40:43 +0000113 uint32_t depthInBlocks,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000114 uint32_t srcBytesPerRow,
Yunchao He9df00a32021-06-07 17:32:43 +0000115 uint32_t srcRowsPerImage,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000116 void* dstData,
Yunchao He9df00a32021-06-07 17:32:43 +0000117 uint32_t dstBytesPerRow,
118 uint32_t dstRowsPerImage) {
Yunchao He3e8f3f92021-04-01 22:40:43 +0000119 for (unsigned int z = 0; z < depthInBlocks; ++z) {
Yunchao He9df00a32021-06-07 17:32:43 +0000120 uint32_t srcDepthOffset = z * srcBytesPerRow * srcRowsPerImage;
121 uint32_t dstDepthOffset = z * dstBytesPerRow * dstRowsPerImage;
Yunchao He3e8f3f92021-04-01 22:40:43 +0000122 for (unsigned int y = 0; y < heightInBlocks; ++y) {
Austin Enge2f083e2021-05-11 01:26:13 +0000123 memcpy(static_cast<uint8_t*>(dstData) + dstDepthOffset + y * dstBytesPerRow,
124 static_cast<const uint8_t*>(srcData) + srcDepthOffset + y * srcBytesPerRow,
Yunchao He3e8f3f92021-04-01 22:40:43 +0000125 widthInBlocks * bytesPerTexelBlock);
126 }
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000127 }
128 }
Austin Engb343e8d2017-07-17 09:38:30 -0400129};
130
Juanmif00c68a2021-08-05 22:55:09 +0000131class CopyTests_T2B : public CopyTests, public DawnTest {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000132 protected:
133 void DoTest(const TextureSpec& textureSpec,
134 const BufferSpec& bufferSpec,
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000135 const wgpu::Extent3D& copySize,
136 wgpu::TextureDimension dimension = wgpu::TextureDimension::e2D) {
Austin Enged8a8c02021-06-04 22:23:56 +0000137 // TODO(crbug.com/dawn/818): support testing arbitrary formats
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000138 ASSERT_EQ(kDefaultFormat, textureSpec.format);
139
140 const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(textureSpec.format);
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000141 // Create a texture that is `width` x `height` with (`level` + 1) mip levels.
142 wgpu::TextureDescriptor descriptor;
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000143 descriptor.dimension = dimension;
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000144 descriptor.size = textureSpec.textureSize;
145 descriptor.sampleCount = 1;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000146 descriptor.format = textureSpec.format;
147 descriptor.mipLevelCount = textureSpec.levelCount;
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000148 descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc;
149 wgpu::Texture texture = device.CreateTexture(&descriptor);
Austin Engb343e8d2017-07-17 09:38:30 -0400150
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000151 // Layout for initial data upload to texture.
152 // Some parts of this result are also reused later.
Tomek Ponitka9d66c532020-07-15 18:06:07 +0000153 const utils::TextureDataCopyLayout copyLayout =
Yunchao Hee5b99032021-06-09 16:01:08 +0000154 utils::GetTextureDataCopyLayoutForTextureAtLevel(
155 textureSpec.format, textureSpec.textureSize, textureSpec.copyLevel, dimension);
Austin Engb343e8d2017-07-17 09:38:30 -0400156
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000157 // Initialize the source texture
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000158 std::vector<RGBA8> textureArrayData = GetExpectedTextureDataRGBA8(copyLayout);
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000159 {
Corentin Wallez80915842021-03-04 18:13:45 +0000160 wgpu::ImageCopyTexture imageCopyTexture =
161 utils::CreateImageCopyTexture(texture, textureSpec.copyLevel, {0, 0, 0});
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000162 wgpu::TextureDataLayout textureDataLayout =
163 utils::CreateTextureDataLayout(0, copyLayout.bytesPerRow, copyLayout.rowsPerImage);
Corentin Wallez80915842021-03-04 18:13:45 +0000164 queue.WriteTexture(&imageCopyTexture, textureArrayData.data(), copyLayout.byteLength,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000165 &textureDataLayout, &copyLayout.mipSize);
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000166 }
Austin Engb343e8d2017-07-17 09:38:30 -0400167
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000168 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
169
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000170 // Create a buffer of `size` and populate it with empty data (0,0,0,0) Note:
171 // Prepopulating the buffer with empty data ensures that there is not random data in the
172 // expectation and helps ensure that the padding due to the bytes per row is not modified
173 // by the copy.
Yan, Shaobo75e5ed62020-09-23 10:28:26 +0000174 wgpu::BufferDescriptor bufferDesc;
175 bufferDesc.size = bufferSpec.size;
176 bufferDesc.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
177 wgpu::Buffer buffer = device.CreateBuffer(&bufferDesc);
Jiawei Shao4b74dbe2018-08-30 16:27:38 +0800178
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000179 {
Corentin Wallez80915842021-03-04 18:13:45 +0000180 wgpu::ImageCopyTexture imageCopyTexture = utils::CreateImageCopyTexture(
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000181 texture, textureSpec.copyLevel, textureSpec.copyOrigin);
Corentin Wallez80915842021-03-04 18:13:45 +0000182 wgpu::ImageCopyBuffer imageCopyBuffer = utils::CreateImageCopyBuffer(
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000183 buffer, bufferSpec.offset, bufferSpec.bytesPerRow, bufferSpec.rowsPerImage);
Corentin Wallez80915842021-03-04 18:13:45 +0000184 encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &copySize);
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000185 }
Austin Engb343e8d2017-07-17 09:38:30 -0400186
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000187 wgpu::CommandBuffer commands = encoder.Finish();
188 queue.Submit(1, &commands);
Austin Engb343e8d2017-07-17 09:38:30 -0400189
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000190 uint64_t bufferOffset = bufferSpec.offset;
Yan, Shaobo75e5ed62020-09-23 10:28:26 +0000191
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000192 uint32_t copyLayer = copySize.depthOrArrayLayers;
193 uint32_t copyDepth = 1;
194 if (dimension == wgpu::TextureDimension::e3D) {
195 copyLayer = 1;
196 copyDepth = copySize.depthOrArrayLayers;
197 }
198
199 const wgpu::Extent3D copySizePerLayer = {copySize.width, copySize.height, copyDepth};
Yunchao He9df00a32021-06-07 17:32:43 +0000200 // Texels in single layer.
Yan, Shaobo75e5ed62020-09-23 10:28:26 +0000201 const uint32_t texelCountInCopyRegion = utils::GetTexelCountInCopyRegion(
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000202 bufferSpec.bytesPerRow, bufferSpec.rowsPerImage, copySizePerLayer, textureSpec.format);
203 const uint32_t maxArrayLayer = textureSpec.copyOrigin.z + copyLayer;
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000204 std::vector<RGBA8> expected(texelCountInCopyRegion);
Yunchao He9df00a32021-06-07 17:32:43 +0000205 for (uint32_t layer = textureSpec.copyOrigin.z; layer < maxArrayLayer; ++layer) {
206 // Copy the data used to create the upload buffer in the specified copy region to have
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000207 // the same format as the expected buffer data.
208 std::fill(expected.begin(), expected.end(), RGBA8());
Yunchao He9df00a32021-06-07 17:32:43 +0000209 const uint32_t texelIndexOffset = copyLayout.texelBlocksPerImage * layer;
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000210 const uint32_t expectedTexelArrayDataStartIndex =
211 texelIndexOffset + (textureSpec.copyOrigin.x +
212 textureSpec.copyOrigin.y * copyLayout.texelBlocksPerRow);
Austin Engb343e8d2017-07-17 09:38:30 -0400213
Yunchao He9df00a32021-06-07 17:32:43 +0000214 CopyTextureData(bytesPerTexel,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000215 textureArrayData.data() + expectedTexelArrayDataStartIndex,
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000216 copySize.width, copySize.height, copyDepth, copyLayout.bytesPerRow,
Yunchao He9df00a32021-06-07 17:32:43 +0000217 copyLayout.rowsPerImage, expected.data(), bufferSpec.bytesPerRow,
218 bufferSpec.rowsPerImage);
Jiawei Shao4b74dbe2018-08-30 16:27:38 +0800219
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000220 EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()), buffer,
221 bufferOffset, static_cast<uint32_t>(expected.size()))
222 << "Texture to Buffer copy failed copying region [(" << textureSpec.copyOrigin.x
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000223 << ", " << textureSpec.copyOrigin.y << ", " << textureSpec.copyOrigin.z << "), ("
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000224 << textureSpec.copyOrigin.x + copySize.width << ", "
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000225 << textureSpec.copyOrigin.y + copySize.height << ", "
shrekshaob00de7f2021-03-22 21:12:36 +0000226 << textureSpec.copyOrigin.z + copySize.depthOrArrayLayers << ")) from "
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000227 << textureSpec.textureSize.width << " x " << textureSpec.textureSize.height
Yunchao He9df00a32021-06-07 17:32:43 +0000228 << " texture at mip level " << textureSpec.copyLevel << " layer " << layer << " to "
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000229 << bufferSpec.size << "-byte buffer with offset " << bufferOffset
230 << " and bytes per row " << bufferSpec.bytesPerRow << std::endl;
Austin Engb343e8d2017-07-17 09:38:30 -0400231
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000232 bufferOffset += bufferSpec.bytesPerRow * bufferSpec.rowsPerImage;
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000233 }
234 }
Austin Engb343e8d2017-07-17 09:38:30 -0400235};
236
Juanmif00c68a2021-08-05 22:55:09 +0000237class CopyTests_B2T : public CopyTests, public DawnTest {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000238 protected:
Austin Engb343e8d2017-07-17 09:38:30 -0400239 static void FillBufferData(RGBA8* data, size_t count) {
240 for (size_t i = 0; i < count; ++i) {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000241 data[i] = RGBA8(static_cast<uint8_t>(i % 256), static_cast<uint8_t>((i / 256) % 256),
242 static_cast<uint8_t>((i / 256 / 256) % 256), 255);
Austin Engb343e8d2017-07-17 09:38:30 -0400243 }
244 }
245
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000246 void DoTest(const TextureSpec& textureSpec,
247 const BufferSpec& bufferSpec,
Yunchao He3e8f3f92021-04-01 22:40:43 +0000248 const wgpu::Extent3D& copySize,
249 wgpu::TextureDimension dimension = wgpu::TextureDimension::e2D) {
Austin Enged8a8c02021-06-04 22:23:56 +0000250 // TODO(crbug.com/dawn/818): support testing arbitrary formats
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000251 ASSERT_EQ(kDefaultFormat, textureSpec.format);
Austin Engb343e8d2017-07-17 09:38:30 -0400252 // Create a buffer of size `size` and populate it with data
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000253 const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(textureSpec.format);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000254 std::vector<RGBA8> bufferData(bufferSpec.size / bytesPerTexel);
Austin Engb343e8d2017-07-17 09:38:30 -0400255 FillBufferData(bufferData.data(), bufferData.size());
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000256 wgpu::Buffer buffer =
257 utils::CreateBufferFromData(device, bufferData.data(), bufferSpec.size,
258 wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst);
Austin Engb343e8d2017-07-17 09:38:30 -0400259
260 // Create a texture that is `width` x `height` with (`level` + 1) mip levels.
Corentin Wallezcab352c2019-10-28 13:27:36 +0000261 wgpu::TextureDescriptor descriptor;
Yunchao He3e8f3f92021-04-01 22:40:43 +0000262 descriptor.dimension = dimension;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000263 descriptor.size = textureSpec.textureSize;
Jiawei Shao8bff3b22018-12-12 09:27:16 +0000264 descriptor.sampleCount = 1;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000265 descriptor.format = textureSpec.format;
266 descriptor.mipLevelCount = textureSpec.levelCount;
Corentin Wallezcab352c2019-10-28 13:27:36 +0000267 descriptor.usage = wgpu::TextureUsage::CopyDst | wgpu::TextureUsage::CopySrc;
268 wgpu::Texture texture = device.CreateTexture(&descriptor);
Austin Engb343e8d2017-07-17 09:38:30 -0400269
Corentin Wallezcab352c2019-10-28 13:27:36 +0000270 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
Austin Engb343e8d2017-07-17 09:38:30 -0400271
Corentin Wallez80915842021-03-04 18:13:45 +0000272 wgpu::ImageCopyBuffer imageCopyBuffer = utils::CreateImageCopyBuffer(
Jiawei Shao92379bf2020-06-21 09:33:44 +0000273 buffer, bufferSpec.offset, bufferSpec.bytesPerRow, bufferSpec.rowsPerImage);
Corentin Wallez80915842021-03-04 18:13:45 +0000274 wgpu::ImageCopyTexture imageCopyTexture =
275 utils::CreateImageCopyTexture(texture, textureSpec.copyLevel, textureSpec.copyOrigin);
276 encoder.CopyBufferToTexture(&imageCopyBuffer, &imageCopyTexture, &copySize);
Austin Engb343e8d2017-07-17 09:38:30 -0400277
Corentin Wallezcab352c2019-10-28 13:27:36 +0000278 wgpu::CommandBuffer commands = encoder.Finish();
Jiawei Shao4b74dbe2018-08-30 16:27:38 +0800279 queue.Submit(1, &commands);
Austin Engb343e8d2017-07-17 09:38:30 -0400280
Yunchao He3e8f3f92021-04-01 22:40:43 +0000281 const utils::TextureDataCopyLayout copyLayout =
Yunchao Hee5b99032021-06-09 16:01:08 +0000282 utils::GetTextureDataCopyLayoutForTextureAtLevel(
283 textureSpec.format, textureSpec.textureSize, textureSpec.copyLevel, dimension,
Yunchao He3e8f3f92021-04-01 22:40:43 +0000284 bufferSpec.rowsPerImage);
285
286 uint32_t copyLayer = copySize.depthOrArrayLayers;
287 uint32_t copyDepth = 1;
288 if (dimension == wgpu::TextureDimension::e3D) {
289 copyLayer = 1;
290 copyDepth = copySize.depthOrArrayLayers;
291 }
292
Jiawei Shao92379bf2020-06-21 09:33:44 +0000293 uint64_t bufferOffset = bufferSpec.offset;
Yunchao He9df00a32021-06-07 17:32:43 +0000294 const uint32_t blockWidth = utils::GetTextureFormatBlockWidth(textureSpec.format);
295 const uint32_t blockHeight = utils::GetTextureFormatBlockHeight(textureSpec.format);
296 const uint32_t texelCountPerLayer = copyDepth * (copyLayout.mipSize.width / blockWidth) *
297 (copyLayout.mipSize.height / blockHeight) *
298 bytesPerTexel;
Yunchao He3e8f3f92021-04-01 22:40:43 +0000299 for (uint32_t layer = 0; layer < copyLayer; ++layer) {
Yunchao He9df00a32021-06-07 17:32:43 +0000300 // Copy and pack the data used to create the buffer in the specified copy region to have
301 // the same format as the expected texture data.
302 std::vector<RGBA8> expected(texelCountPerLayer);
303 CopyTextureData(bytesPerTexel, bufferData.data() + bufferOffset / bytesPerTexel,
Yunchao He3e8f3f92021-04-01 22:40:43 +0000304 copySize.width, copySize.height, copyDepth, bufferSpec.bytesPerRow,
Yunchao He9df00a32021-06-07 17:32:43 +0000305 bufferSpec.rowsPerImage, expected.data(),
306 copySize.width * bytesPerTexel, copySize.height);
Austin Engb343e8d2017-07-17 09:38:30 -0400307
Yunchao He0da94c32021-04-08 14:58:42 +0000308 EXPECT_TEXTURE_EQ(expected.data(), texture,
309 {textureSpec.copyOrigin.x, textureSpec.copyOrigin.y,
310 textureSpec.copyOrigin.z + layer},
311 {copySize.width, copySize.height, copyDepth}, textureSpec.copyLevel)
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000312 << "Buffer to Texture copy failed copying " << bufferSpec.size
313 << "-byte buffer with offset " << bufferSpec.offset << " and bytes per row "
314 << bufferSpec.bytesPerRow << " to [(" << textureSpec.copyOrigin.x << ", "
315 << textureSpec.copyOrigin.y << "), (" << textureSpec.copyOrigin.x + copySize.width
316 << ", " << textureSpec.copyOrigin.y + copySize.height << ")) region of "
317 << textureSpec.textureSize.width << " x " << textureSpec.textureSize.height
Yunchao He3e8f3f92021-04-01 22:40:43 +0000318 << " texture at mip level " << textureSpec.copyLevel << " layer " << layer
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000319 << std::endl;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000320 bufferOffset += copyLayout.bytesPerImage;
321 }
Austin Engb343e8d2017-07-17 09:38:30 -0400322 }
Austin Engb343e8d2017-07-17 09:38:30 -0400323};
324
Juanmif00c68a2021-08-05 22:55:09 +0000325namespace {
326 // The CopyTests Texture to Texture in this class will validate both CopyTextureToTexture and
327 // CopyTextureToTextureInternal.
328 using UsageCopySrc = bool;
Corentin Wallez87ef49c2021-12-07 09:29:46 +0000329 DAWN_TEST_PARAM_STRUCT(CopyTestsParams, UsageCopySrc);
Yancf0e4fc2022-01-06 09:01:58 +0000330
331 using SrcColorFormat = wgpu::TextureFormat;
332 DAWN_TEST_PARAM_STRUCT(SrcColorFormatParams, SrcColorFormat);
Juanmif00c68a2021-08-05 22:55:09 +0000333} // namespace
334
Yancf0e4fc2022-01-06 09:01:58 +0000335template <typename Parent>
336class CopyTests_T2TBase : public CopyTests, public Parent {
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000337 protected:
Austin Engdc518772021-12-22 19:04:33 +0000338 std::vector<wgpu::FeatureName> GetRequiredFeatures() override {
339 return {wgpu::FeatureName::DawnInternalUsages};
Juanmif00c68a2021-08-05 22:55:09 +0000340 }
341
Jiawei Shaoe472c452020-06-08 11:30:01 +0000342 void DoTest(const TextureSpec& srcSpec,
343 const TextureSpec& dstSpec,
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000344 const wgpu::Extent3D& copySize,
Austin Enge2f083e2021-05-11 01:26:13 +0000345 wgpu::TextureDimension srcDimension,
346 wgpu::TextureDimension dstDimension,
Yancf0e4fc2022-01-06 09:01:58 +0000347 bool copyWithinSameTexture = false,
348 bool usageCopySrc = false) {
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000349 const wgpu::TextureFormat format = srcSpec.format;
350
Corentin Wallezcab352c2019-10-28 13:27:36 +0000351 wgpu::TextureDescriptor srcDescriptor;
Austin Enge2f083e2021-05-11 01:26:13 +0000352 srcDescriptor.dimension = srcDimension;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000353 srcDescriptor.size = srcSpec.textureSize;
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000354 srcDescriptor.sampleCount = 1;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000355 srcDescriptor.format = format;
356 srcDescriptor.mipLevelCount = srcSpec.levelCount;
Juanmif00c68a2021-08-05 22:55:09 +0000357 srcDescriptor.usage = wgpu::TextureUsage::CopyDst;
358 // This test will have two versions, one where we check the normal CopyToCopy, and for that
359 // we will add the CopySrc usage, and the one where we test the CopyToCopyInternal, and then
360 // we have to add the CopySrc to the Internal usage.
361 wgpu::DawnTextureInternalUsageDescriptor internalDesc = {};
362 srcDescriptor.nextInChain = &internalDesc;
363 if (usageCopySrc) {
364 srcDescriptor.usage |= wgpu::TextureUsage::CopySrc;
365 } else {
366 internalDesc.internalUsage = wgpu::TextureUsage::CopySrc;
367 }
Yancf0e4fc2022-01-06 09:01:58 +0000368 wgpu::Texture srcTexture = this->device.CreateTexture(&srcDescriptor);
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000369
Jiawei Shaoe472c452020-06-08 11:30:01 +0000370 wgpu::Texture dstTexture;
371 if (copyWithinSameTexture) {
372 dstTexture = srcTexture;
373 } else {
374 wgpu::TextureDescriptor dstDescriptor;
Austin Enge2f083e2021-05-11 01:26:13 +0000375 dstDescriptor.dimension = dstDimension;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000376 dstDescriptor.size = dstSpec.textureSize;
Jiawei Shaoe472c452020-06-08 11:30:01 +0000377 dstDescriptor.sampleCount = 1;
Yancf0e4fc2022-01-06 09:01:58 +0000378 dstDescriptor.format = dstSpec.format;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000379 dstDescriptor.mipLevelCount = dstSpec.levelCount;
Jiawei Shaoe472c452020-06-08 11:30:01 +0000380 dstDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::CopyDst;
Yancf0e4fc2022-01-06 09:01:58 +0000381 dstTexture = this->device.CreateTexture(&dstDescriptor);
Jiawei Shaoe472c452020-06-08 11:30:01 +0000382 }
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000383
Yunchao He987fbed2021-06-21 20:09:37 +0000384 // Create an upload buffer and use it to completely populate the subresources of the src
385 // texture that will be copied from at the given mip level.
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000386 const utils::TextureDataCopyLayout srcDataCopyLayout =
Yunchao Hee5b99032021-06-09 16:01:08 +0000387 utils::GetTextureDataCopyLayoutForTextureAtLevel(
shrekshaob00de7f2021-03-22 21:12:36 +0000388 format,
389 {srcSpec.textureSize.width, srcSpec.textureSize.height,
Yunchao He987fbed2021-06-21 20:09:37 +0000390 srcDimension == wgpu::TextureDimension::e3D
391 ? srcSpec.textureSize.depthOrArrayLayers
392 : copySize.depthOrArrayLayers},
Yunchao Hee5b99032021-06-09 16:01:08 +0000393 srcSpec.copyLevel, srcDimension);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000394
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000395 // Initialize the source texture
396 const std::vector<uint8_t> srcTextureCopyData = GetExpectedTextureData(srcDataCopyLayout);
397 {
Corentin Wallez80915842021-03-04 18:13:45 +0000398 wgpu::ImageCopyTexture imageCopyTexture = utils::CreateImageCopyTexture(
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000399 srcTexture, srcSpec.copyLevel, {0, 0, srcSpec.copyOrigin.z});
400 wgpu::TextureDataLayout textureDataLayout = utils::CreateTextureDataLayout(
401 0, srcDataCopyLayout.bytesPerRow, srcDataCopyLayout.rowsPerImage);
Yancf0e4fc2022-01-06 09:01:58 +0000402 this->queue.WriteTexture(&imageCopyTexture, srcTextureCopyData.data(),
403 srcDataCopyLayout.byteLength, &textureDataLayout,
404 &srcDataCopyLayout.mipSize);
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000405 }
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000406
Yancf0e4fc2022-01-06 09:01:58 +0000407 wgpu::CommandEncoder encoder = this->device.CreateCommandEncoder();
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000408
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000409 // Perform the texture to texture copy
Corentin Wallez80915842021-03-04 18:13:45 +0000410 wgpu::ImageCopyTexture srcImageCopyTexture =
411 utils::CreateImageCopyTexture(srcTexture, srcSpec.copyLevel, srcSpec.copyOrigin);
412 wgpu::ImageCopyTexture dstImageCopyTexture =
413 utils::CreateImageCopyTexture(dstTexture, dstSpec.copyLevel, dstSpec.copyOrigin);
Juanmif00c68a2021-08-05 22:55:09 +0000414
415 if (usageCopySrc) {
416 encoder.CopyTextureToTexture(&srcImageCopyTexture, &dstImageCopyTexture, &copySize);
417 } else {
418 encoder.CopyTextureToTextureInternal(&srcImageCopyTexture, &dstImageCopyTexture,
419 &copySize);
420 }
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000421
Yunchao He987fbed2021-06-21 20:09:37 +0000422 // Create an output buffer and use it to completely populate the subresources of the dst
423 // texture that will be copied to at the given mip level.
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000424 const utils::TextureDataCopyLayout dstDataCopyLayout =
Yunchao Hee5b99032021-06-09 16:01:08 +0000425 utils::GetTextureDataCopyLayoutForTextureAtLevel(
shrekshaob00de7f2021-03-22 21:12:36 +0000426 format,
427 {dstSpec.textureSize.width, dstSpec.textureSize.height,
Yunchao He987fbed2021-06-21 20:09:37 +0000428 dstDimension == wgpu::TextureDimension::e3D
429 ? dstSpec.textureSize.depthOrArrayLayers
430 : copySize.depthOrArrayLayers},
Yunchao Hee5b99032021-06-09 16:01:08 +0000431 dstSpec.copyLevel, dstDimension);
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000432 wgpu::BufferDescriptor outputBufferDescriptor;
433 outputBufferDescriptor.size = dstDataCopyLayout.byteLength;
434 outputBufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
Yancf0e4fc2022-01-06 09:01:58 +0000435 wgpu::Buffer outputBuffer = this->device.CreateBuffer(&outputBufferDescriptor);
Yunchao He13176362021-06-23 17:12:53 +0000436 const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(format);
437 const uint32_t expectedDstDataOffset = dstSpec.copyOrigin.x * bytesPerTexel +
438 dstSpec.copyOrigin.y * dstDataCopyLayout.bytesPerRow;
Corentin Wallez80915842021-03-04 18:13:45 +0000439 wgpu::ImageCopyBuffer outputImageCopyBuffer = utils::CreateImageCopyBuffer(
Yunchao He13176362021-06-23 17:12:53 +0000440 outputBuffer, expectedDstDataOffset, dstDataCopyLayout.bytesPerRow,
441 dstDataCopyLayout.rowsPerImage);
Corentin Wallez80915842021-03-04 18:13:45 +0000442 encoder.CopyTextureToBuffer(&dstImageCopyTexture, &outputImageCopyBuffer, &copySize);
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000443
Corentin Wallezcab352c2019-10-28 13:27:36 +0000444 wgpu::CommandBuffer commands = encoder.Finish();
Yancf0e4fc2022-01-06 09:01:58 +0000445 this->queue.Submit(1, &commands);
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000446
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000447 // Validate if the data in outputBuffer is what we expected, including the untouched data
448 // outside of the copy.
449 {
Austin Enge2f083e2021-05-11 01:26:13 +0000450 // Validate the output buffer slice-by-slice regardless of whether the destination
451 // texture is 3D or 2D. The dimension here doesn't matter - we're only populating the
452 // CPU data to verify against.
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000453 uint32_t copyLayer = copySize.depthOrArrayLayers;
454 uint32_t copyDepth = 1;
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000455
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000456 const uint64_t validDataSizePerDstTextureLayer = utils::RequiredBytesInCopy(
457 dstDataCopyLayout.bytesPerRow, dstDataCopyLayout.mipSize.height,
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000458 dstDataCopyLayout.mipSize.width, dstDataCopyLayout.mipSize.height, copyDepth,
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000459 bytesPerTexel);
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000460
Yunchao He13176362021-06-23 17:12:53 +0000461 // expectedDstDataPerSlice stores one layer of the destination texture.
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000462 std::vector<uint8_t> expectedDstDataPerSlice(validDataSizePerDstTextureLayer);
Yunchao He1fb3f1d2021-04-07 03:08:00 +0000463 for (uint32_t slice = 0; slice < copyLayer; ++slice) {
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000464 // For each source texture array slice involved in the copy, emulate the T2T copy
465 // on the CPU side by "copying" the copy data from the "source texture"
466 // (srcTextureCopyData) to the "destination texture" (expectedDstDataPerSlice).
467 std::fill(expectedDstDataPerSlice.begin(), expectedDstDataPerSlice.end(), 0);
468
469 const uint32_t srcBytesOffset = srcDataCopyLayout.bytesPerImage * slice;
470
471 // Get the offset of the srcTextureCopyData that contains the copy data on the
472 // slice-th texture array layer of the source texture.
473 const uint32_t srcTexelDataOffset =
474 srcBytesOffset + (srcSpec.copyOrigin.x * bytesPerTexel +
475 srcSpec.copyOrigin.y * srcDataCopyLayout.bytesPerRow);
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000476 // Do the T2T "copy" on the CPU side to get the expected texel value at the
Yunchao He9df00a32021-06-07 17:32:43 +0000477 CopyTextureData(bytesPerTexel, &srcTextureCopyData[srcTexelDataOffset],
478 copySize.width, copySize.height, copyDepth,
479 srcDataCopyLayout.bytesPerRow, srcDataCopyLayout.rowsPerImage,
480 &expectedDstDataPerSlice[expectedDstDataOffset],
481 dstDataCopyLayout.bytesPerRow, dstDataCopyLayout.rowsPerImage);
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000482
483 // Compare the content of the destination texture at the (dstSpec.copyOrigin.z +
484 // slice)-th layer to its expected data after the copy (the outputBuffer contains
485 // the data of the destination texture since the dstSpec.copyOrigin.z-th layer).
486 uint64_t outputBufferExpectationBytesOffset =
487 dstDataCopyLayout.bytesPerImage * slice;
488 EXPECT_BUFFER_U32_RANGE_EQ(
489 reinterpret_cast<const uint32_t*>(expectedDstDataPerSlice.data()), outputBuffer,
490 outputBufferExpectationBytesOffset,
491 validDataSizePerDstTextureLayer / sizeof(uint32_t));
492 }
Brandon Jonesd3d3aa02019-03-26 11:06:23 +0000493 }
494 }
495};
496
Yancf0e4fc2022-01-06 09:01:58 +0000497class CopyTests_T2T : public CopyTests_T2TBase<DawnTestWithParams<CopyTestsParams>> {
498 protected:
499 void DoTest(const TextureSpec& srcSpec,
500 const TextureSpec& dstSpec,
501 const wgpu::Extent3D& copySize,
502 bool copyWithinSameTexture = false,
503 wgpu::TextureDimension dimension = wgpu::TextureDimension::e2D) {
504 DoTest(srcSpec, dstSpec, copySize, dimension, dimension, copyWithinSameTexture);
505 }
506
507 void DoTest(const TextureSpec& srcSpec,
508 const TextureSpec& dstSpec,
509 const wgpu::Extent3D& copySize,
510 wgpu::TextureDimension srcDimension,
511 wgpu::TextureDimension dstDimension,
512 bool copyWithinSameTexture = false) {
513 const bool usageCopySrc = GetParam().mUsageCopySrc;
514 // If we do this test with a CopyWithinSameTexture, it will need to have usageCopySrc in the
515 // public usage of the texture as it will later use a CopyTextureToBuffer, that needs the
516 // public usage of it.
517 DAWN_TEST_UNSUPPORTED_IF(!usageCopySrc && copyWithinSameTexture);
518
519 ASSERT_EQ(srcSpec.format, dstSpec.format);
520
521 CopyTests_T2TBase<DawnTestWithParams<CopyTestsParams>>::DoTest(
522 srcSpec, dstSpec, copySize, srcDimension, dstDimension, copyWithinSameTexture,
523 usageCopySrc);
524 }
525};
526
527class CopyTests_Formats : public CopyTests_T2TBase<DawnTestWithParams<SrcColorFormatParams>> {
528 protected:
529 // Texture format is compatible and could be copied to each other if the only diff is srgb-ness.
530 wgpu::TextureFormat GetCopyCompatibleFormat(wgpu::TextureFormat format) {
531 switch (format) {
532 case wgpu::TextureFormat::RGBA8Unorm:
533 return wgpu::TextureFormat::RGBA8UnormSrgb;
534 case wgpu::TextureFormat::RGBA8UnormSrgb:
535 return wgpu::TextureFormat::RGBA8Unorm;
536 case wgpu::TextureFormat::BGRA8Unorm:
537 return wgpu::TextureFormat::BGRA8UnormSrgb;
538 case wgpu::TextureFormat::BGRA8UnormSrgb:
539 return wgpu::TextureFormat::BGRA8Unorm;
540 default:
541 UNREACHABLE();
542 }
543 }
544
545 void DoTest(TextureSpec srcSpec,
546 TextureSpec dstSpec,
547 const wgpu::Extent3D& copySize,
548 wgpu::TextureDimension srcDimension = wgpu::TextureDimension::e2D,
549 wgpu::TextureDimension dstDimension = wgpu::TextureDimension::e2D) {
550 srcSpec.format = GetParam().mSrcColorFormat;
551 dstSpec.format = GetCopyCompatibleFormat(srcSpec.format);
552
553 CopyTests_T2TBase<DawnTestWithParams<SrcColorFormatParams>>::DoTest(
554 srcSpec, dstSpec, copySize, srcDimension, dstDimension);
555 }
556};
557
Corentin Wallez90ad1a32020-06-11 11:23:35 +0000558class CopyTests_B2B : public DawnTest {
559 protected:
560 // This is the same signature as CopyBufferToBuffer except that the buffers are replaced by
561 // only their size.
562 void DoTest(uint64_t sourceSize,
563 uint64_t sourceOffset,
564 uint64_t destinationSize,
565 uint64_t destinationOffset,
566 uint64_t copySize) {
567 ASSERT(sourceSize % 4 == 0);
568 ASSERT(destinationSize % 4 == 0);
569
570 // Create our two test buffers, destination filled with zeros, source filled with non-zeroes
571 std::vector<uint32_t> zeroes(static_cast<size_t>(destinationSize / sizeof(uint32_t)));
572 wgpu::Buffer destination =
573 utils::CreateBufferFromData(device, zeroes.data(), zeroes.size() * sizeof(uint32_t),
574 wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc);
575
576 std::vector<uint32_t> sourceData(static_cast<size_t>(sourceSize / sizeof(uint32_t)));
577 for (size_t i = 0; i < sourceData.size(); i++) {
578 sourceData[i] = i + 1;
579 }
580 wgpu::Buffer source = utils::CreateBufferFromData(device, sourceData.data(),
581 sourceData.size() * sizeof(uint32_t),
582 wgpu::BufferUsage::CopySrc);
583
584 // Submit the copy
585 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
586 encoder.CopyBufferToBuffer(source, sourceOffset, destination, destinationOffset, copySize);
587 wgpu::CommandBuffer commands = encoder.Finish();
588 queue.Submit(1, &commands);
589
590 // Check destination is exactly the expected content.
591 EXPECT_BUFFER_U32_RANGE_EQ(zeroes.data(), destination, 0,
592 destinationOffset / sizeof(uint32_t));
593 EXPECT_BUFFER_U32_RANGE_EQ(sourceData.data() + sourceOffset / sizeof(uint32_t), destination,
594 destinationOffset, copySize / sizeof(uint32_t));
595 uint64_t copyEnd = destinationOffset + copySize;
596 EXPECT_BUFFER_U32_RANGE_EQ(zeroes.data(), destination, copyEnd,
597 (destinationSize - copyEnd) / sizeof(uint32_t));
598 }
599};
600
Brandon Jonesd3105bf2021-12-02 21:43:49 +0000601class ClearBufferTests : public DawnTest {
602 protected:
603 // This is the same signature as ClearBuffer except that the buffers are replaced by
604 // only their size.
605 void DoTest(uint64_t bufferSize, uint64_t clearOffset, uint64_t clearSize) {
606 ASSERT(bufferSize % 4 == 0);
607 ASSERT(clearSize % 4 == 0);
608
609 // Create our test buffer, filled with non-zeroes
610 std::vector<uint32_t> bufferData(static_cast<size_t>(bufferSize / sizeof(uint32_t)));
611 for (size_t i = 0; i < bufferData.size(); i++) {
612 bufferData[i] = i + 1;
613 }
614 wgpu::Buffer buffer = utils::CreateBufferFromData(
615 device, bufferData.data(), bufferData.size() * sizeof(uint32_t),
616 wgpu::BufferUsage::CopyDst | wgpu::BufferUsage::CopySrc);
617
618 std::vector<uint8_t> fillData(static_cast<size_t>(clearSize), 0u);
619
620 // Submit the fill
621 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
622 encoder.ClearBuffer(buffer, clearOffset, clearSize);
623 wgpu::CommandBuffer commands = encoder.Finish();
624 queue.Submit(1, &commands);
625
626 // Check destination is exactly the expected content.
627 EXPECT_BUFFER_U32_RANGE_EQ(bufferData.data(), buffer, 0, clearOffset / sizeof(uint32_t));
628 EXPECT_BUFFER_U8_RANGE_EQ(fillData.data(), buffer, clearOffset, clearSize);
629 uint64_t clearEnd = clearOffset + clearSize;
630 EXPECT_BUFFER_U32_RANGE_EQ(bufferData.data() + clearEnd / sizeof(uint32_t), buffer,
631 clearEnd, (bufferSize - clearEnd) / sizeof(uint32_t));
632 }
633};
634
Austin Engb343e8d2017-07-17 09:38:30 -0400635// Test that copying an entire texture with 256-byte aligned dimensions works
636TEST_P(CopyTests_T2B, FullTextureAligned) {
637 constexpr uint32_t kWidth = 256;
638 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000639
640 TextureSpec textureSpec;
641 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000642
643 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400644}
645
Yan, Shaobo75e5ed62020-09-23 10:28:26 +0000646// Test noop copies
647TEST_P(CopyTests_T2B, ZeroSizedCopy) {
648 constexpr uint32_t kWidth = 256;
649 constexpr uint32_t kHeight = 128;
650
651 TextureSpec textureSpec;
652 textureSpec.textureSize = {kWidth, kHeight, 1};
Yan, Shaobo75e5ed62020-09-23 10:28:26 +0000653
654 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {0, kHeight, 1});
655 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, 0, 1});
656 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, kHeight, 0});
657}
658
Austin Engb343e8d2017-07-17 09:38:30 -0400659// Test that copying an entire texture without 256-byte aligned dimensions works
660TEST_P(CopyTests_T2B, FullTextureUnaligned) {
661 constexpr uint32_t kWidth = 259;
662 constexpr uint32_t kHeight = 127;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000663
664 TextureSpec textureSpec;
665 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000666
667 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400668}
669
670// Test that reading pixels from a 256-byte aligned texture works
671TEST_P(CopyTests_T2B, PixelReadAligned) {
672 constexpr uint32_t kWidth = 256;
673 constexpr uint32_t kHeight = 128;
674 BufferSpec pixelBuffer = MinimumBufferSpec(1, 1);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000675
676 constexpr wgpu::Extent3D kCopySize = {1, 1, 1};
677 constexpr wgpu::Extent3D kTextureSize = {kWidth, kHeight, 1};
678 TextureSpec defaultTextureSpec;
679 defaultTextureSpec.textureSize = kTextureSize;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000680
681 {
682 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000683 DoTest(textureSpec, pixelBuffer, kCopySize);
684 }
685
686 {
687 TextureSpec textureSpec = defaultTextureSpec;
688 textureSpec.copyOrigin = {kWidth - 1, 0, 0};
689 DoTest(textureSpec, pixelBuffer, kCopySize);
690 }
691
692 {
693 TextureSpec textureSpec = defaultTextureSpec;
694 textureSpec.copyOrigin = {0, kHeight - 1, 0};
695 DoTest(textureSpec, pixelBuffer, kCopySize);
696 }
697
698 {
699 TextureSpec textureSpec = defaultTextureSpec;
700 textureSpec.copyOrigin = {kWidth - 1, kHeight - 1, 0};
701 DoTest(textureSpec, pixelBuffer, kCopySize);
702 }
703
704 {
705 TextureSpec textureSpec = defaultTextureSpec;
706 textureSpec.copyOrigin = {kWidth / 3, kHeight / 7, 0};
707 DoTest(textureSpec, pixelBuffer, kCopySize);
708 }
709
710 {
711 TextureSpec textureSpec = defaultTextureSpec;
712 textureSpec.copyOrigin = {kWidth / 7, kHeight / 3, 0};
713 DoTest(textureSpec, pixelBuffer, kCopySize);
714 }
Austin Engb343e8d2017-07-17 09:38:30 -0400715}
716
717// Test that copying pixels from a texture that is not 256-byte aligned works
718TEST_P(CopyTests_T2B, PixelReadUnaligned) {
719 constexpr uint32_t kWidth = 259;
720 constexpr uint32_t kHeight = 127;
721 BufferSpec pixelBuffer = MinimumBufferSpec(1, 1);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000722
723 constexpr wgpu::Extent3D kCopySize = {1, 1, 1};
724 constexpr wgpu::Extent3D kTextureSize = {kWidth, kHeight, 1};
725 TextureSpec defaultTextureSpec;
726 defaultTextureSpec.textureSize = kTextureSize;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000727
728 {
729 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000730 DoTest(textureSpec, pixelBuffer, kCopySize);
731 }
732
733 {
734 TextureSpec textureSpec = defaultTextureSpec;
735 textureSpec.copyOrigin = {kWidth - 1, 0, 0};
736 DoTest(textureSpec, pixelBuffer, kCopySize);
737 }
738
739 {
740 TextureSpec textureSpec = defaultTextureSpec;
741 textureSpec.copyOrigin = {0, kHeight - 1, 0};
742 DoTest(textureSpec, pixelBuffer, kCopySize);
743 }
744
745 {
746 TextureSpec textureSpec = defaultTextureSpec;
747 textureSpec.copyOrigin = {kWidth - 1, kHeight - 1, 0};
748 DoTest(textureSpec, pixelBuffer, kCopySize);
749 }
750
751 {
752 TextureSpec textureSpec = defaultTextureSpec;
753 textureSpec.copyOrigin = {kWidth / 3, kHeight / 7, 0};
754 DoTest(textureSpec, pixelBuffer, kCopySize);
755 }
756
757 {
758 TextureSpec textureSpec = defaultTextureSpec;
759 textureSpec.copyOrigin = {kWidth / 7, kHeight / 3, 0};
760 DoTest(textureSpec, pixelBuffer, kCopySize);
761 }
Austin Engb343e8d2017-07-17 09:38:30 -0400762}
763
764// Test that copying regions with 256-byte aligned sizes works
765TEST_P(CopyTests_T2B, TextureRegionAligned) {
766 constexpr uint32_t kWidth = 256;
767 constexpr uint32_t kHeight = 128;
768 for (unsigned int w : {64, 128, 256}) {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000769 for (unsigned int h : {16, 32, 48}) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000770 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000771 textureSpec.textureSize = {kWidth, kHeight, 1};
772 DoTest(textureSpec, MinimumBufferSpec(w, h), {w, h, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400773 }
774 }
775}
776
777// Test that copying regions without 256-byte aligned sizes works
778TEST_P(CopyTests_T2B, TextureRegionUnaligned) {
779 constexpr uint32_t kWidth = 256;
780 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000781
782 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000783 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
784
Austin Engb343e8d2017-07-17 09:38:30 -0400785 for (unsigned int w : {13, 63, 65}) {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +0000786 for (unsigned int h : {17, 19, 63}) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000787 TextureSpec textureSpec = defaultTextureSpec;
788 DoTest(textureSpec, MinimumBufferSpec(w, h), {w, h, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400789 }
790 }
791}
792
793// Test that copying mips with 256-byte aligned sizes works
794TEST_P(CopyTests_T2B, TextureMipAligned) {
795 constexpr uint32_t kWidth = 256;
796 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000797
798 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000799 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
800
Austin Engb343e8d2017-07-17 09:38:30 -0400801 for (unsigned int i = 1; i < 4; ++i) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000802 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000803 textureSpec.copyLevel = i;
804 textureSpec.levelCount = i + 1;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000805 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i),
806 {kWidth >> i, kHeight >> i, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400807 }
808}
809
Yunchao He4043ee92021-04-30 17:51:58 +0000810// Test that copying mips when one dimension is 256-byte aligned and another dimension reach one
811// works
812TEST_P(CopyTests_T2B, TextureMipDimensionReachOne) {
813 constexpr uint32_t mipLevelCount = 4;
814 constexpr uint32_t kWidth = 256 << mipLevelCount;
815 constexpr uint32_t kHeight = 2;
816
817 TextureSpec defaultTextureSpec;
818 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
819
820 TextureSpec textureSpec = defaultTextureSpec;
821 textureSpec.levelCount = mipLevelCount;
822
823 for (unsigned int i = 0; i < 4; ++i) {
824 textureSpec.copyLevel = i;
825 DoTest(textureSpec,
826 MinimumBufferSpec(std::max(kWidth >> i, 1u), std::max(kHeight >> i, 1u)),
827 {std::max(kWidth >> i, 1u), std::max(kHeight >> i, 1u), 1});
828 }
829}
830
Austin Engb343e8d2017-07-17 09:38:30 -0400831// Test that copying mips without 256-byte aligned sizes works
832TEST_P(CopyTests_T2B, TextureMipUnaligned) {
833 constexpr uint32_t kWidth = 259;
834 constexpr uint32_t kHeight = 127;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000835
836 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000837 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
838
Austin Engb343e8d2017-07-17 09:38:30 -0400839 for (unsigned int i = 1; i < 4; ++i) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000840 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000841 textureSpec.copyLevel = i;
842 textureSpec.levelCount = i + 1;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000843 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i),
844 {kWidth >> i, kHeight >> i, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400845 }
846}
847
848// Test that copying with a 512-byte aligned buffer offset works
849TEST_P(CopyTests_T2B, OffsetBufferAligned) {
850 constexpr uint32_t kWidth = 256;
851 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000852
853 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000854 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000855
Austin Engb343e8d2017-07-17 09:38:30 -0400856 for (unsigned int i = 0; i < 3; ++i) {
857 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
Austin Engcf52d712019-04-05 20:51:29 +0000858 uint64_t offset = 512 * i;
Austin Engb343e8d2017-07-17 09:38:30 -0400859 bufferSpec.size += offset;
860 bufferSpec.offset += offset;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000861 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400862 }
863}
864
865// Test that copying without a 512-byte aligned buffer offset works
866TEST_P(CopyTests_T2B, OffsetBufferUnaligned) {
Austin Engb343e8d2017-07-17 09:38:30 -0400867 constexpr uint32_t kWidth = 128;
868 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000869
870 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000871 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000872
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000873 const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(textureSpec.format);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000874 for (uint32_t i = bytesPerTexel; i < 512; i += bytesPerTexel * 9) {
Austin Engb343e8d2017-07-17 09:38:30 -0400875 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
876 bufferSpec.size += i;
877 bufferSpec.offset += i;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000878 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400879 }
880}
881
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +0000882// Test that copying without a 512-byte aligned buffer offset that is greater than the bytes per row
883// works
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000884TEST_P(CopyTests_T2B, OffsetBufferUnalignedSmallBytesPerRow) {
Austin Engb343e8d2017-07-17 09:38:30 -0400885 constexpr uint32_t kWidth = 32;
886 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000887
888 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000889 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000890
Jiawei Shao60d6d0a2021-03-01 01:23:30 +0000891 const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(textureSpec.format);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000892 for (uint32_t i = 256 + bytesPerTexel; i < 512; i += bytesPerTexel * 9) {
Austin Engb343e8d2017-07-17 09:38:30 -0400893 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
894 bufferSpec.size += i;
895 bufferSpec.offset += i;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000896 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400897 }
898}
899
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +0000900// Test that copying with a greater bytes per row than needed on a 256-byte aligned texture works
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000901TEST_P(CopyTests_T2B, BytesPerRowAligned) {
Austin Engb343e8d2017-07-17 09:38:30 -0400902 constexpr uint32_t kWidth = 256;
903 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000904
905 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000906 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000907
Austin Engb343e8d2017-07-17 09:38:30 -0400908 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
909 for (unsigned int i = 1; i < 4; ++i) {
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +0000910 bufferSpec.bytesPerRow += 256;
Austin Engb343e8d2017-07-17 09:38:30 -0400911 bufferSpec.size += 256 * kHeight;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000912 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400913 }
914}
915
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +0000916// Test that copying with a greater bytes per row than needed on a texture that is not 256-byte
917// aligned works
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000918TEST_P(CopyTests_T2B, BytesPerRowUnaligned) {
Austin Engb343e8d2017-07-17 09:38:30 -0400919 constexpr uint32_t kWidth = 259;
920 constexpr uint32_t kHeight = 127;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000921
922 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000923 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000924
Austin Engb343e8d2017-07-17 09:38:30 -0400925 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
926 for (unsigned int i = 1; i < 4; ++i) {
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +0000927 bufferSpec.bytesPerRow += 256;
Austin Engb343e8d2017-07-17 09:38:30 -0400928 bufferSpec.size += 256 * kHeight;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +0000929 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -0400930 }
931}
932
Tomek Ponitka7ce49242020-08-05 16:43:24 +0000933// Test that copying with bytesPerRow = 0 and bytesPerRow < bytesInACompleteRow works
934// when we're copying one row only
935TEST_P(CopyTests_T2B, BytesPerRowWithOneRowCopy) {
936 constexpr uint32_t kWidth = 259;
937 constexpr uint32_t kHeight = 127;
938
939 TextureSpec textureSpec;
Tomek Ponitka7ce49242020-08-05 16:43:24 +0000940 textureSpec.textureSize = {kWidth, kHeight, 1};
Tomek Ponitka7ce49242020-08-05 16:43:24 +0000941
Tomek Ponitka7ce49242020-08-05 16:43:24 +0000942 {
943 BufferSpec bufferSpec = MinimumBufferSpec(5, 1);
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000944
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000945 // bytesPerRow undefined
Kai Ninomiyacf820d72020-12-16 07:53:30 +0000946 bufferSpec.bytesPerRow = wgpu::kCopyStrideUndefined;
Tomek Ponitka7ce49242020-08-05 16:43:24 +0000947 DoTest(textureSpec, bufferSpec, {5, 1, 1});
948 }
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000949}
950
951TEST_P(CopyTests_T2B, StrideSpecialCases) {
952 TextureSpec textureSpec;
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000953 textureSpec.textureSize = {4, 4, 4};
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000954
955 // bytesPerRow 0
956 for (const wgpu::Extent3D copyExtent :
957 {wgpu::Extent3D{0, 2, 2}, {0, 0, 2}, {0, 2, 0}, {0, 0, 0}}) {
958 DoTest(textureSpec, MinimumBufferSpec(copyExtent, 0, 2), copyExtent);
959 }
960
961 // bytesPerRow undefined
962 for (const wgpu::Extent3D copyExtent :
963 {wgpu::Extent3D{2, 1, 1}, {2, 0, 1}, {2, 1, 0}, {2, 0, 0}}) {
Kai Ninomiyacf820d72020-12-16 07:53:30 +0000964 DoTest(textureSpec, MinimumBufferSpec(copyExtent, wgpu::kCopyStrideUndefined, 2),
965 copyExtent);
Kai Ninomiya16036cf2020-11-06 13:41:50 +0000966 }
967
968 // rowsPerImage 0
969 for (const wgpu::Extent3D copyExtent :
970 {wgpu::Extent3D{2, 0, 2}, {2, 0, 0}, {0, 0, 2}, {0, 0, 0}}) {
971 DoTest(textureSpec, MinimumBufferSpec(copyExtent, 256, 0), copyExtent);
972 }
973
974 // rowsPerImage undefined
975 for (const wgpu::Extent3D copyExtent : {wgpu::Extent3D{2, 2, 1}, {2, 2, 0}}) {
Kai Ninomiyacf820d72020-12-16 07:53:30 +0000976 DoTest(textureSpec, MinimumBufferSpec(copyExtent, 256, wgpu::kCopyStrideUndefined),
977 copyExtent);
Tomek Ponitka7ce49242020-08-05 16:43:24 +0000978 }
979}
980
Yunchao He9680c9f2021-06-03 18:19:06 +0000981// Test copying a single slice with rowsPerImage larger than copy height and rowsPerImage will not
982// take effect. If rowsPerImage takes effect, it looks like the copy may go past the end of the
983// buffer.
984TEST_P(CopyTests_T2B, RowsPerImageShouldNotCauseBufferOOBIfDepthOrArrayLayersIsOne) {
985 // Check various offsets to cover each code path in the 2D split code in TextureCopySplitter.
986 for (uint32_t offset : {0, 4, 64}) {
987 constexpr uint32_t kWidth = 250;
988 constexpr uint32_t kHeight = 3;
989
990 TextureSpec textureSpec;
991 textureSpec.textureSize = {kWidth, kHeight, 1};
992
993 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
994 bufferSpec.rowsPerImage = 2 * kHeight;
995 bufferSpec.offset = offset;
996 bufferSpec.size += offset;
997 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
998 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1}, wgpu::TextureDimension::e3D);
999 }
1000}
1001
1002// Test copying a single row with bytesPerRow larger than copy width and bytesPerRow will not
1003// take effect. If bytesPerRow takes effect, it looks like the copy may go past the end of the
1004// buffer.
1005TEST_P(CopyTests_T2B, BytesPerRowShouldNotCauseBufferOOBIfCopyHeightIsOne) {
1006 // Check various offsets to cover each code path in the 2D split code in TextureCopySplitter.
1007 for (uint32_t offset : {0, 4, 100}) {
1008 constexpr uint32_t kWidth = 250;
1009
1010 TextureSpec textureSpec;
1011 textureSpec.textureSize = {kWidth, 1, 1};
1012
1013 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, 1);
1014 bufferSpec.bytesPerRow = 1280; // the default bytesPerRow is 1024.
1015 bufferSpec.offset = offset;
1016 bufferSpec.size += offset;
1017 DoTest(textureSpec, bufferSpec, {kWidth, 1, 1});
1018 DoTest(textureSpec, bufferSpec, {kWidth, 1, 1}, wgpu::TextureDimension::e3D);
1019 }
1020}
1021
Yunchao He13176362021-06-23 17:12:53 +00001022// A regression test for a bug on D3D12 backend that causes crash when doing texture-to-texture
1023// copy one row with the texture format Depth32Float.
1024TEST_P(CopyTests_T2B, CopyOneRowWithDepth32Float) {
1025 // TODO(crbug.com/dawn/727): currently this test fails on many D3D12 drivers.
1026 DAWN_SUPPRESS_TEST_IF(IsD3D12());
1027
1028 constexpr wgpu::TextureFormat kFormat = wgpu::TextureFormat::Depth32Float;
1029 constexpr uint32_t kPixelsPerRow = 4u;
1030
1031 wgpu::TextureDescriptor textureDescriptor;
1032 textureDescriptor.format = kFormat;
1033 textureDescriptor.size = {kPixelsPerRow, 1, 1};
1034 textureDescriptor.usage = wgpu::TextureUsage::CopySrc | wgpu::TextureUsage::RenderAttachment;
1035 wgpu::Texture texture = device.CreateTexture(&textureDescriptor);
1036
1037 wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
1038
1039 // Initialize the depth texture with 0.5f.
1040 constexpr float kClearDepthValue = 0.5f;
1041 utils::ComboRenderPassDescriptor renderPass({}, texture.CreateView());
1042 renderPass.cDepthStencilAttachmentInfo.clearDepth = kClearDepthValue;
1043 renderPass.cDepthStencilAttachmentInfo.depthLoadOp = wgpu::LoadOp::Clear;
1044 renderPass.cDepthStencilAttachmentInfo.depthStoreOp = wgpu::StoreOp::Store;
1045 wgpu::RenderPassEncoder renderPassEncoder = encoder.BeginRenderPass(&renderPass);
1046 renderPassEncoder.EndPass();
1047
1048 constexpr uint32_t kBufferCopyOffset = kTextureBytesPerRowAlignment;
1049 const uint32_t kBufferSize =
1050 kBufferCopyOffset + utils::GetTexelBlockSizeInBytes(kFormat) * kPixelsPerRow;
1051 wgpu::BufferDescriptor bufferDescriptor;
1052 bufferDescriptor.size = kBufferSize;
1053 bufferDescriptor.usage = wgpu::BufferUsage::CopySrc | wgpu::BufferUsage::CopyDst;
1054 wgpu::Buffer buffer = device.CreateBuffer(&bufferDescriptor);
1055
1056 wgpu::ImageCopyBuffer imageCopyBuffer =
1057 utils::CreateImageCopyBuffer(buffer, kBufferCopyOffset, kTextureBytesPerRowAlignment);
1058 wgpu::ImageCopyTexture imageCopyTexture = utils::CreateImageCopyTexture(texture, 0, {0, 0, 0});
1059
1060 wgpu::Extent3D copySize = textureDescriptor.size;
1061 encoder.CopyTextureToBuffer(&imageCopyTexture, &imageCopyBuffer, &copySize);
1062 wgpu::CommandBuffer commandBuffer = encoder.Finish();
1063 queue.Submit(1, &commandBuffer);
1064
1065 std::array<float, kPixelsPerRow> expectedValues;
1066 std::fill(expectedValues.begin(), expectedValues.end(), kClearDepthValue);
1067 EXPECT_BUFFER_FLOAT_RANGE_EQ(expectedValues.data(), buffer, kBufferCopyOffset, kPixelsPerRow);
1068}
1069
Jiawei Shao92379bf2020-06-21 09:33:44 +00001070// Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001071TEST_P(CopyTests_T2B, Texture2DArrayFull) {
Jiawei Shao4b74dbe2018-08-30 16:27:38 +08001072 constexpr uint32_t kWidth = 256;
1073 constexpr uint32_t kHeight = 128;
1074 constexpr uint32_t kLayers = 6u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001075
1076 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001077 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001078
1079 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kLayers), {kWidth, kHeight, kLayers});
1080}
1081
Jiawei Shao92379bf2020-06-21 09:33:44 +00001082// Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001083TEST_P(CopyTests_T2B, Texture2DArraySubRegion) {
1084 constexpr uint32_t kWidth = 256;
1085 constexpr uint32_t kHeight = 128;
1086 constexpr uint32_t kLayers = 6u;
1087 constexpr uint32_t kBaseLayer = 2u;
1088 constexpr uint32_t kCopyLayers = 3u;
1089
1090 TextureSpec textureSpec;
1091 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1092 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001093
1094 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyLayers),
1095 {kWidth, kHeight, kCopyLayers});
Jiawei Shao4b74dbe2018-08-30 16:27:38 +08001096}
1097
1098// Test that copying texture 2D array mips with 256-byte aligned sizes works
1099TEST_P(CopyTests_T2B, Texture2DArrayMip) {
Jiawei Shao4b74dbe2018-08-30 16:27:38 +08001100 constexpr uint32_t kWidth = 256;
1101 constexpr uint32_t kHeight = 128;
1102 constexpr uint32_t kLayers = 6u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001103
1104 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001105 defaultTextureSpec.textureSize = {kWidth, kHeight, kLayers};
1106
Jiawei Shao4b74dbe2018-08-30 16:27:38 +08001107 for (unsigned int i = 1; i < 4; ++i) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001108 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00001109 textureSpec.copyLevel = i;
1110 textureSpec.levelCount = i + 1;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001111
1112 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i, kLayers),
1113 {kWidth >> i, kHeight >> i, kLayers});
Jiawei Shao4b74dbe2018-08-30 16:27:38 +08001114 }
1115}
1116
Jiawei Shao92379bf2020-06-21 09:33:44 +00001117// Test that copying from a range of texture 2D array layers in one texture-to-buffer-copy when
1118// RowsPerImage is not equal to the height of the texture works.
1119TEST_P(CopyTests_T2B, Texture2DArrayRegionNonzeroRowsPerImage) {
Jiawei Shao92379bf2020-06-21 09:33:44 +00001120 constexpr uint32_t kWidth = 256;
1121 constexpr uint32_t kHeight = 128;
1122 constexpr uint32_t kLayers = 6u;
1123 constexpr uint32_t kBaseLayer = 2u;
1124 constexpr uint32_t kCopyLayers = 3u;
1125
1126 constexpr uint32_t kRowsPerImage = kHeight * 2;
1127
1128 TextureSpec textureSpec;
1129 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1130 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao92379bf2020-06-21 09:33:44 +00001131
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001132 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kRowsPerImage, kCopyLayers);
Jiawei Shao92379bf2020-06-21 09:33:44 +00001133 bufferSpec.rowsPerImage = kRowsPerImage;
1134 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kCopyLayers});
1135}
1136
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001137// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is not a
1138// multiple of 512.
1139TEST_P(CopyTests_T2B, Texture2DArrayRegionWithOffsetOddRowsPerImage) {
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001140 constexpr uint32_t kWidth = 64;
1141 constexpr uint32_t kHeight = 128;
1142 constexpr uint32_t kLayers = 8u;
1143 constexpr uint32_t kBaseLayer = 2u;
1144 constexpr uint32_t kCopyLayers = 5u;
1145
1146 constexpr uint32_t kRowsPerImage = kHeight + 1;
1147
1148 TextureSpec textureSpec;
1149 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1150 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001151
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001152 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kRowsPerImage, kCopyLayers);
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001153 bufferSpec.offset += 128u;
1154 bufferSpec.size += 128u;
1155 bufferSpec.rowsPerImage = kRowsPerImage;
1156 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kCopyLayers});
1157}
1158
1159// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is a multiple
1160// of 512.
1161TEST_P(CopyTests_T2B, Texture2DArrayRegionWithOffsetEvenRowsPerImage) {
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001162 constexpr uint32_t kWidth = 64;
1163 constexpr uint32_t kHeight = 128;
1164 constexpr uint32_t kLayers = 8u;
1165 constexpr uint32_t kBaseLayer = 2u;
1166 constexpr uint32_t kCopyLayers = 4u;
1167
1168 constexpr uint32_t kRowsPerImage = kHeight + 2;
1169
1170 TextureSpec textureSpec;
1171 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1172 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001173
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001174 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kRowsPerImage, kCopyLayers);
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001175 bufferSpec.offset += 128u;
1176 bufferSpec.size += 128u;
1177 bufferSpec.rowsPerImage = kRowsPerImage;
1178 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kCopyLayers});
1179}
1180
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001181// Test that copying whole 3D texture in one texture-to-buffer-copy works.
1182TEST_P(CopyTests_T2B, Texture3DFull) {
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001183 constexpr uint32_t kWidth = 256;
1184 constexpr uint32_t kHeight = 128;
Yunchao Heb2527e62021-05-19 20:34:36 +00001185 constexpr uint32_t kDepth = 6;
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001186
1187 TextureSpec textureSpec;
1188 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1189
1190 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kDepth), {kWidth, kHeight, kDepth},
1191 wgpu::TextureDimension::e3D);
1192}
1193
Yunchao Heef6a4822021-04-27 20:22:17 +00001194// Test that copying a range of texture 3D depths in one texture-to-buffer-copy works.
1195TEST_P(CopyTests_T2B, Texture3DSubRegion) {
Jiawei Shao4589de62021-05-21 02:26:58 +00001196 DAWN_TEST_UNSUPPORTED_IF(IsANGLE()); // TODO(crbug.com/angleproject/5967)
Austin Engfd783ce2021-05-18 21:51:33 +00001197
Yunchao Heef6a4822021-04-27 20:22:17 +00001198 constexpr uint32_t kWidth = 256;
1199 constexpr uint32_t kHeight = 128;
Yunchao Heb2527e62021-05-19 20:34:36 +00001200 constexpr uint32_t kDepth = 6;
Yunchao Heef6a4822021-04-27 20:22:17 +00001201 constexpr uint32_t kBaseDepth = 2u;
1202 constexpr uint32_t kCopyDepth = 3u;
1203
1204 TextureSpec textureSpec;
1205 textureSpec.copyOrigin = {0, 0, kBaseDepth};
1206 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1207
1208 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth),
Yunchao He9df00a32021-06-07 17:32:43 +00001209 {kWidth / 2, kHeight / 2, kCopyDepth}, wgpu::TextureDimension::e3D);
Yunchao Heef6a4822021-04-27 20:22:17 +00001210}
1211
Yunchao Heb2527e62021-05-19 20:34:36 +00001212TEST_P(CopyTests_T2B, Texture3DNoSplitRowDataWithEmptyFirstRow) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001213 constexpr uint32_t kWidth = 2;
1214 constexpr uint32_t kHeight = 4;
1215 constexpr uint32_t kDepth = 3;
1216
1217 TextureSpec textureSpec;
1218 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1219 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1220
1221 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1222 // Base: no split for a row + no empty first row
1223 bufferSpec.offset = 60;
1224 bufferSpec.size += bufferSpec.offset;
1225 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1226
1227 // This test will cover: no split for a row + empty first row
1228 bufferSpec.offset = 260;
1229 bufferSpec.size += bufferSpec.offset;
1230 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1231}
1232
1233TEST_P(CopyTests_T2B, Texture3DSplitRowDataWithoutEmptyFirstRow) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001234 constexpr uint32_t kWidth = 259;
1235 constexpr uint32_t kHeight = 127;
1236 constexpr uint32_t kDepth = 3;
1237
1238 TextureSpec textureSpec;
1239 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1240 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1241
1242 // The test below is designed to test TextureCopySplitter for 3D textures on D3D12.
1243 // This test will cover: split for a row + no empty first row for both split regions
1244 bufferSpec.offset = 260;
1245 bufferSpec.size += bufferSpec.offset;
1246 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1247}
1248
1249TEST_P(CopyTests_T2B, Texture3DSplitRowDataWithEmptyFirstRow) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001250 constexpr uint32_t kWidth = 39;
1251 constexpr uint32_t kHeight = 4;
1252 constexpr uint32_t kDepth = 3;
1253
1254 TextureSpec textureSpec;
1255 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1256 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1257
1258 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1259 // This test will cover: split for a row + empty first row for the head block
1260 bufferSpec.offset = 400;
1261 bufferSpec.size += bufferSpec.offset;
1262 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1263
1264 // This test will cover: split for a row + empty first row for the tail block
1265 bufferSpec.offset = 160;
1266 bufferSpec.size += bufferSpec.offset;
1267 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1268}
1269
1270TEST_P(CopyTests_T2B, Texture3DCopyHeightIsOneCopyWidthIsTiny) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001271 constexpr uint32_t kWidth = 2;
1272 constexpr uint32_t kHeight = 1;
1273 constexpr uint32_t kDepth = 3;
1274
1275 TextureSpec textureSpec;
1276 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1277 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1278
1279 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1280 // Base: no split for a row, no empty row, and copy height is 1
1281 bufferSpec.offset = 60;
1282 bufferSpec.size += bufferSpec.offset;
1283 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1284
1285 // This test will cover: no split for a row + empty first row, and copy height is 1
1286 bufferSpec.offset = 260;
1287 bufferSpec.size += bufferSpec.offset;
1288 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1289}
1290
1291TEST_P(CopyTests_T2B, Texture3DCopyHeightIsOneCopyWidthIsSmall) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001292 constexpr uint32_t kWidth = 39;
1293 constexpr uint32_t kHeight = 1;
1294 constexpr uint32_t kDepth = 3;
1295
1296 TextureSpec textureSpec;
1297 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1298 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1299
1300 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1301 // This test will cover: split for a row + empty first row for the head block, and copy height
1302 // is 1
1303 bufferSpec.offset = 400;
1304 bufferSpec.size += bufferSpec.offset;
1305 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1306
1307 // This test will cover: split for a row + empty first row for the tail block, and copy height
1308 // is 1
1309 bufferSpec.offset = 160;
1310 bufferSpec.size += bufferSpec.offset;
1311 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1312}
1313
Yunchao Hee5b99032021-06-09 16:01:08 +00001314// Test that copying texture 3D array mips with 256-byte aligned sizes works
1315TEST_P(CopyTests_T2B, Texture3DMipAligned) {
1316 constexpr uint32_t kWidth = 256;
1317 constexpr uint32_t kHeight = 128;
1318 constexpr uint32_t kDepth = 64u;
1319
1320 TextureSpec defaultTextureSpec;
1321 defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
1322
1323 for (unsigned int i = 1; i < 6; ++i) {
1324 TextureSpec textureSpec = defaultTextureSpec;
1325 textureSpec.copyLevel = i;
1326 textureSpec.levelCount = i + 1;
1327
1328 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i, kDepth >> i),
1329 {kWidth >> i, kHeight >> i, kDepth >> i}, wgpu::TextureDimension::e3D);
1330 }
1331}
1332
1333// Test that copying texture 3D array mips with 256-byte unaligned sizes works
1334TEST_P(CopyTests_T2B, Texture3DMipUnaligned) {
1335 constexpr uint32_t kWidth = 261;
1336 constexpr uint32_t kHeight = 123;
1337 constexpr uint32_t kDepth = 69u;
1338
1339 TextureSpec defaultTextureSpec;
1340 defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
1341
1342 for (unsigned int i = 1; i < 6; ++i) {
1343 TextureSpec textureSpec = defaultTextureSpec;
1344 textureSpec.copyLevel = i;
1345 textureSpec.levelCount = i + 1;
1346
1347 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i, kDepth >> i),
1348 {kWidth >> i, kHeight >> i, kDepth >> i}, wgpu::TextureDimension::e3D);
1349 }
1350}
1351
Kai Ninomiya2afea0c2020-07-10 20:33:08 +00001352DAWN_INSTANTIATE_TEST(CopyTests_T2B,
1353 D3D12Backend(),
1354 MetalBackend(),
1355 OpenGLBackend(),
Stephen Whitec053b902021-01-19 18:34:22 +00001356 OpenGLESBackend(),
Kai Ninomiya2afea0c2020-07-10 20:33:08 +00001357 VulkanBackend());
Austin Engb343e8d2017-07-17 09:38:30 -04001358
1359// Test that copying an entire texture with 256-byte aligned dimensions works
1360TEST_P(CopyTests_B2T, FullTextureAligned) {
1361 constexpr uint32_t kWidth = 256;
1362 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001363
1364 TextureSpec textureSpec;
1365 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001366
1367 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001368}
1369
Yan, Shaobo75e5ed62020-09-23 10:28:26 +00001370// Test noop copies.
1371TEST_P(CopyTests_B2T, ZeroSizedCopy) {
1372 constexpr uint32_t kWidth = 256;
1373 constexpr uint32_t kHeight = 128;
1374
1375 TextureSpec textureSpec;
1376 textureSpec.textureSize = {kWidth, kHeight, 1};
Yan, Shaobo75e5ed62020-09-23 10:28:26 +00001377
1378 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {0, kHeight, 1});
1379 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, 0, 1});
1380 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, kHeight, 0});
1381}
1382
Austin Engb343e8d2017-07-17 09:38:30 -04001383// Test that copying an entire texture without 256-byte aligned dimensions works
1384TEST_P(CopyTests_B2T, FullTextureUnaligned) {
1385 constexpr uint32_t kWidth = 259;
1386 constexpr uint32_t kHeight = 127;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001387
1388 TextureSpec textureSpec;
1389 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001390
1391 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight), {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001392}
1393
1394// Test that reading pixels from a 256-byte aligned texture works
1395TEST_P(CopyTests_B2T, PixelReadAligned) {
1396 constexpr uint32_t kWidth = 256;
1397 constexpr uint32_t kHeight = 128;
1398 BufferSpec pixelBuffer = MinimumBufferSpec(1, 1);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001399
1400 constexpr wgpu::Extent3D kCopySize = {1, 1, 1};
1401 constexpr wgpu::Extent3D kTextureSize = {kWidth, kHeight, 1};
1402 TextureSpec defaultTextureSpec;
1403 defaultTextureSpec.textureSize = kTextureSize;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001404
1405 {
1406 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001407 DoTest(textureSpec, pixelBuffer, kCopySize);
1408 }
1409
1410 {
1411 TextureSpec textureSpec = defaultTextureSpec;
1412 textureSpec.copyOrigin = {kWidth - 1, 0, 0};
1413 DoTest(textureSpec, pixelBuffer, kCopySize);
1414 }
1415
1416 {
1417 TextureSpec textureSpec = defaultTextureSpec;
1418 textureSpec.copyOrigin = {0, kHeight - 1, 0};
1419 DoTest(textureSpec, pixelBuffer, kCopySize);
1420 }
1421
1422 {
1423 TextureSpec textureSpec = defaultTextureSpec;
1424 textureSpec.copyOrigin = {kWidth - 1, kHeight - 1, 0};
1425 DoTest(textureSpec, pixelBuffer, kCopySize);
1426 }
1427
1428 {
1429 TextureSpec textureSpec = defaultTextureSpec;
1430 textureSpec.copyOrigin = {kWidth / 3, kHeight / 7, 0};
1431 DoTest(textureSpec, pixelBuffer, kCopySize);
1432 }
1433
1434 {
1435 TextureSpec textureSpec = defaultTextureSpec;
1436 textureSpec.copyOrigin = {kWidth / 7, kHeight / 3, 0};
1437 DoTest(textureSpec, pixelBuffer, kCopySize);
1438 }
Austin Engb343e8d2017-07-17 09:38:30 -04001439}
1440
1441// Test that copying pixels from a texture that is not 256-byte aligned works
1442TEST_P(CopyTests_B2T, PixelReadUnaligned) {
1443 constexpr uint32_t kWidth = 259;
1444 constexpr uint32_t kHeight = 127;
1445 BufferSpec pixelBuffer = MinimumBufferSpec(1, 1);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001446
1447 constexpr wgpu::Extent3D kCopySize = {1, 1, 1};
1448 constexpr wgpu::Extent3D kTextureSize = {kWidth, kHeight, 1};
1449 TextureSpec defaultTextureSpec;
1450 defaultTextureSpec.textureSize = kTextureSize;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001451
1452 {
1453 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001454 DoTest(textureSpec, pixelBuffer, kCopySize);
1455 }
1456
1457 {
1458 TextureSpec textureSpec = defaultTextureSpec;
1459 textureSpec.copyOrigin = {kWidth - 1, 0, 0};
1460 DoTest(textureSpec, pixelBuffer, kCopySize);
1461 }
1462
1463 {
1464 TextureSpec textureSpec = defaultTextureSpec;
1465 textureSpec.copyOrigin = {0, kHeight - 1, 0};
1466 DoTest(textureSpec, pixelBuffer, kCopySize);
1467 }
1468
1469 {
1470 TextureSpec textureSpec = defaultTextureSpec;
1471 textureSpec.copyOrigin = {kWidth - 1, kHeight - 1, 0};
1472 DoTest(textureSpec, pixelBuffer, kCopySize);
1473 }
1474
1475 {
1476 TextureSpec textureSpec = defaultTextureSpec;
1477 textureSpec.copyOrigin = {kWidth / 3, kHeight / 7, 0};
1478 DoTest(textureSpec, pixelBuffer, kCopySize);
1479 }
1480
1481 {
1482 TextureSpec textureSpec = defaultTextureSpec;
1483 textureSpec.copyOrigin = {kWidth / 7, kHeight / 3, 0};
1484 DoTest(textureSpec, pixelBuffer, kCopySize);
1485 }
Austin Engb343e8d2017-07-17 09:38:30 -04001486}
1487
1488// Test that copying regions with 256-byte aligned sizes works
1489TEST_P(CopyTests_B2T, TextureRegionAligned) {
1490 constexpr uint32_t kWidth = 256;
1491 constexpr uint32_t kHeight = 128;
1492 for (unsigned int w : {64, 128, 256}) {
Kai Ninomiya2afea0c2020-07-10 20:33:08 +00001493 for (unsigned int h : {16, 32, 48}) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001494 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001495 textureSpec.textureSize = {kWidth, kHeight, 1};
1496 DoTest(textureSpec, MinimumBufferSpec(w, h), {w, h, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001497 }
1498 }
1499}
1500
1501// Test that copying regions without 256-byte aligned sizes works
1502TEST_P(CopyTests_B2T, TextureRegionUnaligned) {
1503 constexpr uint32_t kWidth = 256;
1504 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001505
1506 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001507 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
1508
Austin Engb343e8d2017-07-17 09:38:30 -04001509 for (unsigned int w : {13, 63, 65}) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001510 for (unsigned int h : {17, 19, 63}) {
1511 TextureSpec textureSpec = defaultTextureSpec;
1512 DoTest(textureSpec, MinimumBufferSpec(w, h), {w, h, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001513 }
1514 }
1515}
1516
1517// Test that copying mips with 256-byte aligned sizes works
1518TEST_P(CopyTests_B2T, TextureMipAligned) {
1519 constexpr uint32_t kWidth = 256;
1520 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001521
1522 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001523 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
1524
Austin Engb343e8d2017-07-17 09:38:30 -04001525 for (unsigned int i = 1; i < 4; ++i) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001526 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00001527 textureSpec.copyLevel = i;
1528 textureSpec.levelCount = i + 1;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001529 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i),
1530 {kWidth >> i, kHeight >> i, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001531 }
1532}
1533
1534// Test that copying mips without 256-byte aligned sizes works
1535TEST_P(CopyTests_B2T, TextureMipUnaligned) {
1536 constexpr uint32_t kWidth = 259;
1537 constexpr uint32_t kHeight = 127;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001538
1539 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001540 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
1541
Austin Engb343e8d2017-07-17 09:38:30 -04001542 for (unsigned int i = 1; i < 4; ++i) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001543 TextureSpec textureSpec = defaultTextureSpec;
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00001544 textureSpec.copyLevel = i;
1545 textureSpec.levelCount = i + 1;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001546 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i),
1547 {kWidth >> i, kHeight >> i, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001548 }
1549}
1550
1551// Test that copying with a 512-byte aligned buffer offset works
1552TEST_P(CopyTests_B2T, OffsetBufferAligned) {
1553 constexpr uint32_t kWidth = 256;
1554 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001555
1556 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001557 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001558
Austin Engb343e8d2017-07-17 09:38:30 -04001559 for (unsigned int i = 0; i < 3; ++i) {
1560 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
Austin Engcf52d712019-04-05 20:51:29 +00001561 uint64_t offset = 512 * i;
Austin Engb343e8d2017-07-17 09:38:30 -04001562 bufferSpec.size += offset;
1563 bufferSpec.offset += offset;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001564 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001565 }
1566}
1567
1568// Test that copying without a 512-byte aligned buffer offset works
1569TEST_P(CopyTests_B2T, OffsetBufferUnaligned) {
Austin Engb343e8d2017-07-17 09:38:30 -04001570 constexpr uint32_t kWidth = 256;
1571 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001572
1573 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001574 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001575
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00001576 const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(textureSpec.format);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001577 for (uint32_t i = bytesPerTexel; i < 512; i += bytesPerTexel * 9) {
Austin Engb343e8d2017-07-17 09:38:30 -04001578 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
1579 bufferSpec.size += i;
1580 bufferSpec.offset += i;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001581 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001582 }
1583}
1584
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +00001585// Test that copying without a 512-byte aligned buffer offset that is greater than the bytes per row
1586// works
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001587TEST_P(CopyTests_B2T, OffsetBufferUnalignedSmallBytesPerRow) {
Austin Engb343e8d2017-07-17 09:38:30 -04001588 constexpr uint32_t kWidth = 32;
1589 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001590
1591 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001592 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001593
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00001594 const uint32_t bytesPerTexel = utils::GetTexelBlockSizeInBytes(textureSpec.format);
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001595 for (uint32_t i = 256 + bytesPerTexel; i < 512; i += bytesPerTexel * 9) {
Austin Engb343e8d2017-07-17 09:38:30 -04001596 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
1597 bufferSpec.size += i;
1598 bufferSpec.offset += i;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001599 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001600 }
1601}
1602
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +00001603// Test that copying with a greater bytes per row than needed on a 256-byte aligned texture works
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001604TEST_P(CopyTests_B2T, BytesPerRowAligned) {
Austin Engb343e8d2017-07-17 09:38:30 -04001605 constexpr uint32_t kWidth = 256;
1606 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001607
1608 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001609 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001610
Austin Engb343e8d2017-07-17 09:38:30 -04001611 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
1612 for (unsigned int i = 1; i < 4; ++i) {
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +00001613 bufferSpec.bytesPerRow += 256;
Austin Engb343e8d2017-07-17 09:38:30 -04001614 bufferSpec.size += 256 * kHeight;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001615 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001616 }
1617}
1618
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +00001619// Test that copying with a greater bytes per row than needed on a texture that is not 256-byte
1620// aligned works
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001621TEST_P(CopyTests_B2T, BytesPerRowUnaligned) {
Austin Engb343e8d2017-07-17 09:38:30 -04001622 constexpr uint32_t kWidth = 259;
1623 constexpr uint32_t kHeight = 127;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001624
1625 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001626 textureSpec.textureSize = {kWidth, kHeight, 1};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001627
Austin Engb343e8d2017-07-17 09:38:30 -04001628 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight);
1629 for (unsigned int i = 1; i < 4; ++i) {
Corentin Wallezcdf2d8d2020-04-24 10:02:43 +00001630 bufferSpec.bytesPerRow += 256;
Austin Engb343e8d2017-07-17 09:38:30 -04001631 bufferSpec.size += 256 * kHeight;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001632 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, 1});
Austin Engb343e8d2017-07-17 09:38:30 -04001633 }
1634}
1635
Tomek Ponitka7ce49242020-08-05 16:43:24 +00001636// Test that copying with bytesPerRow = 0 and bytesPerRow < bytesInACompleteRow works
1637// when we're copying one row only
1638TEST_P(CopyTests_B2T, BytesPerRowWithOneRowCopy) {
1639 constexpr uint32_t kWidth = 259;
1640 constexpr uint32_t kHeight = 127;
1641
1642 TextureSpec textureSpec;
Tomek Ponitka7ce49242020-08-05 16:43:24 +00001643 textureSpec.textureSize = {kWidth, kHeight, 1};
Tomek Ponitka7ce49242020-08-05 16:43:24 +00001644
Tomek Ponitka7ce49242020-08-05 16:43:24 +00001645 {
1646 BufferSpec bufferSpec = MinimumBufferSpec(5, 1);
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001647
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001648 // bytesPerRow undefined
Kai Ninomiyacf820d72020-12-16 07:53:30 +00001649 bufferSpec.bytesPerRow = wgpu::kCopyStrideUndefined;
Tomek Ponitka7ce49242020-08-05 16:43:24 +00001650 DoTest(textureSpec, bufferSpec, {5, 1, 1});
1651 }
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001652}
1653
1654TEST_P(CopyTests_B2T, StrideSpecialCases) {
1655 TextureSpec textureSpec;
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001656 textureSpec.textureSize = {4, 4, 4};
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001657
1658 // bytesPerRow 0
1659 for (const wgpu::Extent3D copyExtent :
1660 {wgpu::Extent3D{0, 2, 2}, {0, 0, 2}, {0, 2, 0}, {0, 0, 0}}) {
1661 DoTest(textureSpec, MinimumBufferSpec(copyExtent, 0, 2), copyExtent);
1662 }
1663
1664 // bytesPerRow undefined
1665 for (const wgpu::Extent3D copyExtent :
1666 {wgpu::Extent3D{2, 1, 1}, {2, 0, 1}, {2, 1, 0}, {2, 0, 0}}) {
Kai Ninomiyacf820d72020-12-16 07:53:30 +00001667 DoTest(textureSpec, MinimumBufferSpec(copyExtent, wgpu::kCopyStrideUndefined, 2),
1668 copyExtent);
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001669 }
1670
1671 // rowsPerImage 0
1672 for (const wgpu::Extent3D copyExtent :
1673 {wgpu::Extent3D{2, 0, 2}, {2, 0, 0}, {0, 0, 2}, {0, 0, 0}}) {
1674 DoTest(textureSpec, MinimumBufferSpec(copyExtent, 256, 0), copyExtent);
1675 }
1676
1677 // rowsPerImage undefined
1678 for (const wgpu::Extent3D copyExtent : {wgpu::Extent3D{2, 2, 1}, {2, 2, 0}}) {
Kai Ninomiyacf820d72020-12-16 07:53:30 +00001679 DoTest(textureSpec, MinimumBufferSpec(copyExtent, 256, wgpu::kCopyStrideUndefined),
1680 copyExtent);
Tomek Ponitka7ce49242020-08-05 16:43:24 +00001681 }
1682}
1683
Jiawei Shao92379bf2020-06-21 09:33:44 +00001684// Test that copying whole texture 2D array layers in one texture-to-buffer-copy works.
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001685TEST_P(CopyTests_B2T, Texture2DArrayFull) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001686 constexpr uint32_t kWidth = 256;
1687 constexpr uint32_t kHeight = 128;
1688 constexpr uint32_t kLayers = 6u;
1689
1690 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001691 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001692
1693 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kLayers), {kWidth, kHeight, kLayers});
1694}
1695
Jiawei Shao92379bf2020-06-21 09:33:44 +00001696// Test that copying a range of texture 2D array layers in one texture-to-buffer-copy works.
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001697TEST_P(CopyTests_B2T, Texture2DArraySubRegion) {
1698 constexpr uint32_t kWidth = 256;
1699 constexpr uint32_t kHeight = 128;
1700 constexpr uint32_t kLayers = 6u;
1701 constexpr uint32_t kBaseLayer = 2u;
1702 constexpr uint32_t kCopyLayers = 3u;
1703
1704 TextureSpec textureSpec;
1705 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1706 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001707
1708 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyLayers),
1709 {kWidth, kHeight, kCopyLayers});
1710}
1711
Jiawei Shao92379bf2020-06-21 09:33:44 +00001712// Test that copying into a range of texture 2D array layers in one texture-to-buffer-copy when
1713// RowsPerImage is not equal to the height of the texture works.
1714TEST_P(CopyTests_B2T, Texture2DArrayRegionNonzeroRowsPerImage) {
Jiawei Shao92379bf2020-06-21 09:33:44 +00001715 constexpr uint32_t kWidth = 256;
1716 constexpr uint32_t kHeight = 128;
1717 constexpr uint32_t kLayers = 6u;
1718 constexpr uint32_t kBaseLayer = 2u;
1719 constexpr uint32_t kCopyLayers = 3u;
1720
1721 constexpr uint32_t kRowsPerImage = kHeight * 2;
1722
1723 TextureSpec textureSpec;
1724 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1725 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao92379bf2020-06-21 09:33:44 +00001726
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001727 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kRowsPerImage, kCopyLayers);
Jiawei Shao92379bf2020-06-21 09:33:44 +00001728 bufferSpec.rowsPerImage = kRowsPerImage;
1729 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kCopyLayers});
1730}
1731
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001732// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is not a
1733// multiple of 512.
1734TEST_P(CopyTests_B2T, Texture2DArrayRegionWithOffsetOddRowsPerImage) {
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001735 constexpr uint32_t kWidth = 64;
1736 constexpr uint32_t kHeight = 128;
1737 constexpr uint32_t kLayers = 8u;
1738 constexpr uint32_t kBaseLayer = 2u;
1739 constexpr uint32_t kCopyLayers = 5u;
1740
1741 constexpr uint32_t kRowsPerImage = kHeight + 1;
1742
1743 TextureSpec textureSpec;
1744 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1745 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001746
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001747 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kRowsPerImage, kCopyLayers);
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001748 bufferSpec.offset += 128u;
1749 bufferSpec.size += 128u;
1750 bufferSpec.rowsPerImage = kRowsPerImage;
1751 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kCopyLayers});
1752}
1753
1754// Test a special code path in the D3D12 backends when (BytesPerRow * RowsPerImage) is a multiple
1755// of 512.
1756TEST_P(CopyTests_B2T, Texture2DArrayRegionWithOffsetEvenRowsPerImage) {
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001757 constexpr uint32_t kWidth = 64;
1758 constexpr uint32_t kHeight = 128;
1759 constexpr uint32_t kLayers = 8u;
1760 constexpr uint32_t kBaseLayer = 2u;
1761 constexpr uint32_t kCopyLayers = 5u;
1762
1763 constexpr uint32_t kRowsPerImage = kHeight + 2;
1764
1765 TextureSpec textureSpec;
1766 textureSpec.copyOrigin = {0, 0, kBaseLayer};
1767 textureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001768
Kai Ninomiya16036cf2020-11-06 13:41:50 +00001769 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kRowsPerImage, kCopyLayers);
Jiawei Shao3b17f0b2020-07-15 08:33:39 +00001770 bufferSpec.offset += 128u;
1771 bufferSpec.size += 128u;
1772 bufferSpec.rowsPerImage = kRowsPerImage;
1773 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kCopyLayers});
1774}
1775
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001776// Test that copying whole texture 3D in one buffer-to-texture-copy works.
1777TEST_P(CopyTests_B2T, Texture3DFull) {
Yunchao He3e8f3f92021-04-01 22:40:43 +00001778 constexpr uint32_t kWidth = 256;
1779 constexpr uint32_t kHeight = 128;
Yunchao Heb2527e62021-05-19 20:34:36 +00001780 constexpr uint32_t kDepth = 6;
Yunchao He3e8f3f92021-04-01 22:40:43 +00001781
1782 TextureSpec textureSpec;
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001783 textureSpec.textureSize = {kWidth, kHeight, kDepth};
Yunchao He3e8f3f92021-04-01 22:40:43 +00001784
Yunchao He1fb3f1d2021-04-07 03:08:00 +00001785 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kDepth), {kWidth, kHeight, kDepth},
Yunchao He3e8f3f92021-04-01 22:40:43 +00001786 wgpu::TextureDimension::e3D);
1787}
1788
Yunchao Heef6a4822021-04-27 20:22:17 +00001789// Test that copying a range of texture 3D Depths in one texture-to-buffer-copy works.
1790TEST_P(CopyTests_B2T, Texture3DSubRegion) {
Jiawei Shao4589de62021-05-21 02:26:58 +00001791 DAWN_TEST_UNSUPPORTED_IF(IsANGLE()); // TODO(crbug.com/angleproject/5967)
Austin Engfd783ce2021-05-18 21:51:33 +00001792
Yunchao Heef6a4822021-04-27 20:22:17 +00001793 constexpr uint32_t kWidth = 256;
1794 constexpr uint32_t kHeight = 128;
Yunchao Heb2527e62021-05-19 20:34:36 +00001795 constexpr uint32_t kDepth = 6;
Yunchao Heef6a4822021-04-27 20:22:17 +00001796 constexpr uint32_t kBaseDepth = 2u;
1797 constexpr uint32_t kCopyDepth = 3u;
1798
1799 TextureSpec textureSpec;
1800 textureSpec.copyOrigin = {0, 0, kBaseDepth};
1801 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1802
1803 DoTest(textureSpec, MinimumBufferSpec(kWidth, kHeight, kCopyDepth),
Yunchao He9df00a32021-06-07 17:32:43 +00001804 {kWidth / 2, kHeight / 2, kCopyDepth}, wgpu::TextureDimension::e3D);
Yunchao Heef6a4822021-04-27 20:22:17 +00001805}
1806
Yunchao Heb2527e62021-05-19 20:34:36 +00001807TEST_P(CopyTests_B2T, Texture3DNoSplitRowDataWithEmptyFirstRow) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001808 constexpr uint32_t kWidth = 2;
1809 constexpr uint32_t kHeight = 4;
1810 constexpr uint32_t kDepth = 3;
1811
1812 TextureSpec textureSpec;
1813 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1814 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1815
1816 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1817 // Base: no split for a row + no empty first row
1818 bufferSpec.offset = 60;
1819 bufferSpec.size += bufferSpec.offset;
1820 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1821
1822 // This test will cover: no split for a row + empty first row
1823 bufferSpec.offset = 260;
1824 bufferSpec.size += bufferSpec.offset;
1825 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1826}
1827
1828TEST_P(CopyTests_B2T, Texture3DSplitRowDataWithoutEmptyFirstRow) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001829 constexpr uint32_t kWidth = 259;
1830 constexpr uint32_t kHeight = 127;
1831 constexpr uint32_t kDepth = 3;
1832
1833 TextureSpec textureSpec;
1834 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1835 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1836
1837 // The test below is designed to test TextureCopySplitter for 3D textures on D3D12.
1838 // This test will cover: split for a row + no empty first row for both split regions
1839 bufferSpec.offset = 260;
1840 bufferSpec.size += bufferSpec.offset;
1841 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1842}
1843
1844TEST_P(CopyTests_B2T, Texture3DSplitRowDataWithEmptyFirstRow) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001845 constexpr uint32_t kWidth = 39;
1846 constexpr uint32_t kHeight = 4;
1847 constexpr uint32_t kDepth = 3;
1848
1849 TextureSpec textureSpec;
1850 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1851 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1852
1853 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1854 // This test will cover: split for a row + empty first row for the head block
1855 bufferSpec.offset = 400;
1856 bufferSpec.size += bufferSpec.offset;
1857 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1858
1859 // This test will cover: split for a row + empty first row for the tail block
1860 bufferSpec.offset = 160;
1861 bufferSpec.size += bufferSpec.offset;
1862 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1863}
1864
1865TEST_P(CopyTests_B2T, Texture3DCopyHeightIsOneCopyWidthIsTiny) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001866 constexpr uint32_t kWidth = 2;
1867 constexpr uint32_t kHeight = 1;
1868 constexpr uint32_t kDepth = 3;
1869
1870 TextureSpec textureSpec;
1871 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1872 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1873
1874 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1875 // Base: no split for a row, no empty row, and copy height is 1
1876 bufferSpec.offset = 60;
1877 bufferSpec.size += bufferSpec.offset;
1878 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1879
1880 // This test will cover: no split for a row + empty first row, and copy height is 1
1881 bufferSpec.offset = 260;
1882 bufferSpec.size += bufferSpec.offset;
1883 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1884}
1885
1886TEST_P(CopyTests_B2T, Texture3DCopyHeightIsOneCopyWidthIsSmall) {
Yunchao Heb2527e62021-05-19 20:34:36 +00001887 constexpr uint32_t kWidth = 39;
1888 constexpr uint32_t kHeight = 1;
1889 constexpr uint32_t kDepth = 3;
1890
1891 TextureSpec textureSpec;
1892 textureSpec.textureSize = {kWidth, kHeight, kDepth};
1893 BufferSpec bufferSpec = MinimumBufferSpec(kWidth, kHeight, kDepth);
1894
1895 // The tests below are designed to test TextureCopySplitter for 3D textures on D3D12.
1896 // This test will cover: split for a row + empty first row for the head block, and copy height
1897 // is 1
1898 bufferSpec.offset = 400;
1899 bufferSpec.size += bufferSpec.offset;
1900 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1901
1902 // This test will cover: split for a row + empty first row for the tail block, and copy height
1903 // is 1
1904 bufferSpec.offset = 160;
1905 bufferSpec.size += bufferSpec.offset;
1906 DoTest(textureSpec, bufferSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D);
1907}
1908
Yunchao Hee5b99032021-06-09 16:01:08 +00001909// Test that copying texture 3D array mips with 256-byte aligned sizes works
1910TEST_P(CopyTests_B2T, Texture3DMipAligned) {
1911 constexpr uint32_t kWidth = 256;
1912 constexpr uint32_t kHeight = 128;
1913 constexpr uint32_t kDepth = 64u;
1914
1915 TextureSpec defaultTextureSpec;
1916 defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
1917
1918 for (unsigned int i = 1; i < 6; ++i) {
1919 TextureSpec textureSpec = defaultTextureSpec;
1920 textureSpec.copyLevel = i;
1921 textureSpec.levelCount = i + 1;
1922
1923 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i, kDepth >> i),
1924 {kWidth >> i, kHeight >> i, kDepth >> i}, wgpu::TextureDimension::e3D);
1925 }
1926}
1927
1928// Test that copying texture 3D array mips with 256-byte unaligned sizes works
1929TEST_P(CopyTests_B2T, Texture3DMipUnaligned) {
1930 constexpr uint32_t kWidth = 261;
1931 constexpr uint32_t kHeight = 123;
1932 constexpr uint32_t kDepth = 69u;
1933
1934 TextureSpec defaultTextureSpec;
1935 defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
1936
1937 for (unsigned int i = 1; i < 6; ++i) {
1938 TextureSpec textureSpec = defaultTextureSpec;
1939 textureSpec.copyLevel = i;
1940 textureSpec.levelCount = i + 1;
1941
1942 DoTest(textureSpec, MinimumBufferSpec(kWidth >> i, kHeight >> i, kDepth >> i),
1943 {kWidth >> i, kHeight >> i, kDepth >> i}, wgpu::TextureDimension::e3D);
1944 }
1945}
1946
Kai Ninomiya2afea0c2020-07-10 20:33:08 +00001947DAWN_INSTANTIATE_TEST(CopyTests_B2T,
1948 D3D12Backend(),
1949 MetalBackend(),
1950 OpenGLBackend(),
Stephen Whitec053b902021-01-19 18:34:22 +00001951 OpenGLESBackend(),
Kai Ninomiya2afea0c2020-07-10 20:33:08 +00001952 VulkanBackend());
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00001953
1954TEST_P(CopyTests_T2T, Texture) {
1955 constexpr uint32_t kWidth = 256;
1956 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001957
1958 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001959 textureSpec.textureSize = {kWidth, kHeight, 1};
1960 DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00001961}
1962
Yan, Shaobo75e5ed62020-09-23 10:28:26 +00001963// Test noop copies.
1964TEST_P(CopyTests_T2T, ZeroSizedCopy) {
1965 constexpr uint32_t kWidth = 256;
1966 constexpr uint32_t kHeight = 128;
1967
1968 TextureSpec textureSpec;
Yan, Shaobo75e5ed62020-09-23 10:28:26 +00001969 textureSpec.textureSize = {kWidth, kHeight, 1};
1970 DoTest(textureSpec, textureSpec, {0, kHeight, 1});
1971 DoTest(textureSpec, textureSpec, {kWidth, 0, 1});
1972 DoTest(textureSpec, textureSpec, {kWidth, kHeight, 0});
1973}
1974
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00001975TEST_P(CopyTests_T2T, TextureRegion) {
1976 constexpr uint32_t kWidth = 256;
1977 constexpr uint32_t kHeight = 128;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001978
1979 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001980 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
1981
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00001982 for (unsigned int w : {64, 128, 256}) {
1983 for (unsigned int h : {16, 32, 48}) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00001984 TextureSpec textureSpec = defaultTextureSpec;
1985 DoTest(textureSpec, textureSpec, {w, h, 1});
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00001986 }
1987 }
1988}
1989
Yunchao He13176362021-06-23 17:12:53 +00001990TEST_P(CopyTests_T2T, TextureMip) {
1991 constexpr uint32_t kWidth = 256;
1992 constexpr uint32_t kHeight = 128;
1993
1994 TextureSpec defaultTextureSpec;
1995 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
1996
1997 for (unsigned int i = 1; i < 4; ++i) {
1998 TextureSpec textureSpec = defaultTextureSpec;
1999 textureSpec.copyLevel = i;
2000 textureSpec.levelCount = i + 1;
2001
2002 DoTest(textureSpec, textureSpec, {kWidth >> i, kHeight >> i, 1});
2003 }
2004}
2005
2006TEST_P(CopyTests_T2T, SingleMipSrcMultipleMipDst) {
2007 constexpr uint32_t kWidth = 256;
2008 constexpr uint32_t kHeight = 128;
2009
2010 TextureSpec defaultTextureSpec;
2011
2012 for (unsigned int i = 1; i < 4; ++i) {
2013 TextureSpec srcTextureSpec = defaultTextureSpec;
2014 srcTextureSpec.textureSize = {kWidth >> i, kHeight >> i, 1};
2015
2016 TextureSpec dstTextureSpec = defaultTextureSpec;
2017 dstTextureSpec.textureSize = {kWidth, kHeight, 1};
2018 dstTextureSpec.copyLevel = i;
2019 dstTextureSpec.levelCount = i + 1;
2020
2021 DoTest(srcTextureSpec, dstTextureSpec, {kWidth >> i, kHeight >> i, 1});
2022 }
2023}
2024
2025TEST_P(CopyTests_T2T, MultipleMipSrcSingleMipDst) {
2026 constexpr uint32_t kWidth = 256;
2027 constexpr uint32_t kHeight = 128;
2028
2029 TextureSpec defaultTextureSpec;
2030
2031 for (unsigned int i = 1; i < 4; ++i) {
2032 TextureSpec srcTextureSpec = defaultTextureSpec;
2033 srcTextureSpec.textureSize = {kWidth, kHeight, 1};
2034 srcTextureSpec.copyLevel = i;
2035 srcTextureSpec.levelCount = i + 1;
2036
2037 TextureSpec dstTextureSpec = defaultTextureSpec;
2038 dstTextureSpec.textureSize = {kWidth >> i, kHeight >> i, 1};
2039
2040 DoTest(srcTextureSpec, dstTextureSpec, {kWidth >> i, kHeight >> i, 1});
2041 }
2042}
2043
2044// Test that copying from one mip level to another mip level within the same 2D texture works.
2045TEST_P(CopyTests_T2T, Texture2DSameTextureDifferentMipLevels) {
2046 constexpr uint32_t kWidth = 256;
2047 constexpr uint32_t kHeight = 128;
2048
2049 TextureSpec defaultTextureSpec;
2050 defaultTextureSpec.textureSize = {kWidth, kHeight, 1};
2051 defaultTextureSpec.levelCount = 6;
2052
2053 for (unsigned int i = 1; i < 6; ++i) {
2054 TextureSpec srcSpec = defaultTextureSpec;
2055 srcSpec.copyLevel = i - 1;
2056 TextureSpec dstSpec = defaultTextureSpec;
2057 dstSpec.copyLevel = i;
2058
2059 DoTest(srcSpec, dstSpec, {kWidth >> i, kHeight >> i, 1}, true);
2060 }
2061}
2062
Jiawei Shaoa3636ed2020-05-28 01:01:32 +00002063// Test copying the whole 2D array texture.
Yunchao He1fb3f1d2021-04-07 03:08:00 +00002064TEST_P(CopyTests_T2T, Texture2DArrayFull) {
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00002065 constexpr uint32_t kWidth = 256;
2066 constexpr uint32_t kHeight = 128;
2067 constexpr uint32_t kLayers = 6u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002068
2069 TextureSpec textureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002070 textureSpec.textureSize = {kWidth, kHeight, kLayers};
2071
2072 DoTest(textureSpec, textureSpec, {kWidth, kHeight, kLayers});
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00002073}
2074
Jiawei Shaoa3636ed2020-05-28 01:01:32 +00002075// Test copying a subresource region of the 2D array texture.
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00002076TEST_P(CopyTests_T2T, Texture2DArrayRegion) {
2077 constexpr uint32_t kWidth = 256;
2078 constexpr uint32_t kHeight = 128;
2079 constexpr uint32_t kLayers = 6u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002080
2081 TextureSpec defaultTextureSpec;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002082 defaultTextureSpec.textureSize = {kWidth, kHeight, kLayers};
2083
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00002084 for (unsigned int w : {64, 128, 256}) {
2085 for (unsigned int h : {16, 32, 48}) {
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002086 TextureSpec textureSpec = defaultTextureSpec;
2087 DoTest(textureSpec, textureSpec, {w, h, kLayers});
Brandon Jonesd3d3aa02019-03-26 11:06:23 +00002088 }
2089 }
2090}
2091
Jiawei Shaoa3636ed2020-05-28 01:01:32 +00002092// Test copying one slice of a 2D array texture.
2093TEST_P(CopyTests_T2T, Texture2DArrayCopyOneSlice) {
2094 constexpr uint32_t kWidth = 256;
2095 constexpr uint32_t kHeight = 128;
2096 constexpr uint32_t kLayers = 6u;
2097 constexpr uint32_t kSrcBaseLayer = 1u;
2098 constexpr uint32_t kDstBaseLayer = 3u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002099 constexpr uint32_t kCopyArrayLayerCount = 1u;
2100
2101 TextureSpec defaultTextureSpec;
2102 defaultTextureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002103
2104 TextureSpec srcTextureSpec = defaultTextureSpec;
2105 srcTextureSpec.copyOrigin = {0, 0, kSrcBaseLayer};
2106
2107 TextureSpec dstTextureSpec = defaultTextureSpec;
2108 dstTextureSpec.copyOrigin = {0, 0, kDstBaseLayer};
2109
2110 DoTest(srcTextureSpec, dstTextureSpec, {kWidth, kHeight, kCopyArrayLayerCount});
Jiawei Shaoa3636ed2020-05-28 01:01:32 +00002111}
2112
2113// Test copying multiple contiguous slices of a 2D array texture.
2114TEST_P(CopyTests_T2T, Texture2DArrayCopyMultipleSlices) {
Jiawei Shaoa3636ed2020-05-28 01:01:32 +00002115 constexpr uint32_t kWidth = 256;
2116 constexpr uint32_t kHeight = 128;
2117 constexpr uint32_t kLayers = 6u;
2118 constexpr uint32_t kSrcBaseLayer = 0u;
2119 constexpr uint32_t kDstBaseLayer = 3u;
2120 constexpr uint32_t kCopyArrayLayerCount = 3u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002121
2122 TextureSpec defaultTextureSpec;
2123 defaultTextureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002124
2125 TextureSpec srcTextureSpec = defaultTextureSpec;
2126 srcTextureSpec.copyOrigin = {0, 0, kSrcBaseLayer};
2127
2128 TextureSpec dstTextureSpec = defaultTextureSpec;
2129 dstTextureSpec.copyOrigin = {0, 0, kDstBaseLayer};
2130
2131 DoTest(srcTextureSpec, dstTextureSpec, {kWidth, kHeight, kCopyArrayLayerCount});
Jiawei Shaoa3636ed2020-05-28 01:01:32 +00002132}
2133
Jiawei Shaoe472c452020-06-08 11:30:01 +00002134// Test copying one texture slice within the same texture.
2135TEST_P(CopyTests_T2T, CopyWithinSameTextureOneSlice) {
Jiawei Shaoe472c452020-06-08 11:30:01 +00002136 constexpr uint32_t kWidth = 256u;
2137 constexpr uint32_t kHeight = 128u;
2138 constexpr uint32_t kLayers = 6u;
2139 constexpr uint32_t kSrcBaseLayer = 0u;
2140 constexpr uint32_t kDstBaseLayer = 3u;
2141 constexpr uint32_t kCopyArrayLayerCount = 1u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002142
2143 TextureSpec defaultTextureSpec;
2144 defaultTextureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002145
2146 TextureSpec srcTextureSpec = defaultTextureSpec;
2147 srcTextureSpec.copyOrigin = {0, 0, kSrcBaseLayer};
2148
2149 TextureSpec dstTextureSpec = defaultTextureSpec;
2150 dstTextureSpec.copyOrigin = {0, 0, kDstBaseLayer};
2151
2152 DoTest(srcTextureSpec, dstTextureSpec, {kWidth, kHeight, kCopyArrayLayerCount}, true);
Jiawei Shaoe472c452020-06-08 11:30:01 +00002153}
2154
2155// Test copying multiple contiguous texture slices within the same texture with non-overlapped
2156// slices.
2157TEST_P(CopyTests_T2T, CopyWithinSameTextureNonOverlappedSlices) {
Jiawei Shaoe472c452020-06-08 11:30:01 +00002158 constexpr uint32_t kWidth = 256u;
2159 constexpr uint32_t kHeight = 128u;
2160 constexpr uint32_t kLayers = 6u;
2161 constexpr uint32_t kSrcBaseLayer = 0u;
2162 constexpr uint32_t kDstBaseLayer = 3u;
2163 constexpr uint32_t kCopyArrayLayerCount = 3u;
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002164
2165 TextureSpec defaultTextureSpec;
2166 defaultTextureSpec.textureSize = {kWidth, kHeight, kLayers};
Jiawei Shao59cfe3e2020-06-16 12:26:38 +00002167
2168 TextureSpec srcTextureSpec = defaultTextureSpec;
2169 srcTextureSpec.copyOrigin = {0, 0, kSrcBaseLayer};
2170
2171 TextureSpec dstTextureSpec = defaultTextureSpec;
2172 dstTextureSpec.copyOrigin = {0, 0, kDstBaseLayer};
2173
2174 DoTest(srcTextureSpec, dstTextureSpec, {kWidth, kHeight, kCopyArrayLayerCount}, true);
Jiawei Shaoe472c452020-06-08 11:30:01 +00002175}
2176
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00002177// A regression test (from WebGPU CTS) for an Intel D3D12 driver bug about T2T copy with specific
2178// texture formats. See http://crbug.com/1161355 for more details.
2179TEST_P(CopyTests_T2T, CopyFromNonZeroMipLevelWithTexelBlockSizeLessThan4Bytes) {
2180 // This test can pass on the Windows Intel Vulkan driver version 27.20.100.9168.
Austin Enged8a8c02021-06-04 22:23:56 +00002181 // TODO(crbug.com/dawn/819): enable this test on Intel Vulkan drivers after the upgrade of
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00002182 // try bots.
Jiawei Shao4589de62021-05-21 02:26:58 +00002183 DAWN_SUPPRESS_TEST_IF(IsVulkan() && IsWindows() && IsIntel());
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00002184
2185 constexpr std::array<wgpu::TextureFormat, 11> kFormats = {
2186 {wgpu::TextureFormat::RG8Sint, wgpu::TextureFormat::RG8Uint, wgpu::TextureFormat::RG8Snorm,
2187 wgpu::TextureFormat::RG8Unorm, wgpu::TextureFormat::R16Float, wgpu::TextureFormat::R16Sint,
2188 wgpu::TextureFormat::R16Uint, wgpu::TextureFormat::R8Snorm, wgpu::TextureFormat::R8Unorm,
2189 wgpu::TextureFormat::R8Sint, wgpu::TextureFormat::R8Uint}};
2190
2191 constexpr uint32_t kSrcLevelCount = 4;
2192 constexpr uint32_t kDstLevelCount = 5;
2193 constexpr uint32_t kSrcSize = 2 << kSrcLevelCount;
2194 constexpr uint32_t kDstSize = 2 << kDstLevelCount;
2195 ASSERT_LE(kSrcSize, kTextureBytesPerRowAlignment);
2196 ASSERT_LE(kDstSize, kTextureBytesPerRowAlignment);
2197
Yunchao He13176362021-06-23 17:12:53 +00002198 // The copyLayer to test:
2199 // 1u (non-array texture), 3u (copyLayer < copyWidth), 5u (copyLayer > copyWidth)
2200 constexpr std::array<uint32_t, 3> kTestTextureLayer = {1u, 3u, 5u};
Jiawei Shao00084322021-03-17 08:20:09 +00002201
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00002202 for (wgpu::TextureFormat format : kFormats) {
Stephen White9b9e7b22021-03-02 17:54:19 +00002203 if (HasToggleEnabled("disable_snorm_read") &&
2204 (format == wgpu::TextureFormat::RG8Snorm || format == wgpu::TextureFormat::R8Snorm)) {
2205 continue;
2206 }
2207
Brandon Jones1934e562021-09-14 00:54:59 +00002208 if (HasToggleEnabled("disable_r8_rg8_mipmaps") &&
2209 (format == wgpu::TextureFormat::R8Unorm || format == wgpu::TextureFormat::RG8Unorm)) {
2210 continue;
2211 }
2212
Yunchao He13176362021-06-23 17:12:53 +00002213 for (uint32_t textureLayer : kTestTextureLayer) {
2214 const wgpu::Extent3D kUploadSize = {4u, 4u, textureLayer};
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00002215
2216 for (uint32_t srcLevel = 0; srcLevel < kSrcLevelCount; ++srcLevel) {
2217 for (uint32_t dstLevel = 0; dstLevel < kDstLevelCount; ++dstLevel) {
2218 TextureSpec srcSpec;
2219 srcSpec.levelCount = kSrcLevelCount;
2220 srcSpec.format = format;
2221 srcSpec.copyLevel = srcLevel;
Yunchao He13176362021-06-23 17:12:53 +00002222 srcSpec.textureSize = {kSrcSize, kSrcSize, textureLayer};
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00002223
2224 TextureSpec dstSpec = srcSpec;
2225 dstSpec.levelCount = kDstLevelCount;
2226 dstSpec.copyLevel = dstLevel;
Yunchao He13176362021-06-23 17:12:53 +00002227 dstSpec.textureSize = {kDstSize, kDstSize, textureLayer};
Jiawei Shao60d6d0a2021-03-01 01:23:30 +00002228
2229 DoTest(srcSpec, dstSpec, kUploadSize);
2230 }
2231 }
2232 }
2233 }
2234}
2235
Yunchao He13176362021-06-23 17:12:53 +00002236// Test that copying from one mip level to another mip level within the same 2D array texture works.
2237TEST_P(CopyTests_T2T, Texture2DArraySameTextureDifferentMipLevels) {
2238 constexpr uint32_t kWidth = 256;
2239 constexpr uint32_t kHeight = 128;
2240 constexpr uint32_t kLayers = 8u;
2241
2242 TextureSpec defaultTextureSpec;
2243 defaultTextureSpec.textureSize = {kWidth, kHeight, kLayers};
2244 defaultTextureSpec.levelCount = 6;
2245
2246 for (unsigned int i = 1; i < 6; ++i) {
2247 TextureSpec srcSpec = defaultTextureSpec;
2248 srcSpec.copyLevel = i - 1;
2249 TextureSpec dstSpec = defaultTextureSpec;
2250 dstSpec.copyLevel = i;
2251
2252 DoTest(srcSpec, dstSpec, {kWidth >> i, kHeight >> i, kLayers}, true);
2253 }
2254}
2255
Yunchao He1fb3f1d2021-04-07 03:08:00 +00002256// Test that copying whole 3D texture in one texture-to-texture-copy works.
2257TEST_P(CopyTests_T2T, Texture3DFull) {
Yunchao He1fb3f1d2021-04-07 03:08:00 +00002258 constexpr uint32_t kWidth = 256;
2259 constexpr uint32_t kHeight = 128;
2260 constexpr uint32_t kDepth = 6u;
2261
2262 TextureSpec textureSpec;
2263 textureSpec.textureSize = {kWidth, kHeight, kDepth};
2264
2265 DoTest(textureSpec, textureSpec, {kWidth, kHeight, kDepth}, false, wgpu::TextureDimension::e3D);
2266}
2267
Yunchao He13176362021-06-23 17:12:53 +00002268// Test that copying from one mip level to another mip level within the same 3D texture works.
2269TEST_P(CopyTests_T2T, Texture3DSameTextureDifferentMipLevels) {
2270 constexpr uint32_t kWidth = 256;
2271 constexpr uint32_t kHeight = 128;
2272 constexpr uint32_t kDepth = 6u;
2273
2274 TextureSpec textureSpec;
2275 textureSpec.textureSize = {kWidth, kHeight, kDepth};
2276 textureSpec.levelCount = 2;
2277
2278 TextureSpec dstSpec = textureSpec;
2279 dstSpec.copyLevel = 1;
2280
2281 DoTest(textureSpec, dstSpec, {kWidth >> 1, kHeight >> 1, kDepth >> 1}, true,
2282 wgpu::TextureDimension::e3D);
2283}
2284
Austin Enge2f083e2021-05-11 01:26:13 +00002285// Test that copying whole 3D texture to a 2D array in one texture-to-texture-copy works.
2286TEST_P(CopyTests_T2T, Texture3DTo2DArrayFull) {
Austin Enge2f083e2021-05-11 01:26:13 +00002287 constexpr uint32_t kWidth = 256;
2288 constexpr uint32_t kHeight = 128;
2289 constexpr uint32_t kDepth = 6u;
2290
2291 TextureSpec textureSpec;
2292 textureSpec.textureSize = {kWidth, kHeight, kDepth};
2293
2294 DoTest(textureSpec, textureSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D,
2295 wgpu::TextureDimension::e2D);
2296}
2297
Yunchao He13176362021-06-23 17:12:53 +00002298// Test that copying between 3D texture and 2D array textures works. It includes partial copy
2299// for src and/or dst texture, non-zero offset (copy origin), non-zero mip level.
2300TEST_P(CopyTests_T2T, Texture3DAnd2DArraySubRegion) {
2301 DAWN_TEST_UNSUPPORTED_IF(IsANGLE()); // TODO(crbug.com/angleproject/5967)
Brian Sheedyb17ecc32021-12-02 01:28:26 +00002302 // TODO(crbug.com/dawn/1216): Remove this suppression.
Brian Sheedy75f0f292021-12-02 20:25:58 +00002303 DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsNvidia());
Yunchao He13176362021-06-23 17:12:53 +00002304
2305 constexpr uint32_t kWidth = 8;
2306 constexpr uint32_t kHeight = 4;
2307 constexpr uint32_t kDepth = 2u;
2308
2309 TextureSpec baseSpec;
2310 baseSpec.textureSize = {kWidth, kHeight, kDepth};
2311
2312 TextureSpec srcSpec = baseSpec;
2313 TextureSpec dstSpec = baseSpec;
2314
2315 // dst texture is a partial copy
2316 dstSpec.textureSize = {kWidth * 2, kHeight * 2, kDepth * 2};
2317 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D,
2318 wgpu::TextureDimension::e2D);
2319 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e2D,
2320 wgpu::TextureDimension::e3D);
2321
2322 // src texture is a partial copy
2323 srcSpec.textureSize = {kWidth * 2, kHeight * 2, kDepth * 2};
2324 dstSpec = baseSpec;
2325 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D,
2326 wgpu::TextureDimension::e2D);
2327 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e2D,
2328 wgpu::TextureDimension::e3D);
2329
2330 // Both src and dst texture is a partial copy
2331 srcSpec.textureSize = {kWidth * 2, kHeight * 2, kDepth * 2};
2332 dstSpec.textureSize = {kWidth * 2, kHeight * 2, kDepth * 2};
2333 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D,
2334 wgpu::TextureDimension::e2D);
2335 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e2D,
2336 wgpu::TextureDimension::e3D);
2337
2338 // Non-zero offset (copy origin)
2339 srcSpec = baseSpec;
2340 dstSpec.textureSize = {kWidth * 2, kHeight * 2, kDepth * 2};
2341 dstSpec.copyOrigin = {kWidth, kHeight, kDepth};
2342 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D,
2343 wgpu::TextureDimension::e2D);
2344 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e2D,
2345 wgpu::TextureDimension::e3D);
2346
2347 // Non-zero mip level
2348 srcSpec = baseSpec;
2349 dstSpec.textureSize = {kWidth * 2, kHeight * 2, kDepth * 2};
2350 dstSpec.copyOrigin = {0, 0, 0};
2351 dstSpec.copyLevel = 1;
2352 dstSpec.levelCount = 2;
2353 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e3D,
2354 wgpu::TextureDimension::e2D);
2355 DoTest(srcSpec, dstSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e2D,
2356 wgpu::TextureDimension::e3D);
2357}
2358
Austin Enge2f083e2021-05-11 01:26:13 +00002359// Test that copying whole 2D array to a 3D texture in one texture-to-texture-copy works.
2360TEST_P(CopyTests_T2T, Texture2DArrayTo3DFull) {
Brian Sheedyb17ecc32021-12-02 01:28:26 +00002361 // TODO(crbug.com/dawn/1216): Remove this suppression.
Brian Sheedy75f0f292021-12-02 20:25:58 +00002362 DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsNvidia());
Austin Enge2f083e2021-05-11 01:26:13 +00002363 constexpr uint32_t kWidth = 256;
2364 constexpr uint32_t kHeight = 128;
2365 constexpr uint32_t kDepth = 6u;
2366
2367 TextureSpec textureSpec;
2368 textureSpec.textureSize = {kWidth, kHeight, kDepth};
2369
2370 DoTest(textureSpec, textureSpec, {kWidth, kHeight, kDepth}, wgpu::TextureDimension::e2D,
2371 wgpu::TextureDimension::e3D);
2372}
2373
2374// Test that copying subregion of a 3D texture in one texture-to-texture-copy works.
2375TEST_P(CopyTests_T2T, Texture3DSubRegion) {
Jiawei Shao4589de62021-05-21 02:26:58 +00002376 DAWN_TEST_UNSUPPORTED_IF(IsANGLE()); // TODO(crbug.com/angleproject/5967)
Austin Enge2f083e2021-05-11 01:26:13 +00002377 constexpr uint32_t kWidth = 256;
2378 constexpr uint32_t kHeight = 128;
2379 constexpr uint32_t kDepth = 6u;
2380
2381 TextureSpec textureSpec;
2382 textureSpec.textureSize = {kWidth, kHeight, kDepth};
2383
2384 DoTest(textureSpec, textureSpec, {kWidth / 2, kHeight / 2, kDepth / 2}, false,
2385 wgpu::TextureDimension::e3D);
2386}
2387
2388// Test that copying subregion of a 3D texture to a 2D array in one texture-to-texture-copy works.
2389TEST_P(CopyTests_T2T, Texture3DTo2DArraySubRegion) {
Austin Enge2f083e2021-05-11 01:26:13 +00002390 constexpr uint32_t kWidth = 256;
2391 constexpr uint32_t kHeight = 128;
2392 constexpr uint32_t kDepth = 6u;
2393
2394 TextureSpec textureSpec;
2395 textureSpec.textureSize = {kWidth, kHeight, kDepth};
2396
2397 DoTest(textureSpec, textureSpec, {kWidth / 2, kHeight / 2, kDepth / 2},
2398 wgpu::TextureDimension::e3D, wgpu::TextureDimension::e2D);
2399}
2400
2401// Test that copying subregion of a 2D array to a 3D texture to in one texture-to-texture-copy
2402// works.
2403TEST_P(CopyTests_T2T, Texture2DArrayTo3DSubRegion) {
Jiawei Shao4589de62021-05-21 02:26:58 +00002404 DAWN_TEST_UNSUPPORTED_IF(IsANGLE()); // TODO(crbug.com/angleproject/5967)
Brian Sheedyb17ecc32021-12-02 01:28:26 +00002405 // TODO(crbug.com/dawn/1216): Remove this suppression.
Brian Sheedy75f0f292021-12-02 20:25:58 +00002406 DAWN_SUPPRESS_TEST_IF(IsD3D12() && IsNvidia());
Austin Enge2f083e2021-05-11 01:26:13 +00002407 constexpr uint32_t kWidth = 256;
2408 constexpr uint32_t kHeight = 128;
2409 constexpr uint32_t kDepth = 6u;
2410
2411 TextureSpec textureSpec;
2412 textureSpec.textureSize = {kWidth, kHeight, kDepth};
2413
2414 DoTest(textureSpec, textureSpec, {kWidth / 2, kHeight / 2, kDepth / 2},
2415 wgpu::TextureDimension::e2D, wgpu::TextureDimension::e3D);
2416}
2417
Yunchao He987fbed2021-06-21 20:09:37 +00002418// Test that copying texture 3D array mips in one texture-to-texture-copy works
2419TEST_P(CopyTests_T2T, Texture3DMipAligned) {
2420 constexpr uint32_t kWidth = 256;
2421 constexpr uint32_t kHeight = 128;
2422 constexpr uint32_t kDepth = 64u;
2423
2424 TextureSpec defaultTextureSpec;
2425 defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
2426
2427 for (unsigned int i = 1; i < 6; ++i) {
2428 TextureSpec textureSpec = defaultTextureSpec;
2429 textureSpec.copyLevel = i;
2430 textureSpec.levelCount = i + 1;
2431
2432 DoTest(textureSpec, textureSpec, {kWidth >> i, kHeight >> i, kDepth >> i},
2433 wgpu::TextureDimension::e3D, wgpu::TextureDimension::e3D);
2434 }
2435}
2436
2437// Test that copying texture 3D array mips in one texture-to-texture-copy works
2438TEST_P(CopyTests_T2T, Texture3DMipUnaligned) {
2439 constexpr uint32_t kWidth = 261;
2440 constexpr uint32_t kHeight = 123;
2441 constexpr uint32_t kDepth = 69u;
2442
2443 TextureSpec defaultTextureSpec;
2444 defaultTextureSpec.textureSize = {kWidth, kHeight, kDepth};
2445
2446 for (unsigned int i = 1; i < 6; ++i) {
2447 TextureSpec textureSpec = defaultTextureSpec;
2448 textureSpec.copyLevel = i;
2449 textureSpec.levelCount = i + 1;
2450
2451 DoTest(textureSpec, textureSpec, {kWidth >> i, kHeight >> i, kDepth >> i},
2452 wgpu::TextureDimension::e3D, wgpu::TextureDimension::e3D);
2453 }
2454}
Yunchao He3e8f3f92021-04-01 22:40:43 +00002455
Juanmif00c68a2021-08-05 22:55:09 +00002456DAWN_INSTANTIATE_TEST_P(CopyTests_T2T,
2457 {D3D12Backend(),
2458 D3D12Backend({"use_temp_buffer_in_small_format_texture_to_texture_copy_"
2459 "from_greater_to_less_mip_level"}),
2460 MetalBackend(), OpenGLBackend(), OpenGLESBackend(), VulkanBackend()},
2461 {true, false});
Corentin Wallez90ad1a32020-06-11 11:23:35 +00002462
Yancf0e4fc2022-01-06 09:01:58 +00002463// Test copying between textures that have srgb compatible texture formats;
2464TEST_P(CopyTests_Formats, SrgbCompatibility) {
2465 // Skip backends because which fails to support *-srgb formats
2466 // and bgra* formats.
2467 DAWN_SUPPRESS_TEST_IF(IsOpenGLES());
2468 DAWN_SUPPRESS_TEST_IF(IsOpenGL() && IsLinux());
2469
2470 constexpr uint32_t kWidth = 256;
2471 constexpr uint32_t kHeight = 128;
2472
2473 TextureSpec textureSpec;
2474 textureSpec.textureSize = {kWidth, kHeight, 1};
2475 DoTest(textureSpec, textureSpec, {kWidth, kHeight, 1});
2476}
2477
2478DAWN_INSTANTIATE_TEST_P(CopyTests_Formats,
2479 {D3D12Backend(), MetalBackend(), OpenGLBackend(), OpenGLESBackend(),
2480 VulkanBackend()},
2481 {wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::RGBA8UnormSrgb,
2482 wgpu::TextureFormat::BGRA8Unorm, wgpu::TextureFormat::BGRA8UnormSrgb});
2483
Corentin Wallez90ad1a32020-06-11 11:23:35 +00002484static constexpr uint64_t kSmallBufferSize = 4;
2485static constexpr uint64_t kLargeBufferSize = 1 << 16;
2486
2487// Test copying full buffers
2488TEST_P(CopyTests_B2B, FullCopy) {
2489 DoTest(kSmallBufferSize, 0, kSmallBufferSize, 0, kSmallBufferSize);
2490 DoTest(kLargeBufferSize, 0, kLargeBufferSize, 0, kLargeBufferSize);
2491}
2492
2493// Test copying small pieces of a buffer at different corner case offsets
2494TEST_P(CopyTests_B2B, SmallCopyInBigBuffer) {
2495 constexpr uint64_t kEndOffset = kLargeBufferSize - kSmallBufferSize;
2496 DoTest(kLargeBufferSize, 0, kLargeBufferSize, 0, kSmallBufferSize);
2497 DoTest(kLargeBufferSize, kEndOffset, kLargeBufferSize, 0, kSmallBufferSize);
2498 DoTest(kLargeBufferSize, 0, kLargeBufferSize, kEndOffset, kSmallBufferSize);
2499 DoTest(kLargeBufferSize, kEndOffset, kLargeBufferSize, kEndOffset, kSmallBufferSize);
2500}
2501
2502// Test zero-size copies
2503TEST_P(CopyTests_B2B, ZeroSizedCopy) {
2504 DoTest(kLargeBufferSize, 0, kLargeBufferSize, 0, 0);
2505 DoTest(kLargeBufferSize, 0, kLargeBufferSize, kLargeBufferSize, 0);
2506 DoTest(kLargeBufferSize, kLargeBufferSize, kLargeBufferSize, 0, 0);
2507 DoTest(kLargeBufferSize, kLargeBufferSize, kLargeBufferSize, kLargeBufferSize, 0);
2508}
2509
2510DAWN_INSTANTIATE_TEST(CopyTests_B2B,
2511 D3D12Backend(),
2512 MetalBackend(),
2513 OpenGLBackend(),
Stephen Whiteab59a102020-12-01 18:37:19 +00002514 OpenGLESBackend(),
Corentin Wallez90ad1a32020-06-11 11:23:35 +00002515 VulkanBackend());
Brandon Jonesd3105bf2021-12-02 21:43:49 +00002516
2517// Test clearing full buffers
2518TEST_P(ClearBufferTests, FullClear) {
2519 DoTest(kSmallBufferSize, 0, kSmallBufferSize);
2520 DoTest(kLargeBufferSize, 0, kLargeBufferSize);
2521}
2522
2523// Test clearing small pieces of a buffer at different corner case offsets
2524TEST_P(ClearBufferTests, SmallClearInBigBuffer) {
2525 constexpr uint64_t kEndOffset = kLargeBufferSize - kSmallBufferSize;
2526 DoTest(kLargeBufferSize, 0, kSmallBufferSize);
2527 DoTest(kLargeBufferSize, kSmallBufferSize, kSmallBufferSize);
2528 DoTest(kLargeBufferSize, kEndOffset, kSmallBufferSize);
2529}
2530
2531// Test zero-size clears
2532TEST_P(ClearBufferTests, ZeroSizedClear) {
2533 DoTest(kLargeBufferSize, 0, 0);
2534 DoTest(kLargeBufferSize, kSmallBufferSize, 0);
2535 DoTest(kLargeBufferSize, kLargeBufferSize, 0);
2536}
2537
2538DAWN_INSTANTIATE_TEST(ClearBufferTests,
2539 D3D12Backend(),
2540 MetalBackend(),
2541 OpenGLBackend(),
2542 OpenGLESBackend(),
Corentin Wallez87ef49c2021-12-07 09:29:46 +00002543 VulkanBackend());