Move zero-size copy skips from the frontend to the backend
Bug: chromium:1217741 Change-Id: Ib4884b5aa80124ed9da48262fcae11cf6d605034 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/53883 Commit-Queue: Austin Eng <enga@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
This commit is contained in:
parent
5173a0236d
commit
f8a0f82fad
|
@ -633,16 +633,13 @@ namespace dawn_native {
|
|||
mTopLevelBuffers.insert(destination);
|
||||
}
|
||||
|
||||
// Skip noop copies. Some backends validation rules disallow them.
|
||||
if (size != 0) {
|
||||
CopyBufferToBufferCmd* copy =
|
||||
allocator->Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
|
||||
copy->source = source;
|
||||
copy->sourceOffset = sourceOffset;
|
||||
copy->destination = destination;
|
||||
copy->destinationOffset = destinationOffset;
|
||||
copy->size = size;
|
||||
}
|
||||
CopyBufferToBufferCmd* copy =
|
||||
allocator->Allocate<CopyBufferToBufferCmd>(Command::CopyBufferToBuffer);
|
||||
copy->source = source;
|
||||
copy->sourceOffset = sourceOffset;
|
||||
copy->destination = destination;
|
||||
copy->destinationOffset = destinationOffset;
|
||||
copy->size = size;
|
||||
|
||||
return {};
|
||||
});
|
||||
|
@ -682,23 +679,18 @@ namespace dawn_native {
|
|||
|
||||
ApplyDefaultTextureDataLayoutOptions(&srcLayout, blockInfo, *copySize);
|
||||
|
||||
// Skip noop copies.
|
||||
if (copySize->width != 0 && copySize->height != 0 &&
|
||||
copySize->depthOrArrayLayers != 0) {
|
||||
// Record the copy command.
|
||||
CopyBufferToTextureCmd* copy =
|
||||
allocator->Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
|
||||
copy->source.buffer = source->buffer;
|
||||
copy->source.offset = srcLayout.offset;
|
||||
copy->source.bytesPerRow = srcLayout.bytesPerRow;
|
||||
copy->source.rowsPerImage = srcLayout.rowsPerImage;
|
||||
copy->destination.texture = destination->texture;
|
||||
copy->destination.origin = destination->origin;
|
||||
copy->destination.mipLevel = destination->mipLevel;
|
||||
copy->destination.aspect =
|
||||
ConvertAspect(destination->texture->GetFormat(), destination->aspect);
|
||||
copy->copySize = *copySize;
|
||||
}
|
||||
CopyBufferToTextureCmd* copy =
|
||||
allocator->Allocate<CopyBufferToTextureCmd>(Command::CopyBufferToTexture);
|
||||
copy->source.buffer = source->buffer;
|
||||
copy->source.offset = srcLayout.offset;
|
||||
copy->source.bytesPerRow = srcLayout.bytesPerRow;
|
||||
copy->source.rowsPerImage = srcLayout.rowsPerImage;
|
||||
copy->destination.texture = destination->texture;
|
||||
copy->destination.origin = destination->origin;
|
||||
copy->destination.mipLevel = destination->mipLevel;
|
||||
copy->destination.aspect =
|
||||
ConvertAspect(destination->texture->GetFormat(), destination->aspect);
|
||||
copy->copySize = *copySize;
|
||||
|
||||
return {};
|
||||
});
|
||||
|
@ -738,22 +730,17 @@ namespace dawn_native {
|
|||
|
||||
ApplyDefaultTextureDataLayoutOptions(&dstLayout, blockInfo, *copySize);
|
||||
|
||||
// Skip noop copies.
|
||||
if (copySize->width != 0 && copySize->height != 0 &&
|
||||
copySize->depthOrArrayLayers != 0) {
|
||||
// Record the copy command.
|
||||
CopyTextureToBufferCmd* copy =
|
||||
allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
|
||||
copy->source.texture = source->texture;
|
||||
copy->source.origin = source->origin;
|
||||
copy->source.mipLevel = source->mipLevel;
|
||||
copy->source.aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
|
||||
copy->destination.buffer = destination->buffer;
|
||||
copy->destination.offset = dstLayout.offset;
|
||||
copy->destination.bytesPerRow = dstLayout.bytesPerRow;
|
||||
copy->destination.rowsPerImage = dstLayout.rowsPerImage;
|
||||
copy->copySize = *copySize;
|
||||
}
|
||||
CopyTextureToBufferCmd* copy =
|
||||
allocator->Allocate<CopyTextureToBufferCmd>(Command::CopyTextureToBuffer);
|
||||
copy->source.texture = source->texture;
|
||||
copy->source.origin = source->origin;
|
||||
copy->source.mipLevel = source->mipLevel;
|
||||
copy->source.aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
|
||||
copy->destination.buffer = destination->buffer;
|
||||
copy->destination.offset = dstLayout.offset;
|
||||
copy->destination.bytesPerRow = dstLayout.bytesPerRow;
|
||||
copy->destination.rowsPerImage = dstLayout.rowsPerImage;
|
||||
copy->copySize = *copySize;
|
||||
|
||||
return {};
|
||||
});
|
||||
|
@ -783,22 +770,18 @@ namespace dawn_native {
|
|||
mTopLevelTextures.insert(destination->texture);
|
||||
}
|
||||
|
||||
// Skip noop copies.
|
||||
if (copySize->width != 0 && copySize->height != 0 &&
|
||||
copySize->depthOrArrayLayers != 0) {
|
||||
CopyTextureToTextureCmd* copy =
|
||||
allocator->Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture);
|
||||
copy->source.texture = source->texture;
|
||||
copy->source.origin = source->origin;
|
||||
copy->source.mipLevel = source->mipLevel;
|
||||
copy->source.aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
|
||||
copy->destination.texture = destination->texture;
|
||||
copy->destination.origin = destination->origin;
|
||||
copy->destination.mipLevel = destination->mipLevel;
|
||||
copy->destination.aspect =
|
||||
ConvertAspect(destination->texture->GetFormat(), destination->aspect);
|
||||
copy->copySize = *copySize;
|
||||
}
|
||||
CopyTextureToTextureCmd* copy =
|
||||
allocator->Allocate<CopyTextureToTextureCmd>(Command::CopyTextureToTexture);
|
||||
copy->source.texture = source->texture;
|
||||
copy->source.origin = source->origin;
|
||||
copy->source.mipLevel = source->mipLevel;
|
||||
copy->source.aspect = ConvertAspect(source->texture->GetFormat(), source->aspect);
|
||||
copy->destination.texture = destination->texture;
|
||||
copy->destination.origin = destination->origin;
|
||||
copy->destination.mipLevel = destination->mipLevel;
|
||||
copy->destination.aspect =
|
||||
ConvertAspect(destination->texture->GetFormat(), destination->aspect);
|
||||
copy->copySize = *copySize;
|
||||
|
||||
return {};
|
||||
});
|
||||
|
|
|
@ -626,6 +626,10 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
case Command::CopyBufferToBuffer: {
|
||||
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
|
||||
if (copy->size == 0) {
|
||||
// Skip no-op copies.
|
||||
break;
|
||||
}
|
||||
Buffer* srcBuffer = ToBackend(copy->source.Get());
|
||||
Buffer* dstBuffer = ToBackend(copy->destination.Get());
|
||||
|
||||
|
@ -646,6 +650,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
case Command::CopyBufferToTexture: {
|
||||
CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
Buffer* buffer = ToBackend(copy->source.buffer.Get());
|
||||
Texture* texture = ToBackend(copy->destination.texture.Get());
|
||||
|
||||
|
@ -676,6 +685,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
|
||||
case Command::CopyTextureToBuffer: {
|
||||
CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
Texture* texture = ToBackend(copy->source.texture.Get());
|
||||
Buffer* buffer = ToBackend(copy->destination.buffer.Get());
|
||||
|
||||
|
@ -700,7 +714,11 @@ namespace dawn_native { namespace d3d12 {
|
|||
case Command::CopyTextureToTexture: {
|
||||
CopyTextureToTextureCmd* copy =
|
||||
mCommands.NextCommand<CopyTextureToTextureCmd>();
|
||||
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
Texture* source = ToBackend(copy->source.texture.Get());
|
||||
Texture* destination = ToBackend(copy->destination.texture.Get());
|
||||
|
||||
|
|
|
@ -704,6 +704,10 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
case Command::CopyBufferToBuffer: {
|
||||
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
|
||||
if (copy->size == 0) {
|
||||
// Skip no-op copies.
|
||||
break;
|
||||
}
|
||||
|
||||
ToBackend(copy->source)->EnsureDataInitialized(commandContext);
|
||||
ToBackend(copy->destination)
|
||||
|
@ -721,6 +725,11 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
case Command::CopyBufferToTexture: {
|
||||
CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
auto& copySize = copy->copySize;
|
||||
|
@ -739,6 +748,11 @@ namespace dawn_native { namespace metal {
|
|||
|
||||
case Command::CopyTextureToBuffer: {
|
||||
CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
auto& copySize = copy->copySize;
|
||||
|
@ -814,6 +828,11 @@ namespace dawn_native { namespace metal {
|
|||
case Command::CopyTextureToTexture: {
|
||||
CopyTextureToTextureCmd* copy =
|
||||
mCommands.NextCommand<CopyTextureToTextureCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
Texture* srcTexture = ToBackend(copy->source.texture.Get());
|
||||
Texture* dstTexture = ToBackend(copy->destination.texture.Get());
|
||||
|
||||
|
|
|
@ -612,6 +612,10 @@ namespace dawn_native { namespace opengl {
|
|||
|
||||
case Command::CopyBufferToBuffer: {
|
||||
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
|
||||
if (copy->size == 0) {
|
||||
// Skip no-op copies.
|
||||
break;
|
||||
}
|
||||
|
||||
ToBackend(copy->source)->EnsureDataInitialized();
|
||||
ToBackend(copy->destination)
|
||||
|
@ -630,6 +634,11 @@ namespace dawn_native { namespace opengl {
|
|||
|
||||
case Command::CopyBufferToTexture: {
|
||||
CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
Buffer* buffer = ToBackend(src.buffer.Get());
|
||||
|
@ -664,6 +673,11 @@ namespace dawn_native { namespace opengl {
|
|||
|
||||
case Command::CopyTextureToBuffer: {
|
||||
CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
auto& copySize = copy->copySize;
|
||||
|
@ -771,6 +785,11 @@ namespace dawn_native { namespace opengl {
|
|||
case Command::CopyTextureToTexture: {
|
||||
CopyTextureToTextureCmd* copy =
|
||||
mCommands.NextCommand<CopyTextureToTextureCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
|
||||
|
|
|
@ -516,6 +516,10 @@ namespace dawn_native { namespace vulkan {
|
|||
switch (type) {
|
||||
case Command::CopyBufferToBuffer: {
|
||||
CopyBufferToBufferCmd* copy = mCommands.NextCommand<CopyBufferToBufferCmd>();
|
||||
if (copy->size == 0) {
|
||||
// Skip no-op copies.
|
||||
break;
|
||||
}
|
||||
|
||||
Buffer* srcBuffer = ToBackend(copy->source.Get());
|
||||
Buffer* dstBuffer = ToBackend(copy->destination.Get());
|
||||
|
@ -540,6 +544,11 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
case Command::CopyBufferToTexture: {
|
||||
CopyBufferToTextureCmd* copy = mCommands.NextCommand<CopyBufferToTextureCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
|
||||
|
@ -578,6 +587,11 @@ namespace dawn_native { namespace vulkan {
|
|||
|
||||
case Command::CopyTextureToBuffer: {
|
||||
CopyTextureToBufferCmd* copy = mCommands.NextCommand<CopyTextureToBufferCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
auto& src = copy->source;
|
||||
auto& dst = copy->destination;
|
||||
|
||||
|
@ -610,6 +624,11 @@ namespace dawn_native { namespace vulkan {
|
|||
case Command::CopyTextureToTexture: {
|
||||
CopyTextureToTextureCmd* copy =
|
||||
mCommands.NextCommand<CopyTextureToTextureCmd>();
|
||||
if (copy->copySize.width == 0 || copy->copySize.height == 0 ||
|
||||
copy->copySize.depthOrArrayLayers == 0) {
|
||||
// Skip no-op copies.
|
||||
continue;
|
||||
}
|
||||
TextureCopy& src = copy->source;
|
||||
TextureCopy& dst = copy->destination;
|
||||
SubresourceRange srcRange = GetSubresourcesAffectedByCopy(src, copy->copySize);
|
||||
|
|
|
@ -226,6 +226,22 @@ TEST_F(CopyCommandTest_B2B, Success) {
|
|||
}
|
||||
}
|
||||
|
||||
// Test a successful B2B copy where the last external reference is dropped.
|
||||
// This is a regression test for crbug.com/1217741 where submitting a command
|
||||
// buffer with dropped resources when the copy size is 0 was a use-after-free.
|
||||
TEST_F(CopyCommandTest_B2B, DroppedBuffer) {
|
||||
wgpu::Buffer source = CreateBuffer(16, wgpu::BufferUsage::CopySrc);
|
||||
wgpu::Buffer destination = CreateBuffer(16, wgpu::BufferUsage::CopyDst);
|
||||
|
||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyBufferToBuffer(source, 0, destination, 0, 0);
|
||||
wgpu::CommandBuffer commandBuffer = encoder.Finish();
|
||||
|
||||
source = nullptr;
|
||||
destination = nullptr;
|
||||
device.GetQueue().Submit(1, &commandBuffer);
|
||||
}
|
||||
|
||||
// Test B2B copies with OOB
|
||||
TEST_F(CopyCommandTest_B2B, OutOfBounds) {
|
||||
wgpu::Buffer source = CreateBuffer(16, wgpu::BufferUsage::CopySrc);
|
||||
|
|
Loading…
Reference in New Issue