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

@@ -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();
}
}