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:
parent
ec72443bf1
commit
4b74dbef7b
|
@ -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"}
|
||||
|
|
|
@ -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, ©);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, ©);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue