Change Copy Operation Interfaces to Match WebGPU IDL
Cosmetic changes to copyBufferToTexture and copyTextureToBuffer to match WebGPU IDL. Introduces BufferCopyView, TextureCopyView, TextureAspect, and Origin3D types. Bug: dawn:17 Change-Id: Ic0e7f472a9dc1353d3fc3839ff02f348bb6067e8 Reviewed-on: https://dawn-review.googlesource.com/c/2520 Commit-Queue: Brandon1 Jones <brandon1.jones@intel.com> Reviewed-by: Kai Ninomiya <kainino@chromium.org>
This commit is contained in:
parent
e06d57d338
commit
ac71e34d4a
79
dawn.json
79
dawn.json
|
@ -240,6 +240,16 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"buffer copy view": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
"members": [
|
||||
{"name": "buffer", "type": "buffer"},
|
||||
{"name": "offset", "type": "uint32_t"},
|
||||
{"name": "row pitch", "type": "uint32_t"},
|
||||
{"name": "image height", "type": "uint32_t"}
|
||||
]
|
||||
},
|
||||
"buffer descriptor": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
|
@ -350,47 +360,17 @@
|
|||
{
|
||||
"name": "copy buffer to texture",
|
||||
"args": [
|
||||
{"name": "buffer", "type": "buffer"},
|
||||
{"name": "buffer offset", "type": "uint32_t"},
|
||||
{"name": "row pitch", "type": "uint32_t"},
|
||||
{"name": "texture", "type": "texture"},
|
||||
{"name": "x", "type": "uint32_t"},
|
||||
{"name": "y", "type": "uint32_t"},
|
||||
{"name": "z", "type": "uint32_t"},
|
||||
{"name": "width", "type": "uint32_t"},
|
||||
{"name": "height", "type": "uint32_t"},
|
||||
{"name": "depth", "type": "uint32_t"},
|
||||
{"name": "level", "type": "uint32_t"},
|
||||
{"name": "slice", "type": "uint32_t"}
|
||||
],
|
||||
"TODO": [
|
||||
"Make pretty with Offset and Extents structures",
|
||||
"Allow choosing the aspect (depth vs. stencil)?",
|
||||
"Add these arguments too",
|
||||
{"name": "image height", "type": "uint32_t"}
|
||||
{"name": "source", "type": "buffer copy view", "annotation": "const*"},
|
||||
{"name": "destination", "type": "texture copy view", "annotation": "const*"},
|
||||
{"name": "copy size", "type": "extent 3D", "annotation": "const*"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "copy texture to buffer",
|
||||
"args": [
|
||||
{"name": "texture", "type": "texture"},
|
||||
{"name": "x", "type": "uint32_t"},
|
||||
{"name": "y", "type": "uint32_t"},
|
||||
{"name": "z", "type": "uint32_t"},
|
||||
{"name": "width", "type": "uint32_t"},
|
||||
{"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"}
|
||||
],
|
||||
"TODO": [
|
||||
"Make pretty with Offset and Extents structures",
|
||||
"Allow choosing the aspect (depth vs. stencil)?",
|
||||
"Add these arguments too",
|
||||
{"name": "image height", "type": "uint32_t"}
|
||||
{"name": "source", "type": "texture copy view", "annotation": "const*"},
|
||||
{"name": "destination", "type": "buffer copy view", "annotation": "const*"},
|
||||
{"name": "copy size", "type": "extent 3D", "annotation": "const*"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
@ -689,6 +669,14 @@
|
|||
{"value": 1, "name": "load"}
|
||||
]
|
||||
},
|
||||
"origin 3D": {
|
||||
"category": "structure",
|
||||
"members": [
|
||||
{"name": "x", "type": "uint32_t"},
|
||||
{"name": "y", "type": "uint32_t"},
|
||||
{"name": "z", "type": "uint32_t"}
|
||||
]
|
||||
},
|
||||
"pipeline layout": {
|
||||
"category": "object"
|
||||
},
|
||||
|
@ -1046,6 +1034,25 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"texture aspect": {
|
||||
"category": "bitmask",
|
||||
"values": [
|
||||
{"value": 1, "name": "color"},
|
||||
{"value": 2, "name": "depth"},
|
||||
{"value": 4, "name": "stencil"}
|
||||
]
|
||||
},
|
||||
"texture copy view": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
"members": [
|
||||
{"name": "texture", "type": "texture"},
|
||||
{"name": "level", "type": "uint32_t"},
|
||||
{"name": "slice", "type": "uint32_t"},
|
||||
{"name": "origin", "type": "origin 3D"},
|
||||
{"name": "aspect", "type": "texture aspect"}
|
||||
]
|
||||
},
|
||||
"texture descriptor": {
|
||||
"category": "structure",
|
||||
"extensible": true,
|
||||
|
|
|
@ -68,11 +68,15 @@ void initTextures() {
|
|||
data[i] = static_cast<uint8_t>(i % 253);
|
||||
}
|
||||
|
||||
|
||||
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, 0)
|
||||
.GetResult();
|
||||
dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 0, 0);
|
||||
dawn::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {1024, 1024, 1};
|
||||
dawn::CommandBuffer copy =
|
||||
device.CreateCommandBufferBuilder()
|
||||
.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size)
|
||||
.GetResult();
|
||||
|
||||
queue.Submit(1, ©);
|
||||
}
|
||||
|
|
|
@ -433,9 +433,14 @@ namespace {
|
|||
}
|
||||
|
||||
dawn::Buffer staging = utils::CreateBufferFromData(device, data, rowPitch * iImage.height, dawn::BufferUsageBit::TransferSrc);
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(staging, 0, rowPitch, 0);
|
||||
dawn::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(oTexture, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {iImage.width, iImage.height, 1};
|
||||
auto cmdbuf = device.CreateCommandBufferBuilder()
|
||||
.CopyBufferToTexture(staging, 0, rowPitch, oTexture, 0, 0, 0, iImage.width, iImage.height, 1, 0, 0)
|
||||
.GetResult();
|
||||
.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size)
|
||||
.GetResult();
|
||||
queue.Submit(1, &cmdbuf);
|
||||
|
||||
textures[iTextureID] = oTexture.CreateDefaultTextureView();
|
||||
|
|
|
@ -645,76 +645,58 @@ namespace dawn_native {
|
|||
copy->size = size;
|
||||
}
|
||||
|
||||
void CommandBufferBuilder::CopyBufferToTexture(BufferBase* buffer,
|
||||
uint32_t bufferOffset,
|
||||
uint32_t rowPitch,
|
||||
TextureBase* texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t z,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
uint32_t level,
|
||||
uint32_t slice) {
|
||||
void CommandBufferBuilder::CopyBufferToTexture(const BufferCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
if (ConsumedError(ValidateCanRecordTopLevelCommands())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowPitch == 0) {
|
||||
rowPitch = ComputeDefaultRowPitch(texture, width);
|
||||
}
|
||||
CopyBufferToTextureCmd* copy =
|
||||
mAllocator.Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
|
||||
new (copy) CopyBufferToTextureCmd;
|
||||
copy->source.buffer = buffer;
|
||||
copy->source.offset = bufferOffset;
|
||||
copy->destination.texture = texture;
|
||||
copy->destination.x = x;
|
||||
copy->destination.y = y;
|
||||
copy->destination.z = z;
|
||||
copy->destination.width = width;
|
||||
copy->destination.height = height;
|
||||
copy->destination.depth = depth;
|
||||
copy->destination.level = level;
|
||||
copy->destination.slice = slice;
|
||||
copy->rowPitch = rowPitch;
|
||||
copy->source.buffer = source->buffer;
|
||||
copy->source.offset = source->offset;
|
||||
copy->destination.texture = destination->texture;
|
||||
copy->destination.x = destination->origin.x;
|
||||
copy->destination.y = destination->origin.y;
|
||||
copy->destination.z = destination->origin.z;
|
||||
copy->destination.width = copySize->width;
|
||||
copy->destination.height = copySize->height;
|
||||
copy->destination.depth = copySize->depth;
|
||||
copy->destination.level = destination->level;
|
||||
copy->destination.slice = destination->slice;
|
||||
if (source->rowPitch == 0) {
|
||||
copy->rowPitch = ComputeDefaultRowPitch(destination->texture, copySize->width);
|
||||
} else {
|
||||
copy->rowPitch = source->rowPitch;
|
||||
}
|
||||
}
|
||||
|
||||
void CommandBufferBuilder::CopyTextureToBuffer(TextureBase* texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t z,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
uint32_t level,
|
||||
uint32_t slice,
|
||||
BufferBase* buffer,
|
||||
uint32_t bufferOffset,
|
||||
uint32_t rowPitch) {
|
||||
void CommandBufferBuilder::CopyTextureToBuffer(const TextureCopyView* source,
|
||||
const BufferCopyView* destination,
|
||||
const Extent3D* copySize) {
|
||||
if (ConsumedError(ValidateCanRecordTopLevelCommands())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowPitch == 0) {
|
||||
rowPitch = ComputeDefaultRowPitch(texture, width);
|
||||
}
|
||||
CopyTextureToBufferCmd* copy =
|
||||
mAllocator.Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
|
||||
new (copy) CopyTextureToBufferCmd;
|
||||
copy->source.texture = texture;
|
||||
copy->source.x = x;
|
||||
copy->source.y = y;
|
||||
copy->source.z = z;
|
||||
copy->source.width = width;
|
||||
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;
|
||||
copy->source.texture = source->texture;
|
||||
copy->source.x = source->origin.x;
|
||||
copy->source.y = source->origin.y;
|
||||
copy->source.z = source->origin.z;
|
||||
copy->source.width = copySize->width;
|
||||
copy->source.height = copySize->height;
|
||||
copy->source.depth = copySize->depth;
|
||||
copy->source.level = source->level;
|
||||
copy->source.slice = source->slice;
|
||||
copy->destination.buffer = destination->buffer;
|
||||
copy->destination.offset = destination->offset;
|
||||
if (destination->rowPitch == 0) {
|
||||
copy->rowPitch = ComputeDefaultRowPitch(source->texture, copySize->width);
|
||||
} else {
|
||||
copy->rowPitch = destination->rowPitch;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dawn_native
|
||||
|
|
|
@ -67,30 +67,12 @@ namespace dawn_native {
|
|||
BufferBase* destination,
|
||||
uint32_t destinationOffset,
|
||||
uint32_t size);
|
||||
void CopyBufferToTexture(BufferBase* buffer,
|
||||
uint32_t bufferOffset,
|
||||
uint32_t rowPitch,
|
||||
TextureBase* texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t z,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
uint32_t level,
|
||||
uint32_t slice);
|
||||
void CopyTextureToBuffer(TextureBase* texture,
|
||||
uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t z,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
uint32_t depth,
|
||||
uint32_t level,
|
||||
uint32_t slice,
|
||||
BufferBase* buffer,
|
||||
uint32_t bufferOffset,
|
||||
uint32_t rowPitch);
|
||||
void CopyBufferToTexture(const BufferCopyView* source,
|
||||
const TextureCopyView* destination,
|
||||
const Extent3D* copySize);
|
||||
void CopyTextureToBuffer(const TextureCopyView* source,
|
||||
const BufferCopyView* destination,
|
||||
const Extent3D* copySize);
|
||||
|
||||
// Functions to interact with the encoders
|
||||
bool ConsumedError(MaybeError maybeError) {
|
||||
|
|
|
@ -301,10 +301,14 @@ std::ostringstream& DawnTest::AddTextureExpectation(const char* file,
|
|||
|
||||
// We need to enqueue the copy immediately because by the time we resolve the expectation,
|
||||
// the texture might have been modified.
|
||||
dawn::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(texture, level, 0, {x, y, 0}, dawn::TextureAspect::Color);
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(readback.buffer, readback.offset, rowPitch, 0);
|
||||
dawn::Extent3D copySize = {width, height, 1};
|
||||
dawn::CommandBuffer commands =
|
||||
device.CreateCommandBufferBuilder()
|
||||
.CopyTextureToBuffer(texture, x, y, 0, width, height, 1, level, 0, readback.buffer,
|
||||
readback.offset, rowPitch)
|
||||
.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, ©Size)
|
||||
.GetResult();
|
||||
|
||||
queue.Submit(1, &commands);
|
||||
|
|
|
@ -258,7 +258,12 @@ TEST_P(BindGroupTests, UBOSamplerAndTexture) {
|
|||
.GetResult();
|
||||
|
||||
dawn::CommandBufferBuilder builder = device.CreateCommandBufferBuilder();
|
||||
builder.CopyBufferToTexture(stagingBuffer, 0, widthInBytes, texture, 0, 0, 0, width, height, 1, 0, 0);
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(stagingBuffer, 0, widthInBytes, 0);
|
||||
dawn::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {width, height, 1};
|
||||
builder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
|
||||
dawn::RenderPassEncoder pass = builder.BeginRenderPass(renderPass.renderPassInfo);
|
||||
pass.SetRenderPipeline(pipeline);
|
||||
pass.SetBindGroup(0, bindGroup);
|
||||
|
|
|
@ -100,8 +100,12 @@ class CopyTests_T2B : public CopyTests {
|
|||
// 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);
|
||||
|
||||
cmdBuilder.CopyBufferToTexture(uploadBuffer, 0, rowPitch, texture, 0, 0, 0, width, height, 1, textureSpec.level, slice);
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0);
|
||||
dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
texture, textureSpec.level, slice, {0, 0, 0}, dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {width, height, 1};
|
||||
cmdBuilder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
|
||||
}
|
||||
|
||||
// Create a buffer of size `size * textureSpec.arrayLayer` and populate it with empty data (0,0,0,0)
|
||||
|
@ -117,7 +121,13 @@ class CopyTests_T2B : public CopyTests {
|
|||
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);
|
||||
dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
texture, textureSpec.level, slice, {textureSpec.x, textureSpec.y, 0},
|
||||
dawn::TextureAspect::Color);
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(buffer, bufferOffset, bufferSpec.rowPitch, 0);
|
||||
dawn::Extent3D copySize = {textureSpec.copyWidth, textureSpec.copyHeight, 1};
|
||||
cmdBuilder.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, ©Size);
|
||||
bufferOffset += bufferSpec.size;
|
||||
}
|
||||
|
||||
|
@ -198,12 +208,24 @@ 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);
|
||||
|
||||
cmdBuilder.CopyBufferToTexture(uploadBuffer, 0, rowPitch, texture, 0, 0, 0, width, height, 1, textureSpec.level, 0);
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(uploadBuffer, 0, rowPitch, 0);
|
||||
dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
texture, textureSpec.level, 0, {0, 0, 0}, dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {width, height, 1};
|
||||
cmdBuilder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
|
||||
}
|
||||
|
||||
// Copy to the region [(`x`, `y`), (`x + copyWidth, `y + copyWidth`)] at the `level` mip from the buffer at the specified `offset` and `rowPitch`
|
||||
cmdBuilder.CopyBufferToTexture(buffer, bufferSpec.offset, bufferSpec.rowPitch, texture, textureSpec.x, textureSpec.y, 0, textureSpec.copyWidth, textureSpec.copyHeight, 1, textureSpec.level, 0);
|
||||
{
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(buffer, bufferSpec.offset, bufferSpec.rowPitch, 0);
|
||||
dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
texture, textureSpec.level, 0, {textureSpec.x, textureSpec.y, 0},
|
||||
dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {textureSpec.copyWidth, textureSpec.copyHeight, 1};
|
||||
cmdBuilder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
|
||||
}
|
||||
|
||||
dawn::CommandBuffer commands = cmdBuilder.GetResult();
|
||||
queue.Submit(1, &commands);
|
||||
|
|
|
@ -100,9 +100,14 @@ protected:
|
|||
data[1] = data[rowPixels] = white;
|
||||
|
||||
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, 0)
|
||||
.GetResult();
|
||||
dawn::BufferCopyView bufferCopyView = utils::CreateBufferCopyView(stagingBuffer, 0, 256, 0);
|
||||
dawn::TextureCopyView textureCopyView =
|
||||
utils::CreateTextureCopyView(texture, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {2, 2, 1};
|
||||
dawn::CommandBuffer copy =
|
||||
device.CreateCommandBufferBuilder()
|
||||
.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size)
|
||||
.GetResult();
|
||||
|
||||
queue.Submit(1, ©);
|
||||
mTextureView = texture.CreateDefaultTextureView();
|
||||
|
|
|
@ -124,9 +124,12 @@ protected:
|
|||
dawn::Buffer stagingBuffer = utils::CreateBufferFromData(
|
||||
device, data.data(), data.size() * sizeof(RGBA8),
|
||||
dawn::BufferUsageBit::TransferSrc);
|
||||
builder.CopyBufferToTexture(
|
||||
stagingBuffer, 0, kTextureRowPitchAlignment, mTexture, 0, 0, 0, texWidth,
|
||||
texHeight, 1, level, layer);
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(stagingBuffer, 0, kTextureRowPitchAlignment, 0);
|
||||
dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
mTexture, level, layer, {0, 0, 0}, dawn::TextureAspect::Color);
|
||||
dawn::Extent3D copySize = {texWidth, texHeight, 1};
|
||||
builder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, ©Size);
|
||||
}
|
||||
}
|
||||
dawn::CommandBuffer copy = builder.GetResult();
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "common/Constants.h"
|
||||
#include "common/Math.h"
|
||||
#include "tests/unittests/validation/ValidationTest.h"
|
||||
#include "utils/DawnHelpers.h"
|
||||
|
||||
class CopyCommandTest : public ValidationTest {
|
||||
protected:
|
||||
|
@ -45,6 +46,64 @@ class CopyCommandTest : public ValidationTest {
|
|||
uint32_t rowPitch = Align(width * 4, kTextureRowPitchAlignment);
|
||||
return (rowPitch * (height - 1) + width) * depth;
|
||||
}
|
||||
|
||||
void TestB2TCopy(utils::Expectation expectation,
|
||||
dawn::Buffer srcBuffer,
|
||||
uint32_t srcOffset,
|
||||
uint32_t srcRowPitch,
|
||||
uint32_t srcImageHeight,
|
||||
dawn::Texture destTexture,
|
||||
uint32_t destLevel,
|
||||
uint32_t destSlice,
|
||||
dawn::Origin3D destOrigin,
|
||||
dawn::TextureAspect destAspect,
|
||||
dawn::Extent3D extent3D) {
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(srcBuffer, srcOffset, srcRowPitch, srcImageHeight);
|
||||
dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
destTexture, destLevel, destSlice, destOrigin, destAspect);
|
||||
|
||||
if (expectation == utils::Expectation::Success) {
|
||||
dawn::CommandBuffer commands =
|
||||
AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &extent3D)
|
||||
.GetResult();
|
||||
} else {
|
||||
dawn::CommandBuffer commands =
|
||||
AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &extent3D)
|
||||
.GetResult();
|
||||
}
|
||||
}
|
||||
|
||||
void TestT2BCopy(utils::Expectation expectation,
|
||||
dawn::Texture srcTexture,
|
||||
uint32_t srcLevel,
|
||||
uint32_t srcSlice,
|
||||
dawn::Origin3D srcOrigin,
|
||||
dawn::TextureAspect srcAspect,
|
||||
dawn::Buffer destBuffer,
|
||||
uint32_t destOffset,
|
||||
uint32_t destRowPitch,
|
||||
uint32_t destImageHeight,
|
||||
dawn::Extent3D extent3D) {
|
||||
dawn::BufferCopyView bufferCopyView =
|
||||
utils::CreateBufferCopyView(destBuffer, destOffset, destRowPitch, destImageHeight);
|
||||
dawn::TextureCopyView textureCopyView = utils::CreateTextureCopyView(
|
||||
srcTexture, srcLevel, srcSlice, srcOrigin, srcAspect);
|
||||
|
||||
if (expectation == utils::Expectation::Success) {
|
||||
dawn::CommandBuffer commands =
|
||||
AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, &extent3D)
|
||||
.GetResult();
|
||||
} else {
|
||||
dawn::CommandBuffer commands =
|
||||
AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(&textureCopyView, &bufferCopyView, &extent3D)
|
||||
.GetResult();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CopyCommandTest_B2B : public CopyCommandTest {
|
||||
|
@ -129,40 +188,44 @@ TEST_F(CopyCommandTest_B2T, Success) {
|
|||
|
||||
// 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, 0)
|
||||
// Copy 4x4 block in opposite corner of first mip.
|
||||
.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, 0)
|
||||
// Copy with a buffer offset
|
||||
.CopyBufferToTexture(source, bufferSize - 4, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
|
||||
.GetResult();
|
||||
// Copy 4x4 block in corner of first mip.
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
// Copy 4x4 block in opposite corner of first mip.
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {12, 12, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
// Copy 4x4 block in the 4x4 mip.
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 2, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
// Copy with a buffer offset
|
||||
TestB2TCopy(utils::Expectation::Success, source, bufferSize - 4, 256, 0, destination, 0, 0,
|
||||
{0, 0, 0}, dawn::TextureAspect::Color, {1, 1, 1});
|
||||
}
|
||||
|
||||
// Copies with a 256-byte aligned row pitch but unaligned texture region
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
// Unaligned region
|
||||
.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, 0)
|
||||
// Unaligned region, with buffer offset
|
||||
.CopyBufferToTexture(source, 31 * 4, 256, destination, 0, 0, 0, 3, 3, 1, 0, 0)
|
||||
.GetResult();
|
||||
// Unaligned region
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {3, 4, 1});
|
||||
// Unaligned region with texture offset
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {5, 7, 0},
|
||||
dawn::TextureAspect::Color, {2, 3, 1});
|
||||
// Unaligned region, with buffer offset
|
||||
TestB2TCopy(utils::Expectation::Success, source, 31 * 4, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {3, 3, 1});
|
||||
}
|
||||
|
||||
// Empty copies are valid
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
// An empty copy
|
||||
.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, 0)
|
||||
// An empty copy touching the side of the texture
|
||||
.CopyBufferToTexture(source, 0, 0, destination, 16, 16, 0, 0, 0, 1, 0, 0)
|
||||
.GetResult();
|
||||
// An empty copy
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 0, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {0, 0, 1});
|
||||
// An empty copy touching the end of the buffer
|
||||
TestB2TCopy(utils::Expectation::Success, source, bufferSize, 0, 0, destination, 0, 0, {0, 0,
|
||||
0}, dawn::TextureAspect::Color, {0, 0, 1});
|
||||
// An empty copy touching the side of the texture
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 0, 0, destination, 0, 0, {16, 16, 0},
|
||||
dawn::TextureAspect::Color, {0, 0, 1});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,25 +237,16 @@ TEST_F(CopyCommandTest_B2T, OutOfBoundsOnBuffer) {
|
|||
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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 5, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 4, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 512, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 3, 1});
|
||||
|
||||
// Not OOB on the buffer although row pitch * height overflows
|
||||
// but (row pitch * (height - 1) + width) * depth does not overlow
|
||||
|
@ -200,9 +254,9 @@ TEST_F(CopyCommandTest_B2T, OutOfBoundsOnBuffer) {
|
|||
uint32_t sourceBufferSize = BufferSizeForTextureCopy(7, 3, 1);
|
||||
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, 0)
|
||||
.GetResult();
|
||||
|
||||
TestB2TCopy(utils::Expectation::Success, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {7, 3, 1});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,39 +268,24 @@ TEST_F(CopyCommandTest_B2T, OutOfBoundsOnTexture) {
|
|||
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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, 0, {13, 12, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, 0, {12, 13, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 2, 0, {1, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 0, 0, destination, 5, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {0, 0, 1});
|
||||
|
||||
// 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();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 0, 0, destination, 0, 2, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {0, 0, 1});
|
||||
}
|
||||
|
||||
// Test that we force Z=0 and Depth=1 on copies to 2D textures
|
||||
|
@ -256,18 +295,12 @@ TEST_F(CopyCommandTest_B2T, ZDepthConstraintFor2DTextures) {
|
|||
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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 0, 0, destination, 0, 0, {0, 0, 1},
|
||||
dawn::TextureAspect::Color, {0, 0, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 0, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {0, 0, 0});
|
||||
}
|
||||
|
||||
// Test B2T copies with incorrect buffer usage
|
||||
|
@ -280,18 +313,12 @@ TEST_F(CopyCommandTest_B2T, IncorrectUsage) {
|
|||
dawn::TextureUsageBit::Sampled);
|
||||
|
||||
// Incorrect source usage
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyBufferToTexture(vertex, 0, 256, destination, 0, 0, 0, 4, 4, 1, 0, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, vertex, 0, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
|
||||
// Incorrect destination usage
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyBufferToTexture(source, 0, 256, sampled, 0, 0, 0, 4, 4, 1, 0, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, sampled, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
}
|
||||
|
||||
TEST_F(CopyCommandTest_B2T, IncorrectRowPitch) {
|
||||
|
@ -301,25 +328,16 @@ TEST_F(CopyCommandTest_B2T, IncorrectRowPitch) {
|
|||
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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 0, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {3, 4, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 128, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {4, 4, 1});
|
||||
|
||||
// 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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Failure, source, 0, 256, 0, destination, 0, 0, {0, 0, 0},
|
||||
dawn::TextureAspect::Color, {65, 1, 1});
|
||||
}
|
||||
|
||||
// Test B2T copies with incorrect buffer offset usage
|
||||
|
@ -330,26 +348,17 @@ TEST_F(CopyCommandTest_B2T, IncorrectBufferOffset) {
|
|||
dawn::TextureUsageBit::TransferDst);
|
||||
|
||||
// Correct usage
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
.CopyBufferToTexture(source, bufferSize - 4, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestB2TCopy(utils::Expectation::Success, source, bufferSize - 4, 256, 0, destination, 0, 0, {0,
|
||||
0, 0}, dawn::TextureAspect::Color, {1, 1, 1});
|
||||
|
||||
// Incorrect usages
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.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, 0)
|
||||
.GetResult();
|
||||
}
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyBufferToTexture(source, bufferSize - 7, 256, destination, 0, 0, 0, 1, 1, 1, 0, 0)
|
||||
.GetResult();
|
||||
TestB2TCopy(utils::Expectation::Failure, source, bufferSize - 5, 256, 0, destination, 0, 0,
|
||||
{0, 0, 0}, dawn::TextureAspect::Color, {1, 1, 1});
|
||||
TestB2TCopy(utils::Expectation::Failure, source, bufferSize - 6, 256, 0, destination, 0, 0,
|
||||
{0, 0, 0}, dawn::TextureAspect::Color, {1, 1, 1});
|
||||
TestB2TCopy(utils::Expectation::Failure, source, bufferSize - 7, 256, 0, destination, 0, 0,
|
||||
{0, 0, 0}, dawn::TextureAspect::Color, {1, 1, 1});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -365,40 +374,44 @@ TEST_F(CopyCommandTest_T2B, Success) {
|
|||
|
||||
// Different copies, including some that touch the OOB condition
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
// Copy from 4x4 block in corner of first mip.
|
||||
.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, 0, destination, 0, 256)
|
||||
// Copy from 4x4 block in the 4x4 mip.
|
||||
.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, 0, destination, bufferSize - 4, 256)
|
||||
.GetResult();
|
||||
// Copy from 4x4 block in corner of first mip.
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {4, 4, 1});
|
||||
// Copy from 4x4 block in opposite corner of first mip.
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {12, 12, 0},
|
||||
dawn::TextureAspect::Color, destination, 0, 256, 0, {4, 4, 1});
|
||||
// Copy from 4x4 block in the 4x4 mip.
|
||||
TestT2BCopy(utils::Expectation::Success, source, 2, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {4, 4, 1});
|
||||
// Copy with a buffer offset
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, bufferSize - 4, 256, 0, {1, 1, 1});
|
||||
}
|
||||
|
||||
// Copies with a 256-byte aligned row pitch but unaligned texture region
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
// Unaligned region
|
||||
.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, 0, destination, 0, 256)
|
||||
// Unaligned region, with buffer offset
|
||||
.CopyTextureToBuffer(source, 0, 0, 0, 3, 3, 1, 2, 0, destination, 31 * 4, 256)
|
||||
.GetResult();
|
||||
// Unaligned region
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {3, 4, 1});
|
||||
// Unaligned region with texture offset
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {5, 7, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {2, 3, 1});
|
||||
// Unaligned region, with buffer offset
|
||||
TestT2BCopy(utils::Expectation::Success, source, 2, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 31 * 4, 256, 0, {3, 3, 1});
|
||||
}
|
||||
|
||||
// Empty copies are valid
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeSuccess(device.CreateCommandBufferBuilder())
|
||||
// An empty copy
|
||||
.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, 0, destination, bufferSize, 0)
|
||||
// An empty copy touching the side of the texture
|
||||
.CopyTextureToBuffer(source, 16, 16, 0, 0, 0, 1, 0, 0, destination, 0, 0)
|
||||
.GetResult();
|
||||
// An empty copy
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 0, 0, {0, 0, 1});
|
||||
// An empty copy touching the end of the buffer
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, bufferSize, 0, 0, {0, 0, 1});
|
||||
// An empty copy touching the side of the texture
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {16, 16, 0},
|
||||
dawn::TextureAspect::Color, destination, 0, 0, 0, {0, 0, 1});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,32 +423,20 @@ TEST_F(CopyCommandTest_T2B, OutOfBoundsOnTexture) {
|
|||
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, 0, destination, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {13, 12, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {4, 4, 1});
|
||||
|
||||
// OOB on the texture because y + width overflows
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(source, 12, 13, 0, 4, 4, 1, 0, 0, destination, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {12, 13, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {4, 4, 1});
|
||||
|
||||
// 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, 0, destination, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 2, 0, {1, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {4, 4, 1});
|
||||
|
||||
// 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, 0, destination, 0, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 5, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 0, 0, {0, 0, 1});
|
||||
}
|
||||
|
||||
// Test OOB conditions on the buffer
|
||||
|
@ -446,25 +447,16 @@ TEST_F(CopyCommandTest_T2B, OutOfBoundsOnBuffer) {
|
|||
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, 0, destination, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {4, 5, 1});
|
||||
|
||||
// OOB on the buffer because of the offset
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, 0, destination, 4, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 4, 256, 0, {4, 4, 1});
|
||||
|
||||
// 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, 0, destination, 0, 512)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 512, 0, {4, 3, 1});
|
||||
|
||||
// Not OOB on the buffer although row pitch * height overflows
|
||||
// but (row pitch * (height - 1) + width) * depth does not overlow
|
||||
|
@ -472,9 +464,8 @@ TEST_F(CopyCommandTest_T2B, OutOfBoundsOnBuffer) {
|
|||
uint32_t destinationBufferSize = BufferSizeForTextureCopy(7, 3, 1);
|
||||
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, 0, destinationBuffer, 0, 256)
|
||||
.GetResult();
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destinationBuffer, 0, 256, 0, {7, 3, 1});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -486,18 +477,12 @@ TEST_F(CopyCommandTest_T2B, ZDepthConstraintFor2DTextures) {
|
|||
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, 0, destination, 0, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 1}, dawn::TextureAspect::Color,
|
||||
destination, 0, 0, 0, {0, 0, 1});
|
||||
|
||||
// Depth=0 on an empty copy still errors
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(source, 0, 0, 0, 0, 0, 0, 0, 0, destination, 0, 0)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 0, 0, {0, 0, 0});
|
||||
}
|
||||
|
||||
// Test T2B copies with incorrect buffer usage
|
||||
|
@ -511,18 +496,12 @@ TEST_F(CopyCommandTest_T2B, IncorrectUsage) {
|
|||
dawn::Buffer vertex = CreateBuffer(bufferSize, dawn::BufferUsageBit::Vertex);
|
||||
|
||||
// Incorrect source usage
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(sampled, 0, 0, 0, 4, 4, 1, 0, 0, destination, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, sampled, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {4, 4, 1});
|
||||
|
||||
// Incorrect destination usage
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, 0, vertex, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
vertex, 0, 256, 0, {4, 4, 1});
|
||||
}
|
||||
|
||||
TEST_F(CopyCommandTest_T2B, IncorrectRowPitch) {
|
||||
|
@ -532,25 +511,16 @@ TEST_F(CopyCommandTest_T2B, IncorrectRowPitch) {
|
|||
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, 0, destination, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {3, 4, 1});
|
||||
|
||||
// Row pitch is not 256-byte aligned
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(source, 0, 0, 0, 4, 4, 1, 0, 0, destination, 0, 257)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 257, 0, {4, 4, 1});
|
||||
|
||||
// Row pitch is less than width * bytesPerPixel
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(source, 0, 0, 0, 65, 1, 1, 0, 0, destination, 0, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, 0, 256, 0, {65, 1, 1});
|
||||
}
|
||||
|
||||
// Test T2B copies with incorrect buffer offset usage
|
||||
|
@ -561,26 +531,15 @@ TEST_F(CopyCommandTest_T2B, IncorrectBufferOffset) {
|
|||
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, 0, destination, bufferSize - 4, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Success, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, bufferSize - 4, 256, 0, {1, 1, 1});
|
||||
|
||||
// Incorrect usages
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.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, 0, destination, bufferSize - 6, 256)
|
||||
.GetResult();
|
||||
}
|
||||
{
|
||||
dawn::CommandBuffer commands = AssertWillBeError(device.CreateCommandBufferBuilder())
|
||||
.CopyTextureToBuffer(source, 0, 0, 0, 1, 1, 1, 0, 0, destination, bufferSize - 7, 256)
|
||||
.GetResult();
|
||||
}
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, bufferSize - 5, 256, 0, {1, 1, 1});
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, bufferSize - 6, 256, 0, {1, 1, 1});
|
||||
TestT2BCopy(utils::Expectation::Failure, source, 0, 0, {0, 0, 0}, dawn::TextureAspect::Color,
|
||||
destination, bufferSize - 7, 256, 0, {1, 1, 1});
|
||||
}
|
||||
|
||||
|
|
|
@ -153,6 +153,34 @@ namespace utils {
|
|||
return result;
|
||||
}
|
||||
|
||||
dawn::BufferCopyView CreateBufferCopyView(dawn::Buffer buffer,
|
||||
uint32_t offset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight) {
|
||||
dawn::BufferCopyView bufferCopyView;
|
||||
bufferCopyView.buffer = buffer;
|
||||
bufferCopyView.offset = offset;
|
||||
bufferCopyView.rowPitch = rowPitch;
|
||||
bufferCopyView.imageHeight = imageHeight;
|
||||
|
||||
return bufferCopyView;
|
||||
}
|
||||
|
||||
dawn::TextureCopyView CreateTextureCopyView(dawn::Texture texture,
|
||||
uint32_t level,
|
||||
uint32_t slice,
|
||||
dawn::Origin3D origin,
|
||||
dawn::TextureAspect aspect) {
|
||||
dawn::TextureCopyView textureCopyView;
|
||||
textureCopyView.texture = texture;
|
||||
textureCopyView.level = level;
|
||||
textureCopyView.slice = slice;
|
||||
textureCopyView.origin = origin;
|
||||
textureCopyView.aspect = aspect;
|
||||
|
||||
return textureCopyView;
|
||||
}
|
||||
|
||||
dawn::SamplerDescriptor GetDefaultSamplerDescriptor() {
|
||||
dawn::SamplerDescriptor desc;
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
namespace utils {
|
||||
|
||||
enum Expectation { Success, Failure };
|
||||
|
||||
dawn::ShaderModule CreateShaderModule(const dawn::Device& device,
|
||||
dawn::ShaderStage stage,
|
||||
const char* source);
|
||||
|
@ -35,6 +37,16 @@ namespace utils {
|
|||
return CreateBufferFromData(device, data.begin(), uint32_t(sizeof(T) * data.size()), usage);
|
||||
}
|
||||
|
||||
dawn::BufferCopyView CreateBufferCopyView(dawn::Buffer buffer,
|
||||
uint32_t offset,
|
||||
uint32_t rowPitch,
|
||||
uint32_t imageHeight);
|
||||
dawn::TextureCopyView CreateTextureCopyView(dawn::Texture texture,
|
||||
uint32_t level,
|
||||
uint32_t slice,
|
||||
dawn::Origin3D origin,
|
||||
dawn::TextureAspect aspect);
|
||||
|
||||
struct BasicRenderPass {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
|
Loading…
Reference in New Issue