1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and/or associated documentation files (the
10 * "Materials"), to deal in the Materials without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Materials, and to
13 * permit persons to whom the Materials are furnished to do so, subject to
14 * the following conditions:
16 * The above copyright notice(s) and this permission notice shall be included
17 * in all copies or substantial portions of the Materials.
19 * The Materials are Confidential Information as defined by the
20 * Khronos Membership Agreement until designated non-confidential by Khronos,
21 * at which point this condition clause shall be removed.
23 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
33 * \brief Vulkan Copies And Blitting Tests
34 *//*--------------------------------------------------------------------*/
36 #include "vktApiCopiesAndBlittingTests.hpp"
38 #include "deRandom.hpp"
39 #include "deStringUtil.hpp"
40 #include "deUniquePtr.hpp"
41 #include "vkImageUtil.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vktTestCase.hpp"
44 #include "vktTestCaseUtil.hpp"
45 #include "vkQueryUtil.hpp"
46 #include "vkRefUtil.hpp"
47 #include "vkTypeUtil.hpp"
48 #include "tcuImageCompare.hpp"
49 #include "tcuTextureUtil.hpp"
50 #include "tcuVectorType.hpp"
51 #include "tcuTexture.hpp"
66 VkBufferCopy bufferCopy;
67 VkImageCopy imageCopy;
68 VkBufferImageCopy bufferImageCopy;
69 VkImageBlit imageBlit;
87 std::vector<CopyRegion> regions;
90 class CopiesAndBlittingTestInstance : public vkt::TestInstance
93 CopiesAndBlittingTestInstance (Context& context,
94 TestParams testParams);
95 virtual ~CopiesAndBlittingTestInstance (void);
96 virtual tcu::TestStatus iterate (void) = 0;
99 FILL_MODE_SEQUENTIAL = 0,
107 const TestParams m_params;
109 Move<VkCommandPool> m_cmdPool;
110 Move<VkCommandBuffer> m_cmdBuffer;
111 Move<VkFence> m_fence;
112 de::MovePtr<tcu::TextureLevel> m_sourceTextureLevel;
113 de::MovePtr<tcu::TextureLevel> m_destinationTextureLevel;
114 de::MovePtr<tcu::TextureLevel> m_expectedTextureLevel;
116 VkCommandBufferBeginInfo m_cmdBufferBeginInfo;
118 void generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_SEQUENTIAL);
119 virtual void generateExpectedResult (void);
120 void uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
121 void uploadImage (tcu::ConstPixelBufferAccess imageAccess, const VkImage& image);
122 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
123 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region) = 0;
124 VkImageAspectFlags getAspectFlag (tcu::TextureFormat format);
125 deUint32 calculateSize (tcu::ConstPixelBufferAccess src) const
127 return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
130 de::MovePtr<tcu::TextureLevel> readImage (const vk::DeviceInterface& vk,
133 vk::Allocator& allocator,
136 const VkExtent3D imageSize);
139 CopiesAndBlittingTestInstance::~CopiesAndBlittingTestInstance (void)
143 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
144 : vkt::TestInstance (context)
145 , m_params (testParams)
147 const DeviceInterface& vk = context.getDeviceInterface();
148 const VkDevice vkDevice = context.getDevice();
149 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
151 // Create command pool
153 const VkCommandPoolCreateInfo cmdPoolParams =
155 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
156 DE_NULL, // const void* pNext;
157 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCmdPoolCreateFlags flags;
158 queueFamilyIndex, // deUint32 queueFamilyIndex;
161 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
164 // Create command buffer
166 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
168 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
169 DE_NULL, // const void* pNext;
170 *m_cmdPool, // VkCommandPool commandPool;
171 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
172 1u // deUint32 bufferCount;
175 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
180 const VkFenceCreateInfo fenceParams =
182 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
183 DE_NULL, // const void* pNext;
184 0u // VkFenceCreateFlags flags;
187 m_fence = createFence(vk, vkDevice, &fenceParams);
191 void CopiesAndBlittingTestInstance::generateBuffer(tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
193 de::Random rnd(width ^ height ^ depth);
194 for (int z = 0; z < depth; z++)
196 for (int y = 0; y < height; y++)
198 for (int x = 0; x < width; x++)
202 case FILL_MODE_SEQUENTIAL:
203 buffer.setPixel(tcu::UVec4(x, y, z, 255), x, y, z);
205 case FILL_MODE_WHITE:
206 buffer.setPixel(tcu::UVec4(255, 255, 255, 255), x, y, z);
209 buffer.setPixel(tcu::UVec4(255, 0, 0, 255), x, y, z);
211 case FILL_MODE_RANDOM:
212 buffer.setPixel(tcu::UVec4(rnd.getUint8(), rnd.getUint8(), rnd.getUint8(), 255), x, y, z);
221 void CopiesAndBlittingTestInstance::uploadBuffer(tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
223 const DeviceInterface& vk = m_context.getDeviceInterface();
224 const VkDevice vkDevice = m_context.getDevice();
225 const deUint32 bufferSize = calculateSize(bufferAccess);
228 deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
229 flushMappedMemoryRange(vk, vkDevice, bufferAlloc.getMemory(), bufferAlloc.getOffset(), bufferSize);
232 void CopiesAndBlittingTestInstance::uploadImage(tcu::ConstPixelBufferAccess imageAccess, const VkImage& image)
234 const DeviceInterface& vk = m_context.getDeviceInterface();
235 const VkDevice vkDevice = m_context.getDevice();
236 const VkQueue queue = m_context.getUniversalQueue();
237 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
238 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
240 Move<VkBuffer> buffer;
241 const deUint32 bufferSize = calculateSize(imageAccess);
242 de::MovePtr<Allocation> bufferAlloc;
243 Move<VkCommandBuffer> cmdBuffer;
246 // Create source buffer
248 const VkBufferCreateInfo bufferParams =
250 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
251 DE_NULL, // const void* pNext;
252 0u, // VkBufferCreateFlags flags;
253 bufferSize, // VkDeviceSize size;
254 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
255 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
256 1u, // deUint32 queueFamilyIndexCount;
257 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
260 buffer = createBuffer(vk, vkDevice, &bufferParams);
261 bufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *buffer), MemoryRequirement::HostVisible);
262 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
265 // Create command buffer
267 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
269 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
270 DE_NULL, // const void* pNext;
271 *m_cmdPool, // VkCommandPool commandPool;
272 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
273 1u, // deUint32 bufferCount;
276 cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
281 const VkFenceCreateInfo fenceParams =
283 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
284 DE_NULL, // const void* pNext;
285 0u // VkFenceCreateFlags flags;
288 fence = createFence(vk, vkDevice, &fenceParams);
291 // Barriers for copying buffer to image
292 const VkBufferMemoryBarrier preBufferBarrier =
294 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
295 DE_NULL, // const void* pNext;
296 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
297 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
298 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
299 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
300 *buffer, // VkBuffer buffer;
301 0u, // VkDeviceSize offset;
302 bufferSize // VkDeviceSize size;
305 const VkImageMemoryBarrier preImageBarrier =
307 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
308 DE_NULL, // const void* pNext;
309 0u, // VkAccessFlags srcAccessMask;
310 0u, // VkAccessFlags dstAccessMask;
311 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
312 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
313 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
314 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
315 image, // VkImage image;
316 { // VkImageSubresourceRange subresourceRange;
317 getAspectFlag(imageAccess.getFormat()), // VkImageAspect aspect;
318 0u, // deUint32 baseMipLevel;
319 1u, // deUint32 mipLevels;
320 0u, // deUint32 baseArraySlice;
321 1u, // deUint32 arraySize;
325 const VkImageMemoryBarrier postImageBarrier =
327 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
328 DE_NULL, // const void* pNext;
329 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
330 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
331 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
332 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
333 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
334 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
335 image, // VkImage image;
336 { // VkImageSubresourceRange subresourceRange;
337 getAspectFlag(imageAccess.getFormat()), // VkImageAspect aspect;
338 0u, // deUint32 baseMipLevel;
339 1u, // deUint32 mipLevels;
340 0u, // deUint32 baseArraySlice;
341 1u, // deUint32 arraySize;
345 const VkBufferImageCopy copyRegion =
347 0u, // VkDeviceSize bufferOffset;
348 (deUint32)imageAccess.getWidth(), // deUint32 bufferRowLength;
349 (deUint32)imageAccess.getHeight(), // deUint32 bufferImageHeight;
350 { // VkImageSubresourceLayers imageSubresource;
351 getAspectFlag(imageAccess.getFormat()), // VkImageAspect aspect;
352 0u, // deUint32 mipLevel;
353 0u, // deUint32 baseArrayLayer;
354 1u, // deUint32 layerCount;
356 { 0, 0, 0 }, // VkOffset3D imageOffset;
358 (deUint32)imageAccess.getWidth(),
359 (deUint32)imageAccess.getHeight(),
361 } // VkExtent3D imageExtent;
365 deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
366 flushMappedMemoryRange(vk, vkDevice, bufferAlloc->getMemory(), bufferAlloc->getOffset(), bufferSize);
368 // Copy buffer to image
369 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
371 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
372 DE_NULL, // const void* pNext;
373 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
374 (const VkCommandBufferInheritanceInfo*)DE_NULL,
377 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
378 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &preBufferBarrier, 1, &preImageBarrier);
379 vk.cmdCopyBufferToImage(*cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
380 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
381 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
383 const VkSubmitInfo submitInfo =
385 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
386 DE_NULL, // const void* pNext;
387 0u, // deUint32 waitSemaphoreCount;
388 DE_NULL, // const VkSemaphore* pWaitSemaphores;
389 (const VkPipelineStageFlags*)DE_NULL,
390 1u, // deUint32 commandBufferCount;
391 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
392 0u, // deUint32 signalSemaphoreCount;
393 DE_NULL // const VkSemaphore* pSignalSemaphores;
396 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
397 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), true, ~(0ull) /* infinity */));
400 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult(tcu::ConstPixelBufferAccess result)
402 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel->getAccess();
403 const tcu::UVec4 treshold (0, 0, 0, 0);
405 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expected, result, treshold, tcu::COMPARE_LOG_RESULT))
406 return tcu::TestStatus::fail("CopiesAndBlitting test");
408 return tcu::TestStatus::pass("CopiesAndBlitting test");
411 void CopiesAndBlittingTestInstance::generateExpectedResult()
413 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
414 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
416 m_expectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
417 tcu::copy(m_expectedTextureLevel->getAccess(), dst);
418 for (deUint32 i = 0; i < m_params.regions.size(); i++)
419 copyRegionToTextureLevel(src, m_expectedTextureLevel->getAccess(), m_params.regions[i]);
422 class CopiesAndBlittingTestCase : public vkt::TestCase
425 CopiesAndBlittingTestCase (tcu::TestContext& testCtx,
426 const std::string& name,
427 const std::string& description)
428 : vkt::TestCase (testCtx, name, description)
431 virtual ~CopiesAndBlittingTestCase (void) {}
433 virtual TestInstance* createInstance (Context& context) const = 0;
436 VkImageAspectFlags CopiesAndBlittingTestInstance::getAspectFlag(tcu::TextureFormat format)
438 VkImageAspectFlags aspectFlag = 0;
439 aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
440 aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
443 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
448 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (const vk::DeviceInterface& vk,
451 vk::Allocator& allocator,
454 const VkExtent3D imageSize)
456 Move<VkBuffer> buffer;
457 de::MovePtr<Allocation> bufferAlloc;
458 Move<VkCommandBuffer> cmdBuffer;
460 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
461 const tcu::TextureFormat tcuFormat = mapVkFormat(format);
462 const VkDeviceSize pixelDataSize = imageSize.width * imageSize.height * imageSize.depth * tcu::getPixelSize(tcuFormat);
463 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, imageSize.width, imageSize.height, imageSize.depth));
465 // Create destination buffer
467 const VkBufferCreateInfo bufferParams =
469 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
470 DE_NULL, // const void* pNext;
471 0u, // VkBufferCreateFlags flags;
472 pixelDataSize, // VkDeviceSize size;
473 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
474 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
475 1u, // deUint32 queueFamilyIndexCount;
476 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
479 buffer = createBuffer(vk, device, &bufferParams);
480 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), MemoryRequirement::HostVisible);
481 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
484 // Create command pool and buffer
486 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
488 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
489 DE_NULL, // const void* pNext;
490 *m_cmdPool, // VkCommandPool commandPool;
491 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
492 1u // deUint32 bufferCount;
495 cmdBuffer = allocateCommandBuffer(vk, device, &cmdBufferAllocateInfo);
500 const VkFenceCreateInfo fenceParams =
502 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
503 DE_NULL, // const void* pNext;
504 0u // VkFenceCreateFlags flags;
507 fence = createFence(vk, device, &fenceParams);
510 // Barriers for copying image to buffer
512 const VkImageMemoryBarrier imageBarrier =
514 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
515 DE_NULL, // const void* pNext;
516 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
517 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
518 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
519 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
520 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
521 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
522 image, // VkImage image;
523 { // VkImageSubresourceRange subresourceRange;
524 getAspectFlag(tcuFormat), // VkImageAspectFlags aspectMask;
525 0u, // deUint32 baseMipLevel;
526 1u, // deUint32 mipLevels;
527 0u, // deUint32 baseArraySlice;
528 1u // deUint32 arraySize;
532 const VkBufferMemoryBarrier bufferBarrier =
534 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
535 DE_NULL, // const void* pNext;
536 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
537 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
538 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
539 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
540 *buffer, // VkBuffer buffer;
541 0u, // VkDeviceSize offset;
542 pixelDataSize // VkDeviceSize size;
545 // Copy image to buffer
547 const VkBufferImageCopy copyRegion =
549 0u, // VkDeviceSize bufferOffset;
550 (deUint32)imageSize.width, // deUint32 bufferRowLength;
551 (deUint32)imageSize.height, // deUint32 bufferImageHeight;
552 { getAspectFlag(tcuFormat), 0u, 0u, 1u }, // VkImageSubresourceLayers imageSubresource;
553 { 0, 0, 0 }, // VkOffset3D imageOffset;
554 imageSize // VkExtent3D imageExtent;
557 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
559 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
560 DE_NULL, // const void* pNext;
561 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
562 (const VkCommandBufferInheritanceInfo*)DE_NULL,
565 VK_CHECK(vk.beginCommandBuffer(*cmdBuffer, &cmdBufferBeginInfo));
566 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
567 vk.cmdCopyImageToBuffer(*cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
568 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
569 VK_CHECK(vk.endCommandBuffer(*cmdBuffer));
571 const VkSubmitInfo submitInfo =
573 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
574 DE_NULL, // const void* pNext;
575 0u, // deUint32 waitSemaphoreCount;
576 DE_NULL, // const VkSemaphore* pWaitSemaphores;
577 (const VkPipelineStageFlags*)DE_NULL,
578 1u, // deUint32 commandBufferCount;
579 &cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
580 0u, // deUint32 signalSemaphoreCount;
581 DE_NULL // const VkSemaphore* pSignalSemaphores;
584 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *fence));
585 VK_CHECK(vk.waitForFences(device, 1, &fence.get(), 0, ~(0ull) /* infinity */));
588 invalidateMappedMemoryRange(vk, device, bufferAlloc->getMemory(), bufferAlloc->getOffset(), pixelDataSize);
589 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), bufferAlloc->getHostPtr()));
594 // Copy from image to image.
596 class CopyImageToImage : public CopiesAndBlittingTestInstance
599 CopyImageToImage (Context& context,
601 virtual tcu::TestStatus iterate (void);
603 Move<VkImage> m_source;
604 de::MovePtr<Allocation> m_sourceImageAlloc;
605 Move<VkImage> m_destination;
606 de::MovePtr<Allocation> m_destinationImageAlloc;
608 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
611 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
612 : CopiesAndBlittingTestInstance(context, params)
614 const DeviceInterface& vk = context.getDeviceInterface();
615 const VkDevice vkDevice = context.getDevice();
616 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
617 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
619 VkImageFormatProperties properties;
620 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
621 m_params.src.image.format,
623 VK_IMAGE_TILING_OPTIMAL,
624 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
625 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
626 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
627 m_params.dst.image.format,
629 VK_IMAGE_TILING_OPTIMAL,
630 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
631 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
633 TCU_THROW(NotSupportedError, "Format not supported");
636 // Create source image
638 const VkImageCreateInfo sourceImageParams =
640 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
641 DE_NULL, // const void* pNext;
642 0u, // VkImageCreateFlags flags;
643 VK_IMAGE_TYPE_2D, // VkImageType imageType;
644 m_params.src.image.format, // VkFormat format;
645 m_params.src.image.extent, // VkExtent3D extent;
646 1u, // deUint32 mipLevels;
647 1u, // deUint32 arraySize;
648 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
649 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
650 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
651 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
652 1u, // deUint32 queueFamilyCount;
653 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
654 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
657 m_source = createImage(vk, vkDevice, &sourceImageParams);
658 m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
659 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
662 // Create destination image
664 const VkImageCreateInfo destinationImageParams =
666 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
667 DE_NULL, // const void* pNext;
668 0u, // VkImageCreateFlags flags;
669 VK_IMAGE_TYPE_2D, // VkImageType imageType;
670 m_params.dst.image.format, // VkFormat format;
671 m_params.dst.image.extent, // VkExtent3D extent;
672 1u, // deUint32 mipLevels;
673 1u, // deUint32 arraySize;
674 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
675 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
676 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
677 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
678 1u, // deUint32 queueFamilyCount;
679 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
680 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
683 m_destination = createImage(vk, vkDevice, &destinationImageParams);
684 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
685 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
689 tcu::TestStatus CopyImageToImage::iterate()
691 tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
692 tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
693 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
694 m_params.src.image.extent.width,
695 m_params.src.image.extent.height,
696 m_params.src.image.extent.depth));
697 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_WHITE);
698 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
699 (int)m_params.dst.image.extent.width,
700 (int)m_params.dst.image.extent.height,
701 (int)m_params.dst.image.extent.depth));
702 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_SEQUENTIAL);
703 generateExpectedResult();
705 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get());
706 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get());
708 const DeviceInterface& vk = m_context.getDeviceInterface();
709 const VkDevice vkDevice = m_context.getDevice();
710 const VkQueue queue = m_context.getUniversalQueue();
711 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
713 VkImageCopy* imageCopies = ((VkImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkImageCopy)));
714 for (deUint32 i = 0; i < m_params.regions.size(); i++)
715 imageCopies[i] = m_params.regions[i].imageCopy;
717 // Barriers for copying image to buffer
718 const VkImageMemoryBarrier srcImageBarrier =
720 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
721 DE_NULL, // const void* pNext;
722 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
723 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
724 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout;
725 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
726 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
727 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
728 m_source.get(), // VkImage image;
729 { // VkImageSubresourceRange subresourceRange;
730 getAspectFlag(srcTcuFormat), // VkImageAspectFlags aspectMask;
731 0u, // deUint32 baseMipLevel;
732 1u, // deUint32 mipLevels;
733 0u, // deUint32 baseArraySlice;
734 1u // deUint32 arraySize;
738 const VkImageMemoryBarrier dstImageBarrier =
740 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
741 DE_NULL, // const void* pNext;
742 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
743 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
744 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout;
745 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
746 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
747 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
748 m_destination.get(), // VkImage image;
749 { // VkImageSubresourceRange subresourceRange;
750 getAspectFlag(dstTcuFormat), // VkImageAspectFlags aspectMask;
751 0u, // deUint32 baseMipLevel;
752 1u, // deUint32 mipLevels;
753 0u, // deUint32 baseArraySlice;
754 1u // deUint32 arraySize;
758 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
760 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
761 DE_NULL, // const void* pNext;
762 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
763 (const VkCommandBufferInheritanceInfo*)DE_NULL,
766 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
767 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &srcImageBarrier);
768 vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), imageCopies);
769 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
770 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
772 const VkSubmitInfo submitInfo =
774 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
775 DE_NULL, // const void* pNext;
776 0u, // deUint32 waitSemaphoreCount;
777 DE_NULL, // const VkSemaphore* pWaitSemaphores;
778 (const VkPipelineStageFlags*)DE_NULL,
779 1u, // deUint32 commandBufferCount;
780 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
781 0u, // deUint32 signalSemaphoreCount;
782 DE_NULL // const VkSemaphore* pSignalSemaphores;
785 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
786 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
787 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
790 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(vk, vkDevice, queue, memAlloc, *m_destination, m_params.dst.image.format, m_params.dst.image.extent);
792 return checkTestResult(resultTextureLevel->getAccess());
795 void CopyImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
797 VkOffset3D srcOffset = region.imageCopy.srcOffset;
798 VkOffset3D dstOffset = region.imageCopy.dstOffset;
799 VkExtent3D extent = region.imageCopy.extent;
801 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, extent.width, extent.height);
802 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
803 const tcu::PixelBufferAccess dstWithSrcFormat(srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
804 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, extent.width, extent.height);
806 tcu::copy(dstSubRegion, srcSubRegion);
809 class CopyImageToImageTestCase : public vkt::TestCase
812 CopyImageToImageTestCase (tcu::TestContext& testCtx,
813 const std::string& name,
814 const std::string& description,
815 const TestParams params)
816 : vkt::TestCase (testCtx, name, description)
820 virtual ~CopyImageToImageTestCase (void) {}
822 virtual TestInstance* createInstance (Context& context) const
824 return new CopyImageToImage(context, m_params);
830 // Copy from buffer to buffer.
832 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
835 CopyBufferToBuffer (Context& context, TestParams params);
836 virtual tcu::TestStatus iterate (void);
838 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion);
839 Move<VkBuffer> m_source;
840 de::MovePtr<Allocation> m_sourceBufferAlloc;
841 Move<VkBuffer> m_destination;
842 de::MovePtr<Allocation> m_destinationBufferAlloc;
845 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
846 : CopiesAndBlittingTestInstance (context, params)
848 const DeviceInterface& vk = context.getDeviceInterface();
849 const VkDevice vkDevice = context.getDevice();
850 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
851 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
853 // Create source buffer
855 const VkBufferCreateInfo sourceBufferParams =
857 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
858 DE_NULL, // const void* pNext;
859 0u, // VkBufferCreateFlags flags;
860 m_params.src.buffer.size, // VkDeviceSize size;
861 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
862 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
863 1u, // deUint32 queueFamilyIndexCount;
864 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
867 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
868 m_sourceBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
869 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
872 // Create desctination buffer
874 const VkBufferCreateInfo destinationBufferParams =
876 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
877 DE_NULL, // const void* pNext;
878 0u, // VkBufferCreateFlags flags;
879 m_params.dst.buffer.size, // VkDeviceSize size;
880 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
881 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
882 1u, // deUint32 queueFamilyIndexCount;
883 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
886 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
887 m_destinationBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
888 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
892 tcu::TestStatus CopyBufferToBuffer::iterate()
894 const int srcLevelWidth = (int)(m_params.src.buffer.size/4); // Here the format is VK_FORMAT_R32_UINT, we need to divide the buffer size by 4
895 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
896 generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
898 const int dstLevelWidth = (int)(m_params.dst.buffer.size/4);
899 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
900 generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_WHITE);
902 generateExpectedResult();
904 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
905 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
907 const DeviceInterface& vk = m_context.getDeviceInterface();
908 const VkDevice vkDevice = m_context.getDevice();
909 const VkQueue queue = m_context.getUniversalQueue();
911 const VkBufferMemoryBarrier srcBufferBarrier =
913 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
914 DE_NULL, // const void* pNext;
915 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
916 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
917 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
918 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
919 *m_source, // VkBuffer buffer;
920 0u, // VkDeviceSize offset;
921 m_params.src.buffer.size // VkDeviceSize size;
924 const VkBufferMemoryBarrier dstBufferBarrier =
926 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
927 DE_NULL, // const void* pNext;
928 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
929 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
930 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
931 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
932 *m_destination, // VkBuffer buffer;
933 0u, // VkDeviceSize offset;
934 m_params.dst.buffer.size // VkDeviceSize size;
937 VkBufferCopy* bufferCopies = ((VkBufferCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferCopy)));
938 for (deUint32 i = 0; i < m_params.regions.size(); i++)
939 bufferCopies[i] = m_params.regions[i].bufferCopy;
941 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
943 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
944 DE_NULL, // const void* pNext;
945 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
946 (const VkCommandBufferInheritanceInfo*)DE_NULL,
949 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
950 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
951 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), bufferCopies);
952 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
953 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
955 const VkSubmitInfo submitInfo =
957 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
958 DE_NULL, // const void* pNext;
959 0u, // deUint32 waitSemaphoreCount;
960 DE_NULL, // const VkSemaphore* pWaitSemaphores;
961 (const VkPipelineStageFlags*)DE_NULL,
962 1u, // deUint32 commandBufferCount;
963 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
964 0u, // deUint32 signalSemaphoreCount;
965 DE_NULL // const VkSemaphore* pSignalSemaphores;
968 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
969 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
970 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
973 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
974 invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_params.dst.buffer.size);
975 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
976 deFree(bufferCopies);
978 return checkTestResult(resultLevel->getAccess());
981 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
983 deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
984 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
985 (size_t)region.bufferCopy.size);
988 class BufferToBufferTestCase : public vkt::TestCase
991 BufferToBufferTestCase (tcu::TestContext& testCtx,
992 const std::string& name,
993 const std::string& description,
994 const TestParams params)
995 : vkt::TestCase (testCtx, name, description)
998 virtual ~BufferToBufferTestCase (void) {}
1000 virtual TestInstance* createInstance (Context& context) const
1002 return new CopyBufferToBuffer(context, m_params);
1005 TestParams m_params;
1008 // Copy from image to buffer.
1010 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
1013 CopyImageToBuffer (Context& context,
1014 TestParams testParams);
1015 virtual ~CopyImageToBuffer (void) {}
1016 virtual tcu::TestStatus iterate (void);
1018 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1020 tcu::TextureFormat m_textureFormat;
1021 VkDeviceSize m_bufferSize;
1023 Move<VkImage> m_source;
1024 de::MovePtr<Allocation> m_sourceImageAlloc;
1025 Move<VkBuffer> m_destination;
1026 de::MovePtr<Allocation> m_destinationBufferAlloc;
1029 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
1030 : CopiesAndBlittingTestInstance(context, testParams)
1031 , m_textureFormat(mapVkFormat(testParams.src.image.format))
1032 , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
1034 const DeviceInterface& vk = context.getDeviceInterface();
1035 const VkDevice vkDevice = context.getDevice();
1036 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1037 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1039 // Create source image
1041 const VkImageCreateInfo sourceImageParams =
1043 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1044 DE_NULL, // const void* pNext;
1045 0u, // VkImageCreateFlags flags;
1046 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1047 m_params.src.image.format, // VkFormat format;
1048 m_params.src.image.extent, // VkExtent3D extent;
1049 1u, // deUint32 mipLevels;
1050 1u, // deUint32 arraySize;
1051 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1052 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1053 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1054 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1055 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1056 1u, // deUint32 queueFamilyCount;
1057 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1058 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1061 m_source = createImage(vk, vkDevice, &sourceImageParams);
1062 m_sourceImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::Any);
1063 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1066 // Create destination buffer
1068 const VkBufferCreateInfo destinationBufferParams =
1070 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1071 DE_NULL, // const void* pNext;
1072 0u, // VkBufferCreateFlags flags;
1073 m_bufferSize, // VkDeviceSize size;
1074 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1075 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1076 1u, // deUint32 queueFamilyIndexCount;
1077 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1080 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
1081 m_destinationBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::HostVisible);
1082 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
1086 tcu::TestStatus CopyImageToBuffer::iterate()
1088 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1089 m_params.src.image.extent.width,
1090 m_params.src.image.extent.height,
1091 m_params.src.image.extent.depth));
1092 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_RED);
1093 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1094 generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
1096 generateExpectedResult();
1098 uploadImage(m_sourceTextureLevel->getAccess(), *m_source);
1099 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
1101 const DeviceInterface& vk = m_context.getDeviceInterface();
1102 const VkDevice vkDevice = m_context.getDevice();
1103 const VkQueue queue = m_context.getUniversalQueue();
1105 // Barriers for copying image to buffer
1106 const VkImageMemoryBarrier imageBarrier =
1108 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1109 DE_NULL, // const void* pNext;
1110 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1111 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1112 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout;
1113 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1114 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1115 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1116 *m_source, // VkImage image;
1117 { // VkImageSubresourceRange subresourceRange;
1118 getAspectFlag(m_textureFormat), // VkImageAspectFlags aspectMask;
1119 0u, // deUint32 baseMipLevel;
1120 1u, // deUint32 mipLevels;
1121 0u, // deUint32 baseArraySlice;
1122 1u // deUint32 arraySize;
1126 const VkBufferMemoryBarrier bufferBarrier =
1128 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1129 DE_NULL, // const void* pNext;
1130 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1131 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1132 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1133 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1134 *m_destination, // VkBuffer buffer;
1135 0u, // VkDeviceSize offset;
1136 m_bufferSize // VkDeviceSize size;
1139 // Copy from image to buffer
1140 VkBufferImageCopy* bufferImageCopies = ((VkBufferImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferImageCopy)));
1141 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1142 bufferImageCopies[i] = m_params.regions[i].bufferImageCopy;
1144 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1146 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1147 DE_NULL, // const void* pNext;
1148 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
1149 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1152 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1153 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
1154 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), bufferImageCopies);
1155 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1156 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1158 const VkSubmitInfo submitInfo =
1160 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1161 DE_NULL, // const void* pNext;
1162 0u, // deUint32 waitSemaphoreCount;
1163 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1164 (const VkPipelineStageFlags*)DE_NULL,
1165 1u, // deUint32 commandBufferCount;
1166 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1167 0u, // deUint32 signalSemaphoreCount;
1168 DE_NULL // const VkSemaphore* pSignalSemaphores;
1171 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1172 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1173 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1176 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
1177 invalidateMappedMemoryRange(vk, vkDevice, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset(), m_bufferSize);
1178 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
1179 deFree(bufferImageCopies);
1181 return checkTestResult(resultLevel->getAccess());
1184 class CopyImageToBufferTestCase : public vkt::TestCase
1187 CopyImageToBufferTestCase (tcu::TestContext& testCtx,
1188 const std::string& name,
1189 const std::string& description,
1190 const TestParams params)
1191 : vkt::TestCase (testCtx, name, description)
1195 virtual ~CopyImageToBufferTestCase (void) {}
1197 virtual TestInstance* createInstance (Context& context) const
1199 return new CopyImageToBuffer(context, m_params);
1202 TestParams m_params;
1205 void CopyImageToBuffer::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1207 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
1209 rowLength = region.bufferImageCopy.imageExtent.width;
1211 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
1213 imageHeight = region.bufferImageCopy.imageExtent.height;
1215 const int texelSize = src.getFormat().getPixelSize();
1216 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
1217 const VkOffset3D srcOffset = region.bufferImageCopy.imageOffset;
1218 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
1220 for (deUint32 z = 0; z < extent.depth; z++)
1222 for (deUint32 y = 0; y < extent.height; y++)
1224 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
1225 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z,
1226 region.bufferImageCopy.imageExtent.width, 1, 1);
1227 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1228 tcu::copy(dstSubRegion, srcSubRegion);
1233 // Copy from buffer to image.
1235 class CopyBufferToImage : public CopiesAndBlittingTestInstance
1238 CopyBufferToImage (Context& context,
1239 TestParams testParams);
1240 virtual ~CopyBufferToImage (void) {}
1241 virtual tcu::TestStatus iterate (void);
1243 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region);
1245 tcu::TextureFormat m_textureFormat;
1246 VkDeviceSize m_bufferSize;
1248 Move<VkBuffer> m_source;
1249 de::MovePtr<Allocation> m_sourceBufferAlloc;
1250 Move<VkImage> m_destination;
1251 de::MovePtr<Allocation> m_destinationImageAlloc;
1254 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
1255 : CopiesAndBlittingTestInstance(context, testParams)
1256 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
1257 , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
1259 const DeviceInterface& vk = context.getDeviceInterface();
1260 const VkDevice vkDevice = context.getDevice();
1261 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1262 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
1264 // Create source buffer
1266 const VkBufferCreateInfo sourceBufferParams =
1268 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1269 DE_NULL, // const void* pNext;
1270 0u, // VkBufferCreateFlags flags;
1271 m_bufferSize, // VkDeviceSize size;
1272 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
1273 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1274 1u, // deUint32 queueFamilyIndexCount;
1275 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1278 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
1279 m_sourceBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_source), MemoryRequirement::HostVisible);
1280 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1283 // Create destination image
1285 const VkImageCreateInfo destinationImageParams =
1287 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1288 DE_NULL, // const void* pNext;
1289 0u, // VkImageCreateFlags flags;
1290 VK_IMAGE_TYPE_2D, // VkImageType imageType;
1291 m_params.dst.image.format, // VkFormat format;
1292 m_params.dst.image.extent, // VkExtent3D extent;
1293 1u, // deUint32 mipLevels;
1294 1u, // deUint32 arraySize;
1295 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1296 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1297 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1298 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1299 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1300 1u, // deUint32 queueFamilyCount;
1301 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1302 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1305 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1306 m_destinationImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_destination), MemoryRequirement::Any);
1307 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1311 tcu::TestStatus CopyBufferToImage::iterate()
1313 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
1314 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_WHITE);
1315 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
1316 m_params.dst.image.extent.width,
1317 m_params.dst.image.extent.height,
1318 m_params.dst.image.extent.depth));
1319 generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1, FILL_MODE_SEQUENTIAL);
1321 generateExpectedResult();
1323 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
1324 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination);
1326 const DeviceInterface& vk = m_context.getDeviceInterface();
1327 const VkDevice vkDevice = m_context.getDevice();
1328 const VkQueue queue = m_context.getUniversalQueue();
1329 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1331 // Barriers for copying image to buffer
1332 const VkBufferMemoryBarrier bufferBarrier =
1334 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1335 DE_NULL, // const void* pNext;
1336 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1337 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1338 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1339 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1340 *m_source, // VkBuffer buffer;
1341 0u, // VkDeviceSize offset;
1342 m_bufferSize // VkDeviceSize size;
1345 const VkImageMemoryBarrier imageBarrier =
1347 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1348 DE_NULL, // const void* pNext;
1349 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1350 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1351 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout oldLayout;
1352 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
1353 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1354 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1355 *m_destination, // VkImage image;
1356 { // VkImageSubresourceRange subresourceRange;
1357 getAspectFlag(m_textureFormat), // VkImageAspectFlags aspectMask;
1358 0u, // deUint32 baseMipLevel;
1359 1u, // deUint32 mipLevels;
1360 0u, // deUint32 baseArraySlice;
1361 1u // deUint32 arraySize;
1365 // Copy from buffer to image
1366 VkBufferImageCopy* bufferImageCopies = ((VkBufferImageCopy*)deMalloc(m_params.regions.size() * sizeof(VkBufferImageCopy)));
1367 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1368 bufferImageCopies[i] = m_params.regions[i].bufferImageCopy;
1370 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
1372 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1373 DE_NULL, // const void* pNext;
1374 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
1375 (const VkCommandBufferInheritanceInfo*)DE_NULL,
1378 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
1379 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
1380 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies);
1381 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &imageBarrier);
1382 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
1384 const VkSubmitInfo submitInfo =
1386 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
1387 DE_NULL, // const void* pNext;
1388 0u, // deUint32 waitSemaphoreCount;
1389 DE_NULL, // const VkSemaphore* pWaitSemaphores;
1390 (const VkPipelineStageFlags*)DE_NULL,
1391 1u, // deUint32 commandBufferCount;
1392 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
1393 0u, // deUint32 signalSemaphoreCount;
1394 DE_NULL // const VkSemaphore* pSignalSemaphores;
1397 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
1398 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
1399 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
1402 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(vk, vkDevice, queue, memAlloc, *m_destination, m_params.dst.image.format, m_params.dst.image.extent);
1403 deFree(bufferImageCopies);
1405 return checkTestResult(resultLevel->getAccess());
1408 class CopyBufferToImageTestCase : public vkt::TestCase
1411 CopyBufferToImageTestCase (tcu::TestContext& testCtx,
1412 const std::string& name,
1413 const std::string& description,
1414 const TestParams params)
1415 : vkt::TestCase (testCtx, name, description)
1419 virtual ~CopyBufferToImageTestCase (void) {}
1421 virtual TestInstance* createInstance (Context& context) const
1423 return new CopyBufferToImage(context, m_params);
1426 TestParams m_params;
1429 void CopyBufferToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region)
1431 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
1433 rowLength = region.bufferImageCopy.imageExtent.width;
1435 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
1437 imageHeight = region.bufferImageCopy.imageExtent.height;
1439 const int texelSize = dst.getFormat().getPixelSize();
1440 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
1441 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
1442 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
1444 for (deUint32 z = 0; z < extent.depth; z++)
1446 for (deUint32 y = 0; y < extent.height; y++)
1448 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
1449 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
1450 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
1451 region.bufferImageCopy.imageExtent.width, 1, 1);
1452 tcu::copy(dstSubRegion, srcSubRegion);
1459 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
1461 de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests (new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
1463 const VkExtent3D defaultExtent = {256, 256, 1};
1464 const VkImageSubresourceLayers defaultSourceLayer =
1466 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1467 0u, // uint32_t mipLevel;
1468 0u, // uint32_t baseArrayLayer;
1469 1u, // uint32_t layerCount;
1473 std::ostringstream description;
1474 description << "Copy from image to image";
1477 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1478 params.src.image.extent = defaultExtent;
1479 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1480 params.dst.image.extent = defaultExtent;
1483 const VkImageSubresourceLayers sourceLayer =
1485 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1486 0u, // uint32_t mipLevel;
1487 0u, // uint32_t baseArrayLayer;
1488 1u // uint32_t layerCount;
1490 const VkImageCopy testCopy =
1492 sourceLayer, // VkImageSubresourceLayers srcSubresource;
1493 {0, 0, 0}, // VkOffset3D srcOffset;
1494 sourceLayer, // VkImageSubresourceLayers dstSubresource;
1495 {0, 0, 0}, // VkOffset3D dstOffset;
1496 {256, 256, 1}, // VkExtent3D extent;
1499 CopyRegion imageCopy;
1500 imageCopy.imageCopy = testCopy;
1502 params.regions.push_back(imageCopy);
1505 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "imageToImage_whole", description.str(), params));
1509 std::ostringstream description;
1510 description << "Copy from image to image";
1513 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1514 params.src.image.extent = defaultExtent;
1515 params.dst.image.format = VK_FORMAT_R32_UINT;
1516 params.dst.image.extent = defaultExtent;
1519 const VkImageSubresourceLayers sourceLayer =
1521 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1522 0u, // uint32_t mipLevel;
1523 0u, // uint32_t baseArrayLayer;
1524 1u // uint32_t layerCount;
1526 const VkImageCopy testCopy =
1528 sourceLayer, // VkImageSubresourceLayers srcSubresource;
1529 {0, 0, 0}, // VkOffset3D srcOffset;
1530 sourceLayer, // VkImageSubresourceLayers dstSubresource;
1531 {0, 0, 0}, // VkOffset3D dstOffset;
1532 {256, 256, 1}, // VkExtent3D extent;
1535 CopyRegion imageCopy;
1536 imageCopy.imageCopy = testCopy;
1538 params.regions.push_back(imageCopy);
1541 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_whole_different_format_uncompressed", description.str(), params));
1545 std::ostringstream description;
1546 description << "Copy from image to image";
1549 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1550 params.src.image.extent = defaultExtent;
1551 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1552 params.dst.image.extent = defaultExtent;
1555 const VkImageSubresourceLayers sourceLayer =
1557 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1558 0u, // uint32_t mipLevel;
1559 0u, // uint32_t baseArrayLayer;
1560 1u // uint32_t layerCount;
1562 const VkImageCopy testCopy =
1564 sourceLayer, // VkImageSubresourceLayers srcSubresource;
1565 {0, 0, 0}, // VkOffset3D srcOffset;
1566 sourceLayer, // VkImageSubresourceLayers dstSubresource;
1567 {64, 98, 0}, // VkOffset3D dstOffset;
1568 {16, 16, 1}, // VkExtent3D extent;
1571 CopyRegion imageCopy;
1572 imageCopy.imageCopy = testCopy;
1574 params.regions.push_back(imageCopy);
1577 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_partial", description.str(), params));
1581 std::ostringstream description;
1582 description << "Copy from image to image";
1585 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1586 params.src.image.extent = defaultExtent;
1587 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1588 params.dst.image.extent = defaultExtent;
1590 for (deInt32 i = 0; i < 16; i++)
1592 const VkImageSubresourceLayers sourceLayer =
1594 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
1595 0u, // uint32_t mipLevel;
1596 0u, // uint32_t baseArrayLayer;
1597 1u // uint32_t layerCount;
1599 const VkImageCopy testCopy =
1601 sourceLayer, // VkImageSubresourceLayers srcSubresource;
1602 {0, 0, 0}, // VkOffset3D srcOffset;
1603 sourceLayer, // VkImageSubresourceLayers dstSubresource;
1604 {i*16, 240-i*16, 0}, // VkOffset3D dstOffset;
1605 {16, 16, 1}, // VkExtent3D extent;
1608 CopyRegion imageCopy;
1609 imageCopy.imageCopy = testCopy;
1611 params.regions.push_back(imageCopy);
1614 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_partial_multiple", description.str(), params));
1617 // Copy image to buffer testcases.
1619 std::ostringstream description;
1620 description << "Copy from image to buffer";
1623 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
1624 params.src.image.extent = defaultExtent;
1625 params.dst.buffer.size = 256 * 256;
1627 const VkBufferImageCopy bufferImageCopy =
1629 0u, // VkDeviceSize bufferOffset;
1630 0u, // uint32_t bufferRowLength;
1631 0u, // uint32_t bufferImageHeight;
1632 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
1633 {0, 0, 0}, // VkOffset3D imageOffset;
1634 {16, 16, 1} // VkExtent3D imageExtent;
1636 CopyRegion copyRegion;
1637 copyRegion.bufferImageCopy = bufferImageCopy;
1639 params.regions.push_back(copyRegion);
1641 copiesAndBlittingTests->addChild(new CopyImageToBufferTestCase(testCtx, "image_to_buffer", description.str(), params));
1644 // Copy buffer to image testcases.
1646 std::ostringstream description;
1647 description << "Copy from buffer to image";
1650 params.src.buffer.size = 256 * 256;
1651 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
1652 params.dst.image.extent = defaultExtent;
1654 const VkBufferImageCopy bufferImageCopy =
1656 0u, // VkDeviceSize bufferOffset;
1657 0u, // uint32_t bufferRowLength;
1658 0u, // uint32_t bufferImageHeight;
1659 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
1660 {0, 0, 0}, // VkOffset3D imageOffset;
1661 {16, 16, 1} // VkExtent3D imageExtent;
1663 CopyRegion copyRegion;
1664 copyRegion.bufferImageCopy = bufferImageCopy;
1666 params.regions.push_back(copyRegion);
1668 copiesAndBlittingTests->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_to_image", description.str(), params));
1672 std::ostringstream description;
1673 description << "Copy from buffer to buffer: whole buffer.";
1676 params.src.buffer.size = 256;
1677 params.dst.buffer.size = 256;
1678 const VkBufferCopy bufferCopy = {
1679 0u, // VkDeviceSize srcOffset;
1680 0u, // VkDeviceSize dstOffset;
1681 256u, // VkDeviceSize size;
1683 CopyRegion copyRegion;
1684 copyRegion.bufferCopy = bufferCopy;
1686 params.regions.push_back(copyRegion);
1688 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_whole", description.str(), params));
1692 std::ostringstream description;
1693 description << "Copy from buffer to buffer: small area.";
1696 params.src.buffer.size = 16;
1697 params.dst.buffer.size = 16;
1698 const VkBufferCopy bufferCopy = {
1699 12u, // VkDeviceSize srcOffset;
1700 4u, // VkDeviceSize dstOffset;
1701 1u, // VkDeviceSize size;
1703 CopyRegion copyRegion;
1704 copyRegion.bufferCopy = bufferCopy;
1706 params.regions.push_back(copyRegion);
1708 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_small", description.str(), params));
1712 std::ostringstream description;
1713 description << "Copy from buffer to buffer: more regions.";
1715 const deUint32 size = 16;
1718 params.src.buffer.size = size;
1719 params.dst.buffer.size = size * (size + 1);
1721 // Copy region with size 0..size
1722 for (unsigned int i = 0; i <= size; i++)
1724 const VkBufferCopy bufferCopy = {
1725 0, // VkDeviceSize srcOffset;
1726 i*size, // VkDeviceSize dstOffset;
1727 i, // VkDeviceSize size;
1729 CopyRegion copyRegion;
1730 copyRegion.bufferCopy = bufferCopy;
1731 params.regions.push_back(copyRegion);
1733 copiesAndBlittingTests->addChild(new BufferToBufferTestCase(testCtx, "buffer_to_buffer_regions", description.str(), params));
1737 std::ostringstream description;
1738 description << "Copy from image to image depth";
1741 params.src.image.format = VK_FORMAT_D32_SFLOAT;
1742 params.src.image.extent = defaultExtent;
1743 params.dst.image.format = VK_FORMAT_D32_SFLOAT;
1744 params.dst.image.extent = defaultExtent;
1747 const VkImageSubresourceLayers sourceLayer =
1749 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
1750 0u, // uint32_t mipLevel;
1751 0u, // uint32_t baseArrayLayer;
1752 1u // uint32_t layerCount;
1754 const VkImageCopy testCopy =
1756 sourceLayer, // VkImageSubresourceLayers srcSubresource;
1757 {0, 0, 0}, // VkOffset3D srcOffset;
1758 sourceLayer, // VkImageSubresourceLayers dstSubresource;
1759 {64, 98, 0}, // VkOffset3D dstOffset;
1760 {16, 16, 1}, // VkExtent3D extent;
1763 CopyRegion imageCopy;
1764 imageCopy.imageCopy = testCopy;
1766 params.regions.push_back(imageCopy);
1769 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_depth", description.str(), params));
1773 std::ostringstream description;
1774 description << "Copy from image to image stencil";
1777 params.src.image.format = VK_FORMAT_S8_UINT;
1778 params.src.image.extent = defaultExtent;
1779 params.dst.image.format = VK_FORMAT_S8_UINT;
1780 params.dst.image.extent = defaultExtent;
1783 const VkImageSubresourceLayers sourceLayer =
1785 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
1786 0u, // uint32_t mipLevel;
1787 0u, // uint32_t baseArrayLayer;
1788 1u // uint32_t layerCount;
1790 const VkImageCopy testCopy =
1792 sourceLayer, // VkImageSubresourceLayers srcSubresource;
1793 {0, 0, 0}, // VkOffset3D srcOffset;
1794 sourceLayer, // VkImageSubresourceLayers dstSubresource;
1795 {64, 98, 0}, // VkOffset3D dstOffset;
1796 {16, 16, 1}, // VkExtent3D extent;
1799 CopyRegion imageCopy;
1800 imageCopy.imageCopy = testCopy;
1802 params.regions.push_back(imageCopy);
1805 copiesAndBlittingTests->addChild(new CopyImageToImageTestCase(testCtx, "image_to_image_stencil", description.str(), params));
1808 return copiesAndBlittingTests.release();