Add vulkan external memory large image test
This test catches when image layout is broken, by copying a non-trivial image after it's imported across devices. Bug: dawn:206 Change-Id: Ic980cfe31c0e564176c6c060f4a1fab220737938 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/10162 Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Commit-Queue: Idan Raiter <idanr@google.com>
This commit is contained in:
parent
0b2599c892
commit
786f76574a
|
@ -12,6 +12,7 @@
|
|||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "common/Math.h"
|
||||
#include "tests/DawnTest.h"
|
||||
|
||||
#include "common/vulkan_platform.h"
|
||||
|
@ -908,5 +909,111 @@ TEST_P(VulkanImageWrappingUsageTests, ChainTextureCopy) {
|
|||
IgnoreSignalSemaphore(device, wrappedTexCDevice1);
|
||||
}
|
||||
|
||||
// Tests a larger image is preserved when importing
|
||||
// TODO(http://crbug.com/dawn/206): This fails on AMD
|
||||
TEST_P(VulkanImageWrappingUsageTests, LargerImage) {
|
||||
DAWN_SKIP_TEST_IF(UsesWire() || IsIntel() || IsAMD());
|
||||
|
||||
close(defaultFd);
|
||||
|
||||
dawn::TextureDescriptor descriptor;
|
||||
descriptor.dimension = dawn::TextureDimension::e2D;
|
||||
descriptor.size.width = 640;
|
||||
descriptor.size.height = 480;
|
||||
descriptor.size.depth = 1;
|
||||
descriptor.arrayLayerCount = 1;
|
||||
descriptor.sampleCount = 1;
|
||||
descriptor.format = dawn::TextureFormat::BGRA8Unorm;
|
||||
descriptor.mipLevelCount = 1;
|
||||
descriptor.usage = dawn::TextureUsageBit::CopyDst | dawn::TextureUsageBit::CopySrc;
|
||||
|
||||
// Fill memory with textures to trigger layout issues on AMD
|
||||
std::vector<dawn::Texture> textures;
|
||||
for (int i = 0; i < 20; i++) {
|
||||
textures.push_back(device.CreateTexture(&descriptor));
|
||||
}
|
||||
|
||||
dawn::Queue secondDeviceQueue = secondDevice.CreateQueue();
|
||||
|
||||
// Make an image on |secondDevice|
|
||||
VkImage imageA;
|
||||
VkDeviceMemory allocationA;
|
||||
int memoryFdA;
|
||||
VkDeviceSize allocationSizeA;
|
||||
uint32_t memoryTypeIndexA;
|
||||
CreateBindExportImage(secondDeviceVk, 640, 480, VK_FORMAT_R8G8B8A8_UNORM, &imageA, &allocationA,
|
||||
&allocationSizeA, &memoryTypeIndexA, &memoryFdA);
|
||||
|
||||
// Import the image on |secondDevice|
|
||||
dawn::Texture wrappedTexture = WrapVulkanImage(secondDevice, &descriptor, memoryFdA,
|
||||
allocationSizeA, memoryTypeIndexA, {});
|
||||
|
||||
// Draw a non-trivial picture
|
||||
int width = 640, height = 480, pixelSize = 4;
|
||||
uint32_t rowPitch = Align(width * pixelSize, kTextureRowPitchAlignment);
|
||||
uint32_t size = rowPitch * (height - 1) + width * pixelSize;
|
||||
unsigned char data[size];
|
||||
for (int row = 0; row < height; row++) {
|
||||
for (int col = 0; col < width; col++) {
|
||||
float normRow = static_cast<float>(row) / height;
|
||||
float normCol = static_cast<float>(col) / width;
|
||||
float dist = sqrt(normRow * normRow + normCol * normCol) * 3;
|
||||
dist = dist - static_cast<int>(dist);
|
||||
data[4 * (row * width + col)] = static_cast<unsigned char>(dist * 255);
|
||||
data[4 * (row * width + col) + 1] = static_cast<unsigned char>(dist * 255);
|
||||
data[4 * (row * width + col) + 2] = static_cast<unsigned char>(dist * 255);
|
||||
data[4 * (row * width + col) + 3] = 255;
|
||||
}
|
||||
}
|
||||
|
||||
// Write the picture
|
||||
{
|
||||
dawn::Buffer copySrcBuffer =
|
||||
utils::CreateBufferFromData(secondDevice, data, size, dawn::BufferUsageBit::CopySrc);
|
||||
dawn::BufferCopyView copySrc = utils::CreateBufferCopyView(copySrcBuffer, 0, rowPitch, 0);
|
||||
dawn::TextureCopyView copyDst =
|
||||
utils::CreateTextureCopyView(wrappedTexture, 0, 0, {0, 0, 0});
|
||||
dawn::Extent3D copySize = {width, height, 1};
|
||||
|
||||
dawn::CommandEncoder encoder = secondDevice.CreateCommandEncoder();
|
||||
encoder.CopyBufferToTexture(©Src, ©Dst, ©Size);
|
||||
dawn::CommandBuffer commands = encoder.Finish();
|
||||
secondDeviceQueue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
int signalFd = dawn_native::vulkan::ExportSignalSemaphoreOpaqueFD(secondDevice.Get(),
|
||||
wrappedTexture.Get());
|
||||
int memoryFd = GetMemoryFd(secondDeviceVk, allocationA);
|
||||
|
||||
// Import the image on |device|
|
||||
dawn::Texture nextWrappedTexture = WrapVulkanImage(
|
||||
device, &descriptor, memoryFd, allocationSizeA, memoryTypeIndexA, {signalFd});
|
||||
|
||||
// Copy the image into a buffer for comparison
|
||||
dawn::BufferDescriptor copyDesc;
|
||||
copyDesc.size = size;
|
||||
copyDesc.usage = dawn::BufferUsageBit::CopySrc | dawn::BufferUsageBit::CopyDst;
|
||||
dawn::Buffer copyDstBuffer = device.CreateBuffer(©Desc);
|
||||
{
|
||||
dawn::TextureCopyView copySrc =
|
||||
utils::CreateTextureCopyView(nextWrappedTexture, 0, 0, {0, 0, 0});
|
||||
dawn::BufferCopyView copyDst = utils::CreateBufferCopyView(copyDstBuffer, 0, rowPitch, 0);
|
||||
|
||||
dawn::Extent3D copySize = {width, height, 1};
|
||||
|
||||
dawn::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||
encoder.CopyTextureToBuffer(©Src, ©Dst, ©Size);
|
||||
dawn::CommandBuffer commands = encoder.Finish();
|
||||
queue.Submit(1, &commands);
|
||||
}
|
||||
|
||||
// Check the image is not corrupted on |device|
|
||||
EXPECT_BUFFER_U32_RANGE_EQ(reinterpret_cast<uint32_t*>(data), copyDstBuffer, 0, size / 4);
|
||||
|
||||
IgnoreSignalSemaphore(device, nextWrappedTexture);
|
||||
secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(imageA);
|
||||
secondDeviceVk->GetFencedDeleter()->DeleteWhenUnused(allocationA);
|
||||
}
|
||||
|
||||
DAWN_INSTANTIATE_TEST(VulkanImageWrappingValidationTests, VulkanBackend);
|
||||
DAWN_INSTANTIATE_TEST(VulkanImageWrappingUsageTests, VulkanBackend);
|
||||
|
|
Loading…
Reference in New Issue