Implement copying between a buffer and a texture 2D array on Vulkan (#257)

Implement copying between a buffer and a texture 2D array on Vulkan

This patch implements the creation of a 2D array texture and data
copying between a buffer and a layer of a 2D array texture on
Vulkan back-ends.

TEST=dawn_end2end_tests
This commit is contained in:
Jiawei Shao 2018-08-30 16:27:38 +08:00 committed by Corentin Wallez
parent ec72443bf1
commit 4b74dbef7b
12 changed files with 187 additions and 128 deletions

View File

@ -345,7 +345,8 @@
{"name": "width", "type": "uint32_t"},
{"name": "height", "type": "uint32_t"},
{"name": "depth", "type": "uint32_t"},
{"name": "level", "type": "uint32_t"}
{"name": "level", "type": "uint32_t"},
{"name": "slice", "type": "uint32_t"}
],
"TODO": [
"Make pretty with Offset and Extents structures",
@ -365,6 +366,7 @@
{"name": "height", "type": "uint32_t"},
{"name": "depth", "type": "uint32_t"},
{"name": "level", "type": "uint32_t"},
{"name": "slice", "type": "uint32_t"},
{"name": "buffer", "type": "buffer"},
{"name": "buffer offset", "type": "uint32_t"},
{"name": "row pitch", "type": "uint32_t"}

View File

@ -71,7 +71,7 @@ void initTextures() {
dawn::Buffer stagingBuffer = utils::CreateBufferFromData(device, data.data(), static_cast<uint32_t>(data.size()), dawn::BufferUsageBit::TransferSrc);
dawn::CommandBuffer copy = device.CreateCommandBufferBuilder()
.CopyBufferToTexture(stagingBuffer, 0, 0, texture, 0, 0, 0, 1024, 1024, 1, 0)
.CopyBufferToTexture(stagingBuffer, 0, 0, texture, 0, 0, 0, 1024, 1024, 1, 0, 0)
.GetResult();
queue.Submit(1, &copy);

View File

@ -434,7 +434,7 @@ namespace {
dawn::Buffer staging = utils::CreateBufferFromData(device, data, rowPitch * iImage.height, dawn::BufferUsageBit::TransferSrc);
auto cmdbuf = device.CreateCommandBufferBuilder()
.CopyBufferToTexture(staging, 0, rowPitch, oTexture, 0, 0, 0, iImage.width, iImage.height, 1, 0)
.CopyBufferToTexture(staging, 0, rowPitch, oTexture, 0, 0, 0, iImage.width, iImage.height, 1, 0, 0)
.GetResult();
queue.Submit(1, &cmdbuf);

View File

@ -38,6 +38,10 @@ namespace dawn_native {
DAWN_RETURN_ERROR("Copy mip-level out of range");
}
if (location.slice >= texture->GetArrayLayers()) {
DAWN_RETURN_ERROR("Copy array-layer out of range");
}
// All texture dimensions are in uint32_t so by doing checks in uint64_t we avoid
// overflows.
uint64_t level = location.level;
@ -585,7 +589,8 @@ namespace dawn_native {
uint32_t width,
uint32_t height,
uint32_t depth,
uint32_t level) {
uint32_t level,
uint32_t slice) {
if (rowPitch == 0) {
rowPitch = ComputeDefaultRowPitch(texture, width);
}
@ -602,6 +607,7 @@ namespace dawn_native {
copy->destination.height = height;
copy->destination.depth = depth;
copy->destination.level = level;
copy->destination.slice = slice;
copy->rowPitch = rowPitch;
}
@ -613,6 +619,7 @@ namespace dawn_native {
uint32_t height,
uint32_t depth,
uint32_t level,
uint32_t slice,
BufferBase* buffer,
uint32_t bufferOffset,
uint32_t rowPitch) {
@ -630,6 +637,7 @@ namespace dawn_native {
copy->source.height = height;
copy->source.depth = depth;
copy->source.level = level;
copy->source.slice = slice;
copy->destination.buffer = buffer;
copy->destination.offset = bufferOffset;
copy->rowPitch = rowPitch;

View File

@ -77,7 +77,8 @@ namespace dawn_native {
uint32_t width,
uint32_t height,
uint32_t depth,
uint32_t level);
uint32_t level,
uint32_t slice);
void CopyTextureToBuffer(TextureBase* texture,
uint32_t x,
uint32_t y,
@ -86,6 +87,7 @@ namespace dawn_native {
uint32_t height,
uint32_t depth,
uint32_t level,
uint32_t slice,
BufferBase* buffer,
uint32_t bufferOffset,
uint32_t rowPitch);

View File

@ -64,6 +64,7 @@ namespace dawn_native {
uint32_t x, y, z;
uint32_t width, height, depth;
uint32_t level;
uint32_t slice;
};
struct CopyBufferToBufferCmd {

View File

@ -53,7 +53,7 @@ namespace dawn_native { namespace vulkan {
region.imageSubresource.aspectMask = texture->GetVkAspectMask();
region.imageSubresource.mipLevel = textureLocation.level;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.baseArrayLayer = textureLocation.slice;
region.imageSubresource.layerCount = 1;
region.imageOffset.x = textureLocation.x;

View File

@ -248,7 +248,7 @@ namespace dawn_native { namespace vulkan {
createInfo.format = VulkanImageFormat(GetFormat());
createInfo.extent = VkExtent3D{GetWidth(), GetHeight(), GetDepth()};
createInfo.mipLevels = GetNumMipLevels();
createInfo.arrayLayers = 1;
createInfo.arrayLayers = GetArrayLayers();
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
createInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
createInfo.usage = VulkanImageUsage(GetUsage(), GetFormat());

View File

@ -259,7 +259,7 @@ std::ostringstream& DawnTest::AddTextureExpectation(const char* file,
// the texture might have been modified.
dawn::CommandBuffer commands =
device.CreateCommandBufferBuilder()
.CopyTextureToBuffer(source, x, y, 0, width, height, 1, level, readback.buffer,
.CopyTextureToBuffer(source, x, y, 0, width, height, 1, level, 0, readback.buffer,
readback.offset, rowPitch)
.GetResult();

View File

@ -31,6 +31,7 @@ class CopyTests : public DawnTest {
uint32_t copyWidth;
uint32_t copyHeight;
uint32_t level;
uint32_t arrayLayer = 1u;
};
struct BufferSpec {
@ -57,13 +58,13 @@ class CopyTests : public DawnTest {
class CopyTests_T2B : public CopyTests {
protected:
static void FillTextureData(uint32_t width, uint32_t height, uint32_t texelsPerRow, RGBA8* data) {
static void FillTextureData(uint32_t width, uint32_t height, uint32_t texelsPerRow, RGBA8* data, uint32_t layer) {
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int x = 0; x < width; ++x) {
unsigned int i = x + y * texelsPerRow;
data[i] = RGBA8(
static_cast<uint8_t>(x % 256),
static_cast<uint8_t>(y % 256),
static_cast<uint8_t>((x + layer * x)% 256),
static_cast<uint8_t>((y + layer * y)% 256),
static_cast<uint8_t>(x / 256),
static_cast<uint8_t>(y / 256));
}
@ -77,7 +78,7 @@ class CopyTests_T2B : public CopyTests {
descriptor.width = textureSpec.width;
descriptor.height = textureSpec.height;
descriptor.depth = 1;
descriptor.arrayLayer = 1;
descriptor.arrayLayer = textureSpec.arrayLayer;
descriptor.format = dawn::TextureFormat::R8G8B8A8Unorm;
descriptor.mipLevel = textureSpec.level + 1;
descriptor.usage = dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::TransferSrc;
@ -87,51 +88,62 @@ class CopyTests_T2B : public CopyTests {
uint32_t height = textureSpec.height >> textureSpec.level;
uint32_t rowPitch = Align(kBytesPerTexel * width, kTextureRowPitchAlignment);
uint32_t texelsPerRow = rowPitch / kBytesPerTexel;
uint32_t texelCount = texelsPerRow * (height - 1) + width;
uint32_t texelCountPerLayer = texelsPerRow * (height - 1) + width;
// Create an upload buffer and use it to populate the `level` mip of the texture
std::vector<RGBA8> textureData(texelCount);
FillTextureData(width, height, rowPitch / kBytesPerTexel, textureData.data());
dawn::Buffer uploadBuffer = utils::CreateBufferFromData(device, textureData.data(), static_cast<uint32_t>(sizeof(RGBA8) * textureData.size()), dawn::BufferUsageBit::TransferSrc);
dawn::CommandBufferBuilder cmdBuilder = device.CreateCommandBufferBuilder();
dawn::CommandBuffer commands[2];
std::vector<std::vector<RGBA8>> textureArrayData(textureSpec.arrayLayer);
for (uint32_t slice = 0; slice < textureSpec.arrayLayer; ++slice) {
textureArrayData[slice].resize(texelCountPerLayer);
FillTextureData(width, height, rowPitch / kBytesPerTexel, textureArrayData[slice].data(), slice);
commands[0] = device.CreateCommandBufferBuilder()
.CopyBufferToTexture(uploadBuffer, 0, rowPitch, texture, 0, 0, 0, width, height, 1, textureSpec.level)
.GetResult();
// Create an upload buffer and use it to populate the current slice of the texture in `level` mip level
dawn::Buffer uploadBuffer = utils::CreateBufferFromData(device, textureArrayData[slice].data(),
static_cast<uint32_t>(sizeof(RGBA8) * textureArrayData[slice].size()), dawn::BufferUsageBit::TransferSrc);
// Create a buffer of size `size` and populate it with empty data (0,0,0,0)
cmdBuilder.CopyBufferToTexture(uploadBuffer, 0, rowPitch, texture, 0, 0, 0, width, height, 1, textureSpec.level, slice);
}
// Create a buffer of size `size * textureSpec.arrayLayer` and populate it with empty data (0,0,0,0)
// Note: Prepopulating the buffer with empty data ensures that there is not random data in the expectation
// and helps ensure that the padding due to the row pitch is not modified by the copy
dawn::BufferDescriptor bufDescriptor;
bufDescriptor.size = bufferSpec.size;
bufDescriptor.size = bufferSpec.size * textureSpec.arrayLayer;
bufDescriptor.usage = dawn::BufferUsageBit::TransferSrc | dawn::BufferUsageBit::TransferDst;
dawn::Buffer buffer = device.CreateBuffer(&bufDescriptor);
std::vector<RGBA8> emptyData(bufferSpec.size / kBytesPerTexel);
std::vector<RGBA8> emptyData(bufferSpec.size / kBytesPerTexel * textureSpec.arrayLayer);
buffer.SetSubData(0, static_cast<uint32_t>(emptyData.size() * sizeof(RGBA8)), reinterpret_cast<const uint8_t*>(emptyData.data()));
// Copy the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] from the `level` mip into the buffer at the specified `offset` and `rowPitch`
commands[1] = device.CreateCommandBufferBuilder()
.CopyTextureToBuffer(texture, textureSpec.x, textureSpec.y, 0, textureSpec.copyWidth, textureSpec.copyHeight, 1, textureSpec.level, buffer, bufferSpec.offset, bufferSpec.rowPitch)
.GetResult();
uint32_t bufferOffset = bufferSpec.offset;
for (uint32_t slice = 0; slice < textureSpec.arrayLayer; ++slice) {
// Copy the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] from the `level` mip into the buffer at `offset + bufferSpec.size * slice` and `rowPitch`
cmdBuilder.CopyTextureToBuffer(texture, textureSpec.x, textureSpec.y, 0, textureSpec.copyWidth, textureSpec.copyHeight, 1, textureSpec.level, slice, buffer, bufferOffset, bufferSpec.rowPitch);
bufferOffset += bufferSpec.size;
}
queue.Submit(2, commands);
dawn::CommandBuffer commands = cmdBuilder.GetResult();
queue.Submit(1, &commands);
// Pack the data used to create the upload buffer in the specified copy region to have the same format as the expected buffer data.
bufferOffset = bufferSpec.offset;
std::vector<RGBA8> expected(bufferSpec.rowPitch / kBytesPerTexel * (textureSpec.copyHeight - 1) + textureSpec.copyWidth);
PackTextureData(
&textureData[textureSpec.x + textureSpec.y * (rowPitch / kBytesPerTexel)],
textureSpec.copyWidth,
textureSpec.copyHeight,
rowPitch / kBytesPerTexel,
expected.data(),
bufferSpec.rowPitch / kBytesPerTexel);
for (uint32_t slice = 0; slice < textureSpec.arrayLayer; ++slice) {
// Pack the data used to create the upload buffer in the specified copy region to have the same format as the expected buffer data.
std::fill(expected.begin(), expected.end(), RGBA8());
PackTextureData(
&textureArrayData[slice][textureSpec.x + textureSpec.y * (rowPitch / kBytesPerTexel)],
textureSpec.copyWidth,
textureSpec.copyHeight,
rowPitch / kBytesPerTexel,
expected.data(),
bufferSpec.rowPitch / kBytesPerTexel);
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()), buffer, bufferSpec.offset, static_cast<uint32_t>(expected.size())) <<
"Texture to Buffer copy failed copying region [(" << textureSpec.x << ", " << textureSpec.y << "), (" << textureSpec.x + textureSpec.copyWidth << ", " << textureSpec.y + textureSpec.copyHeight <<
")) from " << textureSpec.width << " x " << textureSpec.height << " texture at mip level " << textureSpec.level <<
" to " << bufferSpec.size << "-byte buffer with offset " << bufferSpec.offset << " and row pitch " << bufferSpec.rowPitch << std::endl;
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<const uint32_t*>(expected.data()), buffer, bufferOffset, static_cast<uint32_t>(expected.size())) <<
"Texture to Buffer copy failed copying region [(" << textureSpec.x << ", " << textureSpec.y << "), (" << textureSpec.x + textureSpec.copyWidth << ", " << textureSpec.y + textureSpec.copyHeight <<
")) from " << textureSpec.width << " x " << textureSpec.height << " texture at mip level " << textureSpec.level << " layer " << slice <<
" to " << bufDescriptor.size << "-byte buffer with offset " << bufferOffset << " and row pitch " << bufferSpec.rowPitch << std::endl;
bufferOffset += bufferSpec.size;
}
}
@ -172,7 +184,7 @@ protected:
descriptor.usage = dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::TransferSrc;
dawn::Texture texture = device.CreateTexture(&descriptor);
dawn::CommandBuffer commands[2];
dawn::CommandBufferBuilder cmdBuilder = device.CreateCommandBufferBuilder();
// Create an upload buffer filled with empty data and use it to populate the `level` mip of the texture
// Note: Prepopulating the texture with empty data ensures that there is not random data in the expectation
@ -187,17 +199,14 @@ protected:
std::vector<RGBA8> emptyData(texelCount);
dawn::Buffer uploadBuffer = utils::CreateBufferFromData(device, emptyData.data(), static_cast<uint32_t>(sizeof(RGBA8) * emptyData.size()), dawn::BufferUsageBit::TransferSrc);
commands[0] = device.CreateCommandBufferBuilder()
.CopyBufferToTexture(uploadBuffer, 0, rowPitch, texture, 0, 0, 0, width, height, 1, textureSpec.level)
.GetResult();
cmdBuilder.CopyBufferToTexture(uploadBuffer, 0, rowPitch, texture, 0, 0, 0, width, height, 1, textureSpec.level, 0);
}
// Copy to the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] at the `level` mip from the buffer at the specified `offset` and `rowPitch`
commands[1] = device.CreateCommandBufferBuilder()
.CopyBufferToTexture(buffer, bufferSpec.offset, bufferSpec.rowPitch, texture, textureSpec.x, textureSpec.y, 0, textureSpec.copyWidth, textureSpec.copyHeight, 1, textureSpec.level)
.GetResult();
cmdBuilder.CopyBufferToTexture(buffer, bufferSpec.offset, bufferSpec.rowPitch, texture, textureSpec.x, textureSpec.y, 0, textureSpec.copyWidth, textureSpec.copyHeight, 1, textureSpec.level, 0);
queue.Submit(2, commands);
dawn::CommandBuffer commands = cmdBuilder.GetResult();
queue.Submit(1, &commands);
// Pack the data used to create the buffer in the specified copy region to have the same format as the expected texture data.
uint32_t rowPitch = Align(kBytesPerTexel * textureSpec.copyWidth, kTextureRowPitchAlignment);
@ -355,6 +364,36 @@ TEST_P(CopyTests_T2B, RowPitchUnaligned) {
}
}
// Test that copying regions of each texture 2D array layer works
TEST_P(CopyTests_T2B, Texture2DArrayRegion)
{
// TODO(jiawei.shao@intel.com): support 2D array texture on OpenGL, D3D12 and Metal.
if (IsOpenGL() || IsD3D12() || IsMetal()) {
std::cout << "Test skipped on OpenGL, D3D12 and Metal" << std::endl;
return;
}
constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kLayers = 6u;
DoTest({ kWidth, kHeight, 0, 0, kWidth, kHeight, 0, kLayers }, MinimumBufferSpec(kWidth, kHeight));
}
// Test that copying texture 2D array mips with 256-byte aligned sizes works
TEST_P(CopyTests_T2B, Texture2DArrayMip) {
// TODO(jiawei.shao@intel.com): support 2D array texture on OpenGL, D3D12 and Metal.
if (IsOpenGL() || IsD3D12() || IsMetal()) {
std::cout << "Test skipped on OpenGL, D3D12 and Metal" << std::endl;
return;
}
constexpr uint32_t kWidth = 256;
constexpr uint32_t kHeight = 128;
constexpr uint32_t kLayers = 6u;
for (unsigned int i = 1; i < 4; ++i) {
DoTest({ kWidth, kHeight, 0, 0, kWidth >> i, kHeight >> i, i, kLayers }, MinimumBufferSpec(kWidth >> i, kHeight >> i));
}
}
DAWN_INSTANTIATE_TEST(CopyTests_T2B, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend)
// Test that copying an entire texture with 256-byte aligned dimensions works

View File

@ -101,7 +101,7 @@ protected:
dawn::Buffer stagingBuffer = utils::CreateBufferFromData(device, data, sizeof(data), dawn::BufferUsageBit::TransferSrc);
dawn::CommandBuffer copy = device.CreateCommandBufferBuilder()
.CopyBufferToTexture(stagingBuffer, 0, 256, texture, 0, 0, 0, 2, 2, 1, 0)
.CopyBufferToTexture(stagingBuffer, 0, 256, texture, 0, 0, 0, 2, 2, 1, 0, 0)
.GetResult();
queue.Submit(1, &copy);

View File

@ -26,14 +26,14 @@ class CopyCommandTest : public ValidationTest {
return device.CreateBuffer(&descriptor);
}
dawn::Texture Create2DTexture(uint32_t width, uint32_t height, uint32_t levels,
dawn::Texture Create2DTexture(uint32_t width, uint32_t height, uint32_t levels, uint32_t arrayLayer,
dawn::TextureFormat format, dawn::TextureUsageBit usage) {
dawn::TextureDescriptor descriptor;
descriptor.dimension = dawn::TextureDimension::e2D;
descriptor.width = width;
descriptor.height = height;
descriptor.depth = 1;
descriptor.arrayLayer = 1;
descriptor.arrayLayer = arrayLayer;
descriptor.format = format;
descriptor.mipLevel = levels;
descriptor.usage = usage;
@ -124,20 +124,20 @@ class CopyCommandTest_B2T : public CopyCommandTest {
TEST_F(CopyCommandTest_B2T, Success) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Buffer source = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferSrc);
dawn::Texture destination = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture destination = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
// Different copies, including some that touch the OOB condition
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
// Copy 4x4 block in corner of first mip.
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 4, 4, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 4, 4, 1, 0, 0)
// Copy 4x4 block in opposite corner of first mip.
.CopyBufferToTexture(source, 0, 256, destination, 12, 12, 0, 4, 4, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 12, 12, 0, 4, 4, 1, 0, 0)
// Copy 4x4 block in the 4x4 mip.
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 4, 4, 1, 2)
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 4, 4, 1, 2, 0)
// Copy with a buffer offset
.CopyBufferToTexture(source, bufferSize - 4, 256, destination, 0, 0, 0, 1, 1, 1, 0)
.CopyBufferToTexture(source, bufferSize - 4, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
.GetResult();
}
@ -145,11 +145,11 @@ TEST_F(CopyCommandTest_B2T, Success) {
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
// Unaligned region
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 3, 4, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 3, 4, 1, 0, 0)
// Unaligned region with texture offset
.CopyBufferToTexture(source, 0, 256, destination, 5, 7, 0, 2, 3, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 5, 7, 0, 2, 3, 1, 0, 0)
// Unaligned region, with buffer offset
.CopyBufferToTexture(source, 31 * 4, 256, destination, 0, 0, 0, 3, 3, 1, 0)
.CopyBufferToTexture(source, 31 * 4, 256, destination, 0, 0, 0, 3, 3, 1, 0, 0)
.GetResult();
}
@ -157,11 +157,11 @@ TEST_F(CopyCommandTest_B2T, Success) {
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
// An empty copy
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 0, 0, 1, 0)
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 0, 0, 1, 0, 0)
// An empty copy touching the end of the buffer
.CopyBufferToTexture(source, bufferSize, 0, destination, 0, 0, 0, 0, 0, 1, 0)
.CopyBufferToTexture(source, bufferSize, 0, destination, 0, 0, 0, 0, 0, 1, 0, 0)
// An empty copy touching the side of the texture
.CopyBufferToTexture(source, 0, 0, destination, 16, 16, 0, 0, 0, 1, 0)
.CopyBufferToTexture(source, 0, 0, destination, 16, 16, 0, 0, 0, 1, 0, 0)
.GetResult();
}
}
@ -170,27 +170,27 @@ TEST_F(CopyCommandTest_B2T, Success) {
TEST_F(CopyCommandTest_B2T, OutOfBoundsOnBuffer) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Buffer source = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferSrc);
dawn::Texture destination = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture destination = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
// OOB on the buffer because we copy too many pixels
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 4, 5, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 4, 5, 1, 0, 0)
.GetResult();
}
// OOB on the buffer because of the offset
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 4, 256, destination, 0, 0, 0, 4, 4, 1, 0)
.CopyBufferToTexture(source, 4, 256, destination, 0, 0, 0, 4, 4, 1, 0, 0)
.GetResult();
}
// OOB on the buffer because (row pitch * (height - 1) + width) * depth overflows
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 512, destination, 0, 0, 0, 4, 3, 1, 0)
.CopyBufferToTexture(source, 0, 512, destination, 0, 0, 0, 4, 3, 1, 0, 0)
.GetResult();
}
@ -201,7 +201,7 @@ TEST_F(CopyCommandTest_B2T, OutOfBoundsOnBuffer) {
ASSERT_TRUE(256 * 3 > sourceBufferSize) << "row pitch * height should overflow buffer";
dawn::Buffer sourceBuffer = CreateBuffer(sourceBufferSize, dawn::BufferUsageBit::TransferSrc);
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(sourceBuffer, 0, 256, destination, 0, 0, 0, 7, 3, 1, 0)
.CopyBufferToTexture(sourceBuffer, 0, 256, destination, 0, 0, 0, 7, 3, 1, 0, 0)
.GetResult();
}
}
@ -210,34 +210,41 @@ TEST_F(CopyCommandTest_B2T, OutOfBoundsOnBuffer) {
TEST_F(CopyCommandTest_B2T, OutOfBoundsOnTexture) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Buffer source = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferSrc);
dawn::Texture destination = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture destination = Create2DTexture(16, 16, 5, 2, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
// OOB on the texture because x + width overflows
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 256, destination, 13, 12, 0, 4, 4, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 13, 12, 0, 4, 4, 1, 0, 0)
.GetResult();
}
// OOB on the texture because y + width overflows
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 256, destination, 12, 13, 0, 4, 4, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 12, 13, 0, 4, 4, 1, 0, 0)
.GetResult();
}
// OOB on the texture because we overflow a non-zero mip
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 256, destination, 1, 0, 0, 4, 4, 1, 2)
.CopyBufferToTexture(source, 0, 256, destination, 1, 0, 0, 4, 4, 1, 2, 0)
.GetResult();
}
// OOB on the texture even on an empty copy when we copy to a non-existent mip.
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 0, 0, 1, 5)
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 0, 0, 1, 5, 0)
.GetResult();
}
// OOB on the texture because slice overflows
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 0, 0, 1, 0, 2)
.GetResult();
}
}
@ -245,20 +252,20 @@ TEST_F(CopyCommandTest_B2T, OutOfBoundsOnTexture) {
// Test that we force Z=0 and Depth=1 on copies to 2D textures
TEST_F(CopyCommandTest_B2T, ZDepthConstraintFor2DTextures) {
dawn::Buffer source = CreateBuffer(16 * 4, dawn::BufferUsageBit::TransferSrc);
dawn::Texture destination = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture destination = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
// Z=1 on an empty copy still errors
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 1, 0, 0, 1, 0)
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 1, 0, 0, 1, 0, 0)
.GetResult();
}
// Depth=0 on an empty copy still errors
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 0, 0, 0, 0)
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 0, 0, 0, 0, 0)
.GetResult();
}
}
@ -267,22 +274,22 @@ TEST_F(CopyCommandTest_B2T, ZDepthConstraintFor2DTextures) {
TEST_F(CopyCommandTest_B2T, IncorrectUsage) {
dawn::Buffer source = CreateBuffer(16 * 4, dawn::BufferUsageBit::TransferSrc);
dawn::Buffer vertex = CreateBuffer(16 * 4, dawn::BufferUsageBit::Vertex);
dawn::Texture destination = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture destination = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
dawn::Texture sampled = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture sampled = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::Sampled);
// Incorrect source usage
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(vertex, 0, 256, destination, 0, 0, 0, 4, 4, 1, 0)
.CopyBufferToTexture(vertex, 0, 256, destination, 0, 0, 0, 4, 4, 1, 0, 0)
.GetResult();
}
// Incorrect destination usage
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 256, sampled, 0, 0, 0, 4, 4, 1, 0)
.CopyBufferToTexture(source, 0, 256, sampled, 0, 0, 0, 4, 4, 1, 0, 0)
.GetResult();
}
}
@ -290,27 +297,27 @@ TEST_F(CopyCommandTest_B2T, IncorrectUsage) {
TEST_F(CopyCommandTest_B2T, IncorrectRowPitch) {
uint32_t bufferSize = BufferSizeForTextureCopy(128, 16, 1);
dawn::Buffer source = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferSrc);
dawn::Texture destination = Create2DTexture(128, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture destination = Create2DTexture(128, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
// Default row pitch is not 256-byte aligned
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 3, 4, 1, 0)
.CopyBufferToTexture(source, 0, 0, destination, 0, 0, 0, 3, 4, 1, 0, 0)
.GetResult();
}
// Row pitch is not 256-byte aligned
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 128, destination, 0, 0, 0, 4, 4, 1, 0)
.CopyBufferToTexture(source, 0, 128, destination, 0, 0, 0, 4, 4, 1, 0, 0)
.GetResult();
}
// Row pitch is less than width * bytesPerPixel
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 65, 1, 1, 0)
.CopyBufferToTexture(source, 0, 256, destination, 0, 0, 0, 65, 1, 1, 0, 0)
.GetResult();
}
}
@ -319,29 +326,29 @@ TEST_F(CopyCommandTest_B2T, IncorrectRowPitch) {
TEST_F(CopyCommandTest_B2T, IncorrectBufferOffset) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Buffer source = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferSrc);
dawn::Texture destination = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture destination = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
// Correct usage
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, bufferSize - 4, 256, destination, 0, 0, 0, 1, 1, 1, 0)
.CopyBufferToTexture(source, bufferSize - 4, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
.GetResult();
}
// Incorrect usages
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, bufferSize - 5, 256, destination, 0, 0, 0, 1, 1, 1, 0)
.CopyBufferToTexture(source, bufferSize - 5, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
.GetResult();
}
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, bufferSize - 6, 256, destination, 0, 0, 0, 1, 1, 1, 0)
.CopyBufferToTexture(source, bufferSize - 6, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
.GetResult();
}
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyBufferToTexture(source, bufferSize - 7, 256, destination, 0, 0, 0, 1, 1, 1, 0)
.CopyBufferToTexture(source, bufferSize - 7, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
.GetResult();
}
}
@ -352,7 +359,7 @@ class CopyCommandTest_T2B : public CopyCommandTest {
// Test a successfull T2B copy
TEST_F(CopyCommandTest_T2B, Success) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Texture source = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture source = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferSrc);
dawn::Buffer destination = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferDst);
@ -360,13 +367,13 @@ TEST_F(CopyCommandTest_T2B, Success) {
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
// Copy from 4x4 block in corner of first mip.
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, 0, destination, 0, 256)
// Copy from 4x4 block in opposite corner of first mip.
.CopyTextureToBuffer(source, 12, 12, 0, 4, 4, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 12, 12, 0, 4, 4, 1, 0, 0, destination, 0, 256)
// Copy from 4x4 block in the 4x4 mip.
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 2, destination, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 2, 0, destination, 0, 256)
// Copy with a buffer offset
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, destination, bufferSize - 4, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, 0, destination, bufferSize - 4, 256)
.GetResult();
}
@ -374,11 +381,11 @@ TEST_F(CopyCommandTest_T2B, Success) {
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
// Unaligned region
.CopyTextureToBuffer(source, 0, 0, 0, 3, 4, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 3, 4, 1, 0, 0, destination, 0, 256)
// Unaligned region with texture offset
.CopyTextureToBuffer(source, 5, 7, 0, 2, 3, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 5, 7, 0, 2, 3, 1, 0, 0, destination, 0, 256)
// Unaligned region, with buffer offset
.CopyTextureToBuffer(source, 0, 0, 0, 3, 3, 1, 2, destination, 31 * 4, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 3, 3, 1, 2, 0, destination, 31 * 4, 256)
.GetResult();
}
@ -386,11 +393,11 @@ TEST_F(CopyCommandTest_T2B, Success) {
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
// An empty copy
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 1, 0, destination, 0, 0)
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 1, 0, 0, destination, 0, 0)
// An empty copy touching the end of the buffer
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 1, 0, destination, bufferSize, 0)
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 1, 0, 0, destination, bufferSize, 0)
// An empty copy touching the side of the texture
.CopyTextureToBuffer(source, 16, 16, 0, 0, 0, 1, 0, destination, 0, 0)
.CopyTextureToBuffer(source, 16, 16, 0, 0, 0, 1, 0, 0, destination, 0, 0)
.GetResult();
}
}
@ -398,35 +405,35 @@ TEST_F(CopyCommandTest_T2B, Success) {
// Test OOB conditions on the texture
TEST_F(CopyCommandTest_T2B, OutOfBoundsOnTexture) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Texture source = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture source = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferSrc);
dawn::Buffer destination = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferDst);
// OOB on the texture because x + width overflows
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 13, 12, 0, 4, 4, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 13, 12, 0, 4, 4, 1, 0, 0, destination, 0, 256)
.GetResult();
}
// OOB on the texture because y + width overflows
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 12, 13, 0, 4, 4, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 12, 13, 0, 4, 4, 1, 0, 0, destination, 0, 256)
.GetResult();
}
// OOB on the texture because we overflow a non-zero mip
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 1, 0, 0, 4, 4, 1, 2, destination, 0, 256)
.CopyTextureToBuffer(source, 1, 0, 0, 4, 4, 1, 2, 0, destination, 0, 256)
.GetResult();
}
// OOB on the texture even on an empty copy when we copy from a non-existent mip.
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 1, 5, destination, 0, 0)
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 1, 5, 0, destination, 0, 0)
.GetResult();
}
}
@ -434,28 +441,28 @@ TEST_F(CopyCommandTest_T2B, OutOfBoundsOnTexture) {
// Test OOB conditions on the buffer
TEST_F(CopyCommandTest_T2B, OutOfBoundsOnBuffer) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Texture source = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture source = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferSrc);
dawn::Buffer destination = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferDst);
// OOB on the buffer because we copy too many pixels
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 4, 5, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 4, 5, 1, 0, 0, destination, 0, 256)
.GetResult();
}
// OOB on the buffer because of the offset
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, destination, 4, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, 0, destination, 4, 256)
.GetResult();
}
// OOB on the buffer because (row pitch * (height - 1) + width) * depth overflows
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 4, 3, 1, 0, destination, 0, 512)
.CopyTextureToBuffer(source, 0, 0, 0, 4, 3, 1, 0, 0, destination, 0, 512)
.GetResult();
}
@ -466,7 +473,7 @@ TEST_F(CopyCommandTest_T2B, OutOfBoundsOnBuffer) {
ASSERT_TRUE(256 * 3 > destinationBufferSize) << "row pitch * height should overflow buffer";
dawn::Buffer destinationBuffer = CreateBuffer(destinationBufferSize, dawn::BufferUsageBit::TransferDst);
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 7, 3, 1, 0, destinationBuffer, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 7, 3, 1, 0, 0, destinationBuffer, 0, 256)
.GetResult();
}
}
@ -474,21 +481,21 @@ TEST_F(CopyCommandTest_T2B, OutOfBoundsOnBuffer) {
// Test that we force Z=0 and Depth=1 on copies from to 2D textures
TEST_F(CopyCommandTest_T2B, ZDepthConstraintFor2DTextures) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Texture source = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture source = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferSrc);
dawn::Buffer destination = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferDst);
// Z=1 on an empty copy still errors
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 1, 0, 0, 1, 0, destination, 0, 0)
.CopyTextureToBuffer(source, 0, 0, 1, 0, 0, 1, 0, 0, destination, 0, 0)
.GetResult();
}
// Depth=0 on an empty copy still errors
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 0, 0, destination, 0, 0)
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 0, 0, 0, destination, 0, 0)
.GetResult();
}
}
@ -496,9 +503,9 @@ TEST_F(CopyCommandTest_T2B, ZDepthConstraintFor2DTextures) {
// Test T2B copies with incorrect buffer usage
TEST_F(CopyCommandTest_T2B, IncorrectUsage) {
uint32_t bufferSize = BufferSizeForTextureCopy(4, 4, 1);
dawn::Texture source = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture source = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferSrc);
dawn::Texture sampled = Create2DTexture(16, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture sampled = Create2DTexture(16, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::Sampled);
dawn::Buffer destination = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferDst);
dawn::Buffer vertex = CreateBuffer(bufferSize, dawn::BufferUsageBit::Vertex);
@ -506,42 +513,42 @@ TEST_F(CopyCommandTest_T2B, IncorrectUsage) {
// Incorrect source usage
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(sampled, 0, 0, 0, 4, 4, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(sampled, 0, 0, 0, 4, 4, 1, 0, 0, destination, 0, 256)
.GetResult();
}
// Incorrect destination usage
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, vertex, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, 0, vertex, 0, 256)
.GetResult();
}
}
TEST_F(CopyCommandTest_T2B, IncorrectRowPitch) {
uint32_t bufferSize = BufferSizeForTextureCopy(128, 16, 1);
dawn::Texture source = Create2DTexture(128, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::Texture source = Create2DTexture(128, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferDst);
dawn::Buffer destination = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferSrc);
// Default row pitch is not 256-byte aligned
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 3, 4, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 3, 4, 1, 0, 0, destination, 0, 256)
.GetResult();
}
// Row pitch is not 256-byte aligned
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, destination, 0, 257)
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, 0, destination, 0, 257)
.GetResult();
}
// Row pitch is less than width * bytesPerPixel
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 65, 1, 1, 0, destination, 0, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 65, 1, 1, 0, 0, destination, 0, 256)
.GetResult();
}
}
@ -549,30 +556,30 @@ TEST_F(CopyCommandTest_T2B, IncorrectRowPitch) {
// Test T2B copies with incorrect buffer offset usage
TEST_F(CopyCommandTest_T2B, IncorrectBufferOffset) {
uint32_t bufferSize = BufferSizeForTextureCopy(128, 16, 1);
dawn::Texture source = Create2DTexture(128, 16, 5, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferSrc);
dawn::Texture source = Create2DTexture(128, 16, 5, 1, dawn::TextureFormat::R8G8B8A8Unorm,
dawn::TextureUsageBit::TransferSrc);
dawn::Buffer destination = CreateBuffer(bufferSize, dawn::BufferUsageBit::TransferDst);
// Correct usage
{
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, destination, bufferSize - 4, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, 0, destination, bufferSize - 4, 256)
.GetResult();
}
// Incorrect usages
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, destination, bufferSize - 5, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, 0, destination, bufferSize - 5, 256)
.GetResult();
}
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, destination, bufferSize - 6, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, 0, destination, bufferSize - 6, 256)
.GetResult();
}
{
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, destination, bufferSize - 7, 256)
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, 0, destination, bufferSize - 7, 256)
.GetResult();
}
}