1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2015-2020 The Khronos Group Inc.
6 * Copyright (c) 2020 Google Inc.
7 * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Vulkan Copies And Blitting Tests
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktApiCopiesAndBlittingTests.hpp"
27
28 #include "deStringUtil.hpp"
29 #include "deUniquePtr.hpp"
30
31 #include "tcuImageCompare.hpp"
32 #include "tcuAstcUtil.hpp"
33 #include "tcuTexture.hpp"
34 #include "tcuTextureUtil.hpp"
35 #include "tcuVectorType.hpp"
36 #include "tcuVectorUtil.hpp"
37 #include "tcuTestLog.hpp"
38 #include "tcuTexLookupVerifier.hpp"
39
40 #include "vkImageUtil.hpp"
41 #include "vkMemUtil.hpp"
42 #include "vkPrograms.hpp"
43 #include "vkQueryUtil.hpp"
44 #include "vkRefUtil.hpp"
45 #include "vktTestCase.hpp"
46 #include "vktTestCaseUtil.hpp"
47 #include "vktTestGroupUtil.hpp"
48 #include "vkTypeUtil.hpp"
49 #include "vkCmdUtil.hpp"
50 #include "vkObjUtil.hpp"
51 #include "vkBuilderUtil.hpp"
52 #include "vkBufferWithMemory.hpp"
53 #include "vkBarrierUtil.hpp"
54
55 #include "pipeline/vktPipelineImageUtil.hpp" // required for compressed image blit
56
57 #include <set>
58 #include <array>
59 #include <algorithm>
60 #include <iterator>
61 #include <sstream>
62
63 namespace vkt
64 {
65
66 namespace api
67 {
68
69 namespace
70 {
71
72 enum FillMode
73 {
74 FILL_MODE_GRADIENT = 0,
75 FILL_MODE_WHITE,
76 FILL_MODE_BLACK,
77 FILL_MODE_RED,
78 FILL_MODE_MULTISAMPLE,
79 FILL_MODE_BLUE_RED_X,
80 FILL_MODE_BLUE_RED_Y,
81 FILL_MODE_BLUE_RED_Z,
82
83 FILL_MODE_LAST
84 };
85
86 enum MirrorModeBits
87 {
88 MIRROR_MODE_X = (1<<0),
89 MIRROR_MODE_Y = (1<<1),
90 MIRROR_MODE_Z = (1<<2),
91 MIRROR_MODE_LAST = (1<<3),
92 };
93
94 using MirrorMode = deUint32;
95
96 enum AllocationKind
97 {
98 ALLOCATION_KIND_SUBALLOCATED,
99 ALLOCATION_KIND_DEDICATED,
100 };
101
102 enum ExtensionUse
103 {
104 EXTENSION_USE_NONE,
105 EXTENSION_USE_COPY_COMMANDS2,
106 };
107
108 template <typename Type>
109 class BinaryCompare
110 {
111 public:
operator ()(const Type & a,const Type & b) const112 bool operator() (const Type& a, const Type& b) const
113 {
114 return deMemCmp(&a, &b, sizeof(Type)) < 0;
115 }
116 };
117
118 typedef std::set<vk::VkFormat, BinaryCompare<vk::VkFormat> > FormatSet;
119
120 FormatSet dedicatedAllocationImageToImageFormatsToTestSet;
121 FormatSet dedicatedAllocationBlittingFormatsToTestSet;
122
123 using namespace vk;
124
convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)125 VkImageCopy2KHR convertvkImageCopyTovkImageCopy2KHR(VkImageCopy imageCopy)
126 {
127 const VkImageCopy2KHR imageCopy2 =
128 {
129 VK_STRUCTURE_TYPE_IMAGE_COPY_2_KHR, // VkStructureType sType;
130 DE_NULL, // const void* pNext;
131 imageCopy.srcSubresource, // VkImageSubresourceLayers srcSubresource;
132 imageCopy.srcOffset, // VkOffset3D srcOffset;
133 imageCopy.dstSubresource, // VkImageSubresourceLayers dstSubresource;
134 imageCopy.dstOffset, // VkOffset3D dstOffset;
135 imageCopy.extent // VkExtent3D extent;
136 };
137 return imageCopy2;
138 }
convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)139 VkBufferCopy2KHR convertvkBufferCopyTovkBufferCopy2KHR(VkBufferCopy bufferCopy)
140 {
141 const VkBufferCopy2KHR bufferCopy2 =
142 {
143 VK_STRUCTURE_TYPE_BUFFER_COPY_2_KHR, // VkStructureType sType;
144 DE_NULL, // const void* pNext;
145 bufferCopy.srcOffset, // VkDeviceSize srcOffset;
146 bufferCopy.dstOffset, // VkDeviceSize dstOffset;
147 bufferCopy.size, // VkDeviceSize size;
148 };
149 return bufferCopy2;
150 }
151
convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)152 VkBufferImageCopy2KHR convertvkBufferImageCopyTovkBufferImageCopy2KHR(VkBufferImageCopy bufferImageCopy)
153 {
154 const VkBufferImageCopy2KHR bufferImageCopy2 =
155 {
156 VK_STRUCTURE_TYPE_BUFFER_IMAGE_COPY_2_KHR, // VkStructureType sType;
157 DE_NULL, // const void* pNext;
158 bufferImageCopy.bufferOffset, // VkDeviceSize bufferOffset;
159 bufferImageCopy.bufferRowLength, // uint32_t bufferRowLength;
160 bufferImageCopy.bufferImageHeight, // uint32_t bufferImageHeight;
161 bufferImageCopy.imageSubresource, // VkImageSubresourceLayers imageSubresource;
162 bufferImageCopy.imageOffset, // VkOffset3D imageOffset;
163 bufferImageCopy.imageExtent // VkExtent3D imageExtent;
164 };
165 return bufferImageCopy2;
166 }
167
convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)168 VkImageBlit2KHR convertvkImageBlitTovkImageBlit2KHR(VkImageBlit imageBlit)
169 {
170 const VkImageBlit2KHR imageBlit2 =
171 {
172 VK_STRUCTURE_TYPE_IMAGE_BLIT_2_KHR, // VkStructureType sType;
173 DE_NULL, // const void* pNext;
174 imageBlit.srcSubresource, // VkImageSubresourceLayers srcSubresource;
175 { // VkOffset3D srcOffsets[2];
176 {
177 imageBlit.srcOffsets[0].x, // VkOffset3D srcOffsets[0].x;
178 imageBlit.srcOffsets[0].y, // VkOffset3D srcOffsets[0].y;
179 imageBlit.srcOffsets[0].z // VkOffset3D srcOffsets[0].z;
180 },
181 {
182 imageBlit.srcOffsets[1].x, // VkOffset3D srcOffsets[1].x;
183 imageBlit.srcOffsets[1].y, // VkOffset3D srcOffsets[1].y;
184 imageBlit.srcOffsets[1].z // VkOffset3D srcOffsets[1].z;
185 }
186 },
187 imageBlit.dstSubresource, // VkImageSubresourceLayers dstSubresource;
188 { // VkOffset3D srcOffsets[2];
189 {
190 imageBlit.dstOffsets[0].x, // VkOffset3D dstOffsets[0].x;
191 imageBlit.dstOffsets[0].y, // VkOffset3D dstOffsets[0].y;
192 imageBlit.dstOffsets[0].z // VkOffset3D dstOffsets[0].z;
193 },
194 {
195 imageBlit.dstOffsets[1].x, // VkOffset3D dstOffsets[1].x;
196 imageBlit.dstOffsets[1].y, // VkOffset3D dstOffsets[1].y;
197 imageBlit.dstOffsets[1].z // VkOffset3D dstOffsets[1].z;
198 }
199 }
200 };
201 return imageBlit2;
202 }
203
convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)204 VkImageResolve2KHR convertvkImageResolveTovkImageResolve2KHR(VkImageResolve imageResolve)
205 {
206 const VkImageResolve2KHR imageResolve2 =
207 {
208 VK_STRUCTURE_TYPE_IMAGE_RESOLVE_2_KHR, // VkStructureType sType;
209 DE_NULL, // const void* pNext;
210 imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
211 imageResolve.srcOffset, // VkOffset3D srcOffset;
212 imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
213 imageResolve.dstOffset, // VkOffset3D dstOffset;
214 imageResolve.extent // VkExtent3D extent;
215 };
216 return imageResolve2;
217 }
218
getAspectFlags(tcu::TextureFormat format)219 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
220 {
221 VkImageAspectFlags aspectFlag = 0;
222 aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
223 aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
224
225 if (!aspectFlag)
226 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
227
228 return aspectFlag;
229 }
230
getAspectFlags(VkFormat format)231 VkImageAspectFlags getAspectFlags (VkFormat format)
232 {
233 if (isCompressedFormat(format))
234 return VK_IMAGE_ASPECT_COLOR_BIT;
235 else
236 return getAspectFlags(mapVkFormat(format));
237 }
238
getSizeCompatibleTcuTextureFormat(VkFormat format)239 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
240 {
241 if (isCompressedFormat(format))
242 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
243 else
244 return mapVkFormat(format);
245 }
246
247 // This is effectively same as vk::isFloatFormat(mapTextureFormat(format))
248 // except that it supports some formats that are not mappable to VkFormat.
249 // When we are checking combined depth and stencil formats, each aspect is
250 // checked separately, and in some cases we construct PBA with a format that
251 // is not mappable to VkFormat.
isFloatFormat(tcu::TextureFormat format)252 bool isFloatFormat (tcu::TextureFormat format)
253 {
254 return tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_FLOATING_POINT;
255 }
256
257 union CopyRegion
258 {
259 VkBufferCopy bufferCopy;
260 VkImageCopy imageCopy;
261 VkBufferImageCopy bufferImageCopy;
262 VkImageBlit imageBlit;
263 VkImageResolve imageResolve;
264 };
265
266 struct ImageParms
267 {
268 VkImageType imageType;
269 VkFormat format;
270 VkExtent3D extent;
271 VkImageTiling tiling;
272 VkImageLayout operationLayout;
273 VkImageCreateFlags createFlags;
274 FillMode fillMode;
275 };
276
277 struct TestParams
278 {
279 union Data
280 {
281 struct Buffer
282 {
283 VkDeviceSize size;
284 } buffer;
285
286 ImageParms image;
287 } src, dst;
288
289 std::vector<CopyRegion> regions;
290
291 union
292 {
293 VkFilter filter;
294 VkSampleCountFlagBits samples;
295 };
296
297 AllocationKind allocationKind;
298 ExtensionUse extensionUse;
299 deUint32 mipLevels;
300 deBool singleCommand;
301 deUint32 barrierCount;
302 deBool separateDepthStencilLayouts;
303 deBool clearDestination;
304
TestParamsvkt::api::__anone7bc485d0111::TestParams305 TestParams (void)
306 {
307 allocationKind = ALLOCATION_KIND_DEDICATED;
308 extensionUse = EXTENSION_USE_NONE;
309 mipLevels = 1u;
310 singleCommand = DE_TRUE;
311 barrierCount = 1u;
312 separateDepthStencilLayouts = DE_FALSE;
313 src.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
314 dst.image.createFlags = VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM;
315 src.image.fillMode = FILL_MODE_GRADIENT;
316 dst.image.fillMode = FILL_MODE_WHITE;
317 clearDestination = DE_FALSE;
318 samples = VK_SAMPLE_COUNT_1_BIT;
319 }
320 };
321
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)322 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
323 const DeviceInterface& vkd,
324 const VkPhysicalDevice& physDevice,
325 const VkDevice device,
326 const VkBuffer& buffer,
327 const MemoryRequirement requirement,
328 Allocator& allocator,
329 AllocationKind allocationKind)
330 {
331 switch (allocationKind)
332 {
333 case ALLOCATION_KIND_SUBALLOCATED:
334 {
335 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
336
337 return allocator.allocate(memoryRequirements, requirement);
338 }
339
340 case ALLOCATION_KIND_DEDICATED:
341 {
342 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
343 }
344
345 default:
346 {
347 TCU_THROW(InternalError, "Invalid allocation kind");
348 }
349 }
350 }
351
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)352 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
353 const DeviceInterface& vkd,
354 const VkPhysicalDevice& physDevice,
355 const VkDevice device,
356 const VkImage& image,
357 const MemoryRequirement requirement,
358 Allocator& allocator,
359 AllocationKind allocationKind)
360 {
361 switch (allocationKind)
362 {
363 case ALLOCATION_KIND_SUBALLOCATED:
364 {
365 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
366
367 return allocator.allocate(memoryRequirements, requirement);
368 }
369
370 case ALLOCATION_KIND_DEDICATED:
371 {
372 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
373 }
374
375 default:
376 {
377 TCU_THROW(InternalError, "Invalid allocation kind");
378 }
379 }
380 }
381
382
getArraySize(const ImageParms & parms)383 inline deUint32 getArraySize(const ImageParms& parms)
384 {
385 return (parms.imageType != VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u;
386 }
387
getCreateFlags(const ImageParms & parms)388 inline VkImageCreateFlags getCreateFlags(const ImageParms& parms)
389 {
390 if (parms.createFlags == VK_IMAGE_CREATE_FLAG_BITS_MAX_ENUM)
391 return parms.imageType == VK_IMAGE_TYPE_2D && parms.extent.depth % 6 == 0 ? VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : 0;
392 else
393 return parms.createFlags;
394 }
395
getExtent3D(const ImageParms & parms,deUint32 mipLevel=0u)396 inline VkExtent3D getExtent3D(const ImageParms& parms, deUint32 mipLevel = 0u)
397 {
398 const bool isCompressed = isCompressedFormat(parms.format);
399 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(parms.format) : 1u;
400 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
401
402 if (isCompressed && mipLevel != 0u)
403 DE_FATAL("Not implemented");
404
405 const VkExtent3D extent =
406 {
407 (parms.extent.width >> mipLevel) * blockWidth,
408 (parms.imageType != VK_IMAGE_TYPE_1D) ? ((parms.extent.height >> mipLevel) * blockHeight) : 1u,
409 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
410 };
411 return extent;
412 }
413
mapCombinedToDepthTransferFormat(const tcu::TextureFormat & combinedFormat)414 const tcu::TextureFormat mapCombinedToDepthTransferFormat (const tcu::TextureFormat& combinedFormat)
415 {
416 tcu::TextureFormat format;
417 switch (combinedFormat.type)
418 {
419 case tcu::TextureFormat::UNORM_INT16:
420 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
421 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNORM_INT16);
422 break;
423 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
424 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::UNSIGNED_INT_24_8_REV);
425 break;
426 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
427 case tcu::TextureFormat::FLOAT:
428 format = tcu::TextureFormat(tcu::TextureFormat::D, tcu::TextureFormat::FLOAT);
429 break;
430 default:
431 DE_ASSERT(false);
432 break;
433 }
434 return format;
435 }
436
437 class CopiesAndBlittingTestInstance : public vkt::TestInstance
438 {
439 public:
440 CopiesAndBlittingTestInstance (Context& context,
441 TestParams testParams);
442 virtual tcu::TestStatus iterate (void) = 0;
443
444 protected:
445 const TestParams m_params;
446
447 Move<VkCommandPool> m_cmdPool;
448 Move<VkCommandBuffer> m_cmdBuffer;
449 Move<VkFence> m_fence;
450 de::MovePtr<tcu::TextureLevel> m_sourceTextureLevel;
451 de::MovePtr<tcu::TextureLevel> m_destinationTextureLevel;
452 de::MovePtr<tcu::TextureLevel> m_expectedTextureLevel[16];
453
454 VkCommandBufferBeginInfo m_cmdBufferBeginInfo;
455
456 void generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth = 1, FillMode = FILL_MODE_GRADIENT);
457 virtual void generateExpectedResult (void);
458 void uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc);
459 void uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels = 1u);
460 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
461 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u) = 0;
calculateSize(tcu::ConstPixelBufferAccess src) const462 deUint32 calculateSize (tcu::ConstPixelBufferAccess src) const
463 {
464 return src.getWidth() * src.getHeight() * src.getDepth() * tcu::getPixelSize(src.getFormat());
465 }
466
467 de::MovePtr<tcu::TextureLevel> readImage (vk::VkImage image,
468 const ImageParms& imageParms,
469 const deUint32 mipLevel = 0u);
470
471 private:
472 void uploadImageAspect (const tcu::ConstPixelBufferAccess& src,
473 const VkImage& dst,
474 const ImageParms& parms,
475 const deUint32 mipLevels = 1u);
476 void readImageAspect (vk::VkImage src,
477 const tcu::PixelBufferAccess& dst,
478 const ImageParms& parms,
479 const deUint32 mipLevel = 0u);
480 };
481
CopiesAndBlittingTestInstance(Context & context,TestParams testParams)482 CopiesAndBlittingTestInstance::CopiesAndBlittingTestInstance (Context& context, TestParams testParams)
483 : vkt::TestInstance (context)
484 , m_params (testParams)
485 {
486 const DeviceInterface& vk = context.getDeviceInterface();
487 const VkDevice vkDevice = context.getDevice();
488 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
489
490 // Create command pool
491 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
492
493 // Create command buffer
494 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
495
496 // Create fence
497 m_fence = createFence(vk, vkDevice);
498 }
499
generateBuffer(tcu::PixelBufferAccess buffer,int width,int height,int depth,FillMode mode)500 void CopiesAndBlittingTestInstance::generateBuffer (tcu::PixelBufferAccess buffer, int width, int height, int depth, FillMode mode)
501 {
502 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(buffer.getFormat().type);
503 tcu::Vec4 maxValue (1.0f);
504
505 if (buffer.getFormat().order == tcu::TextureFormat::S)
506 {
507 // Stencil-only is stored in the first component. Stencil is always 8 bits.
508 maxValue.x() = 1 << 8;
509 }
510 else if (buffer.getFormat().order == tcu::TextureFormat::DS)
511 {
512 // In a combined format, fillWithComponentGradients expects stencil in the fourth component.
513 maxValue.w() = 1 << 8;
514 }
515 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
516 {
517 // The tcu::Vectors we use as pixels are 32-bit, so clamp to that.
518 const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(buffer.getFormat()), tcu::IVec4(32));
519 const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0);
520
521 for (int i = 0; i < 4; ++i)
522 {
523 if (bits[i] != 0)
524 maxValue[i] = static_cast<float>((deUint64(1) << (bits[i] - signBit)) - 1);
525 }
526 }
527
528 if (mode == FILL_MODE_GRADIENT)
529 {
530 tcu::fillWithComponentGradients2(buffer, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), maxValue);
531 return;
532 }
533
534 const tcu::Vec4 redColor (maxValue.x(), 0.0, 0.0, maxValue.w());
535 const tcu::Vec4 greenColor (0.0, maxValue.y(), 0.0, maxValue.w());
536 const tcu::Vec4 blueColor (0.0, 0.0, maxValue.z(), maxValue.w());
537 const tcu::Vec4 whiteColor (maxValue.x(), maxValue.y(), maxValue.z(), maxValue.w());
538 const tcu::Vec4 blackColor (0.0f, 0.0f, 0.0f, 0.0f);
539
540 for (int z = 0; z < depth; ++z)
541 for (int y = 0; y < height; ++y)
542 for (int x = 0; x < width; ++x)
543 {
544 switch (mode)
545 {
546 case FILL_MODE_WHITE:
547 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
548 {
549 buffer.setPixDepth(1.0f, x, y, z);
550 if (tcu::hasStencilComponent(buffer.getFormat().order))
551 buffer.setPixStencil(255, x, y, z);
552 }
553 else
554 buffer.setPixel(whiteColor, x, y, z);
555 break;
556
557 case FILL_MODE_BLACK:
558 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
559 {
560 buffer.setPixDepth(0.0f, x, y, z);
561 if (tcu::hasStencilComponent(buffer.getFormat().order))
562 buffer.setPixStencil(0, x, y, z);
563 }
564 else
565 buffer.setPixel(blackColor, x, y, z);
566 break;
567
568 case FILL_MODE_RED:
569 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
570 {
571 buffer.setPixDepth(redColor[0], x, y, z);
572 if (tcu::hasStencilComponent(buffer.getFormat().order))
573 buffer.setPixStencil((int)redColor[3], x, y, z);
574 }
575 else
576 buffer.setPixel(redColor, x, y, z);
577 break;
578
579 case FILL_MODE_BLUE_RED_X:
580 case FILL_MODE_BLUE_RED_Y:
581 case FILL_MODE_BLUE_RED_Z:
582 bool useBlue;
583 switch (mode)
584 {
585 case FILL_MODE_BLUE_RED_X: useBlue = (x & 1); break;
586 case FILL_MODE_BLUE_RED_Y: useBlue = (y & 1); break;
587 case FILL_MODE_BLUE_RED_Z: useBlue = (z & 1); break;
588 default: DE_ASSERT(false); break;
589 }
590 if (tcu::isCombinedDepthStencilType(buffer.getFormat().type))
591 {
592 buffer.setPixDepth((useBlue ? blueColor[0] : redColor[0]), x, y, z);
593 if (tcu::hasStencilComponent(buffer.getFormat().order))
594 buffer.setPixStencil((useBlue ? (int) blueColor[3] : (int)redColor[3]), x, y, z);
595 }
596 else
597 buffer.setPixel((useBlue ? blueColor : redColor), x, y, z);
598 break;
599
600 case FILL_MODE_MULTISAMPLE:
601 {
602 float xScaled = static_cast<float>(x) / static_cast<float>(width);
603 float yScaled = static_cast<float>(y) / static_cast<float>(height);
604 buffer.setPixel((xScaled == yScaled) ? tcu::Vec4(0.0, 0.5, 0.5, 1.0) : ((xScaled > yScaled) ? greenColor : blueColor), x, y, z);
605 break;
606 }
607
608 default:
609 break;
610 }
611 }
612 }
613
uploadBuffer(tcu::ConstPixelBufferAccess bufferAccess,const Allocation & bufferAlloc)614 void CopiesAndBlittingTestInstance::uploadBuffer (tcu::ConstPixelBufferAccess bufferAccess, const Allocation& bufferAlloc)
615 {
616 const DeviceInterface& vk = m_context.getDeviceInterface();
617 const VkDevice vkDevice = m_context.getDevice();
618 const deUint32 bufferSize = calculateSize(bufferAccess);
619
620 // Write buffer data
621 deMemcpy(bufferAlloc.getHostPtr(), bufferAccess.getDataPtr(), bufferSize);
622 flushAlloc(vk, vkDevice, bufferAlloc);
623 }
624
uploadImageAspect(const tcu::ConstPixelBufferAccess & imageAccess,const VkImage & image,const ImageParms & parms,const deUint32 mipLevels)625 void CopiesAndBlittingTestInstance::uploadImageAspect (const tcu::ConstPixelBufferAccess& imageAccess, const VkImage& image, const ImageParms& parms, const deUint32 mipLevels)
626 {
627 const InstanceInterface& vki = m_context.getInstanceInterface();
628 const DeviceInterface& vk = m_context.getDeviceInterface();
629 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
630 const VkDevice vkDevice = m_context.getDevice();
631 const VkQueue queue = m_context.getUniversalQueue();
632 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
633 Allocator& memAlloc = m_context.getDefaultAllocator();
634 Move<VkBuffer> buffer;
635 const deUint32 bufferSize = calculateSize(imageAccess);
636 de::MovePtr<Allocation> bufferAlloc;
637 const deUint32 arraySize = getArraySize(parms);
638 const VkExtent3D imageExtent = getExtent3D(parms);
639 std::vector <VkBufferImageCopy> copyRegions;
640
641 // Create source buffer
642 {
643 const VkBufferCreateInfo bufferParams =
644 {
645 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
646 DE_NULL, // const void* pNext;
647 0u, // VkBufferCreateFlags flags;
648 bufferSize, // VkDeviceSize size;
649 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
650 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
651 1u, // deUint32 queueFamilyIndexCount;
652 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
653 };
654
655 buffer = createBuffer(vk, vkDevice, &bufferParams);
656 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
657 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
658 }
659
660 // Barriers for copying buffer to image
661 const VkBufferMemoryBarrier preBufferBarrier =
662 {
663 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
664 DE_NULL, // const void* pNext;
665 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
666 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
667 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
668 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
669 *buffer, // VkBuffer buffer;
670 0u, // VkDeviceSize offset;
671 bufferSize // VkDeviceSize size;
672 };
673
674 const VkImageAspectFlags formatAspect = (m_params.separateDepthStencilLayouts) ? getAspectFlags(imageAccess.getFormat()) : getAspectFlags(parms.format);
675 const bool skipPreImageBarrier = (m_params.separateDepthStencilLayouts) ? false : ((formatAspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) &&
676 getAspectFlags(imageAccess.getFormat()) == VK_IMAGE_ASPECT_STENCIL_BIT));
677
678 const VkImageMemoryBarrier preImageBarrier =
679 {
680 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
681 DE_NULL, // const void* pNext;
682 0u, // VkAccessFlags srcAccessMask;
683 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
684 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
685 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
686 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
687 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
688 image, // VkImage image;
689 { // VkImageSubresourceRange subresourceRange;
690 formatAspect, // VkImageAspectFlags aspect;
691 0u, // deUint32 baseMipLevel;
692 mipLevels, // deUint32 mipLevels;
693 0u, // deUint32 baseArraySlice;
694 arraySize, // deUint32 arraySize;
695 }
696 };
697
698 const VkImageMemoryBarrier postImageBarrier =
699 {
700 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
701 DE_NULL, // const void* pNext;
702 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
703 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
704 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
705 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
706 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
707 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
708 image, // VkImage image;
709 { // VkImageSubresourceRange subresourceRange;
710 formatAspect, // VkImageAspectFlags aspect;
711 0u, // deUint32 baseMipLevel;
712 mipLevels, // deUint32 mipLevels;
713 0u, // deUint32 baseArraySlice;
714 arraySize, // deUint32 arraySize;
715 }
716 };
717
718 for (deUint32 mipLevelNdx = 0; mipLevelNdx < mipLevels; mipLevelNdx++)
719 {
720 const VkExtent3D copyExtent =
721 {
722 imageExtent.width >> mipLevelNdx,
723 imageExtent.height >> mipLevelNdx,
724 imageExtent.depth
725 };
726
727 const bool isCompressed = isCompressedFormat(parms.format);
728 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(parms.format) : 1u;
729 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(parms.format) : 1u;
730 deUint32 rowLength = ((copyExtent.width + blockWidth-1) / blockWidth) * blockWidth;
731 deUint32 imageHeight = ((copyExtent.height + blockHeight-1) / blockHeight) * blockHeight;
732
733 const VkBufferImageCopy copyRegion =
734 {
735 0u, // VkDeviceSize bufferOffset;
736 rowLength, // deUint32 bufferRowLength;
737 imageHeight, // deUint32 bufferImageHeight;
738 {
739 getAspectFlags(imageAccess.getFormat()), // VkImageAspectFlags aspect;
740 mipLevelNdx, // deUint32 mipLevel;
741 0u, // deUint32 baseArrayLayer;
742 arraySize, // deUint32 layerCount;
743 }, // VkImageSubresourceLayers imageSubresource;
744 { 0, 0, 0 }, // VkOffset3D imageOffset;
745 copyExtent // VkExtent3D imageExtent;
746 };
747
748 copyRegions.push_back(copyRegion);
749 }
750
751 // Write buffer data
752 deMemcpy(bufferAlloc->getHostPtr(), imageAccess.getDataPtr(), bufferSize);
753 flushAlloc(vk, vkDevice, *bufferAlloc);
754
755 // Copy buffer to image
756 beginCommandBuffer(vk, *m_cmdBuffer);
757 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
758 1, &preBufferBarrier, (skipPreImageBarrier ? 0 : 1), (skipPreImageBarrier ? DE_NULL : &preImageBarrier));
759 vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copyRegions.size(), ©Regions[0]);
760 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, &postImageBarrier);
761 endCommandBuffer(vk, *m_cmdBuffer);
762
763 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
764 }
765
uploadImage(const tcu::ConstPixelBufferAccess & src,VkImage dst,const ImageParms & parms,const deUint32 mipLevels)766 void CopiesAndBlittingTestInstance::uploadImage (const tcu::ConstPixelBufferAccess& src, VkImage dst, const ImageParms& parms, const deUint32 mipLevels)
767 {
768 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
769 {
770 if (tcu::hasDepthComponent(src.getFormat().order))
771 {
772 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(src.getFormat()), src.getWidth(), src.getHeight(), src.getDepth());
773 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH));
774 uploadImageAspect(depthTexture.getAccess(), dst, parms, mipLevels);
775 }
776
777 if (tcu::hasStencilComponent(src.getFormat().order))
778 {
779 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(src.getFormat(), tcu::Sampler::MODE_STENCIL), src.getWidth(), src.getHeight(), src.getDepth());
780 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL));
781 uploadImageAspect(stencilTexture.getAccess(), dst, parms, mipLevels);
782 }
783 }
784 else
785 uploadImageAspect(src, dst, parms, mipLevels);
786 }
787
checkTestResult(tcu::ConstPixelBufferAccess result)788 tcu::TestStatus CopiesAndBlittingTestInstance::checkTestResult (tcu::ConstPixelBufferAccess result)
789 {
790 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
791
792 if (isFloatFormat(result.getFormat()))
793 {
794 const tcu::Vec4 threshold (0.0f);
795 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
796 return tcu::TestStatus::fail("CopiesAndBlitting test");
797 }
798 else
799 {
800 const tcu::UVec4 threshold (0u);
801 if (tcu::hasDepthComponent(result.getFormat().order) || tcu::hasStencilComponent(result.getFormat().order))
802 {
803 if (!tcu::dsThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, 0.1f, tcu::COMPARE_LOG_RESULT))
804 return tcu::TestStatus::fail("CopiesAndBlitting test");
805 }
806 else
807 {
808 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, threshold, tcu::COMPARE_LOG_RESULT))
809 return tcu::TestStatus::fail("CopiesAndBlitting test");
810 }
811 }
812
813 return tcu::TestStatus::pass("CopiesAndBlitting test");
814 }
815
generateExpectedResult(void)816 void CopiesAndBlittingTestInstance::generateExpectedResult (void)
817 {
818 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
819 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
820
821 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
822 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
823
824 for (deUint32 i = 0; i < m_params.regions.size(); i++)
825 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), m_params.regions[i]);
826 }
827
828 class CopiesAndBlittingTestCase : public vkt::TestCase
829 {
830 public:
CopiesAndBlittingTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description)831 CopiesAndBlittingTestCase (tcu::TestContext& testCtx,
832 const std::string& name,
833 const std::string& description)
834 : vkt::TestCase (testCtx, name, description)
835 {}
836
837 virtual TestInstance* createInstance (Context& context) const = 0;
838 };
839
readImageAspect(vk::VkImage image,const tcu::PixelBufferAccess & dst,const ImageParms & imageParms,const deUint32 mipLevel)840 void CopiesAndBlittingTestInstance::readImageAspect (vk::VkImage image,
841 const tcu::PixelBufferAccess& dst,
842 const ImageParms& imageParms,
843 const deUint32 mipLevel)
844 {
845 const InstanceInterface& vki = m_context.getInstanceInterface();
846 const DeviceInterface& vk = m_context.getDeviceInterface();
847 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
848 const VkDevice device = m_context.getDevice();
849 const VkQueue queue = m_context.getUniversalQueue();
850 Allocator& allocator = m_context.getDefaultAllocator();
851
852 Move<VkBuffer> buffer;
853 de::MovePtr<Allocation> bufferAlloc;
854 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
855 const VkDeviceSize pixelDataSize = calculateSize(dst);
856 const VkExtent3D imageExtent = getExtent3D(imageParms, mipLevel);
857
858 // Create destination buffer
859 {
860 const VkBufferCreateInfo bufferParams =
861 {
862 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
863 DE_NULL, // const void* pNext;
864 0u, // VkBufferCreateFlags flags;
865 pixelDataSize, // VkDeviceSize size;
866 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
867 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
868 1u, // deUint32 queueFamilyIndexCount;
869 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
870 };
871
872 buffer = createBuffer(vk, device, &bufferParams);
873 bufferAlloc = allocateBuffer(vki, vk, physDevice, device, *buffer, MemoryRequirement::HostVisible, allocator, m_params.allocationKind);
874 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
875
876 deMemset(bufferAlloc->getHostPtr(), 0, static_cast<size_t>(pixelDataSize));
877 flushAlloc(vk, device, *bufferAlloc);
878 }
879
880 // Barriers for copying image to buffer
881 const VkImageAspectFlags formatAspect = getAspectFlags(imageParms.format);
882 const VkImageMemoryBarrier imageBarrier =
883 {
884 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
885 DE_NULL, // const void* pNext;
886 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
887 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
888 imageParms.operationLayout, // VkImageLayout oldLayout;
889 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
890 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
891 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
892 image, // VkImage image;
893 { // VkImageSubresourceRange subresourceRange;
894 formatAspect, // VkImageAspectFlags aspectMask;
895 mipLevel, // deUint32 baseMipLevel;
896 1u, // deUint32 mipLevels;
897 0u, // deUint32 baseArraySlice;
898 getArraySize(imageParms)// deUint32 arraySize;
899 }
900 };
901
902 const VkBufferMemoryBarrier bufferBarrier =
903 {
904 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
905 DE_NULL, // const void* pNext;
906 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
907 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
908 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
909 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
910 *buffer, // VkBuffer buffer;
911 0u, // VkDeviceSize offset;
912 pixelDataSize // VkDeviceSize size;
913 };
914
915 const VkImageMemoryBarrier postImageBarrier =
916 {
917 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
918 DE_NULL, // const void* pNext;
919 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
920 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
921 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout oldLayout;
922 imageParms.operationLayout, // VkImageLayout newLayout;
923 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
924 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
925 image, // VkImage image;
926 {
927 formatAspect, // VkImageAspectFlags aspectMask;
928 mipLevel, // deUint32 baseMipLevel;
929 1u, // deUint32 mipLevels;
930 0u, // deUint32 baseArraySlice;
931 getArraySize(imageParms) // deUint32 arraySize;
932 } // VkImageSubresourceRange subresourceRange;
933 };
934
935 // Copy image to buffer
936 const bool isCompressed = isCompressedFormat(imageParms.format);
937 const deUint32 blockWidth = (isCompressed) ? getBlockWidth(imageParms.format) : 1u;
938 const deUint32 blockHeight = (isCompressed) ? getBlockHeight(imageParms.format) : 1u;
939 deUint32 rowLength = ((imageExtent.width + blockWidth-1) / blockWidth) * blockWidth;
940 deUint32 imageHeight = ((imageExtent.height + blockHeight-1) / blockHeight) * blockHeight;
941
942 // Copy image to buffer - note that there are cases where m_params.dst.image.format is not the same as dst.getFormat()
943 const VkImageAspectFlags aspect = isCompressedFormat(m_params.dst.image.format) ?
944 static_cast<VkImageAspectFlags>(VK_IMAGE_ASPECT_COLOR_BIT) : getAspectFlags(dst.getFormat());
945 const VkBufferImageCopy copyRegion =
946 {
947 0u, // VkDeviceSize bufferOffset;
948 rowLength, // deUint32 bufferRowLength;
949 imageHeight, // deUint32 bufferImageHeight;
950 {
951 aspect, // VkImageAspectFlags aspect;
952 mipLevel, // deUint32 mipLevel;
953 0u, // deUint32 baseArrayLayer;
954 getArraySize(imageParms), // deUint32 layerCount;
955 }, // VkImageSubresourceLayers imageSubresource;
956 { 0, 0, 0 }, // VkOffset3D imageOffset;
957 imageExtent // VkExtent3D imageExtent;
958 };
959
960 beginCommandBuffer(vk, *m_cmdBuffer);
961 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);
962 vk.cmdCopyImageToBuffer(*m_cmdBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1u, ©Region);
963 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT|VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 1, &postImageBarrier);
964 endCommandBuffer(vk, *m_cmdBuffer);
965
966 submitCommandsAndWait(vk, device, queue, *m_cmdBuffer);
967
968 // Read buffer data
969 invalidateAlloc(vk, device, *bufferAlloc);
970 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferAlloc->getHostPtr()));
971 }
972
readImage(vk::VkImage image,const ImageParms & parms,const deUint32 mipLevel)973 de::MovePtr<tcu::TextureLevel> CopiesAndBlittingTestInstance::readImage (vk::VkImage image,
974 const ImageParms& parms,
975 const deUint32 mipLevel)
976 {
977 const tcu::TextureFormat imageFormat = getSizeCompatibleTcuTextureFormat(parms.format);
978 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(imageFormat, parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth));
979
980 if (tcu::isCombinedDepthStencilType(imageFormat.type))
981 {
982 if (tcu::hasDepthComponent(imageFormat.order))
983 {
984 tcu::TextureLevel depthTexture (mapCombinedToDepthTransferFormat(imageFormat), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
985 readImageAspect(image, depthTexture.getAccess(), parms, mipLevel);
986 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_DEPTH), depthTexture.getAccess());
987 }
988
989 if (tcu::hasStencilComponent(imageFormat.order))
990 {
991 tcu::TextureLevel stencilTexture (tcu::getEffectiveDepthStencilTextureFormat(imageFormat, tcu::Sampler::MODE_STENCIL), parms.extent.width >> mipLevel, parms.extent.height >> mipLevel, parms.extent.depth);
992 readImageAspect(image, stencilTexture.getAccess(), parms, mipLevel);
993 tcu::copy(tcu::getEffectiveDepthStencilAccess(resultLevel->getAccess(), tcu::Sampler::MODE_STENCIL), stencilTexture.getAccess());
994 }
995 }
996 else
997 readImageAspect(image, resultLevel->getAccess(), parms, mipLevel);
998
999 return resultLevel;
1000 }
1001
1002 // Copy from image to image.
1003
1004 class CopyImageToImage : public CopiesAndBlittingTestInstance
1005 {
1006 public:
1007 CopyImageToImage (Context& context,
1008 TestParams params);
1009 virtual tcu::TestStatus iterate (void);
1010
1011 protected:
1012 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
1013
1014 private:
1015 Move<VkImage> m_source;
1016 de::MovePtr<Allocation> m_sourceImageAlloc;
1017 Move<VkImage> m_destination;
1018 de::MovePtr<Allocation> m_destinationImageAlloc;
1019
1020 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1021 };
1022
CopyImageToImage(Context & context,TestParams params)1023 CopyImageToImage::CopyImageToImage (Context& context, TestParams params)
1024 : CopiesAndBlittingTestInstance(context, params)
1025 {
1026 const InstanceInterface& vki = context.getInstanceInterface();
1027 const DeviceInterface& vk = context.getDeviceInterface();
1028 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1029 const VkDevice vkDevice = context.getDevice();
1030 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1031 Allocator& memAlloc = context.getDefaultAllocator();
1032
1033 // Create source image
1034 {
1035 const VkImageCreateInfo sourceImageParams =
1036 {
1037 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1038 DE_NULL, // const void* pNext;
1039 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1040 m_params.src.image.imageType, // VkImageType imageType;
1041 m_params.src.image.format, // VkFormat format;
1042 getExtent3D(m_params.src.image), // VkExtent3D extent;
1043 1u, // deUint32 mipLevels;
1044 getArraySize(m_params.src.image), // deUint32 arraySize;
1045 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1046 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1047 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1048 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1049 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1050 1u, // deUint32 queueFamilyCount;
1051 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1052 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1053 };
1054
1055 m_source = createImage(vk, vkDevice, &sourceImageParams);
1056 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1057 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1058 }
1059
1060 // Create destination image
1061 {
1062 const VkImageCreateInfo destinationImageParams =
1063 {
1064 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1065 DE_NULL, // const void* pNext;
1066 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1067 m_params.dst.image.imageType, // VkImageType imageType;
1068 m_params.dst.image.format, // VkFormat format;
1069 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1070 1u, // deUint32 mipLevels;
1071 getArraySize(m_params.dst.image), // deUint32 arraySize;
1072 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1073 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1074 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1075 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1076 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1077 1u, // deUint32 queueFamilyCount;
1078 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1079 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1080 };
1081
1082 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1083 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1084 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1085 }
1086 }
1087
iterate(void)1088 tcu::TestStatus CopyImageToImage::iterate (void)
1089 {
1090 const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1091 const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1092
1093 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1094 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1095
1096 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1097 (int)m_params.src.image.extent.width,
1098 (int)m_params.src.image.extent.height,
1099 (int)m_params.src.image.extent.depth));
1100 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
1101 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1102 (int)m_params.dst.image.extent.width,
1103 (int)m_params.dst.image.extent.height,
1104 (int)m_params.dst.image.extent.depth));
1105 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.clearDestination ? FILL_MODE_WHITE : FILL_MODE_GRADIENT);
1106 generateExpectedResult();
1107
1108 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
1109 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
1110
1111 const DeviceInterface& vk = m_context.getDeviceInterface();
1112 const VkDevice vkDevice = m_context.getDevice();
1113 const VkQueue queue = m_context.getUniversalQueue();
1114
1115 std::vector<VkImageCopy> imageCopies;
1116 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1117 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1118 {
1119 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1120
1121 // When copying between compressed and uncompressed formats the extent
1122 // members represent the texel dimensions of the source image.
1123 if (srcCompressed)
1124 {
1125 const deUint32 blockWidth = getBlockWidth(m_params.src.image.format);
1126 const deUint32 blockHeight = getBlockHeight(m_params.src.image.format);
1127
1128 imageCopy.srcOffset.x *= blockWidth;
1129 imageCopy.srcOffset.y *= blockHeight;
1130 imageCopy.extent.width *= blockWidth;
1131 imageCopy.extent.height *= blockHeight;
1132 }
1133
1134 if (dstCompressed)
1135 {
1136 const deUint32 blockWidth = getBlockWidth(m_params.dst.image.format);
1137 const deUint32 blockHeight = getBlockHeight(m_params.dst.image.format);
1138
1139 imageCopy.dstOffset.x *= blockWidth;
1140 imageCopy.dstOffset.y *= blockHeight;
1141 }
1142
1143 if (m_params.extensionUse == EXTENSION_USE_NONE)
1144 {
1145 imageCopies.push_back(imageCopy);
1146 }
1147 else
1148 {
1149 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1150 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1151 }
1152 }
1153
1154 const VkImageMemoryBarrier imageBarriers[] =
1155 {
1156 // source image
1157 {
1158 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1159 DE_NULL, // const void* pNext;
1160 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1161 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1162 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1163 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1164 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1165 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1166 m_source.get(), // VkImage image;
1167 { // VkImageSubresourceRange subresourceRange;
1168 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1169 0u, // deUint32 baseMipLevel;
1170 1u, // deUint32 mipLevels;
1171 0u, // deUint32 baseArraySlice;
1172 getArraySize(m_params.src.image)// deUint32 arraySize;
1173 }
1174 },
1175 // destination image
1176 {
1177 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1178 DE_NULL, // const void* pNext;
1179 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1180 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1181 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1182 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1183 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1184 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1185 m_destination.get(), // VkImage image;
1186 { // VkImageSubresourceRange subresourceRange;
1187 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1188 0u, // deUint32 baseMipLevel;
1189 1u, // deUint32 mipLevels;
1190 0u, // deUint32 baseArraySlice;
1191 getArraySize(m_params.dst.image)// deUint32 arraySize;
1192 }
1193 },
1194 };
1195
1196 beginCommandBuffer(vk, *m_cmdBuffer);
1197 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, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1198
1199 if (m_params.clearDestination)
1200 {
1201 VkImageSubresourceRange range = { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u };
1202 VkClearColorValue clearColor;
1203
1204 clearColor.float32[0] = 1.0f;
1205 clearColor.float32[1] = 1.0f;
1206 clearColor.float32[2] = 1.0f;
1207 clearColor.float32[3] = 1.0f;
1208 vk.cmdClearColorImage(*m_cmdBuffer, m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1u, &range);
1209 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, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1210 }
1211
1212 if (m_params.extensionUse == EXTENSION_USE_NONE)
1213 {
1214 vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
1215 }
1216 else
1217 {
1218 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1219 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1220 {
1221 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1222 DE_NULL, // const void* pNext;
1223 m_source.get(), // VkImage srcImage;
1224 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1225 m_destination.get(), // VkImage dstImage;
1226 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1227 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
1228 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1229 };
1230
1231 vk.cmdCopyImage2KHR(*m_cmdBuffer, ©ImageInfo2KHR);
1232 }
1233
1234 endCommandBuffer(vk, *m_cmdBuffer);
1235
1236 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1237
1238 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
1239
1240 return checkTestResult(resultTextureLevel->getAccess());
1241 }
1242
checkTestResult(tcu::ConstPixelBufferAccess result)1243 tcu::TestStatus CopyImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
1244 {
1245 const tcu::Vec4 fThreshold (0.0f);
1246 const tcu::UVec4 uThreshold (0u);
1247
1248 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1249 {
1250 if (tcu::hasDepthComponent(result.getFormat().order))
1251 {
1252 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1253 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1254 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1255
1256 if (isFloatFormat(result.getFormat()))
1257 {
1258 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1259 return tcu::TestStatus::fail("CopiesAndBlitting test");
1260 }
1261 else
1262 {
1263 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1264 return tcu::TestStatus::fail("CopiesAndBlitting test");
1265 }
1266 }
1267
1268 if (tcu::hasStencilComponent(result.getFormat().order))
1269 {
1270 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1271 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1272 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
1273
1274 if (isFloatFormat(result.getFormat()))
1275 {
1276 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1277 return tcu::TestStatus::fail("CopiesAndBlitting test");
1278 }
1279 else
1280 {
1281 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1282 return tcu::TestStatus::fail("CopiesAndBlitting test");
1283 }
1284 }
1285 }
1286 else
1287 {
1288 if (isFloatFormat(result.getFormat()))
1289 {
1290 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1291 return tcu::TestStatus::fail("CopiesAndBlitting test");
1292 }
1293 else
1294 {
1295 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", m_expectedTextureLevel[0]->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1296 return tcu::TestStatus::fail("CopiesAndBlitting test");
1297 }
1298 }
1299
1300 return tcu::TestStatus::pass("CopiesAndBlitting test");
1301 }
1302
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1303 void CopyImageToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1304 {
1305 DE_UNREF(mipLevel);
1306
1307 VkOffset3D srcOffset = region.imageCopy.srcOffset;
1308 VkOffset3D dstOffset = region.imageCopy.dstOffset;
1309 VkExtent3D extent = region.imageCopy.extent;
1310
1311 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1312 {
1313 dstOffset.z = srcOffset.z;
1314 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1315 }
1316 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1317 {
1318 srcOffset.z = dstOffset.z;
1319 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1320 }
1321
1322
1323 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1324 {
1325 DE_ASSERT(src.getFormat() == dst.getFormat());
1326
1327 // Copy depth.
1328 if (tcu::hasDepthComponent(src.getFormat().order))
1329 {
1330 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1331 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1332 tcu::copy(dstSubRegion, srcSubRegion);
1333 }
1334
1335 // Copy stencil.
1336 if (tcu::hasStencilComponent(src.getFormat().order))
1337 {
1338 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1339 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1340 tcu::copy(dstSubRegion, srcSubRegion);
1341 }
1342 }
1343 else
1344 {
1345 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1346 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1347 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1348 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1349
1350 tcu::copy(dstSubRegion, srcSubRegion);
1351 }
1352 }
1353
1354 class CopyImageToImageTestCase : public vkt::TestCase
1355 {
1356 public:
CopyImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1357 CopyImageToImageTestCase (tcu::TestContext& testCtx,
1358 const std::string& name,
1359 const std::string& description,
1360 const TestParams params)
1361 : vkt::TestCase (testCtx, name, description)
1362 , m_params (params)
1363 {}
1364
createInstance(Context & context) const1365 virtual TestInstance* createInstance (Context& context) const
1366 {
1367 return new CopyImageToImage(context, m_params);
1368 }
1369
checkSupport(Context & context) const1370 virtual void checkSupport (Context& context) const
1371 {
1372 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1373 {
1374 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1375 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1376 }
1377
1378 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1379 {
1380 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1381 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1382 }
1383
1384 if (m_params.separateDepthStencilLayouts)
1385 if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1386 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1387
1388 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1389 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1390 {
1391 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1392 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1393 }
1394
1395 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1396 VkImageFormatProperties properties;
1397
1398 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1399 m_params.src.image.format,
1400 m_params.src.image.imageType,
1401 VK_IMAGE_TILING_OPTIMAL,
1402 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1403 0,
1404 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1405 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1406 m_params.dst.image.format,
1407 m_params.dst.image.imageType,
1408 VK_IMAGE_TILING_OPTIMAL,
1409 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1410 0,
1411 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1412 {
1413 TCU_THROW(NotSupportedError, "Format not supported");
1414 }
1415
1416 // Check maxImageDimension1D
1417 {
1418 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1419 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1420
1421 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1422 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1423 }
1424
1425 // Check maxImageDimension2D
1426 {
1427 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1428 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1429 {
1430 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1431 }
1432
1433 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1434 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1435 {
1436 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1437 }
1438 }
1439
1440 // Check maxImageDimension3D
1441 {
1442 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1443 || m_params.src.image.extent.height > limits.maxImageDimension3D
1444 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1445 {
1446 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1447 }
1448
1449 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1450 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1451 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1452 {
1453 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1454 }
1455 }
1456 }
1457
1458 private:
1459 TestParams m_params;
1460 };
1461
1462 class CopyImageToImageMipmap : public CopiesAndBlittingTestInstance
1463 {
1464 public:
1465 CopyImageToImageMipmap (Context& context,
1466 TestParams params);
1467 virtual tcu::TestStatus iterate (void);
1468
1469 protected:
1470 tcu::TestStatus checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected);
1471
1472 private:
1473 Move<VkImage> m_source;
1474 de::MovePtr<Allocation> m_sourceImageAlloc;
1475 Move<VkImage> m_destination;
1476 de::MovePtr<Allocation> m_destinationImageAlloc;
1477
1478 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
1479
1480 };
1481
CopyImageToImageMipmap(Context & context,TestParams params)1482 CopyImageToImageMipmap::CopyImageToImageMipmap (Context& context, TestParams params)
1483 : CopiesAndBlittingTestInstance(context, params)
1484 {
1485 const InstanceInterface& vki = context.getInstanceInterface();
1486 const DeviceInterface& vk = context.getDeviceInterface();
1487 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1488 const VkDevice vkDevice = context.getDevice();
1489 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1490 Allocator& memAlloc = context.getDefaultAllocator();
1491
1492 // Create source image
1493 {
1494 const VkImageCreateInfo sourceImageParams =
1495 {
1496 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1497 DE_NULL, // const void* pNext;
1498 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
1499 m_params.src.image.imageType, // VkImageType imageType;
1500 m_params.src.image.format, // VkFormat format;
1501 getExtent3D(m_params.src.image), // VkExtent3D extent;
1502 params.mipLevels, // deUint32 mipLevels;
1503 getArraySize(m_params.src.image), // deUint32 arraySize;
1504 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1505 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1506 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1507 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1508 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1509 1u, // deUint32 queueFamilyCount;
1510 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1511 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1512 };
1513
1514 m_source = createImage(vk, vkDevice, &sourceImageParams);
1515 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1516 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
1517 }
1518
1519 // Create destination image
1520 {
1521 const VkImageCreateInfo destinationImageParams =
1522 {
1523 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1524 DE_NULL, // const void* pNext;
1525 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
1526 m_params.dst.image.imageType, // VkImageType imageType;
1527 m_params.dst.image.format, // VkFormat format;
1528 getExtent3D(m_params.dst.image), // VkExtent3D extent;
1529 params.mipLevels, // deUint32 mipLevels;
1530 getArraySize(m_params.dst.image), // deUint32 arraySize;
1531 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
1532 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1533 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
1534 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
1535 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1536 1u, // deUint32 queueFamilyCount;
1537 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1538 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1539 };
1540
1541 m_destination = createImage(vk, vkDevice, &destinationImageParams);
1542 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
1543 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
1544 }
1545 }
1546
iterate(void)1547 tcu::TestStatus CopyImageToImageMipmap::iterate (void)
1548 {
1549 const bool srcCompressed = isCompressedFormat(m_params.src.image.format);
1550 const bool dstCompressed = isCompressedFormat(m_params.dst.image.format);
1551
1552 const tcu::TextureFormat srcTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.src.image.format);
1553 const tcu::TextureFormat dstTcuFormat = getSizeCompatibleTcuTextureFormat(m_params.dst.image.format);
1554
1555 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
1556 (int)m_params.src.image.extent.width,
1557 (int)m_params.src.image.extent.height,
1558 (int)m_params.src.image.extent.depth));
1559 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, FILL_MODE_GRADIENT);
1560 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image, m_params.mipLevels);
1561
1562 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
1563 (int)m_params.dst.image.extent.width,
1564 (int)m_params.dst.image.extent.height,
1565 (int)m_params.dst.image.extent.depth));
1566 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_RED);
1567 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
1568
1569 const DeviceInterface& vk = m_context.getDeviceInterface();
1570 const VkDevice vkDevice = m_context.getDevice();
1571 const VkQueue queue = m_context.getUniversalQueue();
1572
1573 std::vector<VkImageCopy> imageCopies;
1574 std::vector<VkImageCopy2KHR> imageCopies2KHR;
1575 for (deUint32 i = 0; i < m_params.regions.size(); i++)
1576 {
1577 VkImageCopy imageCopy = m_params.regions[i].imageCopy;
1578
1579 // When copying between compressed and uncompressed formats the extent
1580 // members represent the texel dimensions of the source image.
1581 if (srcCompressed)
1582 {
1583 const deUint32 blockWidth = getBlockWidth(m_params.src.image.format);
1584 const deUint32 blockHeight = getBlockHeight(m_params.src.image.format);
1585
1586 imageCopy.srcOffset.x *= blockWidth;
1587 imageCopy.srcOffset.y *= blockHeight;
1588 imageCopy.extent.width *= blockWidth;
1589 imageCopy.extent.height *= blockHeight;
1590 }
1591
1592 if (dstCompressed)
1593 {
1594 const deUint32 blockWidth = getBlockWidth(m_params.dst.image.format);
1595 const deUint32 blockHeight = getBlockHeight(m_params.dst.image.format);
1596
1597 imageCopy.dstOffset.x *= blockWidth;
1598 imageCopy.dstOffset.y *= blockHeight;
1599 }
1600
1601 if (m_params.extensionUse == EXTENSION_USE_NONE)
1602 {
1603 imageCopies.push_back(imageCopy);
1604 }
1605 else
1606 {
1607 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1608 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
1609 }
1610 }
1611
1612 const VkImageMemoryBarrier imageBarriers[] =
1613 {
1614 // source image
1615 {
1616 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1617 DE_NULL, // const void* pNext;
1618 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1619 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
1620 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1621 m_params.src.image.operationLayout, // VkImageLayout newLayout;
1622 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1623 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1624 m_source.get(), // VkImage image;
1625 { // VkImageSubresourceRange subresourceRange;
1626 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
1627 0u, // deUint32 baseMipLevel;
1628 m_params.mipLevels, // deUint32 mipLevels;
1629 0u, // deUint32 baseArraySlice;
1630 getArraySize(m_params.src.image)// deUint32 arraySize;
1631 }
1632 },
1633 // destination image
1634 {
1635 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1636 DE_NULL, // const void* pNext;
1637 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1638 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
1639 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1640 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
1641 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
1642 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
1643 m_destination.get(), // VkImage image;
1644 { // VkImageSubresourceRange subresourceRange;
1645 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
1646 0u, // deUint32 baseMipLevel;
1647 m_params.mipLevels, // deUint32 mipLevels;
1648 0u, // deUint32 baseArraySlice;
1649 getArraySize(m_params.dst.image)// deUint32 arraySize;
1650 }
1651 },
1652 };
1653
1654 beginCommandBuffer(vk, *m_cmdBuffer);
1655 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, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
1656
1657 if (m_params.extensionUse == EXTENSION_USE_NONE)
1658 {
1659 vk.cmdCopyImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
1660 }
1661 else
1662 {
1663 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
1664 const VkCopyImageInfo2KHR copyImageInfo2KHR =
1665 {
1666 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
1667 DE_NULL, // const void* pNext;
1668 m_source.get(), // VkImage srcImage;
1669 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
1670 m_destination.get(), // VkImage dstImage;
1671 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
1672 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
1673 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
1674 };
1675
1676 vk.cmdCopyImage2KHR(*m_cmdBuffer, ©ImageInfo2KHR);
1677 }
1678
1679 endCommandBuffer(vk, *m_cmdBuffer);
1680
1681 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
1682
1683 for (deUint32 miplevel = 0; miplevel < m_params.mipLevels; miplevel++)
1684 {
1685 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image, miplevel);
1686 de::MovePtr<tcu::TextureLevel> expectedTextureLevel = readImage(*m_source, m_params.src.image, miplevel);
1687
1688 tcu::TestStatus result = checkResult(resultTextureLevel->getAccess(), expectedTextureLevel->getAccess());
1689 if (result.getCode() != QP_TEST_RESULT_PASS)
1690 return result;
1691 }
1692 return tcu::TestStatus::pass("Pass");
1693 }
1694
checkResult(tcu::ConstPixelBufferAccess result,tcu::ConstPixelBufferAccess expected)1695 tcu::TestStatus CopyImageToImageMipmap::checkResult (tcu::ConstPixelBufferAccess result, tcu::ConstPixelBufferAccess expected)
1696 {
1697 const tcu::Vec4 fThreshold (0.0f);
1698 const tcu::UVec4 uThreshold (0u);
1699
1700 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
1701 {
1702 if (tcu::hasDepthComponent(result.getFormat().order))
1703 {
1704 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1705 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1706 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1707
1708 if (isFloatFormat(result.getFormat()))
1709 {
1710 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1711 return tcu::TestStatus::fail("CopiesAndBlitting test");
1712 }
1713 else
1714 {
1715 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1716 return tcu::TestStatus::fail("CopiesAndBlitting test");
1717 }
1718 }
1719
1720 if (tcu::hasStencilComponent(result.getFormat().order))
1721 {
1722 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1723 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1724 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(expected, mode);
1725
1726 if (isFloatFormat(result.getFormat()))
1727 {
1728 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1729 return tcu::TestStatus::fail("CopiesAndBlitting test");
1730 }
1731 else
1732 {
1733 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1734 return tcu::TestStatus::fail("CopiesAndBlitting test");
1735 }
1736 }
1737 }
1738 else
1739 {
1740 if (isFloatFormat(result.getFormat()))
1741 {
1742 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, fThreshold, tcu::COMPARE_LOG_RESULT))
1743 return tcu::TestStatus::fail("CopiesAndBlitting test");
1744 }
1745 else if (isSnormFormat(mapTextureFormat(result.getFormat())))
1746 {
1747 // There may be an ambiguity between two possible binary representations of 1.0.
1748 // Get rid of that by expanding the data to floats and re-normalizing again.
1749
1750 tcu::TextureLevel resultSnorm (result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
1751 {
1752 tcu::TextureLevel resultFloat (tcu::TextureFormat(resultSnorm.getFormat().order, tcu::TextureFormat::FLOAT), resultSnorm.getWidth(), resultSnorm.getHeight(), resultSnorm.getDepth());
1753
1754 tcu::copy(resultFloat.getAccess(), result);
1755 tcu::copy(resultSnorm, resultFloat.getAccess());
1756 }
1757
1758 tcu::TextureLevel expectedSnorm (expected.getFormat(), expected.getWidth(), expected.getHeight(), expected.getDepth());
1759
1760 {
1761 tcu::TextureLevel expectedFloat (tcu::TextureFormat(expectedSnorm.getFormat().order, tcu::TextureFormat::FLOAT), expectedSnorm.getWidth(), expectedSnorm.getHeight(), expectedSnorm.getDepth());
1762
1763 tcu::copy(expectedFloat.getAccess(), m_expectedTextureLevel[0]->getAccess());
1764 tcu::copy(expectedSnorm, expectedFloat.getAccess());
1765 }
1766
1767 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedSnorm.getAccess(), resultSnorm.getAccess(), uThreshold, tcu::COMPARE_LOG_RESULT))
1768 return tcu::TestStatus::fail("CopiesAndBlitting test");
1769 }
1770 else
1771 {
1772 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expected, result, uThreshold, tcu::COMPARE_LOG_RESULT))
1773 return tcu::TestStatus::fail("CopiesAndBlitting test");
1774 }
1775 }
1776
1777 return tcu::TestStatus::pass("CopiesAndBlitting test");
1778 }
1779
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)1780 void CopyImageToImageMipmap::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
1781 {
1782 DE_UNREF(mipLevel);
1783
1784 VkOffset3D srcOffset = region.imageCopy.srcOffset;
1785 VkOffset3D dstOffset = region.imageCopy.dstOffset;
1786 VkExtent3D extent = region.imageCopy.extent;
1787
1788 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && m_params.dst.image.imageType == VK_IMAGE_TYPE_2D)
1789 {
1790 dstOffset.z = srcOffset.z;
1791 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.dstSubresource.layerCount);
1792 }
1793 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && m_params.dst.image.imageType == VK_IMAGE_TYPE_3D)
1794 {
1795 srcOffset.z = dstOffset.z;
1796 extent.depth = std::max(region.imageCopy.extent.depth, region.imageCopy.srcSubresource.layerCount);
1797 }
1798
1799
1800 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
1801 {
1802 DE_ASSERT(src.getFormat() == dst.getFormat());
1803
1804 // Copy depth.
1805 if (tcu::hasDepthComponent(src.getFormat().order))
1806 {
1807 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1808 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_DEPTH);
1809 tcu::copy(dstSubRegion, srcSubRegion);
1810 }
1811
1812 // Copy stencil.
1813 if (tcu::hasStencilComponent(src.getFormat().order))
1814 {
1815 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1816 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth), tcu::Sampler::MODE_STENCIL);
1817 tcu::copy(dstSubRegion, srcSubRegion);
1818 }
1819 }
1820 else
1821 {
1822 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
1823 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
1824 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
1825 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
1826
1827 tcu::copy(dstSubRegion, srcSubRegion);
1828 }
1829 }
1830
1831 class CopyImageToImageMipmapTestCase : public vkt::TestCase
1832 {
1833 public:
CopyImageToImageMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)1834 CopyImageToImageMipmapTestCase (tcu::TestContext& testCtx,
1835 const std::string& name,
1836 const std::string& description,
1837 const TestParams params)
1838 : vkt::TestCase (testCtx, name, description)
1839 , m_params (params)
1840 {}
1841
createInstance(Context & context) const1842 virtual TestInstance* createInstance (Context& context) const
1843 {
1844 return new CopyImageToImageMipmap(context, m_params);
1845 }
1846
checkSupport(Context & context) const1847 virtual void checkSupport (Context& context) const
1848 {
1849 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
1850 {
1851 if (!context.isDeviceFunctionalitySupported("VK_KHR_dedicated_allocation"))
1852 TCU_THROW(NotSupportedError, "VK_KHR_dedicated_allocation is not supported");
1853 }
1854
1855 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
1856 {
1857 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
1858 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
1859 }
1860
1861 if (m_params.separateDepthStencilLayouts)
1862 if (!context.isDeviceFunctionalitySupported("VK_KHR_separate_depth_stencil_layouts"))
1863 TCU_THROW(NotSupportedError, "VK_KHR_separate_depth_stencil_layouts is not supported");
1864
1865 if ((m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && m_params.src.image.imageType == VK_IMAGE_TYPE_2D) ||
1866 (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && m_params.src.image.imageType == VK_IMAGE_TYPE_3D))
1867 {
1868 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance1"))
1869 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
1870 }
1871
1872 const VkPhysicalDeviceLimits limits = context.getDeviceProperties().limits;
1873 VkImageFormatProperties properties;
1874
1875 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1876 m_params.src.image.format,
1877 m_params.src.image.imageType,
1878 VK_IMAGE_TILING_OPTIMAL,
1879 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
1880 0,
1881 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
1882 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
1883 m_params.dst.image.format,
1884 m_params.dst.image.imageType,
1885 VK_IMAGE_TILING_OPTIMAL,
1886 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
1887 0,
1888 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
1889 {
1890 TCU_THROW(NotSupportedError, "Format not supported");
1891 }
1892
1893 // Check maxImageDimension1D
1894 {
1895 if (m_params.src.image.imageType == VK_IMAGE_TYPE_1D && m_params.src.image.extent.width > limits.maxImageDimension1D)
1896 TCU_THROW(NotSupportedError, "Requested 1D src image dimensions not supported");
1897
1898 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_1D && m_params.dst.image.extent.width > limits.maxImageDimension1D)
1899 TCU_THROW(NotSupportedError, "Requested 1D dst image dimensions not supported");
1900 }
1901
1902 // Check maxImageDimension2D
1903 {
1904 if (m_params.src.image.imageType == VK_IMAGE_TYPE_2D && (m_params.src.image.extent.width > limits.maxImageDimension2D
1905 || m_params.src.image.extent.height > limits.maxImageDimension2D))
1906 {
1907 TCU_THROW(NotSupportedError, "Requested 2D src image dimensions not supported");
1908 }
1909
1910 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_2D && (m_params.dst.image.extent.width > limits.maxImageDimension2D
1911 || m_params.dst.image.extent.height > limits.maxImageDimension2D))
1912 {
1913 TCU_THROW(NotSupportedError, "Requested 2D dst image dimensions not supported");
1914 }
1915 }
1916
1917 // Check maxImageDimension3D
1918 {
1919 if (m_params.src.image.imageType == VK_IMAGE_TYPE_3D && (m_params.src.image.extent.width > limits.maxImageDimension3D
1920 || m_params.src.image.extent.height > limits.maxImageDimension3D
1921 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1922 {
1923 TCU_THROW(NotSupportedError, "Requested 3D src image dimensions not supported");
1924 }
1925
1926 if (m_params.dst.image.imageType == VK_IMAGE_TYPE_3D && (m_params.dst.image.extent.width > limits.maxImageDimension3D
1927 || m_params.dst.image.extent.height > limits.maxImageDimension3D
1928 || m_params.src.image.extent.depth > limits.maxImageDimension3D))
1929 {
1930 TCU_THROW(NotSupportedError, "Requested 3D dst image dimensions not supported");
1931 }
1932 }
1933 }
1934
1935 private:
1936 TestParams m_params;
1937 };
1938
1939 // Copy from buffer to buffer.
1940
1941 class CopyBufferToBuffer : public CopiesAndBlittingTestInstance
1942 {
1943 public:
1944 CopyBufferToBuffer (Context& context, TestParams params);
1945 virtual tcu::TestStatus iterate (void);
1946 private:
1947 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess, tcu::PixelBufferAccess, CopyRegion, deUint32 mipLevel = 0u);
1948 Move<VkBuffer> m_source;
1949 de::MovePtr<Allocation> m_sourceBufferAlloc;
1950 Move<VkBuffer> m_destination;
1951 de::MovePtr<Allocation> m_destinationBufferAlloc;
1952 };
1953
CopyBufferToBuffer(Context & context,TestParams params)1954 CopyBufferToBuffer::CopyBufferToBuffer (Context& context, TestParams params)
1955 : CopiesAndBlittingTestInstance (context, params)
1956 {
1957 const InstanceInterface& vki = context.getInstanceInterface();
1958 const DeviceInterface& vk = context.getDeviceInterface();
1959 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
1960 const VkDevice vkDevice = context.getDevice();
1961 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1962 Allocator& memAlloc = context.getDefaultAllocator();
1963
1964 // Create source buffer
1965 {
1966 const VkBufferCreateInfo sourceBufferParams =
1967 {
1968 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1969 DE_NULL, // const void* pNext;
1970 0u, // VkBufferCreateFlags flags;
1971 m_params.src.buffer.size, // VkDeviceSize size;
1972 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
1973 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1974 1u, // deUint32 queueFamilyIndexCount;
1975 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1976 };
1977
1978 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
1979 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1980 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
1981 }
1982
1983 // Create destination buffer
1984 {
1985 const VkBufferCreateInfo destinationBufferParams =
1986 {
1987 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1988 DE_NULL, // const void* pNext;
1989 0u, // VkBufferCreateFlags flags;
1990 m_params.dst.buffer.size, // VkDeviceSize size;
1991 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1992 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1993 1u, // deUint32 queueFamilyIndexCount;
1994 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1995 };
1996
1997 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
1998 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
1999 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2000 }
2001 }
2002
iterate(void)2003 tcu::TestStatus CopyBufferToBuffer::iterate (void)
2004 {
2005 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
2006 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), srcLevelWidth, 1));
2007 generateBuffer(m_sourceTextureLevel->getAccess(), srcLevelWidth, 1, 1, FILL_MODE_RED);
2008
2009 const int dstLevelWidth = (int)(m_params.dst.buffer.size/4);
2010 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2011 generateBuffer(m_destinationTextureLevel->getAccess(), dstLevelWidth, 1, 1, FILL_MODE_BLACK);
2012
2013 generateExpectedResult();
2014
2015 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2016 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2017
2018 const DeviceInterface& vk = m_context.getDeviceInterface();
2019 const VkDevice vkDevice = m_context.getDevice();
2020 const VkQueue queue = m_context.getUniversalQueue();
2021
2022 const VkBufferMemoryBarrier srcBufferBarrier =
2023 {
2024 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2025 DE_NULL, // const void* pNext;
2026 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
2027 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2028 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2029 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2030 *m_source, // VkBuffer buffer;
2031 0u, // VkDeviceSize offset;
2032 m_params.src.buffer.size // VkDeviceSize size;
2033 };
2034
2035 const VkBufferMemoryBarrier dstBufferBarrier =
2036 {
2037 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2038 DE_NULL, // const void* pNext;
2039 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2040 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2041 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2042 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2043 *m_destination, // VkBuffer buffer;
2044 0u, // VkDeviceSize offset;
2045 m_params.dst.buffer.size // VkDeviceSize size;
2046 };
2047
2048 std::vector<VkBufferCopy> bufferCopies;
2049 std::vector<VkBufferCopy2KHR> bufferCopies2KHR;
2050 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2051 {
2052 if (m_params.extensionUse == EXTENSION_USE_NONE)
2053 {
2054 bufferCopies.push_back(m_params.regions[i].bufferCopy);
2055 }
2056 else
2057 {
2058 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2059 bufferCopies2KHR.push_back(convertvkBufferCopyTovkBufferCopy2KHR(m_params.regions[i].bufferCopy));
2060 }
2061 }
2062
2063 beginCommandBuffer(vk, *m_cmdBuffer);
2064 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2065
2066 if (m_params.extensionUse == EXTENSION_USE_NONE)
2067 {
2068 vk.cmdCopyBuffer(*m_cmdBuffer, m_source.get(), m_destination.get(), (deUint32)m_params.regions.size(), &bufferCopies[0]);
2069 }
2070 else
2071 {
2072 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2073 const VkCopyBufferInfo2KHR copyBufferInfo2KHR =
2074 {
2075 VK_STRUCTURE_TYPE_COPY_BUFFER_INFO_2_KHR, // VkStructureType sType;
2076 DE_NULL, // const void* pNext;
2077 m_source.get(), // VkBuffer srcBuffer;
2078 m_destination.get(), // VkBuffer dstBuffer;
2079 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2080 &bufferCopies2KHR[0] // const VkBufferCopy2KHR* pRegions;
2081 };
2082
2083 vk.cmdCopyBuffer2KHR(*m_cmdBuffer, ©BufferInfo2KHR);
2084 }
2085
2086 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2087 endCommandBuffer(vk, *m_cmdBuffer);
2088 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2089
2090 // Read buffer data
2091 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(mapVkFormat(VK_FORMAT_R32_UINT), dstLevelWidth, 1));
2092 invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2093 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2094
2095 return checkTestResult(resultLevel->getAccess());
2096 }
2097
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2098 void CopyBufferToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2099 {
2100 DE_UNREF(mipLevel);
2101
2102 deMemcpy((deUint8*) dst.getDataPtr() + region.bufferCopy.dstOffset,
2103 (deUint8*) src.getDataPtr() + region.bufferCopy.srcOffset,
2104 (size_t)region.bufferCopy.size);
2105 }
2106
2107 class BufferToBufferTestCase : public vkt::TestCase
2108 {
2109 public:
BufferToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2110 BufferToBufferTestCase (tcu::TestContext& testCtx,
2111 const std::string& name,
2112 const std::string& description,
2113 const TestParams params)
2114 : vkt::TestCase (testCtx, name, description)
2115 , m_params (params)
2116 {}
2117
createInstance(Context & context) const2118 virtual TestInstance* createInstance (Context& context) const
2119 {
2120 return new CopyBufferToBuffer(context, m_params);
2121 }
2122
checkSupport(Context & context) const2123 virtual void checkSupport(Context& context) const
2124 {
2125 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
2126 {
2127 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
2128 {
2129 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2130 }
2131 }
2132 }
2133
2134 private:
2135 TestParams m_params;
2136 };
2137
2138 // Copy from image to buffer.
2139
2140 class CopyImageToBuffer : public CopiesAndBlittingTestInstance
2141 {
2142 public:
2143 CopyImageToBuffer (Context& context,
2144 TestParams testParams);
2145 virtual tcu::TestStatus iterate (void);
2146 private:
2147 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2148
2149 tcu::TextureFormat m_textureFormat;
2150 VkDeviceSize m_bufferSize;
2151
2152 Move<VkImage> m_source;
2153 de::MovePtr<Allocation> m_sourceImageAlloc;
2154 Move<VkBuffer> m_destination;
2155 de::MovePtr<Allocation> m_destinationBufferAlloc;
2156 };
2157
CopyImageToBuffer(Context & context,TestParams testParams)2158 CopyImageToBuffer::CopyImageToBuffer (Context& context, TestParams testParams)
2159 : CopiesAndBlittingTestInstance(context, testParams)
2160 , m_textureFormat(mapVkFormat(testParams.src.image.format))
2161 , m_bufferSize(m_params.dst.buffer.size * tcu::getPixelSize(m_textureFormat))
2162 {
2163 const InstanceInterface& vki = context.getInstanceInterface();
2164 const DeviceInterface& vk = context.getDeviceInterface();
2165 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2166 const VkDevice vkDevice = context.getDevice();
2167 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2168 Allocator& memAlloc = context.getDefaultAllocator();
2169
2170 // Create source image
2171 {
2172 const VkImageCreateInfo sourceImageParams =
2173 {
2174 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2175 DE_NULL, // const void* pNext;
2176 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
2177 m_params.src.image.imageType, // VkImageType imageType;
2178 m_params.src.image.format, // VkFormat format;
2179 getExtent3D(m_params.src.image), // VkExtent3D extent;
2180 1u, // deUint32 mipLevels;
2181 getArraySize(m_params.src.image), // deUint32 arraySize;
2182 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2183 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2184 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2185 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2186 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2187 1u, // deUint32 queueFamilyCount;
2188 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2189 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2190 };
2191
2192 m_source = createImage(vk, vkDevice, &sourceImageParams);
2193 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2194 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
2195 }
2196
2197 // Create destination buffer
2198 {
2199 const VkBufferCreateInfo destinationBufferParams =
2200 {
2201 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2202 DE_NULL, // const void* pNext;
2203 0u, // VkBufferCreateFlags flags;
2204 m_bufferSize, // VkDeviceSize size;
2205 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
2206 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2207 1u, // deUint32 queueFamilyIndexCount;
2208 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2209 };
2210
2211 m_destination = createBuffer(vk, vkDevice, &destinationBufferParams);
2212 m_destinationBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2213 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_destination, m_destinationBufferAlloc->getMemory(), m_destinationBufferAlloc->getOffset()));
2214 }
2215 }
2216
iterate(void)2217 tcu::TestStatus CopyImageToBuffer::iterate (void)
2218 {
2219 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2220 m_params.src.image.extent.width,
2221 m_params.src.image.extent.height,
2222 m_params.src.image.extent.depth));
2223 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth);
2224 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2225 generateBuffer(m_destinationTextureLevel->getAccess(), (int)m_params.dst.buffer.size, 1, 1);
2226
2227 generateExpectedResult();
2228
2229 uploadImage(m_sourceTextureLevel->getAccess(), *m_source, m_params.src.image);
2230 uploadBuffer(m_destinationTextureLevel->getAccess(), *m_destinationBufferAlloc);
2231
2232 const DeviceInterface& vk = m_context.getDeviceInterface();
2233 const VkDevice vkDevice = m_context.getDevice();
2234 const VkQueue queue = m_context.getUniversalQueue();
2235
2236 // Barriers for copying image to buffer
2237 const VkImageMemoryBarrier imageBarrier =
2238 {
2239 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2240 DE_NULL, // const void* pNext;
2241 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2242 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
2243 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2244 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout newLayout;
2245 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2246 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2247 *m_source, // VkImage image;
2248 { // VkImageSubresourceRange subresourceRange;
2249 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2250 0u, // deUint32 baseMipLevel;
2251 1u, // deUint32 mipLevels;
2252 0u, // deUint32 baseArraySlice;
2253 getArraySize(m_params.src.image) // deUint32 arraySize;
2254 }
2255 };
2256
2257 const VkBufferMemoryBarrier bufferBarrier =
2258 {
2259 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
2260 DE_NULL, // const void* pNext;
2261 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2262 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
2263 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2264 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2265 *m_destination, // VkBuffer buffer;
2266 0u, // VkDeviceSize offset;
2267 m_bufferSize // VkDeviceSize size;
2268 };
2269
2270 // Copy from image to buffer
2271 std::vector<VkBufferImageCopy> bufferImageCopies;
2272 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2273 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2274 {
2275 if (m_params.extensionUse == EXTENSION_USE_NONE)
2276 {
2277 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2278 }
2279 else
2280 {
2281 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2282 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2283 }
2284 }
2285
2286 beginCommandBuffer(vk, *m_cmdBuffer);
2287 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);
2288
2289 if (m_params.extensionUse == EXTENSION_USE_NONE)
2290 {
2291 vk.cmdCopyImageToBuffer(*m_cmdBuffer, m_source.get(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, m_destination.get(), (deUint32)m_params.regions.size(), &bufferImageCopies[0]);
2292 }
2293 else
2294 {
2295 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2296 const VkCopyImageToBufferInfo2KHR copyImageToBufferInfo2KHR =
2297 {
2298 VK_STRUCTURE_TYPE_COPY_IMAGE_TO_BUFFER_INFO_2_KHR, // VkStructureType sType;
2299 DE_NULL, // const void* pNext;
2300 m_source.get(), // VkImage srcImage;
2301 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
2302 m_destination.get(), // VkBuffer dstBuffer;
2303 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2304 &bufferImageCopies2KHR[0] // const VkBufferImageCopy2KHR* pRegions;
2305 };
2306
2307 vk.cmdCopyImageToBuffer2KHR(*m_cmdBuffer, ©ImageToBufferInfo2KHR);
2308 }
2309
2310 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &bufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
2311 endCommandBuffer(vk, *m_cmdBuffer);
2312
2313 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2314
2315 // Read buffer data
2316 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(m_textureFormat, (int)m_params.dst.buffer.size, 1));
2317 invalidateAlloc(vk, vkDevice, *m_destinationBufferAlloc);
2318 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_destinationBufferAlloc->getHostPtr()));
2319
2320 return checkTestResult(resultLevel->getAccess());
2321 }
2322
2323 class CopyImageToBufferTestCase : public vkt::TestCase
2324 {
2325 public:
CopyImageToBufferTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2326 CopyImageToBufferTestCase (tcu::TestContext& testCtx,
2327 const std::string& name,
2328 const std::string& description,
2329 const TestParams params)
2330 : vkt::TestCase (testCtx, name, description)
2331 , m_params (params)
2332 {}
2333
createInstance(Context & context) const2334 virtual TestInstance* createInstance (Context& context) const
2335 {
2336 return new CopyImageToBuffer(context, m_params);
2337 }
2338
checkSupport(Context & context) const2339 virtual void checkSupport (Context& context) const
2340 {
2341 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2342 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2343 {
2344 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2345 }
2346 }
2347
2348 private:
2349 TestParams m_params;
2350 };
2351
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2352 void CopyImageToBuffer::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2353 {
2354 DE_UNREF(mipLevel);
2355
2356 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2357 if (!rowLength)
2358 rowLength = region.bufferImageCopy.imageExtent.width;
2359
2360 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2361 if (!imageHeight)
2362 imageHeight = region.bufferImageCopy.imageExtent.height;
2363
2364 const int texelSize = src.getFormat().getPixelSize();
2365 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2366 const VkOffset3D srcOffset = region.bufferImageCopy.imageOffset;
2367 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
2368 const deUint32 baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2369
2370 for (deUint32 z = 0; z < extent.depth; z++)
2371 {
2372 for (deUint32 y = 0; y < extent.height; y++)
2373 {
2374 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2375 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y + y, srcOffset.z + z + baseArrayLayer,
2376 region.bufferImageCopy.imageExtent.width, 1, 1);
2377 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2378 tcu::copy(dstSubRegion, srcSubRegion);
2379 }
2380 }
2381 }
2382
2383 // Copy from buffer to image.
2384
2385 class CopyBufferToImage : public CopiesAndBlittingTestInstance
2386 {
2387 public:
2388 CopyBufferToImage (Context& context,
2389 TestParams testParams);
2390 virtual tcu::TestStatus iterate (void);
2391
2392 private:
2393 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2394
2395 tcu::TextureFormat m_textureFormat;
2396 VkDeviceSize m_bufferSize;
2397
2398 Move<VkBuffer> m_source;
2399 de::MovePtr<Allocation> m_sourceBufferAlloc;
2400 Move<VkImage> m_destination;
2401 de::MovePtr<Allocation> m_destinationImageAlloc;
2402 };
2403
CopyBufferToImage(Context & context,TestParams testParams)2404 CopyBufferToImage::CopyBufferToImage (Context& context, TestParams testParams)
2405 : CopiesAndBlittingTestInstance(context, testParams)
2406 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2407 , m_bufferSize(m_params.src.buffer.size * tcu::getPixelSize(m_textureFormat))
2408 {
2409 const InstanceInterface& vki = context.getInstanceInterface();
2410 const DeviceInterface& vk = context.getDeviceInterface();
2411 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2412 const VkDevice vkDevice = context.getDevice();
2413 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2414 Allocator& memAlloc = context.getDefaultAllocator();
2415
2416 // Create source buffer
2417 {
2418 const VkBufferCreateInfo sourceBufferParams =
2419 {
2420 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2421 DE_NULL, // const void* pNext;
2422 0u, // VkBufferCreateFlags flags;
2423 m_bufferSize, // VkDeviceSize size;
2424 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2425 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2426 1u, // deUint32 queueFamilyIndexCount;
2427 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2428 };
2429
2430 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2431 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2432 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2433 }
2434
2435 // Create destination image
2436 {
2437 const VkImageCreateInfo destinationImageParams =
2438 {
2439 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2440 DE_NULL, // const void* pNext;
2441 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
2442 m_params.dst.image.imageType, // VkImageType imageType;
2443 m_params.dst.image.format, // VkFormat format;
2444 getExtent3D(m_params.dst.image), // VkExtent3D extent;
2445 1u, // deUint32 mipLevels;
2446 getArraySize(m_params.dst.image), // deUint32 arraySize;
2447 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2448 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2449 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2450 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2451 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2452 1u, // deUint32 queueFamilyCount;
2453 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2454 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2455 };
2456
2457 m_destination = createImage(vk, vkDevice, &destinationImageParams);
2458 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2459 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2460 }
2461 }
2462
iterate(void)2463 tcu::TestStatus CopyBufferToImage::iterate (void)
2464 {
2465 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2466 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2467 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2468 m_params.dst.image.extent.width,
2469 m_params.dst.image.extent.height,
2470 m_params.dst.image.extent.depth));
2471
2472 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2473
2474 generateExpectedResult();
2475
2476 uploadBuffer(m_sourceTextureLevel->getAccess(), *m_sourceBufferAlloc);
2477 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2478
2479 const DeviceInterface& vk = m_context.getDeviceInterface();
2480 const VkDevice vkDevice = m_context.getDevice();
2481 const VkQueue queue = m_context.getUniversalQueue();
2482
2483 const VkImageMemoryBarrier imageBarrier =
2484 {
2485 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2486 DE_NULL, // const void* pNext;
2487 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2488 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2489 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2490 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2491 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2492 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2493 *m_destination, // VkImage image;
2494 { // VkImageSubresourceRange subresourceRange;
2495 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2496 0u, // deUint32 baseMipLevel;
2497 1u, // deUint32 mipLevels;
2498 0u, // deUint32 baseArraySlice;
2499 getArraySize(m_params.dst.image) // deUint32 arraySize;
2500 }
2501 };
2502
2503 // Copy from buffer to image
2504 std::vector<VkBufferImageCopy> bufferImageCopies;
2505 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2506 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2507 {
2508 if (m_params.extensionUse == EXTENSION_USE_NONE)
2509 {
2510 bufferImageCopies.push_back(m_params.regions[i].bufferImageCopy);
2511 }
2512 else
2513 {
2514 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2515 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(m_params.regions[i].bufferImageCopy));
2516 }
2517 }
2518
2519 beginCommandBuffer(vk, *m_cmdBuffer);
2520 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);
2521
2522 if (m_params.extensionUse == EXTENSION_USE_NONE)
2523 {
2524 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2525 }
2526 else
2527 {
2528 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2529 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2530 {
2531 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2532 DE_NULL, // const void* pNext;
2533 m_source.get(), // VkBuffer srcBuffer;
2534 m_destination.get(), // VkImage dstImage;
2535 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2536 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2537 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
2538 };
2539
2540 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2541 }
2542
2543
2544 endCommandBuffer(vk, *m_cmdBuffer);
2545
2546 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
2547
2548 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
2549
2550 return checkTestResult(resultLevel->getAccess());
2551 }
2552
2553 class CopyBufferToImageTestCase : public vkt::TestCase
2554 {
2555 public:
CopyBufferToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2556 CopyBufferToImageTestCase (tcu::TestContext& testCtx,
2557 const std::string& name,
2558 const std::string& description,
2559 const TestParams params)
2560 : vkt::TestCase (testCtx, name, description)
2561 , m_params (params)
2562 {}
2563
~CopyBufferToImageTestCase(void)2564 virtual ~CopyBufferToImageTestCase (void) {}
2565
createInstance(Context & context) const2566 virtual TestInstance* createInstance (Context& context) const
2567 {
2568 return new CopyBufferToImage(context, m_params);
2569 }
2570
checkSupport(Context & context) const2571 virtual void checkSupport (Context& context) const
2572 {
2573 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2574 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2575 {
2576 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2577 }
2578 }
2579
2580
2581 private:
2582 TestParams m_params;
2583 };
2584
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2585 void CopyBufferToImage::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2586 {
2587 DE_UNREF(mipLevel);
2588
2589 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2590 if (!rowLength)
2591 rowLength = region.bufferImageCopy.imageExtent.width;
2592
2593 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2594 if (!imageHeight)
2595 imageHeight = region.bufferImageCopy.imageExtent.height;
2596
2597 const int texelSize = dst.getFormat().getPixelSize();
2598 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2599 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
2600 const int texelOffset = (int) region.bufferImageCopy.bufferOffset / texelSize;
2601 const deUint32 baseArrayLayer = region.bufferImageCopy.imageSubresource.baseArrayLayer;
2602
2603 for (deUint32 z = 0; z < extent.depth; z++)
2604 {
2605 for (deUint32 y = 0; y < extent.height; y++)
2606 {
2607 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2608 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2609 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z + baseArrayLayer,
2610 region.bufferImageCopy.imageExtent.width, 1, 1);
2611 tcu::copy(dstSubRegion, srcSubRegion);
2612 }
2613 }
2614 }
2615
2616 class CopyBufferToDepthStencil : public CopiesAndBlittingTestInstance
2617 {
2618 public:
2619 CopyBufferToDepthStencil (Context& context,
2620 TestParams testParams);
2621 virtual tcu::TestStatus iterate (void);
2622 private:
2623 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
2624
2625 tcu::TextureFormat m_textureFormat;
2626 VkDeviceSize m_bufferSize;
2627
2628 Move<VkBuffer> m_source;
2629 de::MovePtr<Allocation> m_sourceBufferAlloc;
2630 Move<VkImage> m_destination;
2631 de::MovePtr<Allocation> m_destinationImageAlloc;
2632 };
2633
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)2634 void CopyBufferToDepthStencil::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
2635 {
2636 DE_UNREF(mipLevel);
2637
2638 deUint32 rowLength = region.bufferImageCopy.bufferRowLength;
2639 if (!rowLength)
2640 rowLength = region.bufferImageCopy.imageExtent.width;
2641
2642 deUint32 imageHeight = region.bufferImageCopy.bufferImageHeight;
2643 if (!imageHeight)
2644 imageHeight = region.bufferImageCopy.imageExtent.height;
2645
2646 const int texelSize = dst.getFormat().getPixelSize();
2647 const VkExtent3D extent = region.bufferImageCopy.imageExtent;
2648 const VkOffset3D dstOffset = region.bufferImageCopy.imageOffset;
2649 const int texelOffset = (int)region.bufferImageCopy.bufferOffset / texelSize;
2650
2651 for (deUint32 z = 0; z < extent.depth; z++)
2652 {
2653 for (deUint32 y = 0; y < extent.height; y++)
2654 {
2655 int texelIndex = texelOffset + (z * imageHeight + y) * rowLength;
2656 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, texelIndex, 0, region.bufferImageCopy.imageExtent.width, 1);
2657 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y + y, dstOffset.z + z,
2658 region.bufferImageCopy.imageExtent.width, 1, 1);
2659
2660 if (region.bufferImageCopy.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT)
2661 {
2662 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_DEPTH), DE_FALSE);
2663 }
2664 else
2665 {
2666 tcu::copy(dstSubRegion, tcu::getEffectiveDepthStencilAccess(srcSubRegion, tcu::Sampler::MODE_STENCIL), DE_FALSE);
2667 }
2668 }
2669 }
2670 }
2671
isSupportedDepthStencilFormat(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat format)2672 bool isSupportedDepthStencilFormat(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat format)
2673 {
2674 VkFormatProperties formatProps;
2675 vki.getPhysicalDeviceFormatProperties(physDevice, format, &formatProps);
2676 return (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) != 0;
2677 }
2678
CopyBufferToDepthStencil(Context & context,TestParams testParams)2679 CopyBufferToDepthStencil::CopyBufferToDepthStencil(Context& context, TestParams testParams)
2680 : CopiesAndBlittingTestInstance(context, testParams)
2681 , m_textureFormat(mapVkFormat(testParams.dst.image.format))
2682 , m_bufferSize(0)
2683 {
2684 const InstanceInterface& vki = context.getInstanceInterface();
2685 const DeviceInterface& vk = context.getDeviceInterface();
2686 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
2687 const VkDevice vkDevice = context.getDevice();
2688 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
2689 Allocator& memAlloc = context.getDefaultAllocator();
2690 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(m_params.dst.image.format).order);
2691 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(m_params.dst.image.format).order);
2692
2693 if (!isSupportedDepthStencilFormat(vki, vkPhysDevice, testParams.dst.image.format))
2694 {
2695 TCU_THROW(NotSupportedError, "Image format not supported.");
2696 }
2697
2698 if (hasDepth)
2699 {
2700 glw::GLuint texelSize = m_textureFormat.getPixelSize();
2701 if (texelSize > sizeof(float))
2702 {
2703 // We must have D32F_S8 format, depth must be packed so we only need
2704 // to allocate space for the D32F part. Stencil will be separate
2705 texelSize = sizeof(float);
2706 }
2707 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height) * static_cast<VkDeviceSize>(texelSize);
2708 }
2709 if (hasStencil)
2710 {
2711 // Stencil is always 8bits and packed.
2712 m_bufferSize += static_cast<VkDeviceSize>(m_params.dst.image.extent.width) * static_cast<VkDeviceSize>(m_params.dst.image.extent.height);
2713 }
2714
2715 // Create source buffer, this is where the depth & stencil data will go that's used by test's regions.
2716 {
2717 const VkBufferCreateInfo sourceBufferParams =
2718 {
2719 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
2720 DE_NULL, // const void* pNext;
2721 0u, // VkBufferCreateFlags flags;
2722 m_bufferSize, // VkDeviceSize size;
2723 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
2724 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2725 1u, // deUint32 queueFamilyIndexCount;
2726 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2727 };
2728
2729 m_source = createBuffer(vk, vkDevice, &sourceBufferParams);
2730 m_sourceBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
2731 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_source, m_sourceBufferAlloc->getMemory(), m_sourceBufferAlloc->getOffset()));
2732 }
2733
2734 // Create destination image
2735 {
2736 const VkImageCreateInfo destinationImageParams =
2737 {
2738 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
2739 DE_NULL, // const void* pNext;
2740 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
2741 m_params.dst.image.imageType, // VkImageType imageType;
2742 m_params.dst.image.format, // VkFormat format;
2743 getExtent3D(m_params.dst.image), // VkExtent3D extent;
2744 1u, // deUint32 mipLevels;
2745 getArraySize(m_params.dst.image), // deUint32 arraySize;
2746 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
2747 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2748 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
2749 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
2750 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
2751 1u, // deUint32 queueFamilyCount;
2752 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
2753 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
2754 };
2755
2756 m_destination = createImage(vk, vkDevice, &destinationImageParams);
2757 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
2758 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
2759 }
2760 }
2761
iterate(void)2762 tcu::TestStatus CopyBufferToDepthStencil::iterate(void)
2763 {
2764 // Create source depth/stencil content. Treat as 1D texture to get different pattern
2765 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat, (int)m_params.src.buffer.size, 1));
2766 // Fill buffer with linear gradiant
2767 generateBuffer(m_sourceTextureLevel->getAccess(), (int)m_params.src.buffer.size, 1, 1);
2768
2769 // Create image layer for depth/stencil
2770 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(m_textureFormat,
2771 m_params.dst.image.extent.width,
2772 m_params.dst.image.extent.height,
2773 m_params.dst.image.extent.depth));
2774
2775 // Fill image layer with 2D gradiant
2776 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
2777
2778 // Fill m_extendedTextureLevel with copy of m_destinationTextureLevel
2779 // Then iterate over each of the regions given in m_params.regions and copy m_sourceTextureLevel content to m_extendedTextureLevel
2780 // This emulates what the HW will be doing.
2781 generateExpectedResult();
2782
2783 // Upload our source depth/stencil content to the source buffer
2784 // This is the buffer that will be used by region commands
2785 std::vector<VkBufferImageCopy> bufferImageCopies;
2786 std::vector<VkBufferImageCopy2KHR> bufferImageCopies2KHR;
2787 VkDeviceSize bufferOffset = 0;
2788 const VkDevice vkDevice = m_context.getDevice();
2789 const DeviceInterface& vk = m_context.getDeviceInterface();
2790 const VkQueue queue = m_context.getUniversalQueue();
2791 char* dstPtr = reinterpret_cast<char*>(m_sourceBufferAlloc->getHostPtr());
2792 bool depthLoaded = DE_FALSE;
2793 bool stencilLoaded = DE_FALSE;
2794 VkDeviceSize depthOffset = 0;
2795 VkDeviceSize stencilOffset = 0;
2796
2797 // To be able to test ordering depth & stencil differently
2798 // we take the given copy regions and use that as the desired order
2799 // and copy the appropriate data into place and compute the appropriate
2800 // data offsets to be used in the copy command.
2801 for (deUint32 i = 0; i < m_params.regions.size(); i++)
2802 {
2803 tcu::ConstPixelBufferAccess bufferAccess = m_sourceTextureLevel->getAccess();
2804 deUint32 bufferSize = bufferAccess.getWidth() * bufferAccess.getHeight() * bufferAccess.getDepth();
2805 VkBufferImageCopy copyData = m_params.regions[i].bufferImageCopy;
2806 char* srcPtr;
2807
2808 if (copyData.imageSubresource.aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT && !depthLoaded)
2809 {
2810 // Create level that is same component as depth buffer (e.g. D16, D24, D32F)
2811 tcu::TextureLevel depthTexture(mapCombinedToDepthTransferFormat(bufferAccess.getFormat()), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2812 bufferSize *= tcu::getPixelSize(depthTexture.getFormat());
2813 // Copy depth component only from source data. This gives us packed depth-only data.
2814 tcu::copy(depthTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_DEPTH));
2815 srcPtr = (char*)depthTexture.getAccess().getDataPtr();
2816 // Copy packed depth-only data to output buffer
2817 deMemcpy(dstPtr, srcPtr, bufferSize);
2818 depthLoaded = DE_TRUE;
2819 depthOffset = bufferOffset;
2820 dstPtr += bufferSize;
2821 bufferOffset += bufferSize;
2822 copyData.bufferOffset += depthOffset;
2823 }
2824 else if (!stencilLoaded)
2825 {
2826 // Create level that is same component as stencil buffer (always 8-bits)
2827 tcu::TextureLevel stencilTexture(tcu::getEffectiveDepthStencilTextureFormat(bufferAccess.getFormat(), tcu::Sampler::MODE_STENCIL), bufferAccess.getWidth(), bufferAccess.getHeight(), bufferAccess.getDepth());
2828 // Copy stencil component only from source data. This gives us packed stencil-only data.
2829 tcu::copy(stencilTexture.getAccess(), tcu::getEffectiveDepthStencilAccess(bufferAccess, tcu::Sampler::MODE_STENCIL));
2830 srcPtr = (char*)stencilTexture.getAccess().getDataPtr();
2831 // Copy packed stencil-only data to output buffer
2832 deMemcpy(dstPtr, srcPtr, bufferSize);
2833 stencilLoaded = DE_TRUE;
2834 stencilOffset = bufferOffset;
2835 dstPtr += bufferSize;
2836 bufferOffset += bufferSize;
2837
2838 // Reference image generation uses pixel offsets based on buffer offset.
2839 // We need to adjust the offset now that the stencil data is not interleaved.
2840 copyData.bufferOffset /= tcu::getPixelSize(m_textureFormat);
2841
2842 copyData.bufferOffset += stencilOffset;
2843 }
2844
2845 if (m_params.extensionUse == EXTENSION_USE_NONE)
2846 {
2847 bufferImageCopies.push_back(copyData);
2848 }
2849 else
2850 {
2851 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2852 bufferImageCopies2KHR.push_back(convertvkBufferImageCopyTovkBufferImageCopy2KHR(copyData));
2853 }
2854 }
2855
2856 flushAlloc(vk, vkDevice, *m_sourceBufferAlloc);
2857
2858 // Upload the depth/stencil data from m_destinationTextureLevel to initialize
2859 // depth and stencil to known values.
2860 // Uses uploadImageAspect so makes its own buffers for depth and stencil
2861 // aspects (as needed) and copies them with independent vkCmdCopyBufferToImage commands.
2862 uploadImage(m_destinationTextureLevel->getAccess(), *m_destination, m_params.dst.image);
2863
2864 const VkImageMemoryBarrier imageBarrier =
2865 {
2866 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
2867 DE_NULL, // const void* pNext;
2868 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
2869 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
2870 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
2871 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
2872 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
2873 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
2874 *m_destination, // VkImage image;
2875 { // VkImageSubresourceRange subresourceRange;
2876 getAspectFlags(m_textureFormat), // VkImageAspectFlags aspectMask;
2877 0u, // deUint32 baseMipLevel;
2878 1u, // deUint32 mipLevels;
2879 0u, // deUint32 baseArraySlice;
2880 1u // deUint32 arraySize;
2881 }
2882 };
2883
2884 // Copy from buffer to depth/stencil image
2885
2886 beginCommandBuffer(vk, *m_cmdBuffer);
2887 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);
2888
2889 if (m_params.extensionUse == EXTENSION_USE_NONE)
2890 {
2891 if (m_params.singleCommand)
2892 {
2893 // Issue a single copy command with regions defined by the test.
2894 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)m_params.regions.size(), bufferImageCopies.data());
2895 }
2896 else
2897 {
2898 // Issue a a copy command per region defined by the test.
2899 for (deUint32 i = 0; i < bufferImageCopies.size(); i++)
2900 {
2901 vk.cmdCopyBufferToImage(*m_cmdBuffer, m_source.get(), m_destination.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopies[i]);
2902 }
2903 }
2904 }
2905 else
2906 {
2907 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
2908
2909 if (m_params.singleCommand)
2910 {
2911 // Issue a single copy command with regions defined by the test.
2912 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2913 {
2914 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2915 DE_NULL, // const void* pNext;
2916 m_source.get(), // VkBuffer srcBuffer;
2917 m_destination.get(), // VkImage dstImage;
2918 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2919 (deUint32)m_params.regions.size(), // uint32_t regionCount;
2920 bufferImageCopies2KHR.data() // const VkBufferImageCopy2KHR* pRegions;
2921 };
2922 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2923 }
2924 else
2925 {
2926 // Issue a a copy command per region defined by the test.
2927 for (deUint32 i = 0; i < bufferImageCopies2KHR.size(); i++)
2928 {
2929 const VkCopyBufferToImageInfo2KHR copyBufferToImageInfo2KHR =
2930 {
2931 VK_STRUCTURE_TYPE_COPY_BUFFER_TO_IMAGE_INFO_2_KHR, // VkStructureType sType;
2932 DE_NULL, // const void* pNext;
2933 m_source.get(), // VkBuffer srcBuffer;
2934 m_destination.get(), // VkImage dstImage;
2935 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
2936 1, // uint32_t regionCount;
2937 &bufferImageCopies2KHR[i] // const VkBufferImageCopy2KHR* pRegions;
2938 };
2939 // Issue a single copy command with regions defined by the test.
2940 vk.cmdCopyBufferToImage2KHR(*m_cmdBuffer, ©BufferToImageInfo2KHR);
2941 }
2942 }
2943 }
2944 endCommandBuffer(vk, *m_cmdBuffer);
2945
2946 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
2947
2948 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image);
2949
2950 // For combined depth/stencil formats both aspects are checked even when the test only
2951 // copies one. Clear such aspects here for both the result and the reference.
2952 if (tcu::hasDepthComponent(m_textureFormat.order) && !depthLoaded)
2953 {
2954 tcu::clearDepth(m_expectedTextureLevel[0]->getAccess(), 0.0f);
2955 tcu::clearDepth(resultLevel->getAccess(), 0.0f);
2956 }
2957 if (tcu::hasStencilComponent(m_textureFormat.order) && !stencilLoaded)
2958 {
2959 tcu::clearStencil(m_expectedTextureLevel[0]->getAccess(), 0);
2960 tcu::clearStencil(resultLevel->getAccess(), 0);
2961 }
2962
2963 return checkTestResult(resultLevel->getAccess());
2964 }
2965
2966 class CopyBufferToDepthStencilTestCase : public vkt::TestCase
2967 {
2968 public:
CopyBufferToDepthStencilTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)2969 CopyBufferToDepthStencilTestCase (tcu::TestContext& testCtx,
2970 const std::string& name,
2971 const std::string& description,
2972 const TestParams params)
2973 : vkt::TestCase(testCtx, name, description)
2974 , m_params(params)
2975 {}
2976
~CopyBufferToDepthStencilTestCase(void)2977 virtual ~CopyBufferToDepthStencilTestCase (void) {}
2978
createInstance(Context & context) const2979 virtual TestInstance* createInstance (Context& context) const
2980 {
2981 return new CopyBufferToDepthStencil(context, m_params);
2982 }
2983
checkSupport(Context & context) const2984 virtual void checkSupport (Context& context) const
2985 {
2986 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
2987 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
2988 {
2989 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
2990 }
2991 }
2992
2993 private:
2994 TestParams m_params;
2995 };
2996
2997 // CompressedTextureForBlit is a helper class that stores compressed texture data.
2998 // Implementation is based on pipeline::TestTexture2D but it allocates only one level
2999 // and has special cases needed for blits to some formats.
3000
3001 class CompressedTextureForBlit
3002 {
3003 public:
3004 CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat);
3005
3006 tcu::PixelBufferAccess getDecompressedAccess() const;
3007 const tcu::CompressedTexture& getCompressedTexture() const;
3008
3009 protected:
3010
3011 tcu::CompressedTexture m_compressedTexture;
3012 de::ArrayBuffer<deUint8> m_decompressedData;
3013 tcu::PixelBufferAccess m_decompressedAccess;
3014 };
3015
CompressedTextureForBlit(const tcu::CompressedTexFormat & srcFormat,int width,int height,int depth,VkFormat dstFormat)3016 CompressedTextureForBlit::CompressedTextureForBlit(const tcu::CompressedTexFormat& srcFormat, int width, int height, int depth, VkFormat dstFormat)
3017 : m_compressedTexture(srcFormat, width, height, depth)
3018 {
3019 de::Random random (123);
3020
3021 const int compressedDataSize (m_compressedTexture.getDataSize());
3022 deUint8* compressedData ((deUint8*)m_compressedTexture.getData());
3023
3024 tcu::TextureFormat decompressedSrcFormat (tcu::getUncompressedFormat(srcFormat));
3025 const int decompressedDataSize (tcu::getPixelSize(decompressedSrcFormat) * width * height * depth);
3026
3027 // generate random data for compresed textre
3028 if (tcu::isAstcFormat(srcFormat))
3029 {
3030 // comparison doesn't currently handle invalid blocks correctly so we use only valid blocks
3031 tcu::astc::generateRandomValidBlocks(compressedData, compressedDataSize / tcu::astc::BLOCK_SIZE_BYTES,
3032 srcFormat, tcu::TexDecompressionParams::ASTCMODE_LDR, random.getUint32());
3033 }
3034 else if ((dstFormat == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) &&
3035 ((srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK) ||
3036 (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)))
3037 {
3038 // special case - when we are blitting compressed image to RGB999E5 image we can't have both big and small values
3039 // in compressed image; to resolve this we are constructing source texture out of set of predefined compressed
3040 // blocks that after decompression will have components in proper range
3041
3042 struct BC6HBlock
3043 {
3044 deUint32 data[4];
3045 };
3046 std::vector<BC6HBlock> validBlocks;
3047
3048 if (srcFormat == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)
3049 {
3050 // define set of few valid blocks that contain values from <0; 1> range
3051 validBlocks =
3052 {
3053 { 1686671500, 3957317723, 3010132342, 2420137890 },
3054 { 3538027716, 298848033, 1925786021, 2022072301 },
3055 { 2614043466, 1636155440, 1023731774, 1894349986 },
3056 { 3433039318, 1294346072, 1587319645, 1738449906 },
3057 { 1386298160, 1639492154, 1273285776, 361562050 },
3058 { 1310110688, 526460754, 3630858047, 537617591 },
3059 { 3270356556, 2432993217, 2415924417, 1792488857 },
3060 { 1204947583, 353249154, 3739153467, 2068076443 },
3061 };
3062 }
3063 else
3064 {
3065 // define set of few valid blocks that contain values from <-1; 1> range
3066 validBlocks =
3067 {
3068 { 2120678840, 3264271120, 4065378848, 3479743703 },
3069 { 1479697556, 3480872527, 3369382558, 568252340 },
3070 { 1301480032, 1607738094, 3055221704, 3663953681 },
3071 { 3531657186, 2285472028, 1429601507, 1969308187 },
3072 { 73229044, 650504649, 1120954865, 2626631975 },
3073 { 3872486086, 15326178, 2565171269, 2857722432 },
3074 { 1301480032, 1607738094, 3055221704, 3663953681 },
3075 { 73229044, 650504649, 1120954865, 2626631975 },
3076 };
3077 }
3078
3079 deUint32* compressedDataUint32 = reinterpret_cast<deUint32*>(compressedData);
3080 const int blocksCount = compressedDataSize / static_cast<int>(sizeof(BC6HBlock));
3081
3082 // fill data using randomly selected valid blocks
3083 for (int blockNdx = 0; blockNdx < blocksCount; blockNdx++)
3084 {
3085 deUint32 selectedBlock = random.getUint32() % static_cast<deUint32>(validBlocks.size());
3086 deMemcpy(compressedDataUint32, validBlocks[selectedBlock].data, sizeof(BC6HBlock));
3087 compressedDataUint32 += 4;
3088 }
3089 }
3090 else if (srcFormat != tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8)
3091 {
3092 // random initial values cause assertion during the decompression in case of COMPRESSEDTEXFORMAT_ETC1_RGB8 format
3093 for (int byteNdx = 0; byteNdx < compressedDataSize; byteNdx++)
3094 compressedData[byteNdx] = 0xFF & random.getUint32();
3095 }
3096
3097 // alocate space for decompressed texture
3098 m_decompressedData.setStorage(decompressedDataSize);
3099 m_decompressedAccess = tcu::PixelBufferAccess(decompressedSrcFormat, width, height, depth, m_decompressedData.getPtr());
3100
3101 // store decompressed data
3102 m_compressedTexture.decompress(m_decompressedAccess, tcu::TexDecompressionParams(tcu::TexDecompressionParams::ASTCMODE_LDR));
3103 }
3104
getDecompressedAccess() const3105 tcu::PixelBufferAccess CompressedTextureForBlit::getDecompressedAccess() const
3106 {
3107 return m_decompressedAccess;
3108 }
3109
getCompressedTexture() const3110 const tcu::CompressedTexture& CompressedTextureForBlit::getCompressedTexture() const
3111 {
3112 return m_compressedTexture;
3113 }
3114
3115 // Copy from image to image with scaling.
3116
3117 class BlittingImages : public CopiesAndBlittingTestInstance
3118 {
3119 public:
3120 BlittingImages (Context& context,
3121 TestParams params);
3122 virtual tcu::TestStatus iterate (void);
3123 protected:
3124 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
3125 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
3126 tcu::PixelBufferAccess dst,
3127 CopyRegion region,
3128 deUint32 mipLevel = 0u);
3129 virtual void generateExpectedResult (void);
3130 void uploadCompressedImage (const VkImage& image, const ImageParms& parms);
3131 private:
3132 bool checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3133 const tcu::ConstPixelBufferAccess& clampedReference,
3134 const tcu::ConstPixelBufferAccess& unclampedReference,
3135 const tcu::TextureFormat& sourceFormat);
3136 bool checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3137 const tcu::ConstPixelBufferAccess& source);
3138
3139 bool checkCompressedNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3140 const tcu::ConstPixelBufferAccess& clampedReference,
3141 const tcu::ConstPixelBufferAccess& unclampedReference,
3142 const tcu::CompressedTexFormat format);
3143 bool checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3144 const tcu::ConstPixelBufferAccess& source,
3145 const tcu::CompressedTexFormat format);
3146
3147
3148 Move<VkImage> m_source;
3149 de::MovePtr<Allocation> m_sourceImageAlloc;
3150 Move<VkImage> m_destination;
3151 de::MovePtr<Allocation> m_destinationImageAlloc;
3152
3153 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel;
3154
3155 // helper used only when bliting from compressed formats
3156 typedef de::SharedPtr<CompressedTextureForBlit> CompressedTextureForBlitSp;
3157 CompressedTextureForBlitSp m_sourceCompressedTexture;
3158 CompressedTextureForBlitSp m_destinationCompressedTexture;
3159 };
3160
BlittingImages(Context & context,TestParams params)3161 BlittingImages::BlittingImages (Context& context, TestParams params)
3162 : CopiesAndBlittingTestInstance(context, params)
3163 {
3164 const InstanceInterface& vki = context.getInstanceInterface();
3165 const DeviceInterface& vk = context.getDeviceInterface();
3166 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
3167 const VkDevice vkDevice = context.getDevice();
3168 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
3169 Allocator& memAlloc = context.getDefaultAllocator();
3170
3171 // Create source image
3172 {
3173 const VkImageCreateInfo sourceImageParams =
3174 {
3175 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3176 DE_NULL, // const void* pNext;
3177 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
3178 m_params.src.image.imageType, // VkImageType imageType;
3179 m_params.src.image.format, // VkFormat format;
3180 getExtent3D(m_params.src.image), // VkExtent3D extent;
3181 1u, // deUint32 mipLevels;
3182 getArraySize(m_params.src.image), // deUint32 arraySize;
3183 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3184 m_params.src.image.tiling, // VkImageTiling tiling;
3185 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3186 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3187 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3188 1u, // deUint32 queueFamilyCount;
3189 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3190 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3191 };
3192
3193 m_source = createImage(vk, vkDevice, &sourceImageParams);
3194 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3195 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
3196 }
3197
3198 // Create destination image
3199 {
3200 const VkImageCreateInfo destinationImageParams =
3201 {
3202 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
3203 DE_NULL, // const void* pNext;
3204 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
3205 m_params.dst.image.imageType, // VkImageType imageType;
3206 m_params.dst.image.format, // VkFormat format;
3207 getExtent3D(m_params.dst.image), // VkExtent3D extent;
3208 1u, // deUint32 mipLevels;
3209 getArraySize(m_params.dst.image), // deUint32 arraySize;
3210 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
3211 m_params.dst.image.tiling, // VkImageTiling tiling;
3212 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
3213 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
3214 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
3215 1u, // deUint32 queueFamilyCount;
3216 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
3217 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
3218 };
3219
3220 m_destination = createImage(vk, vkDevice, &destinationImageParams);
3221 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
3222 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
3223 }
3224 }
3225
iterate(void)3226 tcu::TestStatus BlittingImages::iterate (void)
3227 {
3228 const DeviceInterface& vk = m_context.getDeviceInterface();
3229 const VkDevice vkDevice = m_context.getDevice();
3230 const VkQueue queue = m_context.getUniversalQueue();
3231
3232 const ImageParms& srcImageParams = m_params.src.image;
3233 const int srcWidth = static_cast<int>(srcImageParams.extent.width);
3234 const int srcHeight = static_cast<int>(srcImageParams.extent.height);
3235 const int srcDepth = static_cast<int>(srcImageParams.extent.depth);
3236 const ImageParms& dstImageParams = m_params.dst.image;
3237 const int dstWidth = static_cast<int>(dstImageParams.extent.width);
3238 const int dstHeight = static_cast<int>(dstImageParams.extent.height);
3239 const int dstDepth = static_cast<int>(dstImageParams.extent.depth);
3240
3241 std::vector<VkImageBlit> regions;
3242 std::vector<VkImageBlit2KHR> regions2KHR;
3243
3244 // setup blit regions - they are also needed for reference generation
3245 if (m_params.extensionUse == EXTENSION_USE_NONE)
3246 {
3247 regions.reserve(m_params.regions.size());
3248 for (const auto& r : m_params.regions)
3249 regions.push_back(r.imageBlit);
3250 }
3251 else
3252 {
3253 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3254 regions2KHR.reserve(m_params.regions.size());
3255 for (const auto& r : m_params.regions)
3256 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(r.imageBlit));
3257 }
3258
3259 // generate source image
3260 if (isCompressedFormat(srcImageParams.format))
3261 {
3262 // for compressed images srcImageParams.fillMode is not used - we are using random data
3263 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(srcImageParams.format);
3264 m_sourceCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, dstImageParams.format));
3265 uploadCompressedImage(m_source.get(), srcImageParams);
3266 }
3267 else
3268 {
3269 // non-compressed image is filled with selected fillMode
3270 const tcu::TextureFormat srcTcuFormat = mapVkFormat(srcImageParams.format);
3271 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat, srcWidth, srcHeight, srcDepth));
3272 generateBuffer(m_sourceTextureLevel->getAccess(), srcWidth, srcHeight, srcDepth, srcImageParams.fillMode);
3273 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), srcImageParams);
3274 }
3275
3276 // generate destination image
3277 if (isCompressedFormat(dstImageParams.format))
3278 {
3279 // compressed images are filled with random data
3280 tcu::CompressedTexFormat compressedFormat = mapVkCompressedFormat(dstImageParams.format);
3281 m_destinationCompressedTexture = CompressedTextureForBlitSp(new CompressedTextureForBlit(compressedFormat, srcWidth, srcHeight, srcDepth, VK_FORMAT_UNDEFINED));
3282 uploadCompressedImage(m_destination.get(), dstImageParams);
3283 }
3284 else
3285 {
3286 // non-compressed image is filled with white background
3287 const tcu::TextureFormat dstTcuFormat = mapVkFormat(dstImageParams.format);
3288 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat, dstWidth, dstHeight, dstDepth));
3289 generateBuffer(m_destinationTextureLevel->getAccess(), dstWidth, dstHeight, dstDepth, dstImageParams.fillMode);
3290 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), dstImageParams);
3291 }
3292
3293 generateExpectedResult();
3294
3295 // Barriers for copying images to buffer
3296 const VkImageMemoryBarrier imageBarriers[]
3297 {
3298 {
3299 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3300 DE_NULL, // const void* pNext;
3301 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3302 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
3303 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3304 srcImageParams.operationLayout, // VkImageLayout newLayout;
3305 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3306 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3307 m_source.get(), // VkImage image;
3308 { // VkImageSubresourceRange subresourceRange;
3309 getAspectFlags(srcImageParams.format), // VkImageAspectFlags aspectMask;
3310 0u, // deUint32 baseMipLevel;
3311 1u, // deUint32 mipLevels;
3312 0u, // deUint32 baseArraySlice;
3313 1u // deUint32 arraySize;
3314 }
3315 },
3316 {
3317 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
3318 DE_NULL, // const void* pNext;
3319 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
3320 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
3321 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
3322 dstImageParams.operationLayout, // VkImageLayout newLayout;
3323 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
3324 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
3325 m_destination.get(), // VkImage image;
3326 { // VkImageSubresourceRange subresourceRange;
3327 getAspectFlags(dstImageParams.format), // VkImageAspectFlags aspectMask;
3328 0u, // deUint32 baseMipLevel;
3329 1u, // deUint32 mipLevels;
3330 0u, // deUint32 baseArraySlice;
3331 1u // deUint32 arraySize;
3332 }
3333 }
3334 };
3335
3336 beginCommandBuffer(vk, *m_cmdBuffer);
3337 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, 2, imageBarriers);
3338
3339 if (m_params.extensionUse == EXTENSION_USE_NONE)
3340 {
3341 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), srcImageParams.operationLayout, m_destination.get(), dstImageParams.operationLayout, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter);
3342 }
3343 else
3344 {
3345 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
3346 const VkBlitImageInfo2KHR blitImageInfo2KHR
3347 {
3348 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
3349 DE_NULL, // const void* pNext;
3350 m_source.get(), // VkImage srcImage;
3351 srcImageParams.operationLayout, // VkImageLayout srcImageLayout;
3352 m_destination.get(), // VkImage dstImage;
3353 dstImageParams.operationLayout, // VkImageLayout dstImageLayout;
3354 (deUint32)m_params.regions.size(), // uint32_t regionCount;
3355 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
3356 m_params.filter, // VkFilter filter;
3357 };
3358 vk.cmdBlitImage2KHR(*m_cmdBuffer, &blitImageInfo2KHR);
3359 }
3360
3361 endCommandBuffer(vk, *m_cmdBuffer);
3362 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
3363
3364 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, dstImageParams);
3365 tcu::PixelBufferAccess resultAccess = resultLevel->getAccess();
3366
3367 // if blit was done to a compressed format we need to decompress it to be able to verify it
3368 if (m_destinationCompressedTexture)
3369 {
3370 deUint8* const compressedDataSrc (static_cast<deUint8*>(resultAccess.getDataPtr()));
3371 const tcu::CompressedTexFormat dstCompressedFormat (mapVkCompressedFormat(dstImageParams.format));
3372 tcu::TextureLevel decompressedLevel (getUncompressedFormat(dstCompressedFormat), dstWidth, dstHeight, dstDepth);
3373 tcu::PixelBufferAccess decompressedAccess (decompressedLevel.getAccess());
3374
3375 tcu::decompress(decompressedAccess, dstCompressedFormat, compressedDataSrc);
3376
3377 return checkTestResult(decompressedAccess);
3378 }
3379
3380 return checkTestResult(resultAccess);
3381 }
3382
calculateFloatConversionError(int srcBits)3383 static float calculateFloatConversionError (int srcBits)
3384 {
3385 if (srcBits > 0)
3386 {
3387 const int clampedBits = de::clamp<int>(srcBits, 0, 32);
3388 const float srcMaxValue = de::max((float)(1ULL<<clampedBits) - 1.0f, 1.0f);
3389 const float error = 1.0f / srcMaxValue;
3390
3391 return de::clamp<float>(error, 0.0f, 1.0f);
3392 }
3393 else
3394 return 1.0f;
3395 }
3396
getFormatThreshold(const tcu::TextureFormat & format)3397 tcu::Vec4 getFormatThreshold (const tcu::TextureFormat& format)
3398 {
3399 tcu::Vec4 threshold(0.01f);
3400
3401 switch (format.type)
3402 {
3403 case tcu::TextureFormat::HALF_FLOAT:
3404 threshold = tcu::Vec4(0.005f);
3405 break;
3406
3407 case tcu::TextureFormat::FLOAT:
3408 case tcu::TextureFormat::FLOAT64:
3409 threshold = tcu::Vec4(0.001f);
3410 break;
3411
3412 case tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV:
3413 threshold = tcu::Vec4(0.02f, 0.02f, 0.0625f, 1.0f);
3414 break;
3415
3416 case tcu::TextureFormat::UNSIGNED_INT_999_E5_REV:
3417 threshold = tcu::Vec4(0.05f, 0.05f, 0.05f, 1.0f);
3418 break;
3419
3420 case tcu::TextureFormat::UNORM_INT_1010102_REV:
3421 threshold = tcu::Vec4(0.002f, 0.002f, 0.002f, 0.3f);
3422 break;
3423
3424 case tcu:: TextureFormat::UNORM_INT8:
3425 threshold = tcu::Vec4(0.008f, 0.008f, 0.008f, 0.008f);
3426 break;
3427
3428 default:
3429 const tcu::IVec4 bits = tcu::getTextureFormatMantissaBitDepth(format);
3430 threshold = tcu::Vec4(calculateFloatConversionError(bits.x()),
3431 calculateFloatConversionError(bits.y()),
3432 calculateFloatConversionError(bits.z()),
3433 calculateFloatConversionError(bits.w()));
3434 }
3435
3436 // Return value matching the channel order specified by the format
3437 if (format.order == tcu::TextureFormat::BGR || format.order == tcu::TextureFormat::BGRA)
3438 return threshold.swizzle(2, 1, 0, 3);
3439 else
3440 return threshold;
3441 }
3442
getCompressedFormatThreshold(const tcu::CompressedTexFormat & format)3443 tcu::Vec4 getCompressedFormatThreshold(const tcu::CompressedTexFormat& format)
3444 {
3445 bool isSigned(false);
3446 tcu::IVec4 bitDepth(0);
3447
3448 switch (format)
3449 {
3450 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11:
3451 bitDepth = { 7, 0, 0, 0 };
3452 isSigned = true;
3453 break;
3454
3455 case tcu::COMPRESSEDTEXFORMAT_EAC_R11:
3456 bitDepth = { 8, 0, 0, 0 };
3457 break;
3458
3459 case tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11:
3460 bitDepth = { 7, 7, 0, 0 };
3461 isSigned = true;
3462 break;
3463
3464 case tcu::COMPRESSEDTEXFORMAT_EAC_RG11:
3465 bitDepth = { 8, 8, 0, 0 };
3466 break;
3467
3468 case tcu::COMPRESSEDTEXFORMAT_ETC1_RGB8:
3469 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8:
3470 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8:
3471 bitDepth = { 8, 8, 8, 0 };
3472 break;
3473
3474 case tcu::COMPRESSEDTEXFORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
3475 case tcu::COMPRESSEDTEXFORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
3476 bitDepth = { 8, 8, 8, 1 };
3477 break;
3478
3479 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_RGBA8:
3480 case tcu::COMPRESSEDTEXFORMAT_ETC2_EAC_SRGB8_ALPHA8:
3481 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_RGBA:
3482 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_RGBA:
3483 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_RGBA:
3484 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_RGBA:
3485 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_RGBA:
3486 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_RGBA:
3487 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_RGBA:
3488 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_RGBA:
3489 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_RGBA:
3490 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_RGBA:
3491 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_RGBA:
3492 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_RGBA:
3493 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_RGBA:
3494 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_RGBA:
3495 case tcu::COMPRESSEDTEXFORMAT_ASTC_4x4_SRGB8_ALPHA8:
3496 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x4_SRGB8_ALPHA8:
3497 case tcu::COMPRESSEDTEXFORMAT_ASTC_5x5_SRGB8_ALPHA8:
3498 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x5_SRGB8_ALPHA8:
3499 case tcu::COMPRESSEDTEXFORMAT_ASTC_6x6_SRGB8_ALPHA8:
3500 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x5_SRGB8_ALPHA8:
3501 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x6_SRGB8_ALPHA8:
3502 case tcu::COMPRESSEDTEXFORMAT_ASTC_8x8_SRGB8_ALPHA8:
3503 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x5_SRGB8_ALPHA8:
3504 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x6_SRGB8_ALPHA8:
3505 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x8_SRGB8_ALPHA8:
3506 case tcu::COMPRESSEDTEXFORMAT_ASTC_10x10_SRGB8_ALPHA8:
3507 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x10_SRGB8_ALPHA8:
3508 case tcu::COMPRESSEDTEXFORMAT_ASTC_12x12_SRGB8_ALPHA8:
3509 bitDepth = { 8, 8, 8, 8 };
3510 break;
3511
3512 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_UNORM_BLOCK:
3513 case tcu::COMPRESSEDTEXFORMAT_BC1_RGB_SRGB_BLOCK:
3514 case tcu::COMPRESSEDTEXFORMAT_BC2_UNORM_BLOCK:
3515 case tcu::COMPRESSEDTEXFORMAT_BC2_SRGB_BLOCK:
3516 case tcu::COMPRESSEDTEXFORMAT_BC3_UNORM_BLOCK:
3517 case tcu::COMPRESSEDTEXFORMAT_BC3_SRGB_BLOCK:
3518 bitDepth = { 5, 6, 5, 0 };
3519 break;
3520
3521 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_UNORM_BLOCK:
3522 case tcu::COMPRESSEDTEXFORMAT_BC1_RGBA_SRGB_BLOCK:
3523 case tcu::COMPRESSEDTEXFORMAT_BC7_UNORM_BLOCK:
3524 case tcu::COMPRESSEDTEXFORMAT_BC7_SRGB_BLOCK:
3525 bitDepth = { 5, 5, 5, 1 };
3526 break;
3527
3528 case tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK:
3529 bitDepth = { 7, 0, 0, 0 };
3530 isSigned = true;
3531 break;
3532
3533 case tcu::COMPRESSEDTEXFORMAT_BC4_UNORM_BLOCK:
3534 bitDepth = { 8, 0, 0, 0 };
3535 break;
3536
3537 case tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK:
3538 bitDepth = { 7, 7, 0, 0 };
3539 isSigned = true;
3540 break;
3541
3542 case tcu::COMPRESSEDTEXFORMAT_BC5_UNORM_BLOCK:
3543 bitDepth = { 8, 8, 0, 0 };
3544 break;
3545
3546 case tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK:
3547 return tcu::Vec4(0.01f);
3548 case tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK:
3549 return tcu::Vec4(0.005f);
3550
3551 default:
3552 DE_ASSERT(DE_FALSE);
3553 }
3554
3555 const float range = isSigned ? 1.0f - (-1.0f)
3556 : 1.0f - 0.0f;
3557 tcu::Vec4 v;
3558 for (int i = 0; i < 4; ++i)
3559 {
3560 if (bitDepth[i] == 0)
3561 v[i] = 1.0f;
3562 else
3563 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3564 }
3565 return v;
3566 }
3567
checkNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedExpected,const tcu::ConstPixelBufferAccess & unclampedExpected,const tcu::TextureFormat & srcFormat)3568 bool BlittingImages::checkNonNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3569 const tcu::ConstPixelBufferAccess& clampedExpected,
3570 const tcu::ConstPixelBufferAccess& unclampedExpected,
3571 const tcu::TextureFormat& srcFormat)
3572 {
3573 tcu::TestLog& log (m_context.getTestContext().getLog());
3574 const tcu::TextureFormat dstFormat = result.getFormat();
3575 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3576 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3577 bool isOk = false;
3578
3579 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3580
3581 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3582 // the other must also store values a signed/unsigned integer
3583 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3584 // despite the fact that both formats are sampled as floats
3585 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3586 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3587 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3588 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3589 if (dstImageIsIntClass != srcImageIsIntClass)
3590 {
3591 log << tcu::TestLog::EndSection;
3592 return false;
3593 }
3594
3595 if (isFloatFormat(dstFormat))
3596 {
3597 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
3598 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
3599 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
3600 const tcu::Vec4 threshold = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f);
3601
3602 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3603 log << tcu::TestLog::EndSection;
3604
3605 if (!isOk)
3606 {
3607 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3608 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3609 log << tcu::TestLog::EndSection;
3610 }
3611 }
3612 else
3613 {
3614 tcu::UVec4 threshold;
3615 // Calculate threshold depending on channel width of destination format.
3616 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
3617 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
3618 for (deUint32 i = 0; i < 4; ++i)
3619 threshold[i] = 1 + de::max( ( ( 1 << dstBitDepth[i] ) - 1 ) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
3620
3621 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3622 log << tcu::TestLog::EndSection;
3623
3624 if (!isOk)
3625 {
3626 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3627 isOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedExpected, result, threshold, tcu::COMPARE_LOG_RESULT);
3628 log << tcu::TestLog::EndSection;
3629 }
3630 }
3631
3632 return isOk;
3633 }
3634
checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & clampedReference,const tcu::ConstPixelBufferAccess & unclampedReference,const tcu::CompressedTexFormat format)3635 bool BlittingImages::checkCompressedNonNearestFilteredResult(const tcu::ConstPixelBufferAccess& result,
3636 const tcu::ConstPixelBufferAccess& clampedReference,
3637 const tcu::ConstPixelBufferAccess& unclampedReference,
3638 const tcu::CompressedTexFormat format)
3639 {
3640 tcu::TestLog& log = m_context.getTestContext().getLog();
3641 const tcu::TextureFormat dstFormat = result.getFormat();
3642
3643 // there are rare cases wher one or few pixels have slightly bigger error
3644 // in one of channels this accepted error allows those casses to pass
3645 const tcu::Vec4 acceptedError (0.04f);
3646
3647 const tcu::Vec4 srcMaxDiff = getCompressedFormatThreshold(format);
3648 const tcu::Vec4 dstMaxDiff = m_destinationCompressedTexture ?
3649 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
3650 getFormatThreshold(dstFormat);
3651 const tcu::Vec4 threshold = (srcMaxDiff + dstMaxDiff) * ((m_params.filter == VK_FILTER_CUBIC_EXT) ? 1.5f : 1.0f) + acceptedError;
3652
3653 bool filteredResultVerification(false);
3654 tcu::Vec4 filteredResultMinValue(-6e6);
3655 tcu::Vec4 filteredResultMaxValue(6e6);
3656 tcu::TextureLevel filteredResult;
3657 tcu::TextureLevel filteredClampedReference;
3658 tcu::TextureLevel filteredUnclampedReference;
3659
3660 if (((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
3661 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK)))
3662 {
3663 if ((dstFormat.type == tcu::TextureFormat::FLOAT) ||
3664 (dstFormat.type == tcu::TextureFormat::HALF_FLOAT))
3665 {
3666 // for compressed formats we are using random data and for bc6h formats
3667 // this will give us also large color values; when we are bliting to
3668 // a format that accepts large values we can end up with large diferences
3669 // betwean filtered result and reference; to avoid that we need to remove
3670 // values that are to big from verification
3671 filteredResultVerification = true;
3672 filteredResultMinValue = tcu::Vec4(-10.0f);
3673 filteredResultMaxValue = tcu::Vec4( 10.0f);
3674 }
3675 else if (dstFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
3676 {
3677 // we need to clamp some formats to <0;1> range as it has
3678 // small precision for big numbers compared to reference
3679 filteredResultVerification = true;
3680 filteredResultMinValue = tcu::Vec4(0.0f);
3681 filteredResultMaxValue = tcu::Vec4(1.0f);
3682 }
3683 // else don't use filtered verification
3684 }
3685
3686 if (filteredResultVerification)
3687 {
3688 filteredResult.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3689 tcu::PixelBufferAccess filteredResultAcccess(filteredResult.getAccess());
3690
3691 filteredClampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3692 tcu::PixelBufferAccess filteredClampedAcccess(filteredClampedReference.getAccess());
3693
3694 filteredUnclampedReference.setStorage(dstFormat, result.getWidth(), result.getHeight(), result.getDepth());
3695 tcu::PixelBufferAccess filteredUnclampedResultAcccess(filteredUnclampedReference.getAccess());
3696
3697 for (deInt32 z = 0; z < result.getDepth(); z++)
3698 for (deInt32 y = 0; y < result.getHeight(); y++)
3699 for (deInt32 x = 0; x < result.getWidth(); x++)
3700 {
3701 tcu::Vec4 resultTexel = result.getPixel(x, y, z);
3702 tcu::Vec4 clampedReferenceTexel = clampedReference.getPixel(x, y, z);
3703 tcu::Vec4 unclampedReferenceTexel = unclampedReference.getPixel(x, y, z);
3704
3705 resultTexel = tcu::clamp(resultTexel, filteredResultMinValue, filteredResultMaxValue);
3706 clampedReferenceTexel = tcu::clamp(clampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3707 unclampedReferenceTexel = tcu::clamp(unclampedReferenceTexel, filteredResultMinValue, filteredResultMaxValue);
3708
3709 filteredResultAcccess.setPixel(resultTexel, x, y, z);
3710 filteredClampedAcccess.setPixel(clampedReferenceTexel, x, y, z);
3711 filteredUnclampedResultAcccess.setPixel(unclampedReferenceTexel, x, y, z);
3712 }
3713 }
3714
3715 const tcu::ConstPixelBufferAccess clampedRef = filteredResultVerification ? filteredClampedReference.getAccess() : clampedReference;
3716 const tcu::ConstPixelBufferAccess res = filteredResultVerification ? filteredResult.getAccess() : result;
3717
3718 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
3719 bool isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3720 log << tcu::TestLog::EndSection;
3721
3722 if (!isOk)
3723 {
3724 const tcu::ConstPixelBufferAccess unclampedRef = filteredResultVerification ? filteredUnclampedReference.getAccess() : unclampedReference;
3725
3726 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
3727 isOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedRef, res, threshold, tcu::COMPARE_LOG_RESULT);
3728 log << tcu::TestLog::EndSection;
3729 }
3730
3731 return isOk;
3732 }
3733
3734 //! Utility to encapsulate coordinate computation and loops.
3735 struct CompareEachPixelInEachRegion
3736 {
~CompareEachPixelInEachRegionvkt::api::__anone7bc485d0111::CompareEachPixelInEachRegion3737 virtual ~CompareEachPixelInEachRegion (void) {}
3738 virtual bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const = 0;
3739
forEachvkt::api::__anone7bc485d0111::CompareEachPixelInEachRegion3740 bool forEach (const void* pUserData,
3741 const std::vector<CopyRegion>& regions,
3742 const int sourceWidth,
3743 const int sourceHeight,
3744 const int sourceDepth,
3745 const tcu::PixelBufferAccess& errorMask) const
3746 {
3747 bool compareOk = true;
3748
3749 for (std::vector<CopyRegion>::const_iterator regionIter = regions.begin(); regionIter != regions.end(); ++regionIter)
3750 {
3751 const VkImageBlit& blit = regionIter->imageBlit;
3752
3753 const int xStart = deMin32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3754 const int yStart = deMin32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3755 const int zStart = deMin32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3756 const int xEnd = deMax32(blit.dstOffsets[0].x, blit.dstOffsets[1].x);
3757 const int yEnd = deMax32(blit.dstOffsets[0].y, blit.dstOffsets[1].y);
3758 const int zEnd = deMax32(blit.dstOffsets[0].z, blit.dstOffsets[1].z);
3759 const float xScale = static_cast<float>(blit.srcOffsets[1].x - blit.srcOffsets[0].x) / static_cast<float>(blit.dstOffsets[1].x - blit.dstOffsets[0].x);
3760 const float yScale = static_cast<float>(blit.srcOffsets[1].y - blit.srcOffsets[0].y) / static_cast<float>(blit.dstOffsets[1].y - blit.dstOffsets[0].y);
3761 const float zScale = static_cast<float>(blit.srcOffsets[1].z - blit.srcOffsets[0].z) / static_cast<float>(blit.dstOffsets[1].z - blit.dstOffsets[0].z);
3762 const float srcInvW = 1.0f / static_cast<float>(sourceWidth);
3763 const float srcInvH = 1.0f / static_cast<float>(sourceHeight);
3764 const float srcInvD = 1.0f / static_cast<float>(sourceDepth);
3765
3766 for (int z = zStart; z < zEnd; z++)
3767 for (int y = yStart; y < yEnd; y++)
3768 for (int x = xStart; x < xEnd; x++)
3769 {
3770 const tcu::Vec3 srcNormCoord
3771 (
3772 (xScale * (static_cast<float>(x - blit.dstOffsets[0].x) + 0.5f) + static_cast<float>(blit.srcOffsets[0].x)) * srcInvW,
3773 (yScale * (static_cast<float>(y - blit.dstOffsets[0].y) + 0.5f) + static_cast<float>(blit.srcOffsets[0].y)) * srcInvH,
3774 (zScale * (static_cast<float>(z - blit.dstOffsets[0].z) + 0.5f) + static_cast<float>(blit.srcOffsets[0].z)) * srcInvD
3775 );
3776
3777 if (!compare(pUserData, x, y, z, srcNormCoord))
3778 {
3779 errorMask.setPixel(tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), x, y, z);
3780 compareOk = false;
3781 }
3782 }
3783 }
3784 return compareOk;
3785 }
3786 };
3787
getFloatOrFixedPointFormatThreshold(const tcu::TextureFormat & format)3788 tcu::Vec4 getFloatOrFixedPointFormatThreshold (const tcu::TextureFormat& format)
3789 {
3790 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
3791 const tcu::IVec4 bitDepth = tcu::getTextureFormatBitDepth(format);
3792
3793 if (channelClass == tcu::TEXTURECHANNELCLASS_FLOATING_POINT)
3794 {
3795 return getFormatThreshold(format);
3796 }
3797 else if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT ||
3798 channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT)
3799 {
3800 const bool isSigned = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT);
3801 const float range = isSigned ? 1.0f - (-1.0f)
3802 : 1.0f - 0.0f;
3803
3804 tcu::Vec4 v;
3805 for (int i = 0; i < 4; ++i)
3806 {
3807 if (bitDepth[i] == 0)
3808 v[i] = 1.0f;
3809 else
3810 v[i] = range / static_cast<float>((1 << bitDepth[i]) - 1);
3811 }
3812 return v;
3813 }
3814 else
3815 {
3816 DE_ASSERT(0);
3817 return tcu::Vec4();
3818 }
3819 }
3820
floatNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::Vec4 & sourceThreshold,const tcu::Vec4 & resultThreshold,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3821 bool floatNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
3822 const tcu::ConstPixelBufferAccess& result,
3823 const tcu::Vec4& sourceThreshold,
3824 const tcu::Vec4& resultThreshold,
3825 const tcu::PixelBufferAccess& errorMask,
3826 const std::vector<CopyRegion>& regions)
3827 {
3828 const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
3829 const tcu::IVec4 dstBitDepth (tcu::getTextureFormatBitDepth(result.getFormat()));
3830 tcu::LookupPrecision precision;
3831
3832 precision.colorMask = tcu::notEqual(dstBitDepth, tcu::IVec4(0));
3833 precision.colorThreshold = tcu::max(sourceThreshold, resultThreshold);
3834
3835 const struct Capture
3836 {
3837 const tcu::ConstPixelBufferAccess& source;
3838 const tcu::ConstPixelBufferAccess& result;
3839 const tcu::Sampler& sampler;
3840 const tcu::LookupPrecision& precision;
3841 const bool isSRGB;
3842 } capture =
3843 {
3844 source, result, sampler, precision, tcu::isSRGB(result.getFormat())
3845 };
3846
3847 const struct Loop : CompareEachPixelInEachRegion
3848 {
3849 Loop (void) {}
3850
3851 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3852 {
3853 const Capture& c = *static_cast<const Capture*>(pUserData);
3854 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
3855 tcu::Vec4 dstColor = c.result.getPixel(x, y, z);
3856
3857 // TexLookupVerifier performs a conversion to linear space, so we have to as well
3858 if (c.isSRGB)
3859 dstColor = tcu::sRGBToLinear(dstColor);
3860
3861 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3862 }
3863 } loop;
3864
3865 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3866 }
3867
intNearestBlitCompare(const tcu::ConstPixelBufferAccess & source,const tcu::ConstPixelBufferAccess & result,const tcu::PixelBufferAccess & errorMask,const std::vector<CopyRegion> & regions)3868 bool intNearestBlitCompare (const tcu::ConstPixelBufferAccess& source,
3869 const tcu::ConstPixelBufferAccess& result,
3870 const tcu::PixelBufferAccess& errorMask,
3871 const std::vector<CopyRegion>& regions)
3872 {
3873 const tcu::Sampler sampler (tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
3874 tcu::IntLookupPrecision precision;
3875
3876 {
3877 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(source.getFormat());
3878 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(result.getFormat());
3879
3880 for (deUint32 i = 0; i < 4; ++i) {
3881 precision.colorThreshold[i] = de::max(de::max(srcBitDepth[i] / 8, dstBitDepth[i] / 8), 1);
3882 precision.colorMask[i] = dstBitDepth[i] != 0;
3883 }
3884 }
3885
3886 // Prepare a source image with a matching (converted) pixel format. Ideally, we would've used a wrapper that
3887 // does the conversion on the fly without wasting memory, but this approach is more straightforward.
3888 tcu::TextureLevel convertedSourceTexture (result.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
3889 const tcu::PixelBufferAccess convertedSource = convertedSourceTexture.getAccess();
3890
3891 for (int z = 0; z < source.getDepth(); ++z)
3892 for (int y = 0; y < source.getHeight(); ++y)
3893 for (int x = 0; x < source.getWidth(); ++x)
3894 convertedSource.setPixel(source.getPixelInt(x, y, z), x, y, z); // will be clamped to max. representable value
3895
3896 const struct Capture
3897 {
3898 const tcu::ConstPixelBufferAccess& source;
3899 const tcu::ConstPixelBufferAccess& result;
3900 const tcu::Sampler& sampler;
3901 const tcu::IntLookupPrecision& precision;
3902 } capture =
3903 {
3904 convertedSource, result, sampler, precision
3905 };
3906
3907 const struct Loop : CompareEachPixelInEachRegion
3908 {
3909 Loop (void) {}
3910
3911 bool compare (const void* pUserData, const int x, const int y, const int z, const tcu::Vec3& srcNormCoord) const
3912 {
3913 const Capture& c = *static_cast<const Capture*>(pUserData);
3914 const tcu::TexLookupScaleMode lookupScaleDontCare = tcu::TEX_LOOKUP_SCALE_MINIFY;
3915 const tcu::IVec4 dstColor = c.result.getPixelInt(x, y, z);
3916
3917 return tcu::isLevel3DLookupResultValid(c.source, c.sampler, lookupScaleDontCare, c.precision, srcNormCoord, dstColor);
3918 }
3919 } loop;
3920
3921 return loop.forEach(&capture, regions, source.getWidth(), source.getHeight(), source.getDepth(), errorMask);
3922 }
3923
checkNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source)3924 bool BlittingImages::checkNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3925 const tcu::ConstPixelBufferAccess& source)
3926 {
3927 tcu::TestLog& log (m_context.getTestContext().getLog());
3928 const tcu::TextureFormat dstFormat = result.getFormat();
3929 const tcu::TextureFormat srcFormat = source.getFormat();
3930 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
3931 const tcu::TextureChannelClass srcChannelClass = tcu::getTextureChannelClass(srcFormat.type);
3932
3933 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
3934 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
3935 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
3936 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
3937 bool ok = false;
3938
3939 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
3940
3941 // if either of srcImage or dstImage stores values as a signed/unsigned integer,
3942 // the other must also store values a signed/unsigned integer
3943 // e.g. blit unorm to uscaled is not allowed as uscaled formats store data as integers
3944 // despite the fact that both formats are sampled as floats
3945 bool dstImageIsIntClass = dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3946 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3947 bool srcImageIsIntClass = srcChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
3948 srcChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
3949 if (dstImageIsIntClass != srcImageIsIntClass)
3950 return false;
3951
3952 if (dstImageIsIntClass)
3953 {
3954 ok = intNearestBlitCompare(source, result, errorMask, m_params.regions);
3955 }
3956 else
3957 {
3958 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
3959 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
3960 ok = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions);
3961 }
3962
3963 if (result.getFormat() != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
3964 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
3965
3966 if (!ok)
3967 {
3968 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3969 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3970 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
3971 << tcu::TestLog::EndImageSet;
3972 }
3973 else
3974 {
3975 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
3976 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
3977 << tcu::TestLog::EndImageSet;
3978 }
3979
3980 return ok;
3981 }
3982
checkCompressedNearestFilteredResult(const tcu::ConstPixelBufferAccess & result,const tcu::ConstPixelBufferAccess & source,const tcu::CompressedTexFormat format)3983 bool BlittingImages::checkCompressedNearestFilteredResult (const tcu::ConstPixelBufferAccess& result,
3984 const tcu::ConstPixelBufferAccess& source,
3985 const tcu::CompressedTexFormat format)
3986 {
3987 tcu::TestLog& log (m_context.getTestContext().getLog());
3988 tcu::TextureFormat errorMaskFormat (tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8);
3989 tcu::TextureLevel errorMaskStorage (errorMaskFormat, result.getWidth(), result.getHeight(), result.getDepth());
3990 tcu::PixelBufferAccess errorMask (errorMaskStorage.getAccess());
3991 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
3992 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
3993 const tcu::TextureFormat& resultFormat (result.getFormat());
3994 VkFormat nativeResultFormat (mapTextureFormat(resultFormat));
3995
3996 // there are rare cases wher one or few pixels have slightly bigger error
3997 // in one of channels this accepted error allows those casses to pass
3998 const tcu::Vec4 acceptedError (0.04f);
3999 const tcu::Vec4 srcMaxDiff (acceptedError + getCompressedFormatThreshold(format));
4000 const tcu::Vec4 dstMaxDiff (acceptedError + (m_destinationCompressedTexture ?
4001 getCompressedFormatThreshold(m_destinationCompressedTexture->getCompressedTexture().getFormat()) :
4002 getFloatOrFixedPointFormatThreshold(resultFormat)));
4003
4004 tcu::TextureLevel clampedSourceLevel;
4005 bool clampSource (false);
4006 tcu::Vec4 clampSourceMinValue (-1.0f);
4007 tcu::Vec4 clampSourceMaxValue (1.0f);
4008 tcu::TextureLevel clampedResultLevel;
4009 bool clampResult (false);
4010
4011 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
4012
4013 if (resultFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
4014 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
4015
4016 log << tcu::TestLog::ImageSet("Compare", "Result comparsion")
4017 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias);
4018
4019 // for compressed formats source buffer access is not actual compressed format
4020 // but equivalent uncompressed format that is some cases needs additional
4021 // modifications so that sampling it will produce valid reference
4022 if ((format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK) ||
4023 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_UFLOAT_BLOCK))
4024 {
4025 if (resultFormat.type == tcu::TextureFormat::UNSIGNED_INT_11F_11F_10F_REV)
4026 {
4027 // for compressed formats we are using random data and for some formats it
4028 // can be outside of <-1;1> range - for cases where result is not a float
4029 // format we need to clamp source to <-1;1> range as this will be done on
4030 // the device but not in software sampler in framework
4031 clampSource = true;
4032 // for this format we also need to clamp the result as precision of
4033 // this format is smaller then precision of calculations in framework;
4034 // the biger color valus are the bigger errors can be
4035 clampResult = true;
4036
4037 if (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK)
4038 clampSourceMinValue = tcu::Vec4(0.0f);
4039 }
4040 else if ((resultFormat.type != tcu::TextureFormat::FLOAT) &&
4041 (resultFormat.type != tcu::TextureFormat::HALF_FLOAT))
4042 {
4043 // clamp source for all non float formats
4044 clampSource = true;
4045 }
4046 }
4047
4048 if (isUnormFormat(nativeResultFormat) || isUfloatFormat(nativeResultFormat))
4049 {
4050 // when tested compressed format is signed but the result format
4051 // is unsigned we need to clamp source to <0; x> so that proper
4052 // reference is calculated
4053 if ((format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_R11) ||
4054 (format == tcu::COMPRESSEDTEXFORMAT_EAC_SIGNED_RG11) ||
4055 (format == tcu::COMPRESSEDTEXFORMAT_BC4_SNORM_BLOCK) ||
4056 (format == tcu::COMPRESSEDTEXFORMAT_BC5_SNORM_BLOCK) ||
4057 (format == tcu::COMPRESSEDTEXFORMAT_BC6H_SFLOAT_BLOCK))
4058 {
4059 clampSource = true;
4060 clampSourceMinValue = tcu::Vec4(0.0f);
4061 }
4062 }
4063
4064 if (clampSource || clampResult)
4065 {
4066 if (clampSource)
4067 {
4068 clampedSourceLevel.setStorage(source.getFormat(), source.getWidth(), source.getHeight(), source.getDepth());
4069 tcu::PixelBufferAccess clampedSourceAcccess(clampedSourceLevel.getAccess());
4070
4071 for (deInt32 z = 0; z < source.getDepth() ; z++)
4072 for (deInt32 y = 0; y < source.getHeight() ; y++)
4073 for (deInt32 x = 0; x < source.getWidth() ; x++)
4074 {
4075 tcu::Vec4 texel = source.getPixel(x, y, z);
4076 texel = tcu::clamp(texel, tcu::Vec4(clampSourceMinValue), tcu::Vec4(clampSourceMaxValue));
4077 clampedSourceAcccess.setPixel(texel, x, y, z);
4078 }
4079 }
4080
4081 if (clampResult)
4082 {
4083 clampedResultLevel.setStorage(result.getFormat(), result.getWidth(), result.getHeight(), result.getDepth());
4084 tcu::PixelBufferAccess clampedResultAcccess(clampedResultLevel.getAccess());
4085
4086 for (deInt32 z = 0; z < result.getDepth() ; z++)
4087 for (deInt32 y = 0; y < result.getHeight() ; y++)
4088 for (deInt32 x = 0; x < result.getWidth() ; x++)
4089 {
4090 tcu::Vec4 texel = result.getPixel(x, y, z);
4091 texel = tcu::clamp(texel, tcu::Vec4(-1.0f), tcu::Vec4(1.0f));
4092 clampedResultAcccess.setPixel(texel, x, y, z);
4093 }
4094 }
4095 }
4096
4097 const tcu::ConstPixelBufferAccess src = clampSource ? clampedSourceLevel.getAccess() : source;
4098 const tcu::ConstPixelBufferAccess res = clampResult ? clampedResultLevel.getAccess() : result;
4099
4100 if (floatNearestBlitCompare(src, res, srcMaxDiff, dstMaxDiff, errorMask, m_params.regions))
4101 {
4102 log << tcu::TestLog::EndImageSet;
4103 return true;
4104 }
4105
4106 log << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
4107 << tcu::TestLog::EndImageSet;
4108 return false;
4109 }
4110
checkTestResult(tcu::ConstPixelBufferAccess result)4111 tcu::TestStatus BlittingImages::checkTestResult (tcu::ConstPixelBufferAccess result)
4112 {
4113 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
4114 const std::string failMessage("Result image is incorrect");
4115
4116 if (m_params.filter != VK_FILTER_NEAREST)
4117 {
4118 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4119 {
4120 if (tcu::hasDepthComponent(result.getFormat().order))
4121 {
4122 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4123 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4124 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4125 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4126 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4127
4128 if (!checkNonNearestFilteredResult(depthResult, clampedExpected, unclampedExpected, sourceFormat))
4129 return tcu::TestStatus::fail(failMessage);
4130 }
4131
4132 if (tcu::hasStencilComponent(result.getFormat().order))
4133 {
4134 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4135 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4136 const tcu::ConstPixelBufferAccess clampedExpected = tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[0]->getAccess(), mode);
4137 const tcu::ConstPixelBufferAccess unclampedExpected = tcu::getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel->getAccess(), mode);
4138 const tcu::TextureFormat sourceFormat = tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode);
4139
4140 if (!checkNonNearestFilteredResult(stencilResult, clampedExpected, unclampedExpected, sourceFormat))
4141 return tcu::TestStatus::fail(failMessage);
4142 }
4143 }
4144 else if (m_sourceCompressedTexture)
4145 {
4146 const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4147 if (!checkCompressedNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), compressedLevel.getFormat()))
4148 return tcu::TestStatus::fail(failMessage);
4149 }
4150 else
4151 {
4152 const tcu::TextureFormat sourceFormat = mapVkFormat(m_params.src.image.format);
4153 if (!checkNonNearestFilteredResult(result, m_expectedTextureLevel[0]->getAccess(), m_unclampedExpectedTextureLevel->getAccess(), sourceFormat))
4154 return tcu::TestStatus::fail(failMessage);
4155 }
4156 }
4157 else // NEAREST filtering
4158 {
4159 if (tcu::isCombinedDepthStencilType(result.getFormat().type))
4160 {
4161 if (tcu::hasDepthComponent(result.getFormat().order))
4162 {
4163 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
4164 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4165 const tcu::ConstPixelBufferAccess depthSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4166
4167 if (!checkNearestFilteredResult(depthResult, depthSource))
4168 return tcu::TestStatus::fail(failMessage);
4169 }
4170
4171 if (tcu::hasStencilComponent(result.getFormat().order))
4172 {
4173 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
4174 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
4175 const tcu::ConstPixelBufferAccess stencilSource = tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode);
4176
4177 if (!checkNearestFilteredResult(stencilResult, stencilSource))
4178 return tcu::TestStatus::fail(failMessage);
4179 }
4180 }
4181 else if (m_sourceCompressedTexture)
4182 {
4183 const tcu::CompressedTexture& compressedLevel = m_sourceCompressedTexture->getCompressedTexture();
4184 const tcu::PixelBufferAccess& decompressedLevel = m_sourceCompressedTexture->getDecompressedAccess();
4185
4186 if (!checkCompressedNearestFilteredResult(result, decompressedLevel, compressedLevel.getFormat()))
4187 return tcu::TestStatus::fail(failMessage);
4188 }
4189 else if (!checkNearestFilteredResult(result, m_sourceTextureLevel->getAccess()))
4190 return tcu::TestStatus::fail(failMessage);
4191 }
4192
4193 return tcu::TestStatus::pass("Pass");
4194 }
4195
linearToSRGBIfNeeded(const tcu::TextureFormat & format,const tcu::Vec4 & color)4196 tcu::Vec4 linearToSRGBIfNeeded (const tcu::TextureFormat& format, const tcu::Vec4& color)
4197 {
4198 return isSRGB(format) ? linearToSRGB(color) : color;
4199 }
4200
scaleFromWholeSrcBuffer(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const VkOffset3D regionOffset,const VkOffset3D regionExtent,tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode=0u)4201 void scaleFromWholeSrcBuffer (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const VkOffset3D regionOffset, const VkOffset3D regionExtent, tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode = 0u)
4202 {
4203 DE_ASSERT(filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4204
4205 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4206 filter, filter, 0.0f, false);
4207
4208 float sX = (float)regionExtent.x / (float)dst.getWidth();
4209 float sY = (float)regionExtent.y / (float)dst.getHeight();
4210 float sZ = (float)regionExtent.z / (float)dst.getDepth();
4211
4212 for (int z = 0; z < dst.getDepth(); z++)
4213 for (int y = 0; y < dst.getHeight(); y++)
4214 for (int x = 0; x < dst.getWidth(); x++)
4215 {
4216 float srcX = ((mirrorMode & MIRROR_MODE_X) != 0) ? (float)regionExtent.x + (float)regionOffset.x - ((float)x+0.5f)*sX : (float)regionOffset.x + ((float)x+0.5f)*sX;
4217 float srcY = ((mirrorMode & MIRROR_MODE_Y) != 0) ? (float)regionExtent.y + (float)regionOffset.y - ((float)y+0.5f)*sY : (float)regionOffset.y + ((float)y+0.5f)*sY;
4218 float srcZ = ((mirrorMode & MIRROR_MODE_Z) != 0) ? (float)regionExtent.z + (float)regionOffset.z - ((float)z+0.5f)*sZ : (float)regionOffset.z + ((float)z+0.5f)*sZ;
4219 if (dst.getDepth() > 1)
4220 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, srcX, srcY, srcZ)), x, y, z);
4221 else
4222 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample2D(sampler, filter, srcX, srcY, 0)), x, y);
4223 }
4224 }
4225
blit(const tcu::PixelBufferAccess & dst,const tcu::ConstPixelBufferAccess & src,const tcu::Sampler::FilterMode filter,const MirrorMode mirrorMode)4226 void blit (const tcu::PixelBufferAccess& dst, const tcu::ConstPixelBufferAccess& src, const tcu::Sampler::FilterMode filter, const MirrorMode mirrorMode)
4227 {
4228 DE_ASSERT(filter == tcu::Sampler::NEAREST || filter == tcu::Sampler::LINEAR || filter == tcu::Sampler::CUBIC);
4229
4230 tcu::Sampler sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE,
4231 filter, filter, 0.0f, false);
4232
4233 const float sX = (float)src.getWidth() / (float)dst.getWidth();
4234 const float sY = (float)src.getHeight() / (float)dst.getHeight();
4235 const float sZ = (float)src.getDepth() / (float)dst.getDepth();
4236
4237 const int xOffset = (mirrorMode & MIRROR_MODE_X) ? dst.getWidth() - 1 : 0;
4238 const int yOffset = (mirrorMode & MIRROR_MODE_Y) ? dst.getHeight() - 1 : 0;
4239 const int zOffset = (mirrorMode & MIRROR_MODE_Z) ? dst.getDepth() - 1 : 0;
4240
4241 const int xScale = (mirrorMode & MIRROR_MODE_X) ? -1 : 1;
4242 const int yScale = (mirrorMode & MIRROR_MODE_Y) ? -1 : 1;
4243 const int zScale = (mirrorMode & MIRROR_MODE_Z) ? -1 : 1;
4244
4245 for (int z = 0; z < dst.getDepth(); ++z)
4246 for (int y = 0; y < dst.getHeight(); ++y)
4247 for (int x = 0; x < dst.getWidth(); ++x)
4248 {
4249 dst.setPixel(linearToSRGBIfNeeded(dst.getFormat(), src.sample3D(sampler, filter, ((float)x + 0.5f) * sX, ((float)y + 0.5f) * sY, ((float)z + 0.5f) * sZ)), x * xScale + xOffset, y * yScale + yOffset, z * zScale + zOffset);
4250 }
4251 }
4252
flipCoordinates(CopyRegion & region,const MirrorMode mirrorMode)4253 void flipCoordinates (CopyRegion& region, const MirrorMode mirrorMode)
4254 {
4255 const VkOffset3D dstOffset0 = region.imageBlit.dstOffsets[0];
4256 const VkOffset3D dstOffset1 = region.imageBlit.dstOffsets[1];
4257 const VkOffset3D srcOffset0 = region.imageBlit.srcOffsets[0];
4258 const VkOffset3D srcOffset1 = region.imageBlit.srcOffsets[1];
4259
4260 if (mirrorMode != 0u)
4261 {
4262 //sourceRegion
4263 region.imageBlit.srcOffsets[0].x = std::min(srcOffset0.x, srcOffset1.x);
4264 region.imageBlit.srcOffsets[0].y = std::min(srcOffset0.y, srcOffset1.y);
4265 region.imageBlit.srcOffsets[0].z = std::min(srcOffset0.z, srcOffset1.z);
4266
4267 region.imageBlit.srcOffsets[1].x = std::max(srcOffset0.x, srcOffset1.x);
4268 region.imageBlit.srcOffsets[1].y = std::max(srcOffset0.y, srcOffset1.y);
4269 region.imageBlit.srcOffsets[1].z = std::max(srcOffset0.z, srcOffset1.z);
4270
4271 //destinationRegion
4272 region.imageBlit.dstOffsets[0].x = std::min(dstOffset0.x, dstOffset1.x);
4273 region.imageBlit.dstOffsets[0].y = std::min(dstOffset0.y, dstOffset1.y);
4274 region.imageBlit.dstOffsets[0].z = std::min(dstOffset0.z, dstOffset1.z);
4275
4276 region.imageBlit.dstOffsets[1].x = std::max(dstOffset0.x, dstOffset1.x);
4277 region.imageBlit.dstOffsets[1].y = std::max(dstOffset0.y, dstOffset1.y);
4278 region.imageBlit.dstOffsets[1].z = std::max(dstOffset0.z, dstOffset1.z);
4279 }
4280 }
4281
4282 // Mirror X, Y and Z as required by the offset values in the 3 axes.
getMirrorMode(const VkOffset3D from,const VkOffset3D to)4283 MirrorMode getMirrorMode(const VkOffset3D from, const VkOffset3D to)
4284 {
4285 MirrorMode mode = 0u;
4286
4287 if (from.x > to.x)
4288 mode |= MIRROR_MODE_X;
4289
4290 if (from.y > to.y)
4291 mode |= MIRROR_MODE_Y;
4292
4293 if (from.z > to.z)
4294 mode |= MIRROR_MODE_Z;
4295
4296 return mode;
4297 }
4298
4299 // Mirror the axes that are mirrored either in the source or destination, but not both.
getMirrorMode(const VkOffset3D s1,const VkOffset3D s2,const VkOffset3D d1,const VkOffset3D d2)4300 MirrorMode getMirrorMode(const VkOffset3D s1, const VkOffset3D s2, const VkOffset3D d1, const VkOffset3D d2)
4301 {
4302 static const MirrorModeBits kBits[] = { MIRROR_MODE_X, MIRROR_MODE_Y, MIRROR_MODE_Z };
4303
4304 const MirrorMode source = getMirrorMode(s1, s2);
4305 const MirrorMode destination = getMirrorMode(d1, d2);
4306
4307 MirrorMode mode = 0u;
4308
4309 for (int i = 0; i < DE_LENGTH_OF_ARRAY(kBits); ++i)
4310 {
4311 const MirrorModeBits bit = kBits[i];
4312 if ((source & bit) != (destination & bit))
4313 mode |= bit;
4314 }
4315
4316 return mode;
4317 }
4318
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)4319 void BlittingImages::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
4320 {
4321 DE_UNREF(mipLevel);
4322
4323 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
4324 region.imageBlit.srcOffsets[1],
4325 region.imageBlit.dstOffsets[0],
4326 region.imageBlit.dstOffsets[1]);
4327
4328 flipCoordinates(region, mirrorMode);
4329
4330 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
4331 const VkOffset3D srcExtent =
4332 {
4333 region.imageBlit.srcOffsets[1].x - srcOffset.x,
4334 region.imageBlit.srcOffsets[1].y - srcOffset.y,
4335 region.imageBlit.srcOffsets[1].z - srcOffset.z,
4336 };
4337 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
4338 const VkOffset3D dstExtent =
4339 {
4340 region.imageBlit.dstOffsets[1].x - dstOffset.x,
4341 region.imageBlit.dstOffsets[1].y - dstOffset.y,
4342 region.imageBlit.dstOffsets[1].z - dstOffset.z,
4343 };
4344
4345 tcu::Sampler::FilterMode filter;
4346 switch (m_params.filter)
4347 {
4348 case VK_FILTER_LINEAR: filter = tcu::Sampler::LINEAR; break;
4349 case VK_FILTER_CUBIC_EXT: filter = tcu::Sampler::CUBIC; break;
4350 case VK_FILTER_NEAREST:
4351 default: filter = tcu::Sampler::NEAREST; break;
4352 }
4353
4354 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
4355 {
4356 DE_ASSERT(src.getFormat() == dst.getFormat());
4357
4358 // Scale depth.
4359 if (tcu::hasDepthComponent(src.getFormat().order))
4360 {
4361 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_DEPTH);
4362 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4363 tcu::scale(dstSubRegion, srcSubRegion, filter);
4364
4365 if (filter != tcu::Sampler::NEAREST)
4366 {
4367 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
4368 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_DEPTH);
4369 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter, mirrorMode);
4370 }
4371 }
4372
4373 // Scale stencil.
4374 if (tcu::hasStencilComponent(src.getFormat().order))
4375 {
4376 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z), tcu::Sampler::MODE_STENCIL);
4377 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4378 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4379
4380 if (filter != tcu::Sampler::NEAREST)
4381 {
4382 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
4383 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z), tcu::Sampler::MODE_STENCIL);
4384 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter, mirrorMode);
4385 }
4386 }
4387 }
4388 else
4389 {
4390 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcOffset.z, srcExtent.x, srcExtent.y, srcExtent.z);
4391 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4392 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
4393
4394 if (filter != tcu::Sampler::NEAREST)
4395 {
4396 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel->getAccess(), dstOffset.x, dstOffset.y, dstOffset.z, dstExtent.x, dstExtent.y, dstExtent.z);
4397 scaleFromWholeSrcBuffer(unclampedSubRegion, src, srcOffset, srcExtent, filter, mirrorMode);
4398 }
4399 }
4400 }
4401
generateExpectedResult(void)4402 void BlittingImages::generateExpectedResult (void)
4403 {
4404 const tcu::ConstPixelBufferAccess src = m_sourceCompressedTexture ? m_sourceCompressedTexture->getDecompressedAccess() : m_sourceTextureLevel->getAccess();
4405 const tcu::ConstPixelBufferAccess dst = m_destinationCompressedTexture ? m_destinationCompressedTexture->getDecompressedAccess() : m_destinationTextureLevel->getAccess();
4406
4407 m_expectedTextureLevel[0] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4408 tcu::copy(m_expectedTextureLevel[0]->getAccess(), dst);
4409
4410 if (m_params.filter != VK_FILTER_NEAREST)
4411 {
4412 m_unclampedExpectedTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth(), dst.getHeight(), dst.getDepth()));
4413 tcu::copy(m_unclampedExpectedTextureLevel->getAccess(), dst);
4414 }
4415
4416 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4417 {
4418 CopyRegion region = m_params.regions[i];
4419 copyRegionToTextureLevel(src, m_expectedTextureLevel[0]->getAccess(), region);
4420 }
4421 }
4422
uploadCompressedImage(const VkImage & image,const ImageParms & parms)4423 void BlittingImages::uploadCompressedImage (const VkImage& image, const ImageParms& parms)
4424 {
4425 DE_ASSERT(m_sourceCompressedTexture);
4426
4427 const InstanceInterface& vki = m_context.getInstanceInterface();
4428 const DeviceInterface& vk = m_context.getDeviceInterface();
4429 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
4430 const VkDevice vkDevice = m_context.getDevice();
4431 const VkQueue queue = m_context.getUniversalQueue();
4432 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
4433 Allocator& memAlloc = m_context.getDefaultAllocator();
4434 Move<VkBuffer> buffer;
4435 const deUint32 bufferSize = m_sourceCompressedTexture->getCompressedTexture().getDataSize();
4436 de::MovePtr<Allocation> bufferAlloc;
4437 const deUint32 arraySize = getArraySize(parms);
4438 const VkExtent3D imageExtent
4439 {
4440 parms.extent.width,
4441 (parms.imageType != VK_IMAGE_TYPE_1D) ? parms.extent.height : 1u,
4442 (parms.imageType == VK_IMAGE_TYPE_3D) ? parms.extent.depth : 1u,
4443 };
4444
4445 // Create source buffer
4446 {
4447 const VkBufferCreateInfo bufferParams
4448 {
4449 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
4450 DE_NULL, // const void* pNext;
4451 0u, // VkBufferCreateFlags flags;
4452 bufferSize, // VkDeviceSize size;
4453 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage;
4454 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4455 1u, // deUint32 queueFamilyIndexCount;
4456 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
4457 };
4458
4459 buffer = createBuffer(vk, vkDevice, &bufferParams);
4460 bufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *buffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
4461 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
4462 }
4463
4464 // Barriers for copying buffer to image
4465 const VkBufferMemoryBarrier preBufferBarrier
4466 {
4467 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
4468 DE_NULL, // const void* pNext;
4469 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
4470 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4471 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4472 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4473 *buffer, // VkBuffer buffer;
4474 0u, // VkDeviceSize offset;
4475 bufferSize // VkDeviceSize size;
4476 };
4477
4478 const VkImageMemoryBarrier preImageBarrier
4479 {
4480 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4481 DE_NULL, // const void* pNext;
4482 0u, // VkAccessFlags srcAccessMask;
4483 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4484 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
4485 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
4486 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4487 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4488 image, // VkImage image;
4489 { // VkImageSubresourceRange subresourceRange;
4490 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4491 0u, // deUint32 baseMipLevel;
4492 1u, // deUint32 mipLevels;
4493 0u, // deUint32 baseArraySlice;
4494 arraySize, // deUint32 arraySize;
4495 }
4496 };
4497
4498 const VkImageMemoryBarrier postImageBarrier
4499 {
4500 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4501 DE_NULL, // const void* pNext;
4502 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4503 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4504 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4505 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
4506 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4507 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4508 image, // VkImage image;
4509 { // VkImageSubresourceRange subresourceRange;
4510 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4511 0u, // deUint32 baseMipLevel;
4512 1u, // deUint32 mipLevels;
4513 0u, // deUint32 baseArraySlice;
4514 arraySize, // deUint32 arraySize;
4515 }
4516 };
4517
4518 const VkExtent3D copyExtent
4519 {
4520 imageExtent.width,
4521 imageExtent.height,
4522 imageExtent.depth
4523 };
4524
4525 VkBufferImageCopy copyRegion
4526 {
4527 0u, // VkDeviceSize bufferOffset;
4528 copyExtent.width, // deUint32 bufferRowLength;
4529 copyExtent.height, // deUint32 bufferImageHeight;
4530 {
4531 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
4532 0u, // deUint32 mipLevel;
4533 0u, // deUint32 baseArrayLayer;
4534 arraySize, // deUint32 layerCount;
4535 }, // VkImageSubresourceLayers imageSubresource;
4536 { 0, 0, 0 }, // VkOffset3D imageOffset;
4537 copyExtent // VkExtent3D imageExtent;
4538 };
4539
4540 // Write buffer data
4541 deMemcpy(bufferAlloc->getHostPtr(), m_sourceCompressedTexture->getCompressedTexture().getData(), bufferSize);
4542 flushAlloc(vk, vkDevice, *bufferAlloc);
4543
4544 // Copy buffer to image
4545 beginCommandBuffer(vk, *m_cmdBuffer);
4546 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL,
4547 1, &preBufferBarrier, 1, &preImageBarrier);
4548 vk.cmdCopyBufferToImage(*m_cmdBuffer, *buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1u, ©Region);
4549 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, &postImageBarrier);
4550 endCommandBuffer(vk, *m_cmdBuffer);
4551
4552 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4553 }
4554
4555
4556 class BlitImageTestCase : public vkt::TestCase
4557 {
4558 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)4559 BlitImageTestCase (tcu::TestContext& testCtx,
4560 const std::string& name,
4561 const std::string& description,
4562 const TestParams params)
4563 : vkt::TestCase (testCtx, name, description)
4564 , m_params (params)
4565 {}
4566
createInstance(Context & context) const4567 virtual TestInstance* createInstance (Context& context) const
4568 {
4569 return new BlittingImages(context, m_params);
4570 }
4571
checkSupport(Context & context) const4572 virtual void checkSupport (Context& context) const
4573 {
4574 VkImageFormatProperties properties;
4575 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4576 m_params.src.image.format,
4577 m_params.src.image.imageType,
4578 m_params.src.image.tiling,
4579 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
4580 0,
4581 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4582 {
4583 TCU_THROW(NotSupportedError, "Source format not supported");
4584 }
4585 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
4586 m_params.dst.image.format,
4587 m_params.dst.image.imageType,
4588 m_params.dst.image.tiling,
4589 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
4590 0,
4591 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
4592 {
4593 TCU_THROW(NotSupportedError, "Destination format not supported");
4594 }
4595
4596 VkFormatProperties srcFormatProperties;
4597 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.src.image.format, &srcFormatProperties);
4598 VkFormatFeatureFlags srcFormatFeatures = m_params.src.image.tiling == VK_IMAGE_TILING_LINEAR ? srcFormatProperties.linearTilingFeatures : srcFormatProperties.optimalTilingFeatures;
4599 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
4600 {
4601 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
4602 }
4603
4604 VkFormatProperties dstFormatProperties;
4605 context.getInstanceInterface().getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), m_params.dst.image.format, &dstFormatProperties);
4606 VkFormatFeatureFlags dstFormatFeatures = m_params.dst.image.tiling == VK_IMAGE_TILING_LINEAR ? dstFormatProperties.linearTilingFeatures : dstFormatProperties.optimalTilingFeatures;
4607 if (!(dstFormatFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
4608 {
4609 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
4610 }
4611
4612 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
4613 {
4614 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
4615 }
4616
4617 if (m_params.filter == VK_FILTER_CUBIC_EXT)
4618 {
4619 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
4620
4621 if (!(srcFormatFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
4622 {
4623 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
4624 }
4625 }
4626
4627 if (m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2)
4628 {
4629 if (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2"))
4630 {
4631 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
4632 }
4633 }
4634 }
4635
4636 private:
4637 TestParams m_params;
4638 };
4639
4640 class BlittingMipmaps : public CopiesAndBlittingTestInstance
4641 {
4642 public:
4643 BlittingMipmaps (Context& context,
4644 TestParams params);
4645 virtual tcu::TestStatus iterate (void);
4646 protected:
4647 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result = tcu::ConstPixelBufferAccess());
4648 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel = 0u);
4649 virtual void generateExpectedResult (void);
4650 private:
4651 bool checkNonNearestFilteredResult (void);
4652 bool checkNearestFilteredResult (void);
4653
4654 Move<VkImage> m_source;
4655 de::MovePtr<Allocation> m_sourceImageAlloc;
4656 Move<VkImage> m_destination;
4657 de::MovePtr<Allocation> m_destinationImageAlloc;
4658
4659 de::MovePtr<tcu::TextureLevel> m_unclampedExpectedTextureLevel[16];
4660 };
4661
BlittingMipmaps(Context & context,TestParams params)4662 BlittingMipmaps::BlittingMipmaps (Context& context, TestParams params)
4663 : CopiesAndBlittingTestInstance (context, params)
4664 {
4665 const InstanceInterface& vki = context.getInstanceInterface();
4666 const DeviceInterface& vk = context.getDeviceInterface();
4667 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
4668 const VkDevice vkDevice = context.getDevice();
4669 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
4670 Allocator& memAlloc = context.getDefaultAllocator();
4671
4672 // Create source image
4673 {
4674 const VkImageCreateInfo sourceImageParams =
4675 {
4676 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
4677 DE_NULL, // const void* pNext;
4678 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
4679 m_params.src.image.imageType, // VkImageType imageType;
4680 m_params.src.image.format, // VkFormat format;
4681 getExtent3D(m_params.src.image), // VkExtent3D extent;
4682 1u, // deUint32 mipLevels;
4683 getArraySize(m_params.src.image), // deUint32 arraySize;
4684 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
4685 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
4686 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4687 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
4688 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4689 1u, // deUint32 queueFamilyCount;
4690 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
4691 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4692 };
4693
4694 m_source = createImage(vk, vkDevice, &sourceImageParams);
4695 m_sourceImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_source, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4696 VK_CHECK(vk.bindImageMemory(vkDevice, *m_source, m_sourceImageAlloc->getMemory(), m_sourceImageAlloc->getOffset()));
4697 }
4698
4699 // Create destination image
4700 {
4701 const VkImageCreateInfo destinationImageParams =
4702 {
4703 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
4704 DE_NULL, // const void* pNext;
4705 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
4706 m_params.dst.image.imageType, // VkImageType imageType;
4707 m_params.dst.image.format, // VkFormat format;
4708 getExtent3D(m_params.dst.image), // VkExtent3D extent;
4709 m_params.mipLevels, // deUint32 mipLevels;
4710 getArraySize(m_params.dst.image), // deUint32 arraySize;
4711 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
4712 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
4713 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
4714 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
4715 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
4716 1u, // deUint32 queueFamilyCount;
4717 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
4718 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
4719 };
4720
4721 m_destination = createImage(vk, vkDevice, &destinationImageParams);
4722 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
4723 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
4724 }
4725 }
4726
iterate(void)4727 tcu::TestStatus BlittingMipmaps::iterate (void)
4728 {
4729 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
4730 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
4731 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
4732 m_params.src.image.extent.width,
4733 m_params.src.image.extent.height,
4734 m_params.src.image.extent.depth));
4735 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.src.image.extent.depth, m_params.src.image.fillMode);
4736 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
4737 (int)m_params.dst.image.extent.width,
4738 (int)m_params.dst.image.extent.height,
4739 (int)m_params.dst.image.extent.depth));
4740 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth, m_params.dst.image.fillMode);
4741 generateExpectedResult();
4742
4743 uploadImage(m_sourceTextureLevel->getAccess(), m_source.get(), m_params.src.image);
4744
4745 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, m_params.mipLevels);
4746
4747 const DeviceInterface& vk = m_context.getDeviceInterface();
4748 const VkDevice vkDevice = m_context.getDevice();
4749 const VkQueue queue = m_context.getUniversalQueue();
4750
4751 std::vector<VkImageBlit> regions;
4752 std::vector<VkImageBlit2KHR> regions2KHR;
4753 for (deUint32 i = 0; i < m_params.regions.size(); i++)
4754 {
4755 if (m_params.extensionUse == EXTENSION_USE_NONE)
4756 {
4757 regions.push_back(m_params.regions[i].imageBlit);
4758 }
4759 else
4760 {
4761 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4762 regions2KHR.push_back(convertvkImageBlitTovkImageBlit2KHR(m_params.regions[i].imageBlit));
4763 }
4764 }
4765
4766 // Copy source image to mip level 0 when generating mipmaps with multiple blit commands
4767 if (!m_params.singleCommand)
4768 uploadImage(m_sourceTextureLevel->getAccess(), m_destination.get(), m_params.dst.image, 1u);
4769
4770 beginCommandBuffer(vk, *m_cmdBuffer);
4771
4772 // Blit all mip levels with a single blit command
4773 if (m_params.singleCommand)
4774 {
4775 {
4776 // Source image layout
4777 const VkImageMemoryBarrier srcImageBarrier =
4778 {
4779 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4780 DE_NULL, // const void* pNext;
4781 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4782 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4783 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4784 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4785 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4786 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4787 m_source.get(), // VkImage image;
4788 { // VkImageSubresourceRange subresourceRange;
4789 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
4790 0u, // deUint32 baseMipLevel;
4791 1u, // deUint32 mipLevels;
4792 0u, // deUint32 baseArraySlice;
4793 getArraySize(m_params.src.image) // deUint32 arraySize;
4794 }
4795 };
4796
4797 // Destination image layout
4798 const VkImageMemoryBarrier dstImageBarrier =
4799 {
4800 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4801 DE_NULL, // const void* pNext;
4802 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4803 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4804 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4805 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
4806 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4807 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4808 m_destination.get(), // VkImage image;
4809 { // VkImageSubresourceRange subresourceRange;
4810 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4811 0u, // deUint32 baseMipLevel;
4812 m_params.mipLevels, // deUint32 mipLevels;
4813 0u, // deUint32 baseArraySlice;
4814 getArraySize(m_params.dst.image) // deUint32 arraySize;
4815 }
4816 };
4817
4818 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);
4819 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, &dstImageBarrier);
4820
4821 if (m_params.extensionUse == EXTENSION_USE_NONE)
4822 {
4823 vk.cmdBlitImage(*m_cmdBuffer, m_source.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), ®ions[0], m_params.filter);
4824 }
4825 else
4826 {
4827 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4828 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4829 {
4830 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
4831 DE_NULL, // const void* pNext;
4832 m_source.get(), // VkImage srcImage;
4833 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
4834 m_destination.get(), // VkImage dstImage;
4835 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
4836 (deUint32)m_params.regions.size(), // uint32_t regionCount;
4837 ®ions2KHR[0], // const VkImageBlit2KHR* pRegions;
4838 m_params.filter // VkFilter filter;
4839 };
4840 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4841 }
4842 }
4843 }
4844 // Blit mip levels with multiple blit commands
4845 else
4846 {
4847 // Prepare all mip levels for reading
4848 {
4849 for (deUint32 barrierno = 0; barrierno < m_params.barrierCount; barrierno++)
4850 {
4851 VkImageMemoryBarrier preImageBarrier =
4852 {
4853 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4854 DE_NULL, // const void* pNext;
4855 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4856 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4857 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
4858 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4859 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4860 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4861 m_destination.get(), // VkImage image;
4862 { // VkImageSubresourceRange subresourceRange;
4863 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4864 0u, // deUint32 baseMipLevel;
4865 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels;
4866 0u, // deUint32 baseArraySlice;
4867 getArraySize(m_params.src.image) // deUint32 arraySize;
4868 }
4869 };
4870
4871 if (getArraySize(m_params.src.image) == 1)
4872 {
4873 DE_ASSERT(barrierno < m_params.mipLevels);
4874 preImageBarrier.subresourceRange.baseMipLevel = barrierno;
4875 preImageBarrier.subresourceRange.levelCount = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_MIP_LEVELS;
4876 }
4877 else
4878 {
4879 preImageBarrier.subresourceRange.baseArrayLayer = barrierno;
4880 preImageBarrier.subresourceRange.layerCount = (barrierno + 1 < m_params.barrierCount) ? 1 : VK_REMAINING_ARRAY_LAYERS;
4881 }
4882 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, &preImageBarrier);
4883 }
4884 }
4885
4886 for (deUint32 regionNdx = 0u; regionNdx < (deUint32)m_params.regions.size(); regionNdx++)
4887 {
4888 const deUint32 mipLevel = m_params.regions[regionNdx].imageBlit.dstSubresource.mipLevel;
4889
4890 // Prepare single mip level for writing
4891 const VkImageMemoryBarrier preImageBarrier =
4892 {
4893 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4894 DE_NULL, // const void* pNext;
4895 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
4896 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4897 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
4898 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
4899 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4900 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4901 m_destination.get(), // VkImage image;
4902 { // VkImageSubresourceRange subresourceRange;
4903 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4904 mipLevel, // deUint32 baseMipLevel;
4905 1u, // deUint32 mipLevels;
4906 0u, // deUint32 baseArraySlice;
4907 getArraySize(m_params.dst.image) // deUint32 arraySize;
4908 }
4909 };
4910
4911 // Prepare single mip level for reading
4912 const VkImageMemoryBarrier postImageBarrier =
4913 {
4914 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4915 DE_NULL, // const void* pNext;
4916 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
4917 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
4918 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
4919 m_params.src.image.operationLayout, // VkImageLayout newLayout;
4920 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4921 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4922 m_destination.get(), // VkImage image;
4923 { // VkImageSubresourceRange subresourceRange;
4924 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4925 mipLevel, // deUint32 baseMipLevel;
4926 1u, // deUint32 mipLevels;
4927 0u, // deUint32 baseArraySlice;
4928 getArraySize(m_params.src.image) // deUint32 arraySize;
4929 }
4930 };
4931
4932 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, &preImageBarrier);
4933
4934 if (m_params.extensionUse == EXTENSION_USE_NONE)
4935 {
4936 vk.cmdBlitImage(*m_cmdBuffer, m_destination.get(), m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, 1u, ®ions[regionNdx], m_params.filter);
4937 }
4938 else
4939 {
4940 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
4941 const VkBlitImageInfo2KHR BlitImageInfo2KHR =
4942 {
4943 VK_STRUCTURE_TYPE_BLIT_IMAGE_INFO_2_KHR, // VkStructureType sType;
4944 DE_NULL, // const void* pNext;
4945 m_destination.get(), // VkImage srcImage;
4946 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
4947 m_destination.get(), // VkImage dstImage;
4948 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
4949 1u, // uint32_t regionCount;
4950 ®ions2KHR[regionNdx], // const VkImageBlit2KHR* pRegions;
4951 m_params.filter // VkFilter filter;
4952 };
4953 vk.cmdBlitImage2KHR(*m_cmdBuffer, &BlitImageInfo2KHR);
4954 }
4955
4956 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, &postImageBarrier);
4957 }
4958
4959 // Prepare all mip levels for writing
4960 {
4961 const VkImageMemoryBarrier postImageBarrier =
4962 {
4963 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
4964 DE_NULL, // const void* pNext;
4965 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags srcAccessMask;
4966 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
4967 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
4968 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
4969 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
4970 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
4971 m_destination.get(), // VkImage image;
4972 { // VkImageSubresourceRange subresourceRange;
4973 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
4974 0u, // deUint32 baseMipLevel;
4975 VK_REMAINING_MIP_LEVELS, // deUint32 mipLevels;
4976 0u, // deUint32 baseArraySlice;
4977 getArraySize(m_params.dst.image) // deUint32 arraySize;
4978 }
4979 };
4980
4981 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, &postImageBarrier);
4982 }
4983 }
4984
4985 endCommandBuffer(vk, *m_cmdBuffer);
4986 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
4987
4988 return checkTestResult();
4989 }
4990
checkNonNearestFilteredResult(void)4991 bool BlittingMipmaps::checkNonNearestFilteredResult (void)
4992 {
4993 tcu::TestLog& log (m_context.getTestContext().getLog());
4994 bool allLevelsOk = true;
4995
4996 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
4997 {
4998 // Update reference results with previous results that have been verified.
4999 // This needs to be done such that accumulated errors don't exceed the fixed threshold.
5000 for (deUint32 i = 0; i < m_params.regions.size(); i++)
5001 {
5002 const CopyRegion region = m_params.regions[i];
5003 const deUint32 srcMipLevel = m_params.regions[i].imageBlit.srcSubresource.mipLevel;
5004 const deUint32 dstMipLevel = m_params.regions[i].imageBlit.dstSubresource.mipLevel;
5005 de::MovePtr<tcu::TextureLevel> prevResultLevel;
5006 tcu::ConstPixelBufferAccess src;
5007 if (srcMipLevel < mipLevelNdx)
5008 {
5009 // Generate expected result from rendered result that was previously verified
5010 prevResultLevel = readImage(*m_destination, m_params.dst.image, srcMipLevel);
5011 src = prevResultLevel->getAccess();
5012 }
5013 else
5014 {
5015 // Previous reference mipmaps might have changed, so recompute expected result
5016 src = m_expectedTextureLevel[srcMipLevel]->getAccess();
5017 }
5018 copyRegionToTextureLevel(src, m_expectedTextureLevel[dstMipLevel]->getAccess(), region, dstMipLevel);
5019 }
5020
5021 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5022 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess();
5023
5024 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5025 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5026 tcu::Sampler::MODE_LAST;
5027 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5028 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5029 resultAccess;
5030 const tcu::ConstPixelBufferAccess clampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5031 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5032 m_expectedTextureLevel[mipLevelNdx]->getAccess();
5033 const tcu::ConstPixelBufferAccess unclampedLevel = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5034 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess(), mode) :
5035 m_unclampedExpectedTextureLevel[mipLevelNdx]->getAccess();
5036 const tcu::TextureFormat srcFormat = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5037 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilTextureFormat(mapVkFormat(m_params.src.image.format), mode) :
5038 mapVkFormat(m_params.src.image.format);
5039
5040 const tcu::TextureFormat dstFormat = result.getFormat();
5041 bool singleLevelOk = false;
5042 std::vector <CopyRegion> mipLevelRegions;
5043
5044 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5045 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5046 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5047
5048 log << tcu::TestLog::Section("ClampedSourceImage", "Region with clamped edges on source image.");
5049
5050 if (isFloatFormat(dstFormat))
5051 {
5052 const bool srcIsSRGB = tcu::isSRGB(srcFormat);
5053 const tcu::Vec4 srcMaxDiff = getFormatThreshold(srcFormat) * tcu::Vec4(srcIsSRGB ? 2.0f : 1.0f);
5054 const tcu::Vec4 dstMaxDiff = getFormatThreshold(dstFormat);
5055 const tcu::Vec4 threshold = ( srcMaxDiff + dstMaxDiff ) * ((m_params.filter == VK_FILTER_CUBIC_EXT)? 1.5f : 1.0f);
5056
5057 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5058 log << tcu::TestLog::EndSection;
5059
5060 if (!singleLevelOk)
5061 {
5062 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5063 singleLevelOk = tcu::floatThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5064 log << tcu::TestLog::EndSection;
5065 }
5066 }
5067 else
5068 {
5069 tcu::UVec4 threshold;
5070 // Calculate threshold depending on channel width of destination format.
5071 const tcu::IVec4 dstBitDepth = tcu::getTextureFormatBitDepth(dstFormat);
5072 const tcu::IVec4 srcBitDepth = tcu::getTextureFormatBitDepth(srcFormat);
5073 for (deUint32 i = 0; i < 4; ++i)
5074 threshold[i] = 1 + de::max(((1 << dstBitDepth[i]) - 1) / de::clamp((1 << srcBitDepth[i]) - 1, 1, 256), 1);
5075
5076 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", clampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5077 log << tcu::TestLog::EndSection;
5078
5079 if (!singleLevelOk)
5080 {
5081 log << tcu::TestLog::Section("NonClampedSourceImage", "Region with non-clamped edges on source image.");
5082 singleLevelOk = tcu::intThresholdCompare(log, "Compare", "Result comparsion", unclampedLevel, result, threshold, tcu::COMPARE_LOG_RESULT);
5083 log << tcu::TestLog::EndSection;
5084 }
5085 }
5086 allLevelsOk &= singleLevelOk;
5087 }
5088
5089 return allLevelsOk;
5090 }
5091
checkNearestFilteredResult(void)5092 bool BlittingMipmaps::checkNearestFilteredResult (void)
5093 {
5094 bool allLevelsOk = true;
5095 tcu::TestLog& log (m_context.getTestContext().getLog());
5096
5097 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5098 {
5099 de::MovePtr<tcu::TextureLevel> resultLevel = readImage(*m_destination, m_params.dst.image, mipLevelNdx);
5100 const tcu::ConstPixelBufferAccess& resultAccess = resultLevel->getAccess();
5101
5102 const tcu::Sampler::DepthStencilMode mode = tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_DEPTH :
5103 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::Sampler::MODE_STENCIL :
5104 tcu::Sampler::MODE_LAST;
5105 const tcu::ConstPixelBufferAccess result = tcu::hasDepthComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5106 tcu::hasStencilComponent(resultAccess.getFormat().order) ? getEffectiveDepthStencilAccess(resultAccess, mode) :
5107 resultAccess;
5108 const tcu::ConstPixelBufferAccess source = (m_params.singleCommand || mipLevelNdx == 0) ? // Read from source image
5109 tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5110 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_sourceTextureLevel->getAccess(), mode) :
5111 m_sourceTextureLevel->getAccess()
5112 // Read from destination image
5113 : tcu::hasDepthComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5114 tcu::hasStencilComponent(resultAccess.getFormat().order) ? tcu::getEffectiveDepthStencilAccess(m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess(), mode) :
5115 m_expectedTextureLevel[mipLevelNdx - 1u]->getAccess();
5116 const tcu::TextureFormat dstFormat = result.getFormat();
5117 const tcu::TextureChannelClass dstChannelClass = tcu::getTextureChannelClass(dstFormat.type);
5118 bool singleLevelOk = false;
5119 std::vector <CopyRegion> mipLevelRegions;
5120
5121 for (size_t regionNdx = 0u; regionNdx < m_params.regions.size(); regionNdx++)
5122 if (m_params.regions.at(regionNdx).imageBlit.dstSubresource.mipLevel == mipLevelNdx)
5123 mipLevelRegions.push_back(m_params.regions.at(regionNdx));
5124
5125 tcu::TextureLevel errorMaskStorage (tcu::TextureFormat(tcu::TextureFormat::RGB, tcu::TextureFormat::UNORM_INT8), result.getWidth(), result.getHeight(), result.getDepth());
5126 tcu::PixelBufferAccess errorMask = errorMaskStorage.getAccess();
5127 tcu::Vec4 pixelBias (0.0f, 0.0f, 0.0f, 0.0f);
5128 tcu::Vec4 pixelScale (1.0f, 1.0f, 1.0f, 1.0f);
5129
5130 tcu::clear(errorMask, tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0));
5131
5132 if (dstChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ||
5133 dstChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
5134 {
5135 singleLevelOk = intNearestBlitCompare(source, result, errorMask, mipLevelRegions);
5136 }
5137 else
5138 {
5139 const tcu::Vec4 srcMaxDiff = getFloatOrFixedPointFormatThreshold(source.getFormat());
5140 const tcu::Vec4 dstMaxDiff = getFloatOrFixedPointFormatThreshold(result.getFormat());
5141
5142 singleLevelOk = floatNearestBlitCompare(source, result, srcMaxDiff, dstMaxDiff, errorMask, mipLevelRegions);
5143 }
5144
5145 if (dstFormat != tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
5146 tcu::computePixelScaleBias(result, pixelScale, pixelBias);
5147
5148 if (!singleLevelOk)
5149 {
5150 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5151 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5152 << tcu::TestLog::Image("Reference", "Reference", source, pixelScale, pixelBias)
5153 << tcu::TestLog::Image("ErrorMask", "Error mask", errorMask)
5154 << tcu::TestLog::EndImageSet;
5155 }
5156 else
5157 {
5158 log << tcu::TestLog::ImageSet("Compare", "Result comparsion, level " + de::toString(mipLevelNdx))
5159 << tcu::TestLog::Image("Result", "Result", result, pixelScale, pixelBias)
5160 << tcu::TestLog::EndImageSet;
5161 }
5162
5163 allLevelsOk &= singleLevelOk;
5164 }
5165
5166 return allLevelsOk;
5167 }
5168
checkTestResult(tcu::ConstPixelBufferAccess result)5169 tcu::TestStatus BlittingMipmaps::checkTestResult (tcu::ConstPixelBufferAccess result)
5170 {
5171 DE_UNREF(result);
5172 DE_ASSERT(m_params.filter == VK_FILTER_NEAREST || m_params.filter == VK_FILTER_LINEAR || m_params.filter == VK_FILTER_CUBIC_EXT);
5173 const std::string failMessage("Result image is incorrect");
5174
5175 if (m_params.filter != VK_FILTER_NEAREST)
5176 {
5177 if (!checkNonNearestFilteredResult())
5178 return tcu::TestStatus::fail(failMessage);
5179 }
5180 else // NEAREST filtering
5181 {
5182 if (!checkNearestFilteredResult())
5183 return tcu::TestStatus::fail(failMessage);
5184 }
5185
5186 return tcu::TestStatus::pass("Pass");
5187 }
5188
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)5189 void BlittingMipmaps::copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
5190 {
5191 DE_ASSERT(src.getDepth() == dst.getDepth());
5192
5193 const MirrorMode mirrorMode = getMirrorMode(region.imageBlit.srcOffsets[0],
5194 region.imageBlit.srcOffsets[1],
5195 region.imageBlit.dstOffsets[0],
5196 region.imageBlit.dstOffsets[1]);
5197
5198 flipCoordinates(region, mirrorMode);
5199
5200 const VkOffset3D srcOffset = region.imageBlit.srcOffsets[0];
5201 const VkOffset3D srcExtent =
5202 {
5203 region.imageBlit.srcOffsets[1].x - srcOffset.x,
5204 region.imageBlit.srcOffsets[1].y - srcOffset.y,
5205 region.imageBlit.srcOffsets[1].z - srcOffset.z
5206 };
5207 const VkOffset3D dstOffset = region.imageBlit.dstOffsets[0];
5208 const VkOffset3D dstExtent =
5209 {
5210 region.imageBlit.dstOffsets[1].x - dstOffset.x,
5211 region.imageBlit.dstOffsets[1].y - dstOffset.y,
5212 region.imageBlit.dstOffsets[1].z - dstOffset.z
5213 };
5214
5215 tcu::Sampler::FilterMode filter;
5216 switch (m_params.filter)
5217 {
5218 case VK_FILTER_LINEAR: filter = tcu::Sampler::LINEAR; break;
5219 case VK_FILTER_CUBIC_EXT: filter = tcu::Sampler::CUBIC; break;
5220 case VK_FILTER_NEAREST:
5221 default: filter = tcu::Sampler::NEAREST; break;
5222 }
5223
5224 if (tcu::isCombinedDepthStencilType(src.getFormat().type))
5225 {
5226 DE_ASSERT(src.getFormat() == dst.getFormat());
5227 // Scale depth.
5228 if (tcu::hasDepthComponent(src.getFormat().order))
5229 {
5230 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_DEPTH);
5231 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5232 tcu::scale(dstSubRegion, srcSubRegion, filter);
5233
5234 if (filter != tcu::Sampler::NEAREST)
5235 {
5236 const tcu::ConstPixelBufferAccess depthSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_DEPTH);
5237 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_DEPTH);
5238 scaleFromWholeSrcBuffer(unclampedSubRegion, depthSrc, srcOffset, srcExtent, filter);
5239 }
5240 }
5241
5242 // Scale stencil.
5243 if (tcu::hasStencilComponent(src.getFormat().order))
5244 {
5245 const tcu::ConstPixelBufferAccess srcSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(src, srcOffset.x, srcOffset.y, srcExtent.x, srcExtent.y), tcu::Sampler::MODE_STENCIL);
5246 const tcu::PixelBufferAccess dstSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(dst, dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5247 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5248
5249 if (filter != tcu::Sampler::NEAREST)
5250 {
5251 const tcu::ConstPixelBufferAccess stencilSrc = getEffectiveDepthStencilAccess(src, tcu::Sampler::MODE_STENCIL);
5252 const tcu::PixelBufferAccess unclampedSubRegion = getEffectiveDepthStencilAccess(tcu::getSubregion(m_unclampedExpectedTextureLevel[0]->getAccess(), dstOffset.x, dstOffset.y, dstExtent.x, dstExtent.y), tcu::Sampler::MODE_STENCIL);
5253 scaleFromWholeSrcBuffer(unclampedSubRegion, stencilSrc, srcOffset, srcExtent, filter);
5254 }
5255 }
5256 }
5257 else
5258 {
5259 for (int layerNdx = 0u; layerNdx < src.getDepth(); layerNdx++)
5260 {
5261 const tcu::ConstPixelBufferAccess srcSubRegion = tcu::getSubregion(src, srcOffset.x, srcOffset.y, layerNdx, srcExtent.x, srcExtent.y, 1);
5262 const tcu::PixelBufferAccess dstSubRegion = tcu::getSubregion(dst, dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5263 blit(dstSubRegion, srcSubRegion, filter, mirrorMode);
5264
5265 if (filter != tcu::Sampler::NEAREST)
5266 {
5267 const tcu::PixelBufferAccess unclampedSubRegion = tcu::getSubregion(m_unclampedExpectedTextureLevel[mipLevel]->getAccess(), dstOffset.x, dstOffset.y, layerNdx, dstExtent.x, dstExtent.y, 1);
5268 scaleFromWholeSrcBuffer(unclampedSubRegion, srcSubRegion, srcOffset, srcExtent, filter);
5269 }
5270 }
5271 }
5272 }
5273
generateExpectedResult(void)5274 void BlittingMipmaps::generateExpectedResult (void)
5275 {
5276 const tcu::ConstPixelBufferAccess src = m_sourceTextureLevel->getAccess();
5277 const tcu::ConstPixelBufferAccess dst = m_destinationTextureLevel->getAccess();
5278
5279 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5280 m_expectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5281
5282 tcu::copy(m_expectedTextureLevel[0]->getAccess(), src);
5283
5284 if (m_params.filter != VK_FILTER_NEAREST)
5285 {
5286 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < m_params.mipLevels; mipLevelNdx++)
5287 m_unclampedExpectedTextureLevel[mipLevelNdx] = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dst.getFormat(), dst.getWidth() >> mipLevelNdx, dst.getHeight() >> mipLevelNdx, dst.getDepth()));
5288
5289 tcu::copy(m_unclampedExpectedTextureLevel[0]->getAccess(), src);
5290 }
5291
5292 for (deUint32 i = 0; i < m_params.regions.size(); i++)
5293 {
5294 CopyRegion region = m_params.regions[i];
5295 copyRegionToTextureLevel(m_expectedTextureLevel[m_params.regions[i].imageBlit.srcSubresource.mipLevel]->getAccess(), m_expectedTextureLevel[m_params.regions[i].imageBlit.dstSubresource.mipLevel]->getAccess(), region, m_params.regions[i].imageBlit.dstSubresource.mipLevel);
5296 }
5297 }
5298
5299 class BlitMipmapTestCase : public vkt::TestCase
5300 {
5301 public:
BlitMipmapTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params)5302 BlitMipmapTestCase (tcu::TestContext& testCtx,
5303 const std::string& name,
5304 const std::string& description,
5305 const TestParams params)
5306 : vkt::TestCase (testCtx, name, description)
5307 , m_params (params)
5308 {}
5309
createInstance(Context & context) const5310 virtual TestInstance* createInstance (Context& context) const
5311 {
5312 return new BlittingMipmaps(context, m_params);
5313 }
5314
checkSupport(Context & context) const5315 virtual void checkSupport (Context& context) const
5316 {
5317 const InstanceInterface& vki = context.getInstanceInterface();
5318 const VkPhysicalDevice vkPhysDevice = context.getPhysicalDevice();
5319 {
5320 VkImageFormatProperties properties;
5321 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5322 m_params.src.image.format,
5323 VK_IMAGE_TYPE_2D,
5324 VK_IMAGE_TILING_OPTIMAL,
5325 VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
5326 0,
5327 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5328 {
5329 TCU_THROW(NotSupportedError, "Format not supported");
5330 }
5331 else if ((m_params.src.image.extent.width > properties.maxExtent.width) ||
5332 (m_params.src.image.extent.height > properties.maxExtent.height) ||
5333 (m_params.src.image.extent.depth > properties.maxArrayLayers))
5334 {
5335 TCU_THROW(NotSupportedError, "Image size not supported");
5336 }
5337 }
5338
5339 {
5340 VkImageFormatProperties properties;
5341 if (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
5342 m_params.dst.image.format,
5343 VK_IMAGE_TYPE_2D,
5344 VK_IMAGE_TILING_OPTIMAL,
5345 VK_IMAGE_USAGE_TRANSFER_DST_BIT,
5346 0,
5347 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
5348 {
5349 TCU_THROW(NotSupportedError, "Format not supported");
5350 }
5351 else if ((m_params.dst.image.extent.width > properties.maxExtent.width) ||
5352 (m_params.dst.image.extent.height > properties.maxExtent.height) ||
5353 (m_params.dst.image.extent.depth > properties.maxArrayLayers))
5354 {
5355 TCU_THROW(NotSupportedError, "Image size not supported");
5356 }
5357 else if (m_params.mipLevels > properties.maxMipLevels)
5358 {
5359 TCU_THROW(NotSupportedError, "Number of mip levels not supported");
5360 }
5361 else if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
5362 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
5363 {
5364 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
5365 }
5366 }
5367
5368 const VkFormatProperties srcFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.src.image.format);
5369 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_SRC_BIT))
5370 {
5371 TCU_THROW(NotSupportedError, "Format feature blit source not supported");
5372 }
5373
5374 const VkFormatProperties dstFormatProperties = getPhysicalDeviceFormatProperties (vki, vkPhysDevice, m_params.dst.image.format);
5375 if (!(dstFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_BLIT_DST_BIT))
5376 {
5377 TCU_THROW(NotSupportedError, "Format feature blit destination not supported");
5378 }
5379
5380 if (m_params.filter == VK_FILTER_LINEAR && !(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT))
5381 TCU_THROW(NotSupportedError, "Source format feature sampled image filter linear not supported");
5382
5383 if (m_params.filter == VK_FILTER_CUBIC_EXT)
5384 {
5385 context.requireDeviceFunctionality("VK_EXT_filter_cubic");
5386
5387 if (!(srcFormatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_CUBIC_BIT_EXT))
5388 {
5389 TCU_THROW(NotSupportedError, "Source format feature sampled image filter cubic not supported");
5390 }
5391 }
5392 }
5393
5394 private:
5395 TestParams m_params;
5396 };
5397
5398 // Resolve image to image.
5399
5400 enum ResolveImageToImageOptions{NO_OPTIONAL_OPERATION,
5401 COPY_MS_IMAGE_TO_MS_IMAGE,
5402 COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE,
5403 COPY_MS_IMAGE_LAYER_TO_MS_IMAGE,
5404 COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION,
5405 COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB};
5406 class ResolveImageToImage : public CopiesAndBlittingTestInstance
5407 {
5408 public:
5409 ResolveImageToImage (Context& context,
5410 TestParams params,
5411 const ResolveImageToImageOptions options);
5412 virtual tcu::TestStatus iterate (void);
shouldVerifyIntermediateResults(ResolveImageToImageOptions option)5413 static inline bool shouldVerifyIntermediateResults (ResolveImageToImageOptions option)
5414 {
5415 return option == COPY_MS_IMAGE_TO_MS_IMAGE || option == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || option == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE;
5416 }
5417 protected:
5418 virtual tcu::TestStatus checkTestResult (tcu::ConstPixelBufferAccess result);
5419 void copyMSImageToMSImage (deUint32 copyArraySize);
5420 tcu::TestStatus checkIntermediateCopy (void);
5421 private:
5422 Move<VkImage> m_multisampledImage;
5423 de::MovePtr<Allocation> m_multisampledImageAlloc;
5424
5425 Move<VkImage> m_destination;
5426 de::MovePtr<Allocation> m_destinationImageAlloc;
5427
5428 Move<VkImage> m_multisampledCopyImage;
5429 de::MovePtr<Allocation> m_multisampledCopyImageAlloc;
5430 Move<VkImage> m_multisampledCopyNoCabImage;
5431 de::MovePtr<Allocation> m_multisampledCopyImageNoCabAlloc;
5432
5433 const ResolveImageToImageOptions m_options;
5434
5435 virtual void copyRegionToTextureLevel (tcu::ConstPixelBufferAccess src,
5436 tcu::PixelBufferAccess dst,
5437 CopyRegion region,
5438 deUint32 mipLevel = 0u);
5439 };
5440
ResolveImageToImage(Context & context,TestParams params,const ResolveImageToImageOptions options)5441 ResolveImageToImage::ResolveImageToImage (Context& context, TestParams params, const ResolveImageToImageOptions options)
5442 : CopiesAndBlittingTestInstance (context, params)
5443 , m_options (options)
5444 {
5445 const InstanceInterface& vki = m_context.getInstanceInterface();
5446 const DeviceInterface& vk = m_context.getDeviceInterface();
5447 const VkPhysicalDevice vkPhysDevice = m_context.getPhysicalDevice();
5448 const VkDevice vkDevice = m_context.getDevice();
5449 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
5450 Allocator& memAlloc = m_context.getDefaultAllocator();
5451
5452 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
5453 Move<VkRenderPass> renderPass;
5454
5455 Move<VkShaderModule> vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0);
5456 Move<VkShaderModule> fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0);
5457 std::vector<tcu::Vec4> vertices;
5458
5459 Move<VkBuffer> vertexBuffer;
5460 de::MovePtr<Allocation> vertexBufferAlloc;
5461
5462 Move<VkPipelineLayout> pipelineLayout;
5463 Move<VkPipeline> graphicsPipeline;
5464
5465 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
5466
5467 // Create color image.
5468 {
5469 VkImageCreateInfo colorImageParams =
5470 {
5471 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5472 DE_NULL, // const void* pNext;
5473 getCreateFlags(m_params.src.image), // VkImageCreateFlags flags;
5474 m_params.src.image.imageType, // VkImageType imageType;
5475 m_params.src.image.format, // VkFormat format;
5476 getExtent3D(m_params.src.image), // VkExtent3D extent;
5477 1u, // deUint32 mipLevels;
5478 getArraySize(m_params.src.image), // deUint32 arrayLayers;
5479 rasterizationSamples, // VkSampleCountFlagBits samples;
5480 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5481 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT // VkImageUsageFlags usage;
5482 | VK_IMAGE_USAGE_TRANSFER_SRC_BIT
5483 | VK_IMAGE_USAGE_TRANSFER_DST_BIT
5484 | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
5485 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5486 1u, // deUint32 queueFamilyIndexCount;
5487 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
5488 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5489 };
5490
5491 m_multisampledImage = createImage(vk, vkDevice, &colorImageParams);
5492
5493 // Allocate and bind color image memory.
5494 m_multisampledImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5495 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledImage, m_multisampledImageAlloc->getMemory(), m_multisampledImageAlloc->getOffset()));
5496
5497 switch (m_options)
5498 {
5499 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5500 case COPY_MS_IMAGE_TO_MS_IMAGE:
5501 {
5502 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5503 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5504 // Allocate and bind color image memory.
5505 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5506 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5507 break;
5508 }
5509 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5510 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5511 {
5512 colorImageParams.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5513 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
5514 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5515 // Allocate and bind color image memory.
5516 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5517 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5518 break;
5519 }
5520 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5521 {
5522 colorImageParams.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
5523 colorImageParams.arrayLayers = getArraySize(m_params.dst.image);
5524 m_multisampledCopyImage = createImage(vk, vkDevice, &colorImageParams);
5525 m_multisampledCopyNoCabImage = createImage(vk, vkDevice, &colorImageParams);
5526 // Allocate and bind color image memory.
5527 m_multisampledCopyImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5528 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyImage, m_multisampledCopyImageAlloc->getMemory(), m_multisampledCopyImageAlloc->getOffset()));
5529 m_multisampledCopyImageNoCabAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_multisampledCopyNoCabImage, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5530 VK_CHECK(vk.bindImageMemory(vkDevice, *m_multisampledCopyNoCabImage, m_multisampledCopyImageNoCabAlloc->getMemory(), m_multisampledCopyImageNoCabAlloc->getOffset()));
5531 break;
5532 }
5533
5534 default :
5535 break;
5536 }
5537 }
5538
5539 // Create destination image.
5540 {
5541 const VkImageCreateInfo destinationImageParams =
5542 {
5543 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
5544 DE_NULL, // const void* pNext;
5545 getCreateFlags(m_params.dst.image), // VkImageCreateFlags flags;
5546 m_params.dst.image.imageType, // VkImageType imageType;
5547 m_params.dst.image.format, // VkFormat format;
5548 getExtent3D(m_params.dst.image), // VkExtent3D extent;
5549 1u, // deUint32 mipLevels;
5550 getArraySize(m_params.dst.image), // deUint32 arraySize;
5551 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
5552 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
5553 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
5554 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
5555 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5556 1u, // deUint32 queueFamilyCount;
5557 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
5558 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
5559 };
5560
5561 m_destination = createImage(vk, vkDevice, &destinationImageParams);
5562 m_destinationImageAlloc = allocateImage(vki, vk, vkPhysDevice, vkDevice, *m_destination, MemoryRequirement::Any, memAlloc, m_params.allocationKind);
5563 VK_CHECK(vk.bindImageMemory(vkDevice, *m_destination, m_destinationImageAlloc->getMemory(), m_destinationImageAlloc->getOffset()));
5564 }
5565
5566 // Barriers for image clearing.
5567 std::vector<VkImageMemoryBarrier> srcImageBarriers;
5568
5569 const VkImageMemoryBarrier m_multisampledImageBarrier =
5570 {
5571 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5572 DE_NULL, // const void* pNext;
5573 0u, // VkAccessFlags srcAccessMask;
5574 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
5575 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5576 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5577 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5578 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5579 m_multisampledImage.get(), // VkImage image;
5580 { // VkImageSubresourceRange subresourceRange;
5581 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5582 0u, // deUint32 baseMipLevel;
5583 1u, // deUint32 mipLevels;
5584 0u, // deUint32 baseArraySlice;
5585 getArraySize(m_params.src.image) // deUint32 arraySize;
5586 }
5587 };
5588 const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
5589 {
5590 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5591 DE_NULL, // const void* pNext;
5592 0u, // VkAccessFlags srcAccessMask;
5593 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
5594 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5595 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5596 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5597 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5598 m_multisampledCopyImage.get(), // VkImage image;
5599 { // VkImageSubresourceRange subresourceRange;
5600 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5601 0u, // deUint32 baseMipLevel;
5602 1u, // deUint32 mipLevels;
5603 0u, // deUint32 baseArraySlice;
5604 getArraySize(m_params.dst.image) // deUint32 arraySize;
5605 }
5606 };
5607 const VkImageMemoryBarrier m_multisampledCopyImageNoCabBarrier =
5608 {
5609 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5610 DE_NULL, // const void* pNext;
5611 0u, // VkAccessFlags srcAccessMask;
5612 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
5613 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
5614 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
5615 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5616 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5617 m_multisampledCopyNoCabImage.get(), // VkImage image;
5618 { // VkImageSubresourceRange subresourceRange;
5619 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
5620 0u, // deUint32 baseMipLevel;
5621 1u, // deUint32 mipLevels;
5622 0u, // deUint32 baseArraySlice;
5623 getArraySize(m_params.dst.image) // deUint32 arraySize;
5624 }
5625 };
5626
5627 // Only use one barrier if no options have been given.
5628 if (m_options != DE_NULL)
5629 {
5630 srcImageBarriers.push_back(m_multisampledImageBarrier);
5631 srcImageBarriers.push_back(m_multisampledCopyImageBarrier);
5632 // Add the third barrier if option is as below.
5633 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
5634 srcImageBarriers.push_back(m_multisampledCopyImageNoCabBarrier);
5635 }
5636 else
5637 {
5638 srcImageBarriers.push_back(m_multisampledImageBarrier);
5639 }
5640
5641 // Create render pass.
5642 {
5643 const VkAttachmentDescription attachmentDescriptions[1] =
5644 {
5645 {
5646 0u, // VkAttachmentDescriptionFlags flags;
5647 m_params.src.image.format, // VkFormat format;
5648 rasterizationSamples, // VkSampleCountFlagBits samples;
5649 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
5650 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
5651 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
5652 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
5653 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout initialLayout;
5654 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL // VkImageLayout finalLayout;
5655 },
5656 };
5657
5658 const VkAttachmentReference colorAttachmentReference =
5659 {
5660 0u, // deUint32 attachment;
5661 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
5662 };
5663
5664 const VkSubpassDescription subpassDescription =
5665 {
5666 0u, // VkSubpassDescriptionFlags flags;
5667 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
5668 0u, // deUint32 inputAttachmentCount;
5669 DE_NULL, // const VkAttachmentReference* pInputAttachments;
5670 1u, // deUint32 colorAttachmentCount;
5671 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
5672 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
5673 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
5674 0u, // deUint32 preserveAttachmentCount;
5675 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
5676 };
5677
5678 const VkRenderPassCreateInfo renderPassParams =
5679 {
5680 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
5681 DE_NULL, // const void* pNext;
5682 0u, // VkRenderPassCreateFlags flags;
5683 1u, // deUint32 attachmentCount;
5684 attachmentDescriptions, // const VkAttachmentDescription* pAttachments;
5685 1u, // deUint32 subpassCount;
5686 &subpassDescription, // const VkSubpassDescription* pSubpasses;
5687 0u, // deUint32 dependencyCount;
5688 DE_NULL // const VkSubpassDependency* pDependencies;
5689 };
5690
5691 renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
5692 }
5693
5694 // Create pipeline layout
5695 {
5696 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
5697 {
5698 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
5699 DE_NULL, // const void* pNext;
5700 0u, // VkPipelineLayoutCreateFlags flags;
5701 0u, // deUint32 setLayoutCount;
5702 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
5703 0u, // deUint32 pushConstantRangeCount;
5704 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
5705 };
5706
5707 pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
5708 }
5709
5710 // Create upper half triangle.
5711 {
5712 const tcu::Vec4 a (-1.0, -1.0, 0.0, 1.0);
5713 const tcu::Vec4 b (1.0, -1.0, 0.0, 1.0);
5714 const tcu::Vec4 c (1.0, 1.0, 0.0, 1.0);
5715 // Add triangle.
5716 vertices.push_back(a);
5717 vertices.push_back(c);
5718 vertices.push_back(b);
5719 }
5720
5721 // Create vertex buffer.
5722 {
5723 const VkDeviceSize vertexDataSize = vertices.size() * sizeof(tcu::Vec4);
5724 const VkBufferCreateInfo vertexBufferParams =
5725 {
5726 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
5727 DE_NULL, // const void* pNext;
5728 0u, // VkBufferCreateFlags flags;
5729 vertexDataSize, // VkDeviceSize size;
5730 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
5731 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
5732 1u, // deUint32 queueFamilyIndexCount;
5733 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
5734 };
5735
5736 vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
5737 vertexBufferAlloc = allocateBuffer(vki, vk, vkPhysDevice, vkDevice, *vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_params.allocationKind);
5738 VK_CHECK(vk.bindBufferMemory(vkDevice, *vertexBuffer, vertexBufferAlloc->getMemory(), vertexBufferAlloc->getOffset()));
5739
5740 // Load vertices into vertex buffer.
5741 deMemcpy(vertexBufferAlloc->getHostPtr(), vertices.data(), (size_t)vertexDataSize);
5742 flushAlloc(vk, vkDevice, *vertexBufferAlloc);
5743 }
5744
5745 {
5746 Move<VkFramebuffer> framebuffer;
5747 Move<VkImageView> sourceAttachmentView;
5748
5749 uint32_t baseArrayLayer = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : 0u;
5750
5751 // Create color attachment view.
5752 {
5753 const VkImageViewCreateInfo colorAttachmentViewParams =
5754 {
5755 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
5756 DE_NULL, // const void* pNext;
5757 0u, // VkImageViewCreateFlags flags;
5758 *m_multisampledImage, // VkImage image;
5759 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
5760 m_params.src.image.format, // VkFormat format;
5761 componentMappingRGBA, // VkComponentMapping components;
5762 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, baseArrayLayer, 1u } // VkImageSubresourceRange subresourceRange;
5763 };
5764 sourceAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
5765 }
5766
5767 // Create framebuffer
5768 {
5769 const VkImageView attachments[1] =
5770 {
5771 *sourceAttachmentView,
5772 };
5773
5774 const VkFramebufferCreateInfo framebufferParams =
5775 {
5776 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
5777 DE_NULL, // const void* pNext;
5778 0u, // VkFramebufferCreateFlags flags;
5779 *renderPass, // VkRenderPass renderPass;
5780 1u, // deUint32 attachmentCount;
5781 attachments, // const VkImageView* pAttachments;
5782 m_params.src.image.extent.width, // deUint32 width;
5783 m_params.src.image.extent.height, // deUint32 height;
5784 1u // deUint32 layers;
5785 };
5786
5787 framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
5788 }
5789
5790 // Create pipeline
5791 {
5792 const std::vector<VkViewport> viewports (1, makeViewport(m_params.src.image.extent));
5793 const std::vector<VkRect2D> scissors (1, makeRect2D(m_params.src.image.extent));
5794
5795 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
5796 {
5797 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
5798 DE_NULL, // const void* pNext;
5799 0u, // VkPipelineMultisampleStateCreateFlags flags;
5800 rasterizationSamples, // VkSampleCountFlagBits rasterizationSamples;
5801 VK_FALSE, // VkBool32 sampleShadingEnable;
5802 0.0f, // float minSampleShading;
5803 DE_NULL, // const VkSampleMask* pSampleMask;
5804 VK_FALSE, // VkBool32 alphaToCoverageEnable;
5805 VK_FALSE // VkBool32 alphaToOneEnable;
5806 };
5807
5808 graphicsPipeline = makeGraphicsPipeline(vk, // const DeviceInterface& vk
5809 vkDevice, // const VkDevice device
5810 *pipelineLayout, // const VkPipelineLayout pipelineLayout
5811 *vertexShaderModule, // const VkShaderModule vertexShaderModule
5812 DE_NULL, // const VkShaderModule tessellationControlModule
5813 DE_NULL, // const VkShaderModule tessellationEvalModule
5814 DE_NULL, // const VkShaderModule geometryShaderModule
5815 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
5816 *renderPass, // const VkRenderPass renderPass
5817 viewports, // const std::vector<VkViewport>& viewports
5818 scissors, // const std::vector<VkRect2D>& scissors
5819 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
5820 0u, // const deUint32 subpass
5821 0u, // const deUint32 patchControlPoints
5822 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
5823 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
5824 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
5825 }
5826
5827 // Create command buffer
5828 {
5829 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
5830
5831 // Change the image layouts.
5832 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, uint32_t(srcImageBarriers.size()), srcImageBarriers.data());
5833
5834 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
5835 {
5836 // Clear the 'm_multisampledImage'.
5837 {
5838 const VkClearColorValue clearValue = {{0.0f, 0.0f, 0.0f, 1.0f}};
5839 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
5840 vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
5841 }
5842
5843 // Clear the 'm_multisampledCopyImage' with different color.
5844 {
5845 const VkClearColorValue clearValue = {{1.0f, 1.0f, 1.0f, 1.0f}};
5846 const auto clearRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, m_params.src.image.extent.depth);
5847 vk.cmdClearColorImage(*m_cmdBuffer, m_multisampledCopyImage.get(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearValue, 1u, &clearRange);
5848
5849 const auto postClearMemoryBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT);
5850 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 1u, &postClearMemoryBarrier, 0, (const VkBufferMemoryBarrier*)DE_NULL, 0u, (const VkImageMemoryBarrier*)DE_NULL);
5851 }
5852 }
5853
5854 beginRenderPass(vk, *m_cmdBuffer, *renderPass, *framebuffer, makeRect2D(0, 0, m_params.src.image.extent.width, m_params.src.image.extent.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
5855
5856 const VkDeviceSize vertexBufferOffset = 0u;
5857
5858 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *graphicsPipeline);
5859 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &vertexBuffer.get(), &vertexBufferOffset);
5860 vk.cmdDraw(*m_cmdBuffer, (deUint32)vertices.size(), 1, 0, 0);
5861
5862 endRenderPass(vk, *m_cmdBuffer);
5863 endCommandBuffer(vk, *m_cmdBuffer);
5864 }
5865
5866 // Queue submit.
5867 {
5868 const VkQueue queue = m_context.getUniversalQueue();
5869 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
5870 }
5871 }
5872 }
5873
iterate(void)5874 tcu::TestStatus ResolveImageToImage::iterate (void)
5875 {
5876 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
5877 const tcu::TextureFormat dstTcuFormat = mapVkFormat(m_params.dst.image.format);
5878
5879 // upload the destination image
5880 m_destinationTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(dstTcuFormat,
5881 (int)m_params.dst.image.extent.width,
5882 (int)m_params.dst.image.extent.height,
5883 (int)m_params.dst.image.extent.depth));
5884 generateBuffer(m_destinationTextureLevel->getAccess(), m_params.dst.image.extent.width, m_params.dst.image.extent.height, m_params.dst.image.extent.depth);
5885 uploadImage(m_destinationTextureLevel->getAccess(), m_destination.get(), m_params.dst.image);
5886
5887 m_sourceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(srcTcuFormat,
5888 (int)m_params.src.image.extent.width,
5889 (int)m_params.src.image.extent.height,
5890 (int)m_params.dst.image.extent.depth));
5891
5892 generateBuffer(m_sourceTextureLevel->getAccess(), m_params.src.image.extent.width, m_params.src.image.extent.height, m_params.dst.image.extent.depth, FILL_MODE_MULTISAMPLE);
5893 generateExpectedResult();
5894
5895 VkImage sourceImage = m_multisampledImage.get();
5896 deUint32 sourceArraySize = getArraySize(m_params.src.image);
5897
5898 switch (m_options)
5899 {
5900 case COPY_MS_IMAGE_LAYER_TO_MS_IMAGE:
5901 case COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE:
5902 // Duplicate the multisampled image to a multisampled image array
5903 sourceArraySize = getArraySize(m_params.dst.image); // fall through
5904 case COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION:
5905 case COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB:
5906 case COPY_MS_IMAGE_TO_MS_IMAGE:
5907 copyMSImageToMSImage(sourceArraySize);
5908 sourceImage = m_multisampledCopyImage.get();
5909 break;
5910 default:
5911 break;
5912 }
5913
5914 const DeviceInterface& vk = m_context.getDeviceInterface();
5915 const VkDevice vkDevice = m_context.getDevice();
5916 const VkQueue queue = m_context.getUniversalQueue();
5917
5918 std::vector<VkImageResolve> imageResolves;
5919 std::vector<VkImageResolve2KHR> imageResolves2KHR;
5920 for (CopyRegion region : m_params.regions)
5921 {
5922 // If copying multiple regions, make sure that the same regions are
5923 // used for resolving as the ones used for copying.
5924 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
5925 {
5926 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
5927 getExtent3D(m_params.src.image).height / 2,
5928 getExtent3D(m_params.src.image).depth};
5929
5930 const VkImageResolve imageResolve =
5931 {
5932 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
5933 region.imageResolve.dstOffset, // VkOffset3D srcOffset;
5934 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
5935 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
5936 partialExtent, // VkExtent3D extent;
5937 };
5938
5939 if (m_params.extensionUse == EXTENSION_USE_NONE)
5940 {
5941 imageResolves.push_back(imageResolve);
5942 }
5943 else
5944 {
5945 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5946 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(imageResolve));
5947 }
5948 }
5949 else
5950 {
5951 if (m_params.extensionUse == EXTENSION_USE_NONE)
5952 {
5953 imageResolves.push_back(region.imageResolve);
5954 }
5955 else
5956 {
5957 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
5958 imageResolves2KHR.push_back(convertvkImageResolveTovkImageResolve2KHR(region.imageResolve));
5959 }
5960 }
5961 }
5962
5963 const VkImageMemoryBarrier imageBarriers[] =
5964 {
5965 // source image
5966 {
5967 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5968 DE_NULL, // const void* pNext;
5969 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
5970 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
5971 m_options == NO_OPTIONAL_OPERATION ?
5972 m_params.dst.image.operationLayout :
5973 m_params.src.image.operationLayout, // VkImageLayout oldLayout;
5974 m_params.src.image.operationLayout, // VkImageLayout newLayout;
5975 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5976 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5977 sourceImage, // VkImage image;
5978 { // VkImageSubresourceRange subresourceRange;
5979 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
5980 0u, // deUint32 baseMipLevel;
5981 1u, // deUint32 mipLevels;
5982 0u, // deUint32 baseArraySlice;
5983 sourceArraySize // deUint32 arraySize;
5984 }
5985 },
5986 // destination image
5987 {
5988 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
5989 DE_NULL, // const void* pNext;
5990 0u, // VkAccessFlags srcAccessMask;
5991 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
5992 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
5993 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
5994 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
5995 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
5996 m_destination.get(), // VkImage image;
5997 { // VkImageSubresourceRange subresourceRange;
5998 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
5999 0u, // deUint32 baseMipLevel;
6000 1u, // deUint32 mipLevels;
6001 0u, // deUint32 baseArraySlice;
6002 getArraySize(m_params.dst.image) // deUint32 arraySize;
6003 }
6004 },
6005 };
6006
6007 const VkImageMemoryBarrier postImageBarrier =
6008 {
6009 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6010 DE_NULL, // const void* pNext;
6011 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6012 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
6013 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6014 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6015 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6016 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6017 m_destination.get(), // VkImage image;
6018 { // VkImageSubresourceRange subresourceRange;
6019 getAspectFlags(dstTcuFormat), // VkImageAspectFlags aspectMask;
6020 0u, // deUint32 baseMipLevel;
6021 1u, // deUint32 mipLevels;
6022 0u, // deUint32 baseArraySlice;
6023 getArraySize(m_params.dst.image) // deUint32 arraySize;
6024 }
6025 };
6026
6027 beginCommandBuffer(vk, *m_cmdBuffer);
6028 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, DE_LENGTH_OF_ARRAY(imageBarriers), imageBarriers);
6029
6030 if (m_params.extensionUse == EXTENSION_USE_NONE)
6031 {
6032 vk.cmdResolveImage(*m_cmdBuffer, sourceImage, m_params.src.image.operationLayout, m_destination.get(), m_params.dst.image.operationLayout, (deUint32)m_params.regions.size(), imageResolves.data());
6033 }
6034 else
6035 {
6036 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6037 const VkResolveImageInfo2KHR ResolveImageInfo2KHR =
6038 {
6039 VK_STRUCTURE_TYPE_RESOLVE_IMAGE_INFO_2_KHR, // VkStructureType sType;
6040 DE_NULL, // const void* pNext;
6041 sourceImage, // VkImage srcImage;
6042 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
6043 m_destination.get(), // VkImage dstImage;
6044 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
6045 (deUint32)m_params.regions.size(), // uint32_t regionCount;
6046 imageResolves2KHR.data() // const VkImageResolve2KHR* pRegions;
6047 };
6048 vk.cmdResolveImage2KHR(*m_cmdBuffer, &ResolveImageInfo2KHR);
6049 }
6050
6051 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &postImageBarrier);
6052 endCommandBuffer(vk, *m_cmdBuffer);
6053 submitCommandsAndWait(vk, vkDevice, queue, *m_cmdBuffer);
6054
6055 de::MovePtr<tcu::TextureLevel> resultTextureLevel = readImage(*m_destination, m_params.dst.image);
6056
6057 if (shouldVerifyIntermediateResults(m_options))
6058 {
6059 // Verify the intermediate multisample copy operation happens properly instead of, for example, shuffling samples around or
6060 // resolving the image and giving every sample the same value.
6061 const auto intermediateResult = checkIntermediateCopy();
6062 if (intermediateResult.getCode() != QP_TEST_RESULT_PASS)
6063 return intermediateResult;
6064 }
6065
6066 return checkTestResult(resultTextureLevel->getAccess());
6067 }
6068
checkTestResult(tcu::ConstPixelBufferAccess result)6069 tcu::TestStatus ResolveImageToImage::checkTestResult (tcu::ConstPixelBufferAccess result)
6070 {
6071 const tcu::ConstPixelBufferAccess expected = m_expectedTextureLevel[0]->getAccess();
6072 const float fuzzyThreshold = 0.01f;
6073
6074 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6075 {
6076 // Check that all the layers that have not been written to are solid white.
6077 tcu::Vec4 expectedColor (1.0f, 1.0f, 1.0f, 1.0f);
6078 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image) - 1; ++arrayLayerNdx)
6079 {
6080 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6081 if(resultSub.getPixel(0, 0) != expectedColor)
6082 return tcu::TestStatus::fail("CopiesAndBlitting test. Layers image differs from initialized value.");
6083 }
6084
6085 // Check that the layer that has been copied to is the same as the layer that has been copied from.
6086 const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, 2u, expected.getWidth(), expected.getHeight(), 1u);
6087 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, 4u, result.getWidth(), result.getHeight(), 1u);
6088 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6089 return tcu::TestStatus::fail("CopiesAndBlitting test");
6090 }
6091 else
6092 {
6093 for (int arrayLayerNdx = 0; arrayLayerNdx < (int)getArraySize(m_params.dst.image); ++arrayLayerNdx)
6094 {
6095 const tcu::ConstPixelBufferAccess expectedSub = getSubregion (expected, 0u, 0u, arrayLayerNdx, expected.getWidth(), expected.getHeight(), 1u);
6096 const tcu::ConstPixelBufferAccess resultSub = getSubregion (result, 0u, 0u, arrayLayerNdx, result.getWidth(), result.getHeight(), 1u);
6097 if (!tcu::fuzzyCompare(m_context.getTestContext().getLog(), "Compare", "Result comparsion", expectedSub, resultSub, fuzzyThreshold, tcu::COMPARE_LOG_RESULT))
6098 return tcu::TestStatus::fail("CopiesAndBlitting test");
6099 }
6100 }
6101
6102 return tcu::TestStatus::pass("CopiesAndBlitting test");
6103 }
6104
copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src,tcu::PixelBufferAccess dst,CopyRegion region,deUint32 mipLevel)6105 void ResolveImageToImage::copyRegionToTextureLevel(tcu::ConstPixelBufferAccess src, tcu::PixelBufferAccess dst, CopyRegion region, deUint32 mipLevel)
6106 {
6107 DE_UNREF(mipLevel);
6108
6109 VkOffset3D srcOffset = region.imageResolve.srcOffset;
6110 srcOffset.z = region.imageResolve.srcSubresource.baseArrayLayer;
6111 VkOffset3D dstOffset = region.imageResolve.dstOffset;
6112 dstOffset.z = region.imageResolve.dstSubresource.baseArrayLayer;
6113 VkExtent3D extent = region.imageResolve.extent;
6114 extent.depth = region.imageResolve.srcSubresource.layerCount;
6115
6116 const tcu::ConstPixelBufferAccess srcSubRegion = getSubregion (src, srcOffset.x, srcOffset.y, srcOffset.z, extent.width, extent.height, extent.depth);
6117 // CopyImage acts like a memcpy. Replace the destination format with the srcformat to use a memcpy.
6118 const tcu::PixelBufferAccess dstWithSrcFormat (srcSubRegion.getFormat(), dst.getSize(), dst.getDataPtr());
6119 const tcu::PixelBufferAccess dstSubRegion = getSubregion (dstWithSrcFormat, dstOffset.x, dstOffset.y, dstOffset.z, extent.width, extent.height, extent.depth);
6120
6121 tcu::copy(dstSubRegion, srcSubRegion);
6122 }
6123
checkIntermediateCopy(void)6124 tcu::TestStatus ResolveImageToImage::checkIntermediateCopy (void)
6125 {
6126 const auto& vkd = m_context.getDeviceInterface();
6127 const auto device = m_context.getDevice();
6128 const auto queue = m_context.getUniversalQueue();
6129 const auto queueIndex = m_context.getUniversalQueueFamilyIndex();
6130 auto& alloc = m_context.getDefaultAllocator();
6131 const auto currentLayout = m_params.src.image.operationLayout;
6132 const auto numDstLayers = getArraySize(m_params.dst.image);
6133 const auto numInputAttachments = m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE ? 2u : numDstLayers + 1u; // For the source image.
6134 constexpr auto numSets = 2u; // 1 for the output buffer, 1 for the input attachments.
6135 const auto fbWidth = m_params.src.image.extent.width;
6136 const auto fbHeight = m_params.src.image.extent.height;
6137
6138 // Push constants.
6139 const std::array<int, 3> pushConstantData =
6140 {{
6141 static_cast<int>(fbWidth),
6142 static_cast<int>(fbHeight),
6143 static_cast<int>(m_params.samples),
6144 }};
6145 const auto pushConstantSize = static_cast<deUint32>(pushConstantData.size() * sizeof(decltype(pushConstantData)::value_type));
6146
6147 // Shader modules.
6148 const auto vertexModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("vert"), 0u);
6149 const auto verificationModule = createShaderModule(vkd, device, m_context.getBinaryCollection().get("verify"), 0u);
6150
6151 // Descriptor sets.
6152 DescriptorPoolBuilder poolBuilder;
6153 poolBuilder.addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6154 poolBuilder.addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, numInputAttachments);
6155 const auto descriptorPool = poolBuilder.build(vkd, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, numSets);
6156
6157 DescriptorSetLayoutBuilder layoutBuilderBuffer;
6158 layoutBuilderBuffer.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT);
6159 const auto outputBufferSetLayout = layoutBuilderBuffer.build(vkd, device);
6160
6161 DescriptorSetLayoutBuilder layoutBuilderAttachments;
6162 for (deUint32 i = 0u; i < numInputAttachments; ++i)
6163 layoutBuilderAttachments.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
6164 const auto inputAttachmentsSetLayout = layoutBuilderAttachments.build(vkd, device);
6165
6166 const auto descriptorSetBuffer = makeDescriptorSet(vkd, device, descriptorPool.get(), outputBufferSetLayout.get());
6167 const auto descriptorSetAttachments = makeDescriptorSet(vkd, device, descriptorPool.get(), inputAttachmentsSetLayout.get());
6168
6169 // Array with raw descriptor sets.
6170 const std::array<VkDescriptorSet, numSets> descriptorSets =
6171 {{
6172 descriptorSetBuffer.get(),
6173 descriptorSetAttachments.get(),
6174 }};
6175
6176 // Pipeline layout.
6177 const std::array<VkDescriptorSetLayout, numSets> setLayouts =
6178 {{
6179 outputBufferSetLayout.get(),
6180 inputAttachmentsSetLayout.get(),
6181 }};
6182
6183 const VkPushConstantRange pushConstantRange =
6184 {
6185 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
6186 0u, // deUint32 offset;
6187 pushConstantSize, // deUint32 size;
6188 };
6189
6190 const VkPipelineLayoutCreateInfo pipelineLayoutInfo =
6191 {
6192 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
6193 nullptr, // const void* pNext;
6194 0u, // VkPipelineLayoutCreateFlags flags;
6195 static_cast<deUint32>(setLayouts.size()), // deUint32 setLayoutCount;
6196 setLayouts.data(), // const VkDescriptorSetLayout* pSetLayouts;
6197 1u, // deUint32 pushConstantRangeCount;
6198 &pushConstantRange, // const VkPushConstantRange* pPushConstantRanges;
6199 };
6200
6201 const auto pipelineLayout = createPipelineLayout(vkd, device, &pipelineLayoutInfo);
6202
6203 // Render pass.
6204 const VkAttachmentDescription commonAttachmentDescription =
6205 {
6206 0u, // VkAttachmentDescriptionFlags flags;
6207 m_params.src.image.format, // VkFormat format;
6208 m_params.samples, // VkSampleCountFlagBits samples;
6209 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
6210 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
6211 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
6212 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
6213 currentLayout, // VkImageLayout initialLayout;
6214 currentLayout, // VkImageLayout finalLayout;
6215 };
6216 const std::vector<VkAttachmentDescription> attachmentDescriptions(numInputAttachments, commonAttachmentDescription);
6217
6218 std::vector<VkAttachmentReference> inputAttachmentReferences;
6219 inputAttachmentReferences.reserve(numInputAttachments);
6220 for (deUint32 i = 0u; i < numInputAttachments; ++i)
6221 {
6222 const VkAttachmentReference reference = { i, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL };
6223 inputAttachmentReferences.push_back(reference);
6224 }
6225
6226 const VkSubpassDescription subpassDescription =
6227 {
6228 0u, // VkSubpassDescriptionFlags flags;
6229 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
6230 static_cast<deUint32>(inputAttachmentReferences.size()), // deUint32 inputAttachmentCount;
6231 inputAttachmentReferences.data(), // const VkAttachmentReference* pInputAttachments;
6232 0u, // deUint32 colorAttachmentCount;
6233 nullptr, // const VkAttachmentReference* pColorAttachments;
6234 nullptr, // const VkAttachmentReference* pResolveAttachments;
6235 nullptr, // const VkAttachmentReference* pDepthStencilAttachment;
6236 0u, // deUint32 preserveAttachmentCount;
6237 nullptr, // const deUint32* pPreserveAttachments;
6238 };
6239
6240 const VkRenderPassCreateInfo renderPassInfo =
6241 {
6242 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
6243 nullptr, // const void* pNext;
6244 0u, // VkRenderPassCreateFlags flags;
6245 static_cast<deUint32>(attachmentDescriptions.size()), // deUint32 attachmentCount;
6246 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments;
6247 1u, // deUint32 subpassCount;
6248 &subpassDescription, // const VkSubpassDescription* pSubpasses;
6249 0u, // deUint32 dependencyCount;
6250 nullptr, // const VkSubpassDependency* pDependencies;
6251 };
6252
6253 const auto renderPass = createRenderPass(vkd, device, &renderPassInfo);
6254
6255 // Framebuffer.
6256 std::vector<Move<VkImageView>> imageViews;
6257 std::vector<VkImageView> imageViewsRaw;
6258
6259
6260 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6261 {
6262 imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 2u, 1u)));
6263 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 4u, 1u)));
6264 }
6265 else
6266 {
6267 imageViews.push_back(makeImageView(vkd, device, m_multisampledImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.src.image.format, makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)));
6268 for (deUint32 i = 0u; i < numDstLayers; ++i)
6269 {
6270 const auto subresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, i, 1u);
6271 imageViews.push_back(makeImageView(vkd, device, m_multisampledCopyImage.get(), VK_IMAGE_VIEW_TYPE_2D, m_params.dst.image.format, subresourceRange));
6272 }
6273 }
6274
6275
6276 imageViewsRaw.reserve(imageViews.size());
6277 std::transform(begin(imageViews), end(imageViews), std::back_inserter(imageViewsRaw), [](const Move<VkImageView>& ptr) { return ptr.get(); });
6278
6279 const auto framebuffer = makeFramebuffer(vkd, device, renderPass.get(), static_cast<deUint32>(imageViewsRaw.size()), imageViewsRaw.data(), fbWidth, fbHeight);
6280
6281 // Storage buffer.
6282 const auto bufferCount = static_cast<size_t>(fbWidth * fbHeight * m_params.samples);
6283 const auto bufferSize = static_cast<VkDeviceSize>(bufferCount * sizeof(deInt32));
6284 BufferWithMemory buffer (vkd, device, alloc, makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible);
6285 auto& bufferAlloc = buffer.getAllocation();
6286 void* bufferData = bufferAlloc.getHostPtr();
6287
6288 // Update descriptor sets.
6289 DescriptorSetUpdateBuilder updater;
6290
6291 const auto bufferInfo = makeDescriptorBufferInfo(buffer.get(), 0ull, bufferSize);
6292 updater.writeSingle(descriptorSetBuffer.get(), DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &bufferInfo);
6293
6294 std::vector<VkDescriptorImageInfo> imageInfos;
6295 imageInfos.reserve(imageViewsRaw.size());
6296 for (size_t i = 0; i < imageViewsRaw.size(); ++i)
6297 imageInfos.push_back(makeDescriptorImageInfo(DE_NULL, imageViewsRaw[i], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL));
6298
6299 for (size_t i = 0; i < imageInfos.size(); ++i)
6300 updater.writeSingle(descriptorSetAttachments.get(), DescriptorSetUpdateBuilder::Location::binding(static_cast<deUint32>(i)), VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &imageInfos[i]);
6301
6302 updater.update(vkd, device);
6303
6304 // Vertex buffer.
6305 std::vector<tcu::Vec4> fullScreenQuad;
6306 {
6307 // Full screen quad so every framebuffer pixel and sample location is verified by the shader.
6308 const tcu::Vec4 topLeft (-1.0f, -1.0f, 0.0f, 1.0f);
6309 const tcu::Vec4 topRight ( 1.0f, -1.0f, 0.0f, 1.0f);
6310 const tcu::Vec4 bottomLeft (-1.0f, 1.0f, 0.0f, 1.0f);
6311 const tcu::Vec4 bottomRight ( 1.0f, 1.0f, 0.0f, 1.0f);
6312
6313 fullScreenQuad.reserve(6u);
6314 fullScreenQuad.push_back(topLeft);
6315 fullScreenQuad.push_back(topRight);
6316 fullScreenQuad.push_back(bottomRight);
6317 fullScreenQuad.push_back(topLeft);
6318 fullScreenQuad.push_back(bottomRight);
6319 fullScreenQuad.push_back(bottomLeft);
6320 }
6321
6322 const auto vertexBufferSize = static_cast<VkDeviceSize>(fullScreenQuad.size() * sizeof(decltype(fullScreenQuad)::value_type));
6323 const auto vertexBufferInfo = makeBufferCreateInfo(vertexBufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
6324 const BufferWithMemory vertexBuffer (vkd, device, alloc, vertexBufferInfo, MemoryRequirement::HostVisible);
6325 const auto vertexBufferHandler = vertexBuffer.get();
6326 auto& vertexBufferAlloc = vertexBuffer.getAllocation();
6327 void* vertexBufferData = vertexBufferAlloc.getHostPtr();
6328 const VkDeviceSize vertexBufferOffset = 0ull;
6329
6330 deMemcpy(vertexBufferData, fullScreenQuad.data(), static_cast<size_t>(vertexBufferSize));
6331 flushAlloc(vkd, device, vertexBufferAlloc);
6332
6333 // Graphics pipeline.
6334 const std::vector<VkViewport> viewports (1, makeViewport(m_params.src.image.extent));
6335 const std::vector<VkRect2D> scissors (1, makeRect2D(m_params.src.image.extent));
6336
6337 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
6338 {
6339 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
6340 nullptr, // const void* pNext;
6341 0u, // VkPipelineMultisampleStateCreateFlags flags;
6342 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
6343 VK_FALSE, // VkBool32 sampleShadingEnable;
6344 0.0f, // float minSampleShading;
6345 nullptr, // const VkSampleMask* pSampleMask;
6346 VK_FALSE, // VkBool32 alphaToCoverageEnable;
6347 VK_FALSE // VkBool32 alphaToOneEnable;
6348 };
6349
6350 const auto graphicsPipeline = makeGraphicsPipeline(
6351 vkd, // const DeviceInterface& vk
6352 device, // const VkDevice device
6353 pipelineLayout.get(), // const VkPipelineLayout pipelineLayout
6354 vertexModule.get(), // const VkShaderModule vertexShaderModule
6355 DE_NULL, // const VkShaderModule tessellationControlModule
6356 DE_NULL, // const VkShaderModule tessellationEvalModule
6357 DE_NULL, // const VkShaderModule geometryShaderModule
6358 verificationModule.get(), // const VkShaderModule fragmentShaderModule
6359 renderPass.get(), // const VkRenderPass renderPass
6360 viewports, // const std::vector<VkViewport>& viewports
6361 scissors, // const std::vector<VkRect2D>& scissors
6362 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
6363 0u, // const deUint32 subpass
6364 0u, // const deUint32 patchControlPoints
6365 nullptr, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
6366 nullptr, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
6367 &multisampleStateParams); // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
6368
6369 // Command buffer.
6370 const auto cmdPool = makeCommandPool(vkd, device, queueIndex);
6371 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6372 const auto cmdBuffer = cmdBufferPtr.get();
6373
6374 // Make sure multisample copy data is available to the fragment shader.
6375 const auto imagesBarrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
6376
6377 // Make sure verification buffer data is available on the host.
6378 const auto bufferBarrier = makeMemoryBarrier(VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6379
6380 // Record and submit command buffer.
6381 beginCommandBuffer(vkd, cmdBuffer);
6382 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 1u, &imagesBarrier, 0u, nullptr, 0u, nullptr);
6383 beginRenderPass(vkd, cmdBuffer, renderPass.get(), framebuffer.get(), makeRect2D(m_params.src.image.extent));
6384 vkd.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline.get());
6385 vkd.cmdBindVertexBuffers(cmdBuffer, 0u, 1u, &vertexBufferHandler, &vertexBufferOffset);
6386 vkd.cmdPushConstants(cmdBuffer, pipelineLayout.get(), VK_SHADER_STAGE_FRAGMENT_BIT, 0u, pushConstantSize, pushConstantData.data());
6387 vkd.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout.get(), 0u, static_cast<deUint32>(descriptorSets.size()), descriptorSets.data(), 0u, nullptr);
6388 vkd.cmdDraw(cmdBuffer, static_cast<deUint32>(fullScreenQuad.size()), 1u, 0u, 0u);
6389 endRenderPass(vkd, cmdBuffer);
6390 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &bufferBarrier, 0u, nullptr, 0u, nullptr);
6391 endCommandBuffer(vkd, cmdBuffer);
6392 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6393
6394 // Verify intermediate results.
6395 invalidateAlloc(vkd, device, bufferAlloc);
6396 std::vector<deInt32> outputFlags (bufferCount, 0);
6397 deMemcpy(outputFlags.data(), bufferData, static_cast<size_t>(bufferSize));
6398
6399 auto& log = m_context.getTestContext().getLog();
6400 log << tcu::TestLog::Message << "Verifying intermediate multisample copy results" << tcu::TestLog::EndMessage;
6401
6402 const auto sampleCount = static_cast<deUint32>(m_params.samples);
6403
6404 for (deUint32 x = 0u; x < fbWidth; ++x)
6405 for (deUint32 y = 0u; y < fbHeight; ++y)
6406 for (deUint32 s = 0u; s < sampleCount; ++s)
6407 {
6408 const auto index = (y * fbWidth + x) * sampleCount + s;
6409 if (!outputFlags[index])
6410 {
6411 std::ostringstream msg;
6412 msg << "Intermediate verification failed for coordinates (" << x << ", " << y << ") sample " << s;
6413 return tcu::TestStatus::fail(msg.str());
6414 }
6415 }
6416
6417 log << tcu::TestLog::Message << "Intermediate multisample copy verification passed" << tcu::TestLog::EndMessage;
6418 return tcu::TestStatus::pass("Pass");
6419 }
6420
copyMSImageToMSImage(deUint32 copyArraySize)6421 void ResolveImageToImage::copyMSImageToMSImage (deUint32 copyArraySize)
6422 {
6423 const DeviceInterface& vk = m_context.getDeviceInterface();
6424 const VkDevice vkDevice = m_context.getDevice();
6425 const VkQueue queue = m_context.getUniversalQueue();
6426 const tcu::TextureFormat srcTcuFormat = mapVkFormat(m_params.src.image.format);
6427 std::vector<VkImageCopy> imageCopies;
6428 std::vector<VkImageCopy2KHR> imageCopies2KHR;
6429
6430 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6431 {
6432 const VkImageSubresourceLayers sourceSubresourceLayers =
6433 {
6434 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6435 0u, // deUint32 mipLevel;
6436 2u, // deUint32 baseArrayLayer;
6437 1u // deUint32 layerCount;
6438 };
6439
6440 const VkImageSubresourceLayers destinationSubresourceLayers =
6441 {
6442 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
6443 0u, // deUint32 mipLevel;
6444 4u, // deUint32 baseArrayLayer;
6445 1u // deUint32 layerCount;
6446 };
6447
6448 const VkImageCopy imageCopy =
6449 {
6450 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
6451 {0, 0, 0}, // VkOffset3D srcOffset;
6452 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
6453 {0, 0, 0}, // VkOffset3D dstOffset;
6454 getExtent3D(m_params.src.image), // VkExtent3D extent;
6455 };
6456
6457 if (m_params.extensionUse == EXTENSION_USE_NONE)
6458 {
6459 imageCopies.push_back(imageCopy);
6460 }
6461 else
6462 {
6463 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6464 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6465 }
6466 }
6467 else if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6468 {
6469 VkExtent3D partialExtent = {getExtent3D(m_params.src.image).width / 2,
6470 getExtent3D(m_params.src.image).height / 2,
6471 getExtent3D(m_params.src.image).depth};
6472
6473 for (CopyRegion region : m_params.regions)
6474 {
6475 const VkImageCopy imageCopy =
6476 {
6477 region.imageResolve.srcSubresource, // VkImageSubresourceLayers srcSubresource;
6478 region.imageResolve.srcOffset, // VkOffset3D srcOffset;
6479 region.imageResolve.dstSubresource, // VkImageSubresourceLayers dstSubresource;
6480 region.imageResolve.dstOffset, // VkOffset3D dstOffset;
6481 partialExtent, // VkExtent3D extent;
6482 };
6483
6484 if (m_params.extensionUse == EXTENSION_USE_NONE)
6485 {
6486 imageCopies.push_back(imageCopy);
6487 }
6488 else
6489 {
6490 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6491 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6492 }
6493 }
6494 }
6495 else
6496 {
6497 for (deUint32 layerNdx = 0; layerNdx < copyArraySize; ++layerNdx)
6498 {
6499 const VkImageSubresourceLayers sourceSubresourceLayers =
6500 {
6501 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6502 0u, // deUint32 mipLevel;
6503 0u, // deUint32 baseArrayLayer;
6504 1u // deUint32 layerCount;
6505 };
6506
6507 const VkImageSubresourceLayers destinationSubresourceLayers =
6508 {
6509 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;//getAspectFlags(dstTcuFormat)
6510 0u, // deUint32 mipLevel;
6511 layerNdx, // deUint32 baseArrayLayer;
6512 1u // deUint32 layerCount;
6513 };
6514
6515 const VkImageCopy imageCopy =
6516 {
6517 sourceSubresourceLayers, // VkImageSubresourceLayers srcSubresource;
6518 {0, 0, 0}, // VkOffset3D srcOffset;
6519 destinationSubresourceLayers, // VkImageSubresourceLayers dstSubresource;
6520 {0, 0, 0}, // VkOffset3D dstOffset;
6521 getExtent3D(m_params.src.image), // VkExtent3D extent;
6522 };
6523
6524 if (m_params.extensionUse == EXTENSION_USE_NONE)
6525 {
6526 imageCopies.push_back(imageCopy);
6527 }
6528 else
6529 {
6530 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6531 imageCopies2KHR.push_back(convertvkImageCopyTovkImageCopy2KHR(imageCopy));
6532 }
6533 }
6534 }
6535
6536 std::vector<VkImageMemoryBarrier> imageBarriers;
6537
6538 // m_multisampledImage
6539 const VkImageMemoryBarrier m_multisampledImageBarrier =
6540 {
6541 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6542 DE_NULL, // const void* pNext;
6543 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask;
6544 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
6545 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6546 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6547 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6548 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6549 m_multisampledImage.get(), // VkImage image;
6550 { // VkImageSubresourceRange subresourceRange;
6551 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6552 0u, // deUint32 baseMipLevel;
6553 1u, // deUint32 mipLevels;
6554 0u, // deUint32 baseArraySlice;
6555 getArraySize(m_params.src.image) // deUint32 arraySize;
6556 }
6557 };
6558 // m_multisampledCopyImage
6559 const VkImageMemoryBarrier m_multisampledCopyImageBarrier =
6560 {
6561 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6562 DE_NULL, // const void* pNext;
6563 0, // VkAccessFlags srcAccessMask;
6564 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6565 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6566 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6567 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6568 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6569 m_multisampledCopyImage.get(), // VkImage image;
6570 { // VkImageSubresourceRange subresourceRange;
6571 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6572 0u, // deUint32 baseMipLevel;
6573 1u, // deUint32 mipLevels;
6574 0u, // deUint32 baseArraySlice;
6575 copyArraySize // deUint32 arraySize;
6576 }
6577 };
6578 // m_multisampledCopyNoCabImage (no USAGE_COLOR_ATTACHMENT_BIT)
6579 const VkImageMemoryBarrier m_multisampledCopyNoCabImageBarrier =
6580 {
6581 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6582 DE_NULL, // const void* pNext;
6583 0, // VkAccessFlags srcAccessMask;
6584 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
6585 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
6586 m_params.dst.image.operationLayout, // VkImageLayout newLayout;
6587 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6588 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6589 m_multisampledCopyNoCabImage.get(), // VkImage image;
6590 { // VkImageSubresourceRange subresourceRange;
6591 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6592 0u, // deUint32 baseMipLevel;
6593 1u, // deUint32 mipLevels;
6594 0u, // deUint32 baseArraySlice;
6595 copyArraySize // deUint32 arraySize;
6596 }
6597 };
6598
6599 // Only use one barrier if no options have been given.
6600 if (m_options != DE_NULL)
6601 {
6602 imageBarriers.push_back(m_multisampledImageBarrier);
6603 imageBarriers.push_back(m_multisampledCopyImageBarrier);
6604 // Add the third barrier if option is as below.
6605 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6606 imageBarriers.push_back(m_multisampledCopyNoCabImageBarrier);
6607 }
6608 else
6609 {
6610 imageBarriers.push_back(m_multisampledImageBarrier);
6611 }
6612
6613 const VkImageMemoryBarrier postImageBarriers =
6614 // destination image
6615 {
6616 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6617 DE_NULL, // const void* pNext;
6618 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6619 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
6620 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6621 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6622 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6623 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6624 m_multisampledCopyImage.get(), // VkImage image;
6625 { // VkImageSubresourceRange subresourceRange;
6626 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6627 0u, // deUint32 baseMipLevel;
6628 1u, // deUint32 mipLevels;
6629 0u, // deUint32 baseArraySlice;
6630 copyArraySize // deUint32 arraySize;
6631 }
6632 };
6633 const VkImageMemoryBarrier betweenCopyImageBarrier =
6634 // destination image (no USAGE_COLOR_ATTACHMENT_BIT)
6635 {
6636 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
6637 DE_NULL, // const void* pNext;
6638 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
6639 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
6640 m_params.dst.image.operationLayout, // VkImageLayout oldLayout;
6641 m_params.src.image.operationLayout, // VkImageLayout newLayout;
6642 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
6643 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
6644 m_multisampledCopyNoCabImage.get(), // VkImage image;
6645 { // VkImageSubresourceRange subresourceRange;
6646 getAspectFlags(srcTcuFormat), // VkImageAspectFlags aspectMask;
6647 0u, // deUint32 baseMipLevel;
6648 1u, // deUint32 mipLevels;
6649 0u, // deUint32 baseArraySlice;
6650 copyArraySize // deUint32 arraySize;
6651 }
6652 };
6653
6654 beginCommandBuffer(vk, *m_cmdBuffer);
6655 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, uint32_t(imageBarriers.size()), imageBarriers.data());
6656
6657 if (m_params.extensionUse == EXTENSION_USE_NONE)
6658 {
6659 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6660 {
6661 vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyNoCabImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6662 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &betweenCopyImageBarrier);
6663 vk.cmdCopyImage(*m_cmdBuffer, m_multisampledCopyNoCabImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6664 }
6665 else
6666 {
6667 vk.cmdCopyImage(*m_cmdBuffer, m_multisampledImage.get(), m_params.src.image.operationLayout, m_multisampledCopyImage.get(), m_params.dst.image.operationLayout, (deUint32)imageCopies.size(), imageCopies.data());
6668 }
6669 }
6670 else
6671 {
6672 if(m_options == COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB)
6673 {
6674 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6675 const VkCopyImageInfo2KHR copyImageInfo2KHR =
6676 {
6677 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
6678 DE_NULL, // const void* pNext;
6679 m_multisampledImage.get(), // VkImage srcImage;
6680 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
6681 m_multisampledCopyNoCabImage.get(), // VkImage dstImage;
6682 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout dstImageLayout;
6683 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
6684 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
6685 };
6686 const VkCopyImageInfo2KHR copyImageInfo2KHRCopy =
6687 {
6688 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
6689 DE_NULL, // const void* pNext;
6690 m_multisampledCopyNoCabImage.get(), // VkImage srcImage;
6691 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // VkImageLayout srcImageLayout;
6692 m_multisampledCopyImage.get(), // VkImage dstImage;
6693 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
6694 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
6695 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
6696 };
6697
6698 vk.cmdCopyImage2KHR(*m_cmdBuffer, ©ImageInfo2KHR);
6699 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &betweenCopyImageBarrier);
6700 vk.cmdCopyImage2KHR(*m_cmdBuffer, ©ImageInfo2KHRCopy);
6701 }
6702 else
6703 {
6704 DE_ASSERT(m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2);
6705 const VkCopyImageInfo2KHR copyImageInfo2KHR =
6706 {
6707 VK_STRUCTURE_TYPE_COPY_IMAGE_INFO_2_KHR, // VkStructureType sType;
6708 DE_NULL, // const void* pNext;
6709 m_multisampledImage.get(), // VkImage srcImage;
6710 m_params.src.image.operationLayout, // VkImageLayout srcImageLayout;
6711 m_multisampledCopyImage.get(), // VkImage dstImage;
6712 m_params.dst.image.operationLayout, // VkImageLayout dstImageLayout;
6713 (deUint32)imageCopies2KHR.size(), // uint32_t regionCount;
6714 imageCopies2KHR.data() // const VkImageCopy2KHR* pRegions;
6715 };
6716
6717 vk.cmdCopyImage2KHR(*m_cmdBuffer, ©ImageInfo2KHR);
6718 }
6719 }
6720
6721 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarriers);
6722 endCommandBuffer(vk, *m_cmdBuffer);
6723
6724 submitCommandsAndWait (vk, vkDevice, queue, *m_cmdBuffer);
6725 }
6726
6727 class ResolveImageToImageTestCase : public vkt::TestCase
6728 {
6729 public:
ResolveImageToImageTestCase(tcu::TestContext & testCtx,const std::string & name,const std::string & description,const TestParams params,const ResolveImageToImageOptions options=NO_OPTIONAL_OPERATION)6730 ResolveImageToImageTestCase (tcu::TestContext& testCtx,
6731 const std::string& name,
6732 const std::string& description,
6733 const TestParams params,
6734 const ResolveImageToImageOptions options = NO_OPTIONAL_OPERATION)
6735 : vkt::TestCase (testCtx, name, description)
6736 , m_params (params)
6737 , m_options (options)
6738 {}
6739
6740 virtual void initPrograms (SourceCollections& programCollection) const;
6741
createInstance(Context & context) const6742 virtual TestInstance* createInstance (Context& context) const
6743 {
6744 return new ResolveImageToImage(context, m_params, m_options);
6745 }
6746
checkSupport(Context & context) const6747 virtual void checkSupport (Context& context) const
6748 {
6749 const VkSampleCountFlagBits rasterizationSamples = m_params.samples;
6750
6751 // Intermediate result check uses fragmentStoresAndAtomics.
6752 if (ResolveImageToImage::shouldVerifyIntermediateResults(m_options) && !context.getDeviceFeatures().fragmentStoresAndAtomics)
6753 {
6754 TCU_THROW(NotSupportedError, "fragmentStoresAndAtomics not supported");
6755 }
6756
6757 if (!(context.getDeviceProperties().limits.framebufferColorSampleCounts & rasterizationSamples))
6758 throw tcu::NotSupportedError("Unsupported number of rasterization samples");
6759
6760 VkImageFormatProperties properties;
6761 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6762 m_params.src.image.format,
6763 m_params.src.image.imageType,
6764 VK_IMAGE_TILING_OPTIMAL,
6765 VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 0,
6766 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED) ||
6767 (context.getInstanceInterface().getPhysicalDeviceImageFormatProperties (context.getPhysicalDevice(),
6768 m_params.dst.image.format,
6769 m_params.dst.image.imageType,
6770 VK_IMAGE_TILING_OPTIMAL,
6771 VK_IMAGE_USAGE_TRANSFER_DST_BIT, 0,
6772 &properties) == VK_ERROR_FORMAT_NOT_SUPPORTED))
6773 {
6774 TCU_THROW(NotSupportedError, "Format not supported");
6775 }
6776
6777 if ((m_params.extensionUse == EXTENSION_USE_COPY_COMMANDS2) &&
6778 (!context.isDeviceFunctionalitySupported("VK_KHR_copy_commands2")))
6779 {
6780 TCU_THROW(NotSupportedError, "VK_KHR_copy_commands2 is not supported");
6781 }
6782 }
6783
6784 private:
6785 TestParams m_params;
6786 const ResolveImageToImageOptions m_options;
6787 };
6788
initPrograms(SourceCollections & programCollection) const6789 void ResolveImageToImageTestCase::initPrograms (SourceCollections& programCollection) const
6790 {
6791 programCollection.glslSources.add("vert") << glu::VertexSource(
6792 "#version 310 es\n"
6793 "layout (location = 0) in highp vec4 a_position;\n"
6794 "void main()\n"
6795 "{\n"
6796 " gl_Position = a_position;\n"
6797 "}\n");
6798
6799
6800 programCollection.glslSources.add("frag") << glu::FragmentSource(
6801 "#version 310 es\n"
6802 "layout (location = 0) out highp vec4 o_color;\n"
6803 "void main()\n"
6804 "{\n"
6805 " o_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6806 "}\n");
6807
6808 if (m_options == COPY_MS_IMAGE_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE || m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE || m_options == COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION)
6809 {
6810 // The shader verifies all layers in the copied image are the same as the source image.
6811 // This needs an image view per layer in the copied image.
6812 // Set 0 contains the output buffer.
6813 // Set 1 contains the input attachments.
6814
6815 std::ostringstream verificationShader;
6816
6817 verificationShader
6818 << "#version 450\n"
6819 << "\n"
6820 << "layout (push_constant, std430) uniform PushConstants {\n"
6821 << " int width;\n"
6822 << " int height;\n"
6823 << " int samples;\n"
6824 << "};\n"
6825 << "layout (set=0, binding=0) buffer VerificationResults {\n"
6826 << " int verificationFlags[];\n"
6827 << "};\n"
6828 << "layout (input_attachment_index=0, set=1, binding=0) uniform subpassInputMS attachment0;\n"
6829 ;
6830
6831 const auto dstLayers = getArraySize(m_params.dst.image);
6832
6833 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6834 {
6835 verificationShader << "layout (input_attachment_index=1, set=1, binding=1) uniform subpassInputMS attachment1;\n";
6836 }
6837 else
6838 {
6839 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6840 {
6841 const auto i = layerNdx + 1u;
6842 verificationShader << "layout (input_attachment_index=" << i << ", set=1, binding=" << i << ") uniform subpassInputMS attachment" << i << ";\n";
6843 }
6844 }
6845
6846 // Using a loop to iterate over each sample avoids the need for the sampleRateShading feature. The pipeline needs to be
6847 // created with a single sample.
6848 verificationShader
6849 << "\n"
6850 << "void main() {\n"
6851 << " for (int sampleID = 0; sampleID < samples; ++sampleID) {\n"
6852 << " vec4 orig = subpassLoad(attachment0, sampleID);\n"
6853 ;
6854
6855 std::ostringstream testCondition;
6856 if (m_options == COPY_MS_IMAGE_LAYER_TO_MS_IMAGE)
6857 {
6858 verificationShader << " vec4 copy = subpassLoad(attachment1, sampleID);\n";
6859 testCondition << "orig == copy";
6860 }
6861 else
6862 {
6863 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6864 {
6865 const auto i = layerNdx + 1u;
6866 verificationShader << " vec4 copy" << i << " = subpassLoad(attachment" << i << ", sampleID);\n";
6867 }
6868
6869 for (deUint32 layerNdx = 0u; layerNdx < dstLayers; ++layerNdx)
6870 {
6871 const auto i = layerNdx + 1u;
6872 testCondition << (layerNdx == 0u ? "" : " && ") << "orig == copy" << i;
6873 }
6874 }
6875
6876 verificationShader
6877 << "\n"
6878 << " ivec3 coords = ivec3(int(gl_FragCoord.x), int(gl_FragCoord.y), sampleID);\n"
6879 << " int bufferPos = (coords.y * width + coords.x) * samples + coords.z;\n"
6880 << "\n"
6881 << " verificationFlags[bufferPos] = ((" << testCondition.str() << ") ? 1 : 0); \n"
6882 << " }\n"
6883 << "}\n"
6884 ;
6885
6886 programCollection.glslSources.add("verify") << glu::FragmentSource(verificationShader.str());
6887 }
6888 }
6889
6890 struct BufferOffsetParams
6891 {
6892 static constexpr deUint32 kMaxOffset = 8u;
6893
6894 deUint32 srcOffset;
6895 deUint32 dstOffset;
6896 };
6897
checkZerosAt(const std::vector<deUint8> & bufferData,deUint32 from,deUint32 count)6898 void checkZerosAt(const std::vector<deUint8>& bufferData, deUint32 from, deUint32 count)
6899 {
6900 constexpr deUint8 zero{0};
6901 for (deUint32 i = 0; i < count; ++i)
6902 {
6903 const auto& val = bufferData[from + i];
6904 if (val != zero)
6905 {
6906 std::ostringstream msg;
6907 msg << "Unexpected non-zero byte found at position " << (from + i) << ": " << static_cast<int>(val);
6908 TCU_FAIL(msg.str());
6909 }
6910 }
6911 }
6912
bufferOffsetTest(Context & ctx,BufferOffsetParams params)6913 tcu::TestStatus bufferOffsetTest (Context& ctx, BufferOffsetParams params)
6914 {
6915 // Try to copy blocks of sizes 1 to kMaxOffset. Each copy region will use a block of kMaxOffset*2 bytes to take into account srcOffset and dstOffset.
6916 constexpr auto kMaxOffset = BufferOffsetParams::kMaxOffset;
6917 constexpr auto kBlockSize = kMaxOffset * 2u;
6918 constexpr auto kBufferSize = kMaxOffset * kBlockSize;
6919
6920 DE_ASSERT(params.srcOffset < kMaxOffset);
6921 DE_ASSERT(params.dstOffset < kMaxOffset);
6922
6923 const auto& vkd = ctx.getDeviceInterface();
6924 const auto device = ctx.getDevice();
6925 auto& alloc = ctx.getDefaultAllocator();
6926 const auto qIndex = ctx.getUniversalQueueFamilyIndex();
6927 const auto queue = ctx.getUniversalQueue();
6928
6929 const auto srcBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
6930 const auto dstBufferInfo = makeBufferCreateInfo(kBufferSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT);
6931
6932 BufferWithMemory srcBuffer (vkd, device, alloc, srcBufferInfo, MemoryRequirement::HostVisible);
6933 BufferWithMemory dstBuffer (vkd, device, alloc, dstBufferInfo, MemoryRequirement::HostVisible);
6934 auto& srcAlloc = srcBuffer.getAllocation();
6935 auto& dstAlloc = dstBuffer.getAllocation();
6936
6937 // Zero-out destination buffer.
6938 deMemset(dstAlloc.getHostPtr(), 0, kBufferSize);
6939 flushAlloc(vkd, device, dstAlloc);
6940
6941 // Fill source buffer with nonzero bytes.
6942 std::vector<deUint8> srcData;
6943 srcData.reserve(kBufferSize);
6944 for (deUint32 i = 0; i < kBufferSize; ++i)
6945 srcData.push_back(static_cast<deUint8>(100u + i));
6946 deMemcpy(srcAlloc.getHostPtr(), srcData.data(), de::dataSize(srcData));
6947 flushAlloc(vkd, device, srcAlloc);
6948
6949 // Copy regions.
6950 std::vector<VkBufferCopy> copies;
6951 copies.reserve(kMaxOffset);
6952 for (deUint32 i = 0; i < kMaxOffset; ++i)
6953 {
6954 const auto blockStart = kBlockSize * i;
6955 const auto copySize = i + 1u;
6956 const auto bufferCopy = makeBufferCopy(params.srcOffset + blockStart, params.dstOffset + blockStart, copySize);
6957 copies.push_back(bufferCopy);
6958 }
6959
6960 const auto cmdPool = makeCommandPool(vkd, device, qIndex);
6961 const auto cmdBufferPtr = allocateCommandBuffer(vkd, device, cmdPool.get(), VK_COMMAND_BUFFER_LEVEL_PRIMARY);
6962 const auto cmdBuffer = cmdBufferPtr.get();
6963
6964 beginCommandBuffer(vkd, cmdBuffer);
6965 vkd.cmdCopyBuffer(cmdBuffer, srcBuffer.get(), dstBuffer.get(), static_cast<deUint32>(copies.size()), copies.data());
6966 const auto barrier = makeMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT);
6967 vkd.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 1u, &barrier, 0u, nullptr, 0u, nullptr);
6968 endCommandBuffer(vkd, cmdBuffer);
6969 submitCommandsAndWait(vkd, device, queue, cmdBuffer);
6970 invalidateAlloc(vkd, device, dstAlloc);
6971
6972 // Verify destination buffer data.
6973 std::vector<deUint8> dstData(kBufferSize);
6974 deMemcpy(dstData.data(), dstAlloc.getHostPtr(), de::dataSize(dstData));
6975
6976 for (deUint32 blockIdx = 0; blockIdx < kMaxOffset; ++blockIdx)
6977 {
6978 const auto blockStart = kBlockSize * blockIdx;
6979 const auto copySize = blockIdx + 1u;
6980
6981 // Verify no data has been written before dstOffset.
6982 checkZerosAt(dstData, blockStart, params.dstOffset);
6983
6984 // Verify copied block.
6985 for (deUint32 i = 0; i < copySize; ++i)
6986 {
6987 const auto& dstVal = dstData[blockStart + params.dstOffset + i];
6988 const auto& srcVal = srcData[blockStart + params.srcOffset + i];
6989 if (dstVal != srcVal)
6990 {
6991 std::ostringstream msg;
6992 msg << "Unexpected value found at position " << (blockStart + params.dstOffset + i) << ": expected " << static_cast<int>(srcVal) << " but found " << static_cast<int>(dstVal);
6993 TCU_FAIL(msg.str());
6994 }
6995 }
6996
6997 // Verify no data has been written after copy block.
6998 checkZerosAt(dstData, blockStart + params.dstOffset + copySize, kBlockSize - (params.dstOffset + copySize));
6999 }
7000
7001 return tcu::TestStatus::pass("Pass");
7002 }
7003
getSampleCountCaseName(VkSampleCountFlagBits sampleFlag)7004 std::string getSampleCountCaseName (VkSampleCountFlagBits sampleFlag)
7005 {
7006 return de::toLower(de::toString(getSampleCountFlagsStr(sampleFlag)).substr(16));
7007 }
7008
getFormatCaseName(VkFormat format)7009 std::string getFormatCaseName (VkFormat format)
7010 {
7011 return de::toLower(de::toString(getFormatStr(format)).substr(10));
7012 }
7013
getImageLayoutCaseName(VkImageLayout layout)7014 std::string getImageLayoutCaseName (VkImageLayout layout)
7015 {
7016 switch (layout)
7017 {
7018 case VK_IMAGE_LAYOUT_GENERAL:
7019 return "general";
7020 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
7021 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
7022 return "optimal";
7023 default:
7024 DE_ASSERT(false);
7025 return "";
7026 }
7027 }
7028
7029 const deInt32 defaultSize = 64;
7030 const deInt32 defaultHalfSize = defaultSize / 2;
7031 const deInt32 defaultFourthSize = defaultSize / 4;
7032 const deInt32 defaultSixteenthSize = defaultSize / 16;
7033 const VkExtent3D defaultExtent = {defaultSize, defaultSize, 1};
7034 const VkExtent3D defaultHalfExtent = {defaultHalfSize, defaultHalfSize, 1};
7035 const VkExtent3D default1dExtent = {defaultSize, 1, 1};
7036 const VkExtent3D default3dExtent = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
7037
7038 const VkImageSubresourceLayers defaultSourceLayer =
7039 {
7040 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
7041 0u, // deUint32 mipLevel;
7042 0u, // deUint32 baseArrayLayer;
7043 1u, // deUint32 layerCount;
7044 };
7045
addImageToImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)7046 void addImageToImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7047 {
7048 tcu::TestContext& testCtx = group->getTestContext();
7049
7050 {
7051 TestParams params;
7052 params.src.image.imageType = VK_IMAGE_TYPE_2D;
7053 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
7054 params.src.image.extent = defaultExtent;
7055 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7056 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7057 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7058 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
7059 params.dst.image.extent = defaultExtent;
7060 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7061 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7062 params.allocationKind = allocationKind;
7063 params.extensionUse = extensionUse;
7064
7065 {
7066 const VkImageCopy testCopy =
7067 {
7068 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7069 {0, 0, 0}, // VkOffset3D srcOffset;
7070 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7071 {0, 0, 0}, // VkOffset3D dstOffset;
7072 defaultExtent, // VkExtent3D extent;
7073 };
7074
7075 CopyRegion imageCopy;
7076 imageCopy.imageCopy = testCopy;
7077 params.regions.push_back(imageCopy);
7078 }
7079
7080 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image", "Whole image", params));
7081 }
7082
7083 {
7084 TestParams params;
7085 params.src.image.imageType = VK_IMAGE_TYPE_2D;
7086 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
7087 params.src.image.extent = defaultExtent;
7088 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7089 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7090 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7091 params.dst.image.format = VK_FORMAT_R32_UINT;
7092 params.dst.image.extent = defaultExtent;
7093 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7094 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7095 params.allocationKind = allocationKind;
7096 params.extensionUse = extensionUse;
7097
7098 {
7099 const VkImageCopy testCopy =
7100 {
7101 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7102 {0, 0, 0}, // VkOffset3D srcOffset;
7103 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7104 {0, 0, 0}, // VkOffset3D dstOffset;
7105 defaultExtent, // VkExtent3D extent;
7106 };
7107
7108 CopyRegion imageCopy;
7109 imageCopy.imageCopy = testCopy;
7110 params.regions.push_back(imageCopy);
7111 }
7112
7113 group->addChild(new CopyImageToImageTestCase(testCtx, "whole_image_diff_fromat", "Whole image with different format", params));
7114 }
7115
7116 {
7117 TestParams params;
7118 params.src.image.imageType = VK_IMAGE_TYPE_2D;
7119 params.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
7120 params.src.image.extent = defaultExtent;
7121 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7122 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7123 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7124 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
7125 params.dst.image.extent = defaultExtent;
7126 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7127 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7128 params.allocationKind = allocationKind;
7129 params.extensionUse = extensionUse;
7130
7131 {
7132 const VkImageCopy testCopy =
7133 {
7134 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7135 {0, 0, 0}, // VkOffset3D srcOffset;
7136 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7137 {defaultFourthSize, defaultFourthSize / 2, 0}, // VkOffset3D dstOffset;
7138 {defaultFourthSize / 2, defaultFourthSize / 2, 1}, // VkExtent3D extent;
7139 };
7140
7141 CopyRegion imageCopy;
7142 imageCopy.imageCopy = testCopy;
7143 params.regions.push_back(imageCopy);
7144 }
7145
7146 group->addChild(new CopyImageToImageTestCase(testCtx, "partial_image", "Partial image", params));
7147 }
7148
7149 static const struct
7150 {
7151 std::string name;
7152 vk::VkFormat format1;
7153 vk::VkFormat format2;
7154 } formats [] =
7155 {
7156 { "diff_format", vk::VK_FORMAT_R32_UINT, vk::VK_FORMAT_R8G8B8A8_UNORM },
7157 { "same_format", vk::VK_FORMAT_R8G8B8A8_UNORM, vk::VK_FORMAT_R8G8B8A8_UNORM }
7158 };
7159 static const struct
7160 {
7161 std::string name;
7162 vk::VkBool32 clear;
7163 } clears [] =
7164 {
7165 { "clear", VK_TRUE },
7166 { "noclear", VK_FALSE }
7167 };
7168 static const struct
7169 {
7170 std::string name;
7171 VkExtent3D extent;
7172 } extents [] =
7173 {
7174 { "npot", {65u, 63u, 1u} },
7175 { "pot", {64u, 64u, 1u} }
7176 };
7177
7178 for (const auto& format : formats)
7179 {
7180 for (const auto& clear : clears)
7181 {
7182 for (const auto& extent : extents)
7183 {
7184 TestParams params;
7185 params.src.image.imageType = VK_IMAGE_TYPE_2D;
7186 params.src.image.format = format.format1;
7187 params.src.image.extent = extent.extent;
7188 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7189 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7190 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7191 params.dst.image.format = format.format2;
7192 params.dst.image.extent = extent.extent;
7193 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7194 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7195 params.allocationKind = allocationKind;
7196 params.extensionUse = extensionUse;
7197 params.clearDestination = clear.clear;
7198
7199 {
7200 VkImageCopy testCopy =
7201 {
7202 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7203 {34, 34, 0}, // VkOffset3D srcOffset;
7204 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7205 {0, 0, 0}, // VkOffset3D dstOffset;
7206 {31, 29, 1} // VkExtent3D extent;
7207 };
7208
7209 if (extent.name == "pot")
7210 {
7211 testCopy.srcOffset = { 16, 16, 0 };
7212 testCopy.extent = { 32, 32, 1 };
7213 }
7214
7215 CopyRegion imageCopy;
7216 imageCopy.imageCopy = testCopy;
7217 params.regions.push_back(imageCopy);
7218 }
7219
7220 // Example test case name: "partial_image_npot_diff_format_clear"
7221 const std::string testCaseName = "partial_image_" + extent.name + "_" + format.name + "_" + clear.name;
7222
7223 group->addChild(new CopyImageToImageTestCase(testCtx, testCaseName, "", params));
7224 }
7225 }
7226 }
7227
7228 {
7229 TestParams params;
7230 params.src.image.imageType = VK_IMAGE_TYPE_2D;
7231 params.src.image.format = VK_FORMAT_D32_SFLOAT;
7232 params.src.image.extent = defaultExtent;
7233 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7234 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7235 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7236 params.dst.image.format = VK_FORMAT_D32_SFLOAT;
7237 params.dst.image.extent = defaultExtent;
7238 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7239 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7240 params.allocationKind = allocationKind;
7241 params.extensionUse = extensionUse;
7242
7243 {
7244 const VkImageSubresourceLayers sourceLayer =
7245 {
7246 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
7247 0u, // deUint32 mipLevel;
7248 0u, // deUint32 baseArrayLayer;
7249 1u // deUint32 layerCount;
7250 };
7251 const VkImageCopy testCopy =
7252 {
7253 sourceLayer, // VkImageSubresourceLayers srcSubresource;
7254 {0, 0, 0}, // VkOffset3D srcOffset;
7255 sourceLayer, // VkImageSubresourceLayers dstSubresource;
7256 {defaultFourthSize, defaultFourthSize / 2, 0}, // VkOffset3D dstOffset;
7257 {defaultFourthSize / 2, defaultFourthSize / 2, 1}, // VkExtent3D extent;
7258 };
7259
7260 CopyRegion imageCopy;
7261 imageCopy.imageCopy = testCopy;
7262 params.regions.push_back(imageCopy);
7263 }
7264
7265 group->addChild(new CopyImageToImageTestCase(testCtx, "depth", "With depth", params));
7266 }
7267
7268 {
7269 TestParams params;
7270 params.src.image.imageType = VK_IMAGE_TYPE_2D;
7271 params.src.image.format = VK_FORMAT_S8_UINT;
7272 params.src.image.extent = defaultExtent;
7273 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7274 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
7275 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7276 params.dst.image.format = VK_FORMAT_S8_UINT;
7277 params.dst.image.extent = defaultExtent;
7278 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7279 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
7280 params.allocationKind = allocationKind;
7281 params.extensionUse = extensionUse;
7282
7283 {
7284 const VkImageSubresourceLayers sourceLayer =
7285 {
7286 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
7287 0u, // deUint32 mipLevel;
7288 0u, // deUint32 baseArrayLayer;
7289 1u // deUint32 layerCount;
7290 };
7291 const VkImageCopy testCopy =
7292 {
7293 sourceLayer, // VkImageSubresourceLayers srcSubresource;
7294 {0, 0, 0}, // VkOffset3D srcOffset;
7295 sourceLayer, // VkImageSubresourceLayers dstSubresource;
7296 {defaultFourthSize, defaultFourthSize / 2, 0}, // VkOffset3D dstOffset;
7297 {defaultFourthSize / 2, defaultFourthSize / 2, 1}, // VkExtent3D extent;
7298 };
7299
7300 CopyRegion imageCopy;
7301 imageCopy.imageCopy = testCopy;
7302 params.regions.push_back(imageCopy);
7303 }
7304
7305 group->addChild(new CopyImageToImageTestCase(testCtx, "stencil", "With stencil", params));
7306 }
7307 }
7308
7309 struct CopyColorTestParams
7310 {
7311 TestParams params;
7312 const VkFormat* compatibleFormats;
7313 };
7314
addImageToImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,TestParams params)7315 void addImageToImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, TestParams params)
7316 {
7317 const VkImageLayout copySrcLayouts[] =
7318 {
7319 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7320 VK_IMAGE_LAYOUT_GENERAL
7321 };
7322 const VkImageLayout copyDstLayouts[] =
7323 {
7324 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7325 VK_IMAGE_LAYOUT_GENERAL
7326 };
7327
7328 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
7329 {
7330 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
7331
7332 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
7333 {
7334 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
7335
7336 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
7337 getImageLayoutCaseName(params.dst.image.operationLayout);
7338 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
7339 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
7340 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
7341 }
7342 }
7343 }
7344
isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams & testParams)7345 bool isAllowedImageToImageAllFormatsColorSrcFormatTests(const CopyColorTestParams& testParams)
7346 {
7347 bool result = true;
7348
7349 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
7350 {
7351 DE_ASSERT(!dedicatedAllocationImageToImageFormatsToTestSet.empty());
7352
7353 result =
7354 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.dst.image.format) ||
7355 de::contains(dedicatedAllocationImageToImageFormatsToTestSet, testParams.params.src.image.format);
7356 }
7357
7358 return result;
7359 }
7360
addImageToImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,CopyColorTestParams testParams)7361 void addImageToImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, CopyColorTestParams testParams)
7362 {
7363 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format.
7364 const VkFormat srcFormatOnly[2] = { testParams.params.src.image.format, VK_FORMAT_UNDEFINED };
7365 const VkFormat* formatList = (testParams.compatibleFormats ? testParams.compatibleFormats : srcFormatOnly);
7366
7367 for (int dstFormatIndex = 0; formatList[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
7368 {
7369 testParams.params.dst.image.format = formatList[dstFormatIndex];
7370
7371 const VkFormat srcFormat = testParams.params.src.image.format;
7372 const VkFormat dstFormat = testParams.params.dst.image.format;
7373
7374 if (!isSupportedByFramework(dstFormat) && !isCompressedFormat(dstFormat))
7375 continue;
7376
7377 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
7378 continue;
7379
7380 if (isCompressedFormat(srcFormat) && isCompressedFormat(dstFormat))
7381 if ((getBlockWidth(srcFormat) != getBlockWidth(dstFormat)) || (getBlockHeight(srcFormat) != getBlockHeight(dstFormat)))
7382 continue;
7383
7384 const std::string description = "Copy to destination format " + getFormatCaseName(dstFormat);
7385 addTestGroup(group, getFormatCaseName(dstFormat), description, addImageToImageAllFormatsColorSrcFormatDstFormatTests, testParams.params);
7386 }
7387 }
7388
7389 const VkFormat compatibleFormats8Bit[] =
7390 {
7391 VK_FORMAT_R4G4_UNORM_PACK8,
7392 VK_FORMAT_R8_UNORM,
7393 VK_FORMAT_R8_SNORM,
7394 VK_FORMAT_R8_USCALED,
7395 VK_FORMAT_R8_SSCALED,
7396 VK_FORMAT_R8_UINT,
7397 VK_FORMAT_R8_SINT,
7398 VK_FORMAT_R8_SRGB,
7399
7400 VK_FORMAT_UNDEFINED
7401 };
7402 const VkFormat compatibleFormats16Bit[] =
7403 {
7404 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7405 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
7406 VK_FORMAT_R5G6B5_UNORM_PACK16,
7407 VK_FORMAT_B5G6R5_UNORM_PACK16,
7408 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
7409 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
7410 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
7411 VK_FORMAT_R8G8_UNORM,
7412 VK_FORMAT_R8G8_SNORM,
7413 VK_FORMAT_R8G8_USCALED,
7414 VK_FORMAT_R8G8_SSCALED,
7415 VK_FORMAT_R8G8_UINT,
7416 VK_FORMAT_R8G8_SINT,
7417 VK_FORMAT_R8G8_SRGB,
7418 VK_FORMAT_R16_UNORM,
7419 VK_FORMAT_R16_SNORM,
7420 VK_FORMAT_R16_USCALED,
7421 VK_FORMAT_R16_SSCALED,
7422 VK_FORMAT_R16_UINT,
7423 VK_FORMAT_R16_SINT,
7424 VK_FORMAT_R16_SFLOAT,
7425 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
7426 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
7427
7428 VK_FORMAT_UNDEFINED
7429 };
7430 const VkFormat compatibleFormats24Bit[] =
7431 {
7432 VK_FORMAT_R8G8B8_UNORM,
7433 VK_FORMAT_R8G8B8_SNORM,
7434 VK_FORMAT_R8G8B8_USCALED,
7435 VK_FORMAT_R8G8B8_SSCALED,
7436 VK_FORMAT_R8G8B8_UINT,
7437 VK_FORMAT_R8G8B8_SINT,
7438 VK_FORMAT_R8G8B8_SRGB,
7439 VK_FORMAT_B8G8R8_UNORM,
7440 VK_FORMAT_B8G8R8_SNORM,
7441 VK_FORMAT_B8G8R8_USCALED,
7442 VK_FORMAT_B8G8R8_SSCALED,
7443 VK_FORMAT_B8G8R8_UINT,
7444 VK_FORMAT_B8G8R8_SINT,
7445 VK_FORMAT_B8G8R8_SRGB,
7446
7447 VK_FORMAT_UNDEFINED
7448 };
7449 const VkFormat compatibleFormats32Bit[] =
7450 {
7451 VK_FORMAT_R8G8B8A8_UNORM,
7452 VK_FORMAT_R8G8B8A8_SNORM,
7453 VK_FORMAT_R8G8B8A8_USCALED,
7454 VK_FORMAT_R8G8B8A8_SSCALED,
7455 VK_FORMAT_R8G8B8A8_UINT,
7456 VK_FORMAT_R8G8B8A8_SINT,
7457 VK_FORMAT_R8G8B8A8_SRGB,
7458 VK_FORMAT_B8G8R8A8_UNORM,
7459 VK_FORMAT_B8G8R8A8_SNORM,
7460 VK_FORMAT_B8G8R8A8_USCALED,
7461 VK_FORMAT_B8G8R8A8_SSCALED,
7462 VK_FORMAT_B8G8R8A8_UINT,
7463 VK_FORMAT_B8G8R8A8_SINT,
7464 VK_FORMAT_B8G8R8A8_SRGB,
7465 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
7466 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
7467 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
7468 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
7469 VK_FORMAT_A8B8G8R8_UINT_PACK32,
7470 VK_FORMAT_A8B8G8R8_SINT_PACK32,
7471 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
7472 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
7473 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
7474 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
7475 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
7476 VK_FORMAT_A2R10G10B10_UINT_PACK32,
7477 VK_FORMAT_A2R10G10B10_SINT_PACK32,
7478 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
7479 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
7480 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
7481 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
7482 VK_FORMAT_A2B10G10R10_UINT_PACK32,
7483 VK_FORMAT_A2B10G10R10_SINT_PACK32,
7484 VK_FORMAT_R16G16_UNORM,
7485 VK_FORMAT_R16G16_SNORM,
7486 VK_FORMAT_R16G16_USCALED,
7487 VK_FORMAT_R16G16_SSCALED,
7488 VK_FORMAT_R16G16_UINT,
7489 VK_FORMAT_R16G16_SINT,
7490 VK_FORMAT_R16G16_SFLOAT,
7491 VK_FORMAT_R32_UINT,
7492 VK_FORMAT_R32_SINT,
7493 VK_FORMAT_R32_SFLOAT,
7494
7495 VK_FORMAT_UNDEFINED
7496 };
7497 const VkFormat compatibleFormats48Bit[] =
7498 {
7499 VK_FORMAT_R16G16B16_UNORM,
7500 VK_FORMAT_R16G16B16_SNORM,
7501 VK_FORMAT_R16G16B16_USCALED,
7502 VK_FORMAT_R16G16B16_SSCALED,
7503 VK_FORMAT_R16G16B16_UINT,
7504 VK_FORMAT_R16G16B16_SINT,
7505 VK_FORMAT_R16G16B16_SFLOAT,
7506
7507 VK_FORMAT_UNDEFINED
7508 };
7509 const VkFormat compatibleFormats64Bit[] =
7510 {
7511 VK_FORMAT_R16G16B16A16_UNORM,
7512 VK_FORMAT_R16G16B16A16_SNORM,
7513 VK_FORMAT_R16G16B16A16_USCALED,
7514 VK_FORMAT_R16G16B16A16_SSCALED,
7515 VK_FORMAT_R16G16B16A16_UINT,
7516 VK_FORMAT_R16G16B16A16_SINT,
7517 VK_FORMAT_R16G16B16A16_SFLOAT,
7518 VK_FORMAT_R32G32_UINT,
7519 VK_FORMAT_R32G32_SINT,
7520 VK_FORMAT_R32G32_SFLOAT,
7521 VK_FORMAT_R64_UINT,
7522 VK_FORMAT_R64_SINT,
7523 VK_FORMAT_R64_SFLOAT,
7524
7525 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
7526 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
7527 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
7528 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
7529 VK_FORMAT_BC4_UNORM_BLOCK,
7530 VK_FORMAT_BC4_SNORM_BLOCK,
7531
7532 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
7533 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
7534 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
7535 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
7536
7537 VK_FORMAT_EAC_R11_UNORM_BLOCK,
7538 VK_FORMAT_EAC_R11_SNORM_BLOCK,
7539
7540 VK_FORMAT_UNDEFINED
7541 };
7542 const VkFormat compatibleFormats96Bit[] =
7543 {
7544 VK_FORMAT_R32G32B32_UINT,
7545 VK_FORMAT_R32G32B32_SINT,
7546 VK_FORMAT_R32G32B32_SFLOAT,
7547
7548 VK_FORMAT_UNDEFINED
7549 };
7550 const VkFormat compatibleFormats128Bit[] =
7551 {
7552 VK_FORMAT_R32G32B32A32_UINT,
7553 VK_FORMAT_R32G32B32A32_SINT,
7554 VK_FORMAT_R32G32B32A32_SFLOAT,
7555 VK_FORMAT_R64G64_UINT,
7556 VK_FORMAT_R64G64_SINT,
7557 VK_FORMAT_R64G64_SFLOAT,
7558
7559 VK_FORMAT_BC2_UNORM_BLOCK,
7560 VK_FORMAT_BC2_SRGB_BLOCK,
7561 VK_FORMAT_BC3_UNORM_BLOCK,
7562 VK_FORMAT_BC3_SRGB_BLOCK,
7563 VK_FORMAT_BC5_UNORM_BLOCK,
7564 VK_FORMAT_BC5_SNORM_BLOCK,
7565 VK_FORMAT_BC6H_UFLOAT_BLOCK,
7566 VK_FORMAT_BC6H_SFLOAT_BLOCK,
7567 VK_FORMAT_BC7_UNORM_BLOCK,
7568 VK_FORMAT_BC7_SRGB_BLOCK,
7569
7570 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
7571 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
7572
7573 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
7574 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
7575
7576 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
7577 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
7578 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
7579 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
7580 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
7581 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
7582 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
7583 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
7584 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
7585 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
7586 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
7587 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
7588 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
7589 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
7590 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
7591 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
7592 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
7593 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
7594 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
7595 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
7596 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
7597 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
7598 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
7599 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
7600 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
7601 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
7602 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
7603 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
7604
7605 VK_FORMAT_UNDEFINED
7606 };
7607 const VkFormat compatibleFormats192Bit[] =
7608 {
7609 VK_FORMAT_R64G64B64_UINT,
7610 VK_FORMAT_R64G64B64_SINT,
7611 VK_FORMAT_R64G64B64_SFLOAT,
7612
7613 VK_FORMAT_UNDEFINED
7614 };
7615 const VkFormat compatibleFormats256Bit[] =
7616 {
7617 VK_FORMAT_R64G64B64A64_UINT,
7618 VK_FORMAT_R64G64B64A64_SINT,
7619 VK_FORMAT_R64G64B64A64_SFLOAT,
7620
7621 VK_FORMAT_UNDEFINED
7622 };
7623
7624 const VkFormat* colorImageFormatsToTest[] =
7625 {
7626 compatibleFormats8Bit,
7627 compatibleFormats16Bit,
7628 compatibleFormats24Bit,
7629 compatibleFormats32Bit,
7630 compatibleFormats48Bit,
7631 compatibleFormats64Bit,
7632 compatibleFormats96Bit,
7633 compatibleFormats128Bit,
7634 compatibleFormats192Bit,
7635 compatibleFormats256Bit
7636 };
7637
7638 const VkFormat dedicatedAllocationImageToImageFormatsToTest[] =
7639 {
7640 // From compatibleFormats8Bit
7641 VK_FORMAT_R4G4_UNORM_PACK8,
7642 VK_FORMAT_R8_SRGB,
7643
7644 // From compatibleFormats16Bit
7645 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7646 VK_FORMAT_R16_SFLOAT,
7647
7648 // From compatibleFormats24Bit
7649 VK_FORMAT_R8G8B8_UNORM,
7650 VK_FORMAT_B8G8R8_SRGB,
7651
7652 // From compatibleFormats32Bit
7653 VK_FORMAT_R8G8B8A8_UNORM,
7654 VK_FORMAT_R32_SFLOAT,
7655
7656 // From compatibleFormats48Bit
7657 VK_FORMAT_R16G16B16_UNORM,
7658 VK_FORMAT_R16G16B16_SFLOAT,
7659
7660 // From compatibleFormats64Bit
7661 VK_FORMAT_R16G16B16A16_UNORM,
7662 VK_FORMAT_R64_SFLOAT,
7663
7664 // From compatibleFormats96Bit
7665 VK_FORMAT_R32G32B32_UINT,
7666 VK_FORMAT_R32G32B32_SFLOAT,
7667
7668 // From compatibleFormats128Bit
7669 VK_FORMAT_R32G32B32A32_UINT,
7670 VK_FORMAT_R64G64_SFLOAT,
7671
7672 // From compatibleFormats192Bit
7673 VK_FORMAT_R64G64B64_UINT,
7674 VK_FORMAT_R64G64B64_SFLOAT,
7675
7676 // From compatibleFormats256Bit
7677 VK_FORMAT_R64G64B64A64_UINT,
7678 VK_FORMAT_R64G64B64A64_SFLOAT,
7679 };
7680
addImageToImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)7681 void addImageToImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7682 {
7683 if (allocationKind == ALLOCATION_KIND_DEDICATED)
7684 {
7685 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7686 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
7687 dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7688 }
7689
7690 // 2D tests.
7691 {
7692 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
7693
7694 TestParams params;
7695 params.src.image.imageType = VK_IMAGE_TYPE_2D;
7696 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7697 params.src.image.extent = defaultExtent;
7698 params.dst.image.extent = defaultExtent;
7699 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7700 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7701 params.allocationKind = allocationKind;
7702 params.extensionUse = extensionUse;
7703
7704 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
7705 {
7706 const VkImageCopy testCopy =
7707 {
7708 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7709 {0, 0, 0}, // VkOffset3D srcOffset;
7710 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7711 {i, defaultSize - i - defaultFourthSize, 0}, // VkOffset3D dstOffset;
7712 {defaultFourthSize, defaultFourthSize, 1}, // VkExtent3D extent;
7713 };
7714
7715 CopyRegion imageCopy;
7716 imageCopy.imageCopy = testCopy;
7717
7718 params.regions.push_back(imageCopy);
7719 }
7720
7721 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7722 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7723 {
7724 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
7725 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7726 {
7727 params.src.image.format = compatibleFormats[srcFormatIndex];
7728 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7729 continue;
7730
7731 CopyColorTestParams testParams;
7732 testParams.params = params;
7733 testParams.compatibleFormats = compatibleFormats;
7734
7735 const std::string testName = getFormatCaseName(params.src.image.format);
7736 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
7737 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7738 }
7739 }
7740
7741 group->addChild(subGroup.release());
7742 }
7743
7744 // 1D tests.
7745 {
7746 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
7747
7748 TestParams params;
7749 params.src.image.imageType = VK_IMAGE_TYPE_1D;
7750 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
7751 params.src.image.extent = default1dExtent;
7752 params.dst.image.extent = default1dExtent;
7753 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7754 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7755 params.allocationKind = allocationKind;
7756 params.extensionUse = extensionUse;
7757
7758 for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
7759 {
7760 const VkImageCopy testCopy =
7761 {
7762 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7763 {0, 0, 0}, // VkOffset3D srcOffset;
7764 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7765 {i, 0, 0}, // VkOffset3D dstOffset;
7766 {defaultFourthSize, 1, 1}, // VkExtent3D extent;
7767 };
7768
7769 CopyRegion imageCopy;
7770 imageCopy.imageCopy = testCopy;
7771
7772 params.regions.push_back(imageCopy);
7773 }
7774
7775 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7776 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7777 {
7778 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
7779 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7780 {
7781 params.src.image.format = compatibleFormats[srcFormatIndex];
7782 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7783 continue;
7784
7785 CopyColorTestParams testParams;
7786 testParams.params = params;
7787 testParams.compatibleFormats = nullptr;
7788
7789 const std::string testName = getFormatCaseName(params.src.image.format);
7790 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
7791 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7792 }
7793 }
7794
7795 group->addChild(subGroup.release());
7796 }
7797
7798 // 3D tests. Note we use smaller dimensions here for performance reasons.
7799 {
7800 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
7801
7802 TestParams params;
7803 params.src.image.imageType = VK_IMAGE_TYPE_3D;
7804 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
7805 params.src.image.extent = default3dExtent;
7806 params.dst.image.extent = default3dExtent;
7807 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7808 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7809 params.allocationKind = allocationKind;
7810 params.extensionUse = extensionUse;
7811
7812 for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
7813 {
7814 const VkImageCopy testCopy =
7815 {
7816 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7817 {0, 0, 0}, // VkOffset3D srcOffset;
7818 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7819 {i, defaultFourthSize - i - defaultSixteenthSize, i}, // VkOffset3D dstOffset;
7820 {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize}, // VkExtent3D extent;
7821 };
7822
7823 CopyRegion imageCopy;
7824 imageCopy.imageCopy = testCopy;
7825
7826 params.regions.push_back(imageCopy);
7827 }
7828
7829 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
7830 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
7831 {
7832 const VkFormat* compatibleFormats = colorImageFormatsToTest[compatibleFormatsIndex];
7833 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
7834 {
7835 params.src.image.format = compatibleFormats[srcFormatIndex];
7836 if (!isSupportedByFramework(params.src.image.format) && !isCompressedFormat(params.src.image.format))
7837 continue;
7838
7839 CopyColorTestParams testParams;
7840 testParams.params = params;
7841 testParams.compatibleFormats = nullptr;
7842
7843 const std::string testName = getFormatCaseName(params.src.image.format);
7844 const std::string description = "Copy from source format " + getFormatCaseName(params.src.image.format);
7845 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsColorSrcFormatTests, testParams);
7846 }
7847 }
7848
7849 group->addChild(subGroup.release());
7850 }
7851 }
7852
addImageToImageDimensionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)7853 void addImageToImageDimensionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
7854 {
7855 tcu::TestContext& testCtx = group->getTestContext();
7856
7857 const VkFormat testFormats[][2] =
7858 {
7859 // From compatibleFormats8Bit
7860 {
7861 VK_FORMAT_R4G4_UNORM_PACK8,
7862 VK_FORMAT_R8_SRGB
7863 },
7864 // From compatibleFormats16Bit
7865 {
7866 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
7867 VK_FORMAT_R16_SFLOAT,
7868 },
7869 // From compatibleFormats24Bit
7870 {
7871 VK_FORMAT_R8G8B8_UNORM,
7872 VK_FORMAT_B8G8R8_SRGB
7873 },
7874 // From compatibleFormats32Bit
7875 {
7876 VK_FORMAT_R8G8B8A8_UNORM,
7877 VK_FORMAT_R32_SFLOAT
7878 },
7879 // From compatibleFormats48Bit
7880 {
7881 VK_FORMAT_R16G16B16_UNORM,
7882 VK_FORMAT_R16G16B16_SFLOAT
7883 },
7884 // From compatibleFormats64Bit
7885 {
7886 VK_FORMAT_R16G16B16A16_UNORM,
7887 VK_FORMAT_R64_SFLOAT
7888 },
7889 // From compatibleFormats96Bit
7890 {
7891 VK_FORMAT_R32G32B32_UINT,
7892 VK_FORMAT_R32G32B32_SFLOAT
7893 },
7894 // From compatibleFormats128Bit
7895 {
7896 VK_FORMAT_R32G32B32A32_UINT,
7897 VK_FORMAT_R64G64_SFLOAT
7898 },
7899 // From compatibleFormats192Bit
7900 {
7901 VK_FORMAT_R64G64B64_UINT,
7902 VK_FORMAT_R64G64B64_SFLOAT,
7903 },
7904 // From compatibleFormats256Bit
7905 {
7906 VK_FORMAT_R64G64B64A64_UINT,
7907 VK_FORMAT_R64G64B64A64_SFLOAT
7908 }
7909 };
7910
7911 const tcu::UVec2 imageDimensions[] =
7912 {
7913 // large pot x small pot
7914 tcu::UVec2(4096, 4u),
7915 tcu::UVec2(8192, 4u),
7916 tcu::UVec2(16384, 4u),
7917 tcu::UVec2(32768, 4u),
7918
7919 // large pot x small npot
7920 tcu::UVec2(4096, 6u),
7921 tcu::UVec2(8192, 6u),
7922 tcu::UVec2(16384, 6u),
7923 tcu::UVec2(32768, 6u),
7924
7925 // small pot x large pot
7926 tcu::UVec2(4u, 4096),
7927 tcu::UVec2(4u, 8192),
7928 tcu::UVec2(4u, 16384),
7929 tcu::UVec2(4u, 32768),
7930
7931 // small npot x large pot
7932 tcu::UVec2(6u, 4096),
7933 tcu::UVec2(6u, 8192),
7934 tcu::UVec2(6u, 16384),
7935 tcu::UVec2(6u, 32768)
7936 };
7937
7938 const VkImageLayout copySrcLayouts[] =
7939 {
7940 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
7941 VK_IMAGE_LAYOUT_GENERAL
7942 };
7943
7944 const VkImageLayout copyDstLayouts[] =
7945 {
7946 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
7947 VK_IMAGE_LAYOUT_GENERAL
7948 };
7949
7950 if (allocationKind == ALLOCATION_KIND_DEDICATED)
7951 {
7952 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7953 dedicatedAllocationImageToImageFormatsToTestSet.insert(dedicatedAllocationImageToImageFormatsToTest[compatibleFormatsIndex]);
7954 }
7955
7956 // Image dimensions
7957 for (size_t dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(imageDimensions); dimensionNdx++)
7958 {
7959 CopyRegion copyRegion;
7960 CopyColorTestParams testParams;
7961
7962 const VkExtent3D extent = { imageDimensions[dimensionNdx].x(), imageDimensions[dimensionNdx].y(), 1 };
7963
7964 const VkImageCopy testCopy =
7965 {
7966 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
7967 {0, 0, 0}, // VkOffset3D srcOffset;
7968 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
7969 {0, 0, 0}, // VkOffset3D dstOffset;
7970 extent, // VkExtent3D extent;
7971 };
7972
7973 testParams.params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7974 testParams.params.src.image.imageType = VK_IMAGE_TYPE_2D;
7975 testParams.params.src.image.extent = extent;
7976
7977 testParams.params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
7978 testParams.params.dst.image.imageType = VK_IMAGE_TYPE_2D;
7979 testParams.params.dst.image.extent = extent;
7980
7981 copyRegion.imageCopy = testCopy;
7982 testParams.params.allocationKind = allocationKind;
7983 testParams.params.extensionUse = extensionUse;
7984
7985 testParams.params.regions.push_back(copyRegion);
7986
7987 const std::string dimensionStr = "src" + de::toString(testParams.params.src.image.extent.width) + "x" + de::toString(testParams.params.src.image.extent.height)
7988 + "_dst" + de::toString(testParams.params.dst.image.extent.width) + "x" + de::toString(testParams.params.dst.image.extent.height);
7989 tcu::TestCaseGroup* imageSizeGroup = new tcu::TestCaseGroup(testCtx, dimensionStr.c_str(), ("Image sizes " + dimensionStr).c_str());
7990
7991 // Compatible formats for copying
7992 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(testFormats); compatibleFormatsIndex++)
7993 {
7994 const VkFormat* compatibleFormats = testFormats[compatibleFormatsIndex];
7995
7996 testParams.compatibleFormats = compatibleFormats;
7997
7998 // Source image format
7999 for (int srcFormatIndex = 0; srcFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); srcFormatIndex++)
8000 {
8001 testParams.params.src.image.format = testParams.compatibleFormats[srcFormatIndex];
8002
8003 if (!isSupportedByFramework(testParams.params.src.image.format) && !isCompressedFormat(testParams.params.src.image.format))
8004 continue;
8005
8006 const std::string srcDescription = "Copy from source format " + getFormatCaseName(testParams.params.src.image.format);
8007 tcu::TestCaseGroup* srcFormatGroup = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.src.image.format).c_str(), srcDescription.c_str());
8008
8009 // Destination image format
8010 for (int dstFormatIndex = 0; dstFormatIndex < DE_LENGTH_OF_ARRAY(testFormats[compatibleFormatsIndex]); dstFormatIndex++)
8011 {
8012 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
8013
8014 if (!isSupportedByFramework(testParams.params.dst.image.format) && !isCompressedFormat(testParams.params.dst.image.format))
8015 continue;
8016
8017 if (!isAllowedImageToImageAllFormatsColorSrcFormatTests(testParams))
8018 continue;
8019
8020 if (isCompressedFormat(testParams.params.src.image.format) && isCompressedFormat(testParams.params.dst.image.format))
8021 {
8022 if ((getBlockWidth(testParams.params.src.image.format) != getBlockWidth(testParams.params.dst.image.format))
8023 || (getBlockHeight(testParams.params.src.image.format) != getBlockHeight(testParams.params.dst.image.format)))
8024 continue;
8025 }
8026
8027 const std::string dstDescription = "Copy to destination format " + getFormatCaseName(testParams.params.dst.image.format);
8028 tcu::TestCaseGroup* dstFormatGroup = new tcu::TestCaseGroup(testCtx, getFormatCaseName(testParams.params.dst.image.format).c_str(), dstDescription.c_str());
8029
8030 // Source/destionation image layouts
8031 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); srcLayoutNdx++)
8032 {
8033 testParams.params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8034
8035 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); dstLayoutNdx++)
8036 {
8037 testParams.params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8038
8039 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
8040 const std::string description = "From layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) + " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
8041 const TestParams params = testParams.params;
8042
8043 dstFormatGroup->addChild(new CopyImageToImageTestCase(testCtx, testName, description, params));
8044 }
8045 }
8046
8047 srcFormatGroup->addChild(dstFormatGroup);
8048 }
8049
8050 imageSizeGroup->addChild(srcFormatGroup);
8051 }
8052 }
8053
8054 group->addChild(imageSizeGroup);
8055 }
8056 }
8057
addImageToImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)8058 void addImageToImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
8059 {
8060 const VkImageLayout copySrcLayouts[] =
8061 {
8062 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
8063 VK_IMAGE_LAYOUT_GENERAL
8064 };
8065 const VkImageLayout copyDstLayouts[] =
8066 {
8067 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
8068 VK_IMAGE_LAYOUT_GENERAL
8069 };
8070
8071 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(copySrcLayouts); ++srcLayoutNdx)
8072 {
8073 params.src.image.operationLayout = copySrcLayouts[srcLayoutNdx];
8074 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(copyDstLayouts); ++dstLayoutNdx)
8075 {
8076 params.dst.image.operationLayout = copyDstLayouts[dstLayoutNdx];
8077
8078 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
8079 getImageLayoutCaseName(params.dst.image.operationLayout);
8080 const std::string description = "From layout " + getImageLayoutCaseName(params.src.image.operationLayout) +
8081 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
8082 group->addChild(new CopyImageToImageTestCase(group->getTestContext(), testName, description, params));
8083 }
8084 }
8085 }
8086
addImageToImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8087 void addImageToImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8088 {
8089 const VkFormat depthAndStencilFormats[] =
8090 {
8091 VK_FORMAT_D16_UNORM,
8092 VK_FORMAT_X8_D24_UNORM_PACK32,
8093 VK_FORMAT_D32_SFLOAT,
8094 VK_FORMAT_S8_UINT,
8095 VK_FORMAT_D16_UNORM_S8_UINT,
8096 VK_FORMAT_D24_UNORM_S8_UINT,
8097 VK_FORMAT_D32_SFLOAT_S8_UINT,
8098 };
8099
8100 // 2D tests.
8101 {
8102 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D copies"));
8103
8104 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
8105 {
8106 TestParams params;
8107 params.src.image.imageType = VK_IMAGE_TYPE_2D;
8108 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
8109 params.src.image.extent = defaultExtent;
8110 params.dst.image.extent = defaultExtent;
8111 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
8112 params.dst.image.format = params.src.image.format;
8113 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8114 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8115 params.allocationKind = allocationKind;
8116 params.extensionUse = extensionUse;
8117 params.separateDepthStencilLayouts = DE_FALSE;
8118
8119 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
8120 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
8121
8122 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
8123 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8124 const VkImageSubresourceLayers defaultDSSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8125
8126 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
8127 {
8128 CopyRegion copyRegion;
8129 const VkOffset3D srcOffset = {0, 0, 0};
8130 const VkOffset3D dstOffset = {i, defaultSize - i - defaultFourthSize, 0};
8131 const VkExtent3D extent = {defaultFourthSize, defaultFourthSize, 1};
8132
8133 if (hasDepth)
8134 {
8135 const VkImageCopy testCopy =
8136 {
8137 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
8138 srcOffset, // VkOffset3D srcOffset;
8139 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
8140 dstOffset, // VkOffset3D dstOffset;
8141 extent, // VkExtent3D extent;
8142 };
8143
8144 copyRegion.imageCopy = testCopy;
8145 params.regions.push_back(copyRegion);
8146 }
8147 if (hasStencil)
8148 {
8149 const VkImageCopy testCopy =
8150 {
8151 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
8152 srcOffset, // VkOffset3D srcOffset;
8153 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
8154 dstOffset, // VkOffset3D dstOffset;
8155 extent, // VkExtent3D extent;
8156 };
8157
8158 copyRegion.imageCopy = testCopy;
8159 params.regions.push_back(copyRegion);
8160 }
8161 }
8162
8163 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
8164 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8165 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8166
8167 if (hasDepth && hasStencil)
8168 {
8169 params.separateDepthStencilLayouts = DE_TRUE;
8170 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
8171 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
8172 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8173
8174 // DS Image copy
8175 {
8176 params.separateDepthStencilLayouts = DE_FALSE;
8177 // Clear previous vkImageCopy elements
8178 params.regions.clear();
8179
8180 for (deInt32 i = 0; i < defaultSize; i += defaultFourthSize)
8181 {
8182 CopyRegion copyRegion;
8183 const VkOffset3D srcOffset = {0, 0, 0};
8184 const VkOffset3D dstOffset = {i, defaultSize - i - defaultFourthSize, 0};
8185 const VkExtent3D extent = {defaultFourthSize, defaultFourthSize, 1};
8186
8187 const VkImageCopy testCopy =
8188 {
8189 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
8190 srcOffset, // VkOffset3D srcOffset;
8191 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
8192 dstOffset, // VkOffset3D dstOffset;
8193 extent, // VkExtent3D extent;
8194 };
8195
8196 copyRegion.imageCopy = testCopy;
8197 params.regions.push_back(copyRegion);
8198 }
8199
8200 const std::string testName3 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_depth_stencil_aspects";
8201 const std::string description3 = "Copy both depth and stencil aspects from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8202 addTestGroup(subGroup.get(), testName3, description3, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8203 }
8204 }
8205 }
8206
8207 group->addChild(subGroup.release());
8208 }
8209
8210 // 1D tests.
8211 {
8212 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D copies"));
8213
8214 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
8215 {
8216 TestParams params;
8217 params.src.image.imageType = VK_IMAGE_TYPE_1D;
8218 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
8219 params.src.image.extent = default1dExtent;
8220 params.dst.image.extent = default1dExtent;
8221 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
8222 params.dst.image.format = params.src.image.format;
8223 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8224 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8225 params.allocationKind = allocationKind;
8226 params.extensionUse = extensionUse;
8227
8228 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
8229 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
8230
8231 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
8232 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8233
8234 for (deInt32 i = defaultFourthSize; i < defaultSize; i += defaultSize / 2)
8235 {
8236 CopyRegion copyRegion;
8237 const VkOffset3D srcOffset = {0, 0, 0};
8238 const VkOffset3D dstOffset = {i, 0, 0};
8239 const VkExtent3D extent = {defaultFourthSize, 1, 1};
8240
8241 if (hasDepth)
8242 {
8243 const VkImageCopy testCopy =
8244 {
8245 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
8246 srcOffset, // VkOffset3D srcOffset;
8247 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
8248 dstOffset, // VkOffset3D dstOffset;
8249 extent, // VkExtent3D extent;
8250 };
8251
8252 copyRegion.imageCopy = testCopy;
8253 params.regions.push_back(copyRegion);
8254 }
8255 if (hasStencil)
8256 {
8257 const VkImageCopy testCopy =
8258 {
8259 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
8260 srcOffset, // VkOffset3D srcOffset;
8261 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
8262 dstOffset, // VkOffset3D dstOffset;
8263 extent, // VkExtent3D extent;
8264 };
8265
8266 copyRegion.imageCopy = testCopy;
8267 params.regions.push_back(copyRegion);
8268 }
8269 }
8270
8271 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
8272 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8273 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8274
8275 if (hasDepth && hasStencil)
8276 {
8277 params.separateDepthStencilLayouts = DE_TRUE;
8278 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
8279 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
8280 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8281 }
8282 }
8283
8284 group->addChild(subGroup.release());
8285 }
8286
8287 // 3D tests. Note we use smaller dimensions here for performance reasons.
8288 {
8289 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D copies"));
8290
8291 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
8292 {
8293 TestParams params;
8294 params.src.image.imageType = VK_IMAGE_TYPE_3D;
8295 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
8296 params.src.image.extent = default3dExtent;
8297 params.dst.image.extent = default3dExtent;
8298 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
8299 params.dst.image.format = params.src.image.format;
8300 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8301 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8302 params.allocationKind = allocationKind;
8303 params.extensionUse = extensionUse;
8304
8305 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
8306 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
8307
8308 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
8309 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
8310
8311 for (deInt32 i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
8312 {
8313 CopyRegion copyRegion;
8314 const VkOffset3D srcOffset = {0, 0, 0};
8315 const VkOffset3D dstOffset = {i, defaultFourthSize - i - defaultSixteenthSize, i};
8316 const VkExtent3D extent = {defaultSixteenthSize, defaultSixteenthSize, defaultSixteenthSize};
8317
8318 if (hasDepth)
8319 {
8320 const VkImageCopy testCopy =
8321 {
8322 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
8323 srcOffset, // VkOffset3D srcOffset;
8324 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
8325 dstOffset, // VkOffset3D dstOffset;
8326 extent, // VkExtent3D extent;
8327 };
8328
8329 copyRegion.imageCopy = testCopy;
8330 params.regions.push_back(copyRegion);
8331 }
8332 if (hasStencil)
8333 {
8334 const VkImageCopy testCopy =
8335 {
8336 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
8337 srcOffset, // VkOffset3D srcOffset;
8338 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
8339 dstOffset, // VkOffset3D dstOffset;
8340 extent, // VkExtent3D extent;
8341 };
8342
8343 copyRegion.imageCopy = testCopy;
8344 params.regions.push_back(copyRegion);
8345 }
8346 }
8347
8348 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
8349 const std::string description = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format);
8350 addTestGroup(subGroup.get(), testName, description, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8351
8352 if (hasDepth && hasStencil)
8353 {
8354 params.separateDepthStencilLayouts = DE_TRUE;
8355 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format) + "_separate_layouts";
8356 const std::string description2 = "Copy from " + getFormatCaseName(params.src.image.format) + " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
8357 addTestGroup(subGroup.get(), testName2, description2, addImageToImageAllFormatsDepthStencilFormatsTests, params);
8358 }
8359 }
8360
8361 group->addChild(subGroup.release());
8362 }
8363 }
8364
addImageToImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8365 void addImageToImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8366 {
8367 addTestGroup(group, "color", "Copy image to image with color formats", addImageToImageAllFormatsColorTests, allocationKind, extensionUse);
8368 addTestGroup(group, "depth_stencil", "Copy image to image with depth/stencil formats", addImageToImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
8369 }
8370
addImageToImage3dImagesTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8371 void addImageToImage3dImagesTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8372 {
8373 tcu::TestContext& testCtx = group->getTestContext();
8374
8375 {
8376 TestParams params3DTo2D;
8377 const deUint32 slicesLayers = 16u;
8378 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
8379 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8380 params3DTo2D.src.image.extent = defaultHalfExtent;
8381 params3DTo2D.src.image.extent.depth = slicesLayers;
8382 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8383 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8384 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
8385 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8386 params3DTo2D.dst.image.extent = defaultHalfExtent;
8387 params3DTo2D.dst.image.extent.depth = slicesLayers;
8388 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8389 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8390 params3DTo2D.allocationKind = allocationKind;
8391 params3DTo2D.extensionUse = extensionUse;
8392
8393 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8394 {
8395 const VkImageSubresourceLayers sourceLayer =
8396 {
8397 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8398 0u, // deUint32 mipLevel;
8399 0u, // deUint32 baseArrayLayer;
8400 1u // deUint32 layerCount;
8401 };
8402
8403 const VkImageSubresourceLayers destinationLayer =
8404 {
8405 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8406 0u, // deUint32 mipLevel;
8407 slicesLayersNdx, // deUint32 baseArrayLayer;
8408 1u // deUint32 layerCount;
8409 };
8410
8411 const VkImageCopy testCopy =
8412 {
8413 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8414 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
8415 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8416 {0, 0, 0}, // VkOffset3D dstOffset;
8417 defaultHalfExtent, // VkExtent3D extent;
8418 };
8419
8420 CopyRegion imageCopy;
8421 imageCopy.imageCopy = testCopy;
8422
8423 params3DTo2D.regions.push_back(imageCopy);
8424 }
8425 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_by_slices", "copy 2d layers to 3d slices one by one", params3DTo2D));
8426 }
8427
8428 {
8429 TestParams params2DTo3D;
8430 const deUint32 slicesLayers = 16u;
8431 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
8432 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8433 params2DTo3D.src.image.extent = defaultHalfExtent;
8434 params2DTo3D.src.image.extent.depth = slicesLayers;
8435 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8436 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8437 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
8438 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8439 params2DTo3D.dst.image.extent = defaultHalfExtent;
8440 params2DTo3D.dst.image.extent.depth = slicesLayers;
8441 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8442 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8443 params2DTo3D.allocationKind = allocationKind;
8444 params2DTo3D.extensionUse = extensionUse;
8445
8446 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8447 {
8448 const VkImageSubresourceLayers sourceLayer =
8449 {
8450 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8451 0u, // deUint32 mipLevel;
8452 slicesLayersNdx, // deUint32 baseArrayLayer;
8453 1u // deUint32 layerCount;
8454 };
8455
8456 const VkImageSubresourceLayers destinationLayer =
8457 {
8458 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8459 0u, // deUint32 mipLevel;
8460 0u, // deUint32 baseArrayLayer;
8461 1u // deUint32 layerCount;
8462 };
8463
8464 const VkImageCopy testCopy =
8465 {
8466 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8467 {0, 0, 0}, // VkOffset3D srcOffset;
8468 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8469 {0, 0, (deInt32)slicesLayersNdx}, // VkOffset3D dstOffset;
8470 defaultHalfExtent, // VkExtent3D extent;
8471 };
8472
8473 CopyRegion imageCopy;
8474 imageCopy.imageCopy = testCopy;
8475
8476 params2DTo3D.regions.push_back(imageCopy);
8477 }
8478
8479 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_by_layers", "copy 3d slices to 2d layers one by one", params2DTo3D));
8480 }
8481
8482 {
8483 TestParams params3DTo2D;
8484 const deUint32 slicesLayers = 16u;
8485 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
8486 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8487 params3DTo2D.src.image.extent = defaultHalfExtent;
8488 params3DTo2D.src.image.extent.depth = slicesLayers;
8489 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8490 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8491 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
8492 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8493 params3DTo2D.dst.image.extent = defaultHalfExtent;
8494 params3DTo2D.dst.image.extent.depth = slicesLayers;
8495 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8496 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8497 params3DTo2D.allocationKind = allocationKind;
8498 params3DTo2D.extensionUse = extensionUse;
8499
8500 {
8501 const VkImageSubresourceLayers sourceLayer =
8502 {
8503 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8504 0u, // deUint32 mipLevel;
8505 0u, // deUint32 baseArrayLayer;
8506 1u // deUint32 layerCount;
8507 };
8508
8509 const VkImageSubresourceLayers destinationLayer =
8510 {
8511 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8512 0u, // deUint32 mipLevel;
8513 0, // deUint32 baseArrayLayer;
8514 slicesLayers // deUint32 layerCount;
8515 };
8516
8517 const VkImageCopy testCopy =
8518 {
8519 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8520 {0, 0, 0}, // VkOffset3D srcOffset;
8521 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8522 {0, 0, 0}, // VkOffset3D dstOffset;
8523 params3DTo2D.src.image.extent // VkExtent3D extent;
8524 };
8525
8526 CopyRegion imageCopy;
8527 imageCopy.imageCopy = testCopy;
8528
8529 params3DTo2D.regions.push_back(imageCopy);
8530 }
8531 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_whole", "copy 3d slices to 2d layers all at once", params3DTo2D));
8532 }
8533
8534 {
8535 TestParams params2DTo3D;
8536 const deUint32 slicesLayers = 16u;
8537 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
8538 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8539 params2DTo3D.src.image.extent = defaultHalfExtent;
8540 params2DTo3D.src.image.extent.depth = slicesLayers;
8541 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8542 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8543 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
8544 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8545 params2DTo3D.dst.image.extent = defaultHalfExtent;
8546 params2DTo3D.dst.image.extent.depth = slicesLayers;
8547 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8548 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8549 params2DTo3D.allocationKind = allocationKind;
8550 params2DTo3D.extensionUse = extensionUse;
8551
8552 {
8553 const VkImageSubresourceLayers sourceLayer =
8554 {
8555 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8556 0u, // deUint32 mipLevel;
8557 0u, // deUint32 baseArrayLayer;
8558 slicesLayers // deUint32 layerCount;
8559 };
8560
8561 const VkImageSubresourceLayers destinationLayer =
8562 {
8563 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8564 0u, // deUint32 mipLevel;
8565 0u, // deUint32 baseArrayLayer;
8566 1u // deUint32 layerCount;
8567 };
8568
8569 const VkImageCopy testCopy =
8570 {
8571 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8572 {0, 0, 0}, // VkOffset3D srcOffset;
8573 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8574 {0, 0, 0}, // VkOffset3D dstOffset;
8575 params2DTo3D.src.image.extent, // VkExtent3D extent;
8576 };
8577
8578 CopyRegion imageCopy;
8579 imageCopy.imageCopy = testCopy;
8580
8581 params2DTo3D.regions.push_back(imageCopy);
8582 }
8583
8584 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_whole", "copy 2d layers to 3d slices all at once", params2DTo3D));
8585 }
8586
8587 {
8588 TestParams params3DTo2D;
8589 const deUint32 slicesLayers = 16u;
8590 params3DTo2D.src.image.imageType = VK_IMAGE_TYPE_3D;
8591 params3DTo2D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8592 params3DTo2D.src.image.extent = defaultHalfExtent;
8593 params3DTo2D.src.image.extent.depth = slicesLayers;
8594 params3DTo2D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8595 params3DTo2D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8596 params3DTo2D.dst.image.imageType = VK_IMAGE_TYPE_2D;
8597 params3DTo2D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8598 params3DTo2D.dst.image.extent = defaultHalfExtent;
8599 params3DTo2D.dst.image.extent.depth = slicesLayers;
8600 params3DTo2D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8601 params3DTo2D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8602 params3DTo2D.allocationKind = allocationKind;
8603 params3DTo2D.extensionUse = extensionUse;
8604
8605 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
8606 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
8607
8608 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8609 {
8610 const VkImageSubresourceLayers sourceLayer =
8611 {
8612 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8613 0u, // deUint32 mipLevel;
8614 0u, // deUint32 baseArrayLayer;
8615 1u // deUint32 layerCount;
8616 };
8617
8618 const VkImageSubresourceLayers destinationLayer =
8619 {
8620 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8621 0u, // deUint32 mipLevel;
8622 slicesLayersNdx, // deUint32 baseArrayLayer;
8623 1u // deUint32 layerCount;
8624 };
8625
8626
8627 const VkImageCopy testCopy =
8628 {
8629 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8630 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)slicesLayersNdx}, // VkOffset3D srcOffset;
8631 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8632 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D dstOffset;
8633 {
8634 (defaultHalfExtent.width - regionWidth*slicesLayersNdx),
8635 (defaultHalfExtent.height - regionHeight*slicesLayersNdx),
8636 1
8637 } // VkExtent3D extent;
8638 };
8639
8640 CopyRegion imageCopy;
8641 imageCopy.imageCopy = testCopy;
8642 params3DTo2D.regions.push_back(imageCopy);
8643 }
8644 group->addChild(new CopyImageToImageTestCase(testCtx, "3d_to_2d_regions", "copy 3d slices regions to 2d layers", params3DTo2D));
8645 }
8646
8647 {
8648 TestParams params2DTo3D;
8649 const deUint32 slicesLayers = 16u;
8650 params2DTo3D.src.image.imageType = VK_IMAGE_TYPE_2D;
8651 params2DTo3D.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8652 params2DTo3D.src.image.extent = defaultHalfExtent;
8653 params2DTo3D.src.image.extent.depth = slicesLayers;
8654 params2DTo3D.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8655 params2DTo3D.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8656 params2DTo3D.dst.image.imageType = VK_IMAGE_TYPE_3D;
8657 params2DTo3D.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8658 params2DTo3D.dst.image.extent = defaultHalfExtent;
8659 params2DTo3D.dst.image.extent.depth = slicesLayers;
8660 params2DTo3D.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8661 params2DTo3D.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8662 params2DTo3D.allocationKind = allocationKind;
8663 params2DTo3D.extensionUse = extensionUse;
8664
8665 const deUint32 regionWidth = defaultHalfExtent.width / slicesLayers -1;
8666 const deUint32 regionHeight = defaultHalfExtent.height / slicesLayers -1 ;
8667
8668 for (deUint32 slicesLayersNdx = 0; slicesLayersNdx < slicesLayers; ++slicesLayersNdx)
8669 {
8670 const VkImageSubresourceLayers sourceLayer =
8671 {
8672 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8673 0u, // deUint32 mipLevel;
8674 slicesLayersNdx, // deUint32 baseArrayLayer;
8675 1u // deUint32 layerCount;
8676 };
8677
8678 const VkImageSubresourceLayers destinationLayer =
8679 {
8680 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8681 0u, // deUint32 mipLevel;
8682 0u, // deUint32 baseArrayLayer;
8683 1u // deUint32 layerCount;
8684 };
8685
8686 const VkImageCopy testCopy =
8687 {
8688 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8689 {(deInt32)(regionWidth*slicesLayersNdx), 0, 0}, // VkOffset3D srcOffset;
8690 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8691 {0, (deInt32)(regionHeight*slicesLayersNdx), (deInt32)(slicesLayersNdx)}, // VkOffset3D dstOffset;
8692 {
8693 defaultHalfExtent.width - regionWidth*slicesLayersNdx,
8694 defaultHalfExtent.height - regionHeight*slicesLayersNdx,
8695 1
8696 } // VkExtent3D extent;
8697 };
8698
8699 CopyRegion imageCopy;
8700 imageCopy.imageCopy = testCopy;
8701
8702 params2DTo3D.regions.push_back(imageCopy);
8703 }
8704
8705 group->addChild(new CopyImageToImageTestCase(testCtx, "2d_to_3d_regions", "copy 2d layers regions to 3d slices", params2DTo3D));
8706 }
8707 }
8708
addImageToImageCubeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)8709 void addImageToImageCubeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
8710 {
8711 tcu::TestContext& testCtx = group->getTestContext();
8712
8713 {
8714 TestParams paramsCubeToArray;
8715 const deUint32 arrayLayers = 6u;
8716 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8717 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
8718 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8719 paramsCubeToArray.src.image.extent = defaultHalfExtent;
8720 paramsCubeToArray.src.image.extent.depth = arrayLayers;
8721 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8722 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8723 paramsCubeToArray.dst.image.createFlags = 0;
8724 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
8725 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8726 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
8727 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
8728 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8729 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8730 paramsCubeToArray.allocationKind = allocationKind;
8731 paramsCubeToArray.extensionUse = extensionUse;
8732
8733 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8734 {
8735 const VkImageSubresourceLayers sourceLayer =
8736 {
8737 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8738 0u, // deUint32 mipLevel;
8739 arrayLayersNdx, // deUint32 baseArrayLayer;
8740 1u // deUint32 layerCount;
8741 };
8742
8743 const VkImageSubresourceLayers destinationLayer =
8744 {
8745 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8746 0u, // deUint32 mipLevel;
8747 arrayLayersNdx, // deUint32 baseArrayLayer;
8748 1u // deUint32 layerCount;
8749 };
8750
8751 const VkImageCopy testCopy =
8752 {
8753 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8754 {0, 0, 0}, // VkOffset3D srcOffset;
8755 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8756 {0, 0, 0}, // VkOffset3D dstOffset;
8757 defaultHalfExtent // VkExtent3D extent;
8758 };
8759
8760 CopyRegion imageCopy;
8761 imageCopy.imageCopy = testCopy;
8762
8763 paramsCubeToArray.regions.push_back(imageCopy);
8764 }
8765
8766 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_layers", "copy cube compatible image to 2d layers layer by layer", paramsCubeToArray));
8767 }
8768
8769 {
8770 TestParams paramsCubeToArray;
8771 const deUint32 arrayLayers = 6u;
8772 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8773 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
8774 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8775 paramsCubeToArray.src.image.extent = defaultHalfExtent;
8776 paramsCubeToArray.src.image.extent.depth = arrayLayers;
8777 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8778 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8779 paramsCubeToArray.dst.image.createFlags = 0;
8780 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
8781 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8782 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
8783 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
8784 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8785 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8786 paramsCubeToArray.allocationKind = allocationKind;
8787 paramsCubeToArray.extensionUse = extensionUse;
8788
8789 {
8790 const VkImageSubresourceLayers sourceLayer =
8791 {
8792 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8793 0u, // deUint32 mipLevel;
8794 0u, // deUint32 baseArrayLayer;
8795 arrayLayers // deUint32 layerCount;
8796 };
8797
8798 const VkImageSubresourceLayers destinationLayer =
8799 {
8800 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8801 0u, // deUint32 mipLevel;
8802 0u, // deUint32 baseArrayLayer;
8803 arrayLayers // deUint32 layerCount;
8804 };
8805
8806 const VkImageCopy testCopy =
8807 {
8808 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8809 {0, 0, 0}, // VkOffset3D srcOffset;
8810 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8811 {0, 0, 0}, // VkOffset3D dstOffset;
8812 defaultHalfExtent // VkExtent3D extent;
8813 };
8814
8815 CopyRegion imageCopy;
8816 imageCopy.imageCopy = testCopy;
8817
8818 paramsCubeToArray.regions.push_back(imageCopy);
8819 }
8820
8821 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_array_whole", "copy cube compatible image to 2d layers all at once", paramsCubeToArray));
8822 }
8823
8824 {
8825 TestParams paramsArrayToCube;
8826 const deUint32 arrayLayers = 6u;
8827 paramsArrayToCube.src.image.createFlags = 0;
8828 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
8829 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8830 paramsArrayToCube.src.image.extent = defaultHalfExtent;
8831 paramsArrayToCube.src.image.extent.depth = arrayLayers;
8832 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8833 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8834 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8835 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
8836 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8837 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
8838 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
8839 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8840 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8841 paramsArrayToCube.allocationKind = allocationKind;
8842 paramsArrayToCube.extensionUse = extensionUse;
8843
8844 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8845 {
8846 const VkImageSubresourceLayers sourceLayer =
8847 {
8848 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8849 0u, // deUint32 mipLevel;
8850 arrayLayersNdx, // deUint32 baseArrayLayer;
8851 1u // deUint32 layerCount;
8852 };
8853
8854 const VkImageSubresourceLayers destinationLayer =
8855 {
8856 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8857 0u, // deUint32 mipLevel;
8858 arrayLayersNdx, // deUint32 baseArrayLayer;
8859 1u // deUint32 layerCount;
8860 };
8861
8862 const VkImageCopy testCopy =
8863 {
8864 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8865 {0, 0, 0}, // VkOffset3D srcOffset;
8866 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8867 {0, 0, 0}, // VkOffset3D dstOffset;
8868 defaultHalfExtent // VkExtent3D extent;
8869 };
8870
8871 CopyRegion imageCopy;
8872 imageCopy.imageCopy = testCopy;
8873
8874 paramsArrayToCube.regions.push_back(imageCopy);
8875 }
8876
8877 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_layers", "copy 2d layers to cube compatible image layer by layer", paramsArrayToCube));
8878 }
8879
8880 {
8881 TestParams paramsArrayToCube;
8882 const deUint32 arrayLayers = 6u;
8883 paramsArrayToCube.src.image.createFlags = 0;
8884 paramsArrayToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
8885 paramsArrayToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8886 paramsArrayToCube.src.image.extent = defaultHalfExtent;
8887 paramsArrayToCube.src.image.extent.depth = arrayLayers;
8888 paramsArrayToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8889 paramsArrayToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8890 paramsArrayToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8891 paramsArrayToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
8892 paramsArrayToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8893 paramsArrayToCube.dst.image.extent = defaultHalfExtent;
8894 paramsArrayToCube.dst.image.extent.depth = arrayLayers;
8895 paramsArrayToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8896 paramsArrayToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8897 paramsArrayToCube.allocationKind = allocationKind;
8898 paramsArrayToCube.extensionUse = extensionUse;
8899
8900 {
8901 const VkImageSubresourceLayers sourceLayer =
8902 {
8903 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8904 0u, // deUint32 mipLevel;
8905 0u, // deUint32 baseArrayLayer;
8906 arrayLayers // deUint32 layerCount;
8907 };
8908
8909 const VkImageSubresourceLayers destinationLayer =
8910 {
8911 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8912 0u, // deUint32 mipLevel;
8913 0u, // deUint32 baseArrayLayer;
8914 arrayLayers // deUint32 layerCount;
8915 };
8916
8917 const VkImageCopy testCopy =
8918 {
8919 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8920 {0, 0, 0}, // VkOffset3D srcOffset;
8921 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8922 {0, 0, 0}, // VkOffset3D dstOffset;
8923 defaultHalfExtent // VkExtent3D extent;
8924 };
8925
8926 CopyRegion imageCopy;
8927 imageCopy.imageCopy = testCopy;
8928
8929 paramsArrayToCube.regions.push_back(imageCopy);
8930 }
8931
8932 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_cube_whole", "copy 2d layers to cube compatible image all at once", paramsArrayToCube));
8933 }
8934
8935 {
8936 TestParams paramsCubeToArray;
8937 const deUint32 arrayLayers = 6u;
8938 paramsCubeToArray.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8939 paramsCubeToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
8940 paramsCubeToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8941 paramsCubeToArray.src.image.extent = defaultHalfExtent;
8942 paramsCubeToArray.src.image.extent.depth = arrayLayers;
8943 paramsCubeToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8944 paramsCubeToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
8945 paramsCubeToArray.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8946 paramsCubeToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
8947 paramsCubeToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
8948 paramsCubeToArray.dst.image.extent = defaultHalfExtent;
8949 paramsCubeToArray.dst.image.extent.depth = arrayLayers;
8950 paramsCubeToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
8951 paramsCubeToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
8952 paramsCubeToArray.allocationKind = allocationKind;
8953 paramsCubeToArray.extensionUse = extensionUse;
8954
8955 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
8956 {
8957 const VkImageSubresourceLayers sourceLayer =
8958 {
8959 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8960 0u, // deUint32 mipLevel;
8961 arrayLayersNdx, // deUint32 baseArrayLayer;
8962 1u // deUint32 layerCount;
8963 };
8964
8965 const VkImageSubresourceLayers destinationLayer =
8966 {
8967 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
8968 0u, // deUint32 mipLevel;
8969 arrayLayersNdx, // deUint32 baseArrayLayer;
8970 1u // deUint32 layerCount;
8971 };
8972
8973 const VkImageCopy testCopy =
8974 {
8975 sourceLayer, // VkImageSubresourceLayers srcSubresource;
8976 {0, 0, 0}, // VkOffset3D srcOffset;
8977 destinationLayer, // VkImageSubresourceLayers dstSubresource;
8978 {0, 0, 0}, // VkOffset3D dstOffset;
8979 defaultHalfExtent // VkExtent3D extent;
8980 };
8981
8982 CopyRegion imageCopy;
8983 imageCopy.imageCopy = testCopy;
8984
8985 paramsCubeToArray.regions.push_back(imageCopy);
8986 }
8987
8988 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_layers", "copy cube compatible image to cube compatible image layer by layer", paramsCubeToArray));
8989 }
8990
8991 {
8992 TestParams paramsCubeToCube;
8993 const deUint32 arrayLayers = 6u;
8994 paramsCubeToCube.src.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
8995 paramsCubeToCube.src.image.imageType = VK_IMAGE_TYPE_2D;
8996 paramsCubeToCube.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
8997 paramsCubeToCube.src.image.extent = defaultHalfExtent;
8998 paramsCubeToCube.src.image.extent.depth = arrayLayers;
8999 paramsCubeToCube.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9000 paramsCubeToCube.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9001 paramsCubeToCube.dst.image.createFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
9002 paramsCubeToCube.dst.image.imageType = VK_IMAGE_TYPE_2D;
9003 paramsCubeToCube.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9004 paramsCubeToCube.dst.image.extent = defaultHalfExtent;
9005 paramsCubeToCube.dst.image.extent.depth = arrayLayers;
9006 paramsCubeToCube.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9007 paramsCubeToCube.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9008 paramsCubeToCube.allocationKind = allocationKind;
9009 paramsCubeToCube.extensionUse = extensionUse;
9010
9011 {
9012 const VkImageSubresourceLayers sourceLayer =
9013 {
9014 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9015 0u, // deUint32 mipLevel;
9016 0u, // deUint32 baseArrayLayer;
9017 arrayLayers // deUint32 layerCount;
9018 };
9019
9020 const VkImageSubresourceLayers destinationLayer =
9021 {
9022 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9023 0u, // deUint32 mipLevel;
9024 0u, // deUint32 baseArrayLayer;
9025 arrayLayers // deUint32 layerCount;
9026 };
9027
9028 const VkImageCopy testCopy =
9029 {
9030 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9031 {0, 0, 0}, // VkOffset3D srcOffset;
9032 destinationLayer, // VkImageSubresourceLayers dstSubresource;
9033 {0, 0, 0}, // VkOffset3D dstOffset;
9034 defaultHalfExtent // VkExtent3D extent;
9035 };
9036
9037 CopyRegion imageCopy;
9038 imageCopy.imageCopy = testCopy;
9039
9040 paramsCubeToCube.regions.push_back(imageCopy);
9041 }
9042
9043 group->addChild(new CopyImageToImageTestCase(testCtx, "cube_to_cube_whole", "copy cube compatible image to cube compatible image all at once", paramsCubeToCube));
9044 }
9045 }
9046
addImageToImageArrayTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9047 void addImageToImageArrayTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9048 {
9049 tcu::TestContext& testCtx = group->getTestContext();
9050
9051 {
9052 TestParams paramsArrayToArray;
9053 const deUint32 arrayLayers = 16u;
9054 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
9055 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9056 paramsArrayToArray.src.image.extent = defaultHalfExtent;
9057 paramsArrayToArray.src.image.extent.depth = arrayLayers;
9058 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9059 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9060 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
9061 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9062 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
9063 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
9064 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9065 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9066 paramsArrayToArray.allocationKind = allocationKind;
9067 paramsArrayToArray.extensionUse = extensionUse;
9068
9069 for (deUint32 arrayLayersNdx = 0; arrayLayersNdx < arrayLayers; ++arrayLayersNdx)
9070 {
9071 const VkImageSubresourceLayers sourceLayer =
9072 {
9073 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9074 0u, // deUint32 mipLevel;
9075 arrayLayersNdx, // deUint32 baseArrayLayer;
9076 1u // deUint32 layerCount;
9077 };
9078
9079 const VkImageSubresourceLayers destinationLayer =
9080 {
9081 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9082 0u, // deUint32 mipLevel;
9083 arrayLayersNdx, // deUint32 baseArrayLayer;
9084 1u // deUint32 layerCount;
9085 };
9086
9087 const VkImageCopy testCopy =
9088 {
9089 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9090 {0, 0, 0}, // VkOffset3D srcOffset;
9091 destinationLayer, // VkImageSubresourceLayers dstSubresource;
9092 {0, 0, 0}, // VkOffset3D dstOffset;
9093 defaultHalfExtent // VkExtent3D extent;
9094 };
9095
9096 CopyRegion imageCopy;
9097 imageCopy.imageCopy = testCopy;
9098
9099 paramsArrayToArray.regions.push_back(imageCopy);
9100 }
9101
9102 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_layers", "copy 2d array image to 2d array image layer by layer", paramsArrayToArray));
9103 }
9104
9105 {
9106 TestParams paramsArrayToArray;
9107 const deUint32 arrayLayers = 16u;
9108 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
9109 paramsArrayToArray.src.image.format = VK_FORMAT_R8G8B8A8_UINT;
9110 paramsArrayToArray.src.image.extent = defaultHalfExtent;
9111 paramsArrayToArray.src.image.extent.depth = arrayLayers;
9112 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9113 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9114 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
9115 paramsArrayToArray.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9116 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
9117 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
9118 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9119 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9120 paramsArrayToArray.allocationKind = allocationKind;
9121 paramsArrayToArray.extensionUse = extensionUse;
9122
9123 {
9124 const VkImageSubresourceLayers sourceLayer =
9125 {
9126 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9127 0u, // deUint32 mipLevel;
9128 0u, // deUint32 baseArrayLayer;
9129 arrayLayers // deUint32 layerCount;
9130 };
9131
9132 const VkImageSubresourceLayers destinationLayer =
9133 {
9134 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9135 0u, // deUint32 mipLevel;
9136 0u, // deUint32 baseArrayLayer;
9137 arrayLayers // deUint32 layerCount;
9138 };
9139
9140 const VkImageCopy testCopy =
9141 {
9142 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9143 {0, 0, 0}, // VkOffset3D srcOffset;
9144 destinationLayer, // VkImageSubresourceLayers dstSubresource;
9145 {0, 0, 0}, // VkOffset3D dstOffset;
9146 defaultHalfExtent // VkExtent3D extent;
9147 };
9148
9149 CopyRegion imageCopy;
9150 imageCopy.imageCopy = testCopy;
9151
9152 paramsArrayToArray.regions.push_back(imageCopy);
9153 }
9154
9155 group->addChild(new CopyImageToImageTestCase(testCtx, "array_to_array_whole", "copy 2d array image to 2d array image all at once", paramsArrayToArray));
9156 }
9157
9158 {
9159 TestParams paramsArrayToArray;
9160 const deUint32 arrayLayers = 16u;
9161 paramsArrayToArray.src.image.imageType = VK_IMAGE_TYPE_2D;
9162 paramsArrayToArray.src.image.extent = defaultHalfExtent;
9163 paramsArrayToArray.src.image.extent.depth = arrayLayers;
9164 paramsArrayToArray.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9165 paramsArrayToArray.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9166 paramsArrayToArray.dst.image.imageType = VK_IMAGE_TYPE_2D;
9167 paramsArrayToArray.dst.image.extent = defaultHalfExtent;
9168 paramsArrayToArray.dst.image.extent.depth = arrayLayers;
9169 paramsArrayToArray.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9170 paramsArrayToArray.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9171 paramsArrayToArray.allocationKind = allocationKind;
9172 paramsArrayToArray.extensionUse = extensionUse;
9173 paramsArrayToArray.mipLevels = deLog2Floor32(deMinu32(defaultHalfExtent.width, defaultHalfExtent.height)) + 1u;
9174
9175 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < paramsArrayToArray.mipLevels; mipLevelNdx++)
9176 {
9177 const VkImageSubresourceLayers sourceLayer =
9178 {
9179 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9180 mipLevelNdx, // deUint32 mipLevel;
9181 0u, // deUint32 baseArrayLayer;
9182 arrayLayers // deUint32 layerCount;
9183 };
9184
9185 const VkImageSubresourceLayers destinationLayer =
9186 {
9187 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9188 mipLevelNdx, // deUint32 mipLevel;
9189 0u, // deUint32 baseArrayLayer;
9190 arrayLayers // deUint32 layerCount;
9191 };
9192
9193 const VkExtent3D extent =
9194 {
9195 (deUint32)deMax(defaultHalfExtent.width >> mipLevelNdx, 1), // deUint32 width;
9196 (deUint32)deMax(defaultHalfExtent.height >> mipLevelNdx, 1), // deUint32 height;
9197 1u, // deUint32 depth;
9198 };
9199
9200 const VkImageCopy testCopy =
9201 {
9202 sourceLayer, // VkImageSubresourceLayers srcSubresource;
9203 {0, 0, 0}, // VkOffset3D srcOffset;
9204 destinationLayer, // VkImageSubresourceLayers dstSubresource;
9205 {0, 0, 0}, // VkOffset3D dstOffset;
9206 extent // VkExtent3D extent;
9207 };
9208
9209 CopyRegion imageCopy;
9210 imageCopy.imageCopy = testCopy;
9211
9212 paramsArrayToArray.regions.push_back(imageCopy);
9213 }
9214
9215 VkFormat imageFormats [] = { VK_FORMAT_R8G8B8A8_UINT, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_S8_UINT};
9216
9217 for (deUint32 imageFormatsNdx = 0; imageFormatsNdx < DE_LENGTH_OF_ARRAY(imageFormats); imageFormatsNdx++)
9218 {
9219 paramsArrayToArray.src.image.format = imageFormats[imageFormatsNdx];
9220 paramsArrayToArray.dst.image.format = imageFormats[imageFormatsNdx];
9221 for (deUint32 regionNdx = 0u; regionNdx < paramsArrayToArray.regions.size(); regionNdx++)
9222 {
9223 paramsArrayToArray.regions[regionNdx].imageCopy.srcSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
9224 paramsArrayToArray.regions[regionNdx].imageCopy.dstSubresource.aspectMask = getImageAspectFlags(mapVkFormat(imageFormats[imageFormatsNdx]));
9225 }
9226 std::ostringstream testName;
9227 const std::string formatName = getFormatName(imageFormats[imageFormatsNdx]);
9228 testName << "array_to_array_whole_mipmap_" << de::toLower(formatName.substr(10));
9229 group->addChild(new CopyImageToImageMipmapTestCase(testCtx, testName.str(), "copy 2d array mipmap image to 2d array mipmap image all at once", paramsArrayToArray));
9230 }
9231 }
9232 }
9233
addImageToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9234 void addImageToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9235 {
9236 addTestGroup(group, "simple_tests", "Copy from image to image simple tests", addImageToImageSimpleTests, allocationKind, extensionUse);
9237 addTestGroup(group, "all_formats", "Copy from image to image with all compatible formats", addImageToImageAllFormatsTests, allocationKind, extensionUse);
9238 addTestGroup(group, "3d_images", "Coping operations on 3d images", addImageToImage3dImagesTests, allocationKind, extensionUse);
9239 addTestGroup(group, "dimensions", "Copying operations on different image dimensions", addImageToImageDimensionsTests, allocationKind, extensionUse);
9240 addTestGroup(group, "cube", "Coping operations on cube compatible images", addImageToImageCubeTests, allocationKind, extensionUse);
9241 addTestGroup(group, "array", "Copying operations on array of images", addImageToImageArrayTests, allocationKind, extensionUse);
9242 }
9243
addImageToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9244 void addImageToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9245 {
9246 tcu::TestContext& testCtx = group->getTestContext();
9247
9248 {
9249 TestParams params;
9250 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9251 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9252 params.src.image.extent = defaultExtent;
9253 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9254 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9255 params.dst.buffer.size = defaultSize * defaultSize;
9256 params.allocationKind = allocationKind;
9257 params.extensionUse = extensionUse;
9258
9259 const VkBufferImageCopy bufferImageCopy =
9260 {
9261 0u, // VkDeviceSize bufferOffset;
9262 0u, // deUint32 bufferRowLength;
9263 0u, // deUint32 bufferImageHeight;
9264 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9265 {0, 0, 0}, // VkOffset3D imageOffset;
9266 defaultExtent // VkExtent3D imageExtent;
9267 };
9268 CopyRegion copyRegion;
9269 copyRegion.bufferImageCopy = bufferImageCopy;
9270
9271 params.regions.push_back(copyRegion);
9272
9273 group->addChild(new CopyImageToBufferTestCase(testCtx, "whole", "Copy from image to buffer", params));
9274 }
9275
9276 {
9277 TestParams params;
9278 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9279 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9280 params.src.image.extent = defaultExtent;
9281 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9282 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9283 params.dst.buffer.size = defaultSize * defaultSize;
9284 params.allocationKind = allocationKind;
9285 params.extensionUse = extensionUse;
9286
9287 const VkBufferImageCopy bufferImageCopy =
9288 {
9289 defaultSize * defaultHalfSize, // VkDeviceSize bufferOffset;
9290 0u, // deUint32 bufferRowLength;
9291 0u, // deUint32 bufferImageHeight;
9292 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9293 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9294 defaultHalfExtent // VkExtent3D imageExtent;
9295 };
9296 CopyRegion copyRegion;
9297 copyRegion.bufferImageCopy = bufferImageCopy;
9298
9299 params.regions.push_back(copyRegion);
9300
9301 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset", "Copy from image to buffer with buffer offset", params));
9302 }
9303
9304 {
9305 TestParams params;
9306 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9307 params.src.image.format = VK_FORMAT_R8_UNORM;
9308 params.src.image.extent = defaultExtent;
9309 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9310 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9311 params.dst.buffer.size = defaultSize * defaultSize;
9312 params.allocationKind = allocationKind;
9313 params.extensionUse = extensionUse;
9314
9315 const VkBufferImageCopy bufferImageCopy =
9316 {
9317 defaultSize * defaultHalfSize + 1u, // VkDeviceSize bufferOffset;
9318 0u, // deUint32 bufferRowLength;
9319 0u, // deUint32 bufferImageHeight;
9320 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9321 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9322 defaultHalfExtent // VkExtent3D imageExtent;
9323 };
9324 CopyRegion copyRegion;
9325 copyRegion.bufferImageCopy = bufferImageCopy;
9326
9327 params.regions.push_back(copyRegion);
9328
9329 group->addChild(new CopyImageToBufferTestCase(testCtx, "buffer_offset_relaxed", "Copy from image to buffer with buffer offset not a multiple of 4", params));
9330 }
9331
9332 {
9333 TestParams params;
9334 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9335 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9336 params.src.image.extent = defaultExtent;
9337 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9338 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9339 params.dst.buffer.size = defaultSize * defaultSize;
9340 params.allocationKind = allocationKind;
9341 params.extensionUse = extensionUse;
9342
9343 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
9344 const VkDeviceSize bufferSize = pixelSize * params.dst.buffer.size;
9345 const VkDeviceSize offsetSize = pixelSize * defaultFourthSize * defaultFourthSize;
9346 deUint32 divisor = 1;
9347 for (VkDeviceSize offset = 0; offset < bufferSize - offsetSize; offset += offsetSize, ++divisor)
9348 {
9349 const deUint32 bufferRowLength = defaultFourthSize;
9350 const deUint32 bufferImageHeight = defaultFourthSize;
9351 const VkExtent3D imageExtent = {defaultFourthSize / divisor, defaultFourthSize, 1};
9352 DE_ASSERT(!bufferRowLength || bufferRowLength >= imageExtent.width);
9353 DE_ASSERT(!bufferImageHeight || bufferImageHeight >= imageExtent.height);
9354 DE_ASSERT(imageExtent.width * imageExtent.height *imageExtent.depth <= offsetSize);
9355
9356 CopyRegion region;
9357 const VkBufferImageCopy bufferImageCopy =
9358 {
9359 offset, // VkDeviceSize bufferOffset;
9360 bufferRowLength, // deUint32 bufferRowLength;
9361 bufferImageHeight, // deUint32 bufferImageHeight;
9362 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9363 {0, 0, 0}, // VkOffset3D imageOffset;
9364 imageExtent // VkExtent3D imageExtent;
9365 };
9366 region.bufferImageCopy = bufferImageCopy;
9367 params.regions.push_back(region);
9368 }
9369
9370 group->addChild(new CopyImageToBufferTestCase(testCtx, "regions", "Copy from image to buffer with multiple regions", params));
9371 }
9372
9373 {
9374 TestParams params;
9375 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9376 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9377 params.src.image.extent = defaultExtent;
9378 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9379 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9380 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
9381 params.allocationKind = allocationKind;
9382 params.extensionUse = extensionUse;
9383
9384 const VkBufferImageCopy bufferImageCopy =
9385 {
9386 0u, // VkDeviceSize bufferOffset;
9387 defaultSize, // deUint32 bufferRowLength;
9388 defaultSize, // deUint32 bufferImageHeight;
9389 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9390 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9391 defaultHalfExtent // VkExtent3D imageExtent;
9392 };
9393 CopyRegion copyRegion;
9394 copyRegion.bufferImageCopy = bufferImageCopy;
9395
9396 params.regions.push_back(copyRegion);
9397
9398 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer", "Copy from image to a buffer that is just large enough to contain the data", params));
9399 }
9400
9401 {
9402 TestParams params;
9403 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9404 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9405 params.src.image.extent = defaultExtent;
9406 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9407 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
9408 params.dst.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9409 params.allocationKind = allocationKind;
9410 params.extensionUse = extensionUse;
9411
9412 const VkBufferImageCopy bufferImageCopy =
9413 {
9414 defaultFourthSize, // VkDeviceSize bufferOffset;
9415 defaultSize, // deUint32 bufferRowLength;
9416 defaultSize, // deUint32 bufferImageHeight;
9417 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9418 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9419 defaultHalfExtent // VkExtent3D imageExtent;
9420 };
9421 CopyRegion copyRegion;
9422 copyRegion.bufferImageCopy = bufferImageCopy;
9423
9424 params.regions.push_back(copyRegion);
9425
9426 group->addChild(new CopyImageToBufferTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from image to a buffer that is just large enough to contain the data", params));
9427 }
9428
9429 {
9430 TestParams params;
9431 deUint32 arrayLayers = 16u;
9432 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9433 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9434 params.src.image.extent = defaultHalfExtent;
9435 params.src.image.extent.depth = arrayLayers;
9436 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9437 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9438 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
9439 params.allocationKind = allocationKind;
9440 params.extensionUse = extensionUse;
9441
9442 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
9443 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9444 {
9445 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9446 const VkBufferImageCopy bufferImageCopy =
9447 {
9448 offset, // VkDeviceSize bufferOffset;
9449 0u, // deUint32 bufferRowLength;
9450 0u, // deUint32 bufferImageHeight;
9451 {
9452 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9453 0u, // deUint32 mipLevel;
9454 arrayLayerNdx, // deUint32 baseArrayLayer;
9455 1u, // deUint32 layerCount;
9456 }, // VkImageSubresourceLayers imageSubresource;
9457 {0, 0, 0}, // VkOffset3D imageOffset;
9458 defaultHalfExtent // VkExtent3D imageExtent;
9459 };
9460 CopyRegion copyRegion;
9461 copyRegion.bufferImageCopy = bufferImageCopy;
9462
9463 params.regions.push_back(copyRegion);
9464 }
9465 group->addChild(new CopyImageToBufferTestCase(testCtx, "array", "Copy each layer from array to buffer", params));
9466 }
9467
9468 {
9469 TestParams params;
9470 deUint32 arrayLayers = 16u;
9471 params.src.image.imageType = VK_IMAGE_TYPE_2D;
9472 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9473 params.src.image.extent = defaultHalfExtent;
9474 params.src.image.extent.depth = arrayLayers;
9475 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9476 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9477 params.dst.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
9478 params.allocationKind = allocationKind;
9479 params.extensionUse = extensionUse;
9480
9481 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.src.image.format));
9482 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9483 {
9484 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9485 const VkBufferImageCopy bufferImageCopy =
9486 {
9487 offset, // VkDeviceSize bufferOffset;
9488 defaultHalfSize, // deUint32 bufferRowLength;
9489 defaultHalfSize, // deUint32 bufferImageHeight;
9490 {
9491 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9492 0u, // deUint32 mipLevel;
9493 arrayLayerNdx, // deUint32 baseArrayLayer;
9494 1u, // deUint32 layerCount;
9495 }, // VkImageSubresourceLayers imageSubresource;
9496 {0, 0, 0}, // VkOffset3D imageOffset;
9497 defaultHalfExtent // VkExtent3D imageExtent;
9498 };
9499 CopyRegion copyRegion;
9500 copyRegion.bufferImageCopy = bufferImageCopy;
9501
9502 params.regions.push_back(copyRegion);
9503 }
9504 group->addChild(new CopyImageToBufferTestCase(testCtx, "array_tightly_sized_buffer", "Copy each layer from array to tightly sized buffer", params));
9505 }
9506 }
9507
addBufferToDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9508 void addBufferToDepthStencilTests(tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9509 {
9510 tcu::TestContext& testCtx = group->getTestContext();
9511
9512 const struct
9513 {
9514 const char* name;
9515 const VkFormat format;
9516 } depthAndStencilFormats[] =
9517 {
9518 { "d16_unorm", VK_FORMAT_D16_UNORM },
9519 { "x8_d24_unorm_pack32", VK_FORMAT_X8_D24_UNORM_PACK32 },
9520 { "d32_sfloat", VK_FORMAT_D32_SFLOAT },
9521 { "d16_unorm_s8_uint", VK_FORMAT_D16_UNORM_S8_UINT },
9522 { "d24_unorm_s8_uint", VK_FORMAT_D24_UNORM_S8_UINT },
9523 { "d32_sfloat_s8_uint", VK_FORMAT_D32_SFLOAT_S8_UINT }
9524 };
9525
9526 const VkImageSubresourceLayers depthSourceLayer =
9527 {
9528 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask;
9529 0u, // deUint32 mipLevel;
9530 0u, // deUint32 baseArrayLayer;
9531 1u, // deUint32 layerCount;
9532 };
9533
9534 const VkBufferImageCopy bufferDepthCopy =
9535 {
9536 0u, // VkDeviceSize bufferOffset;
9537 0u, // deUint32 bufferRowLength;
9538 0u, // deUint32 bufferImageHeight;
9539 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
9540 {0, 0, 0}, // VkOffset3D imageOffset;
9541 defaultExtent // VkExtent3D imageExtent;
9542 };
9543
9544 const VkBufferImageCopy bufferDepthCopyOffset =
9545 {
9546 32, // VkDeviceSize bufferOffset;
9547 defaultHalfSize + defaultFourthSize, // deUint32 bufferRowLength;
9548 defaultHalfSize + defaultFourthSize, // deUint32 bufferImageHeight;
9549 depthSourceLayer, // VkImageSubresourceLayers imageSubresource;
9550 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9551 defaultHalfExtent // VkExtent3D imageExtent;
9552 };
9553
9554 const VkImageSubresourceLayers stencilSourceLayer =
9555 {
9556 VK_IMAGE_ASPECT_STENCIL_BIT, // VkImageAspectFlags aspectMask;
9557 0u, // deUint32 mipLevel;
9558 0u, // deUint32 baseArrayLayer;
9559 1u, // deUint32 layerCount;
9560 };
9561
9562 const VkBufferImageCopy bufferStencilCopy =
9563 {
9564 0u, // VkDeviceSize bufferOffset;
9565 0u, // deUint32 bufferRowLength;
9566 0u, // deUint32 bufferImageHeight;
9567 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
9568 {0, 0, 0}, // VkOffset3D imageOffset;
9569 defaultExtent // VkExtent3D imageExtent;
9570 };
9571
9572 const VkBufferImageCopy bufferStencilCopyOffset =
9573 {
9574 32, // VkDeviceSize bufferOffset;
9575 defaultHalfSize + defaultFourthSize, // deUint32 bufferRowLength;
9576 defaultHalfSize + defaultFourthSize, // deUint32 bufferImageHeight;
9577 stencilSourceLayer, // VkImageSubresourceLayers imageSubresource;
9578 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9579 defaultHalfExtent // VkExtent3D imageExtent;
9580 };
9581
9582 const bool useOffset[] = {false, true};
9583
9584 // Note: Depth stencil tests I want to do
9585 // Formats: D16, D24S8, D32FS8
9586 // Test writing each component with separate CopyBufferToImage commands
9587 // Test writing both components in one CopyBufferToImage command
9588 // Swap order of writes of Depth & Stencil
9589 // whole surface, subimages?
9590 // Similar tests as BufferToImage?
9591 for (const auto config : depthAndStencilFormats)
9592 for (const auto offset : useOffset)
9593 {
9594 // TODO: Check that this format is supported before creating tests?
9595 //if (isSupportedDepthStencilFormat(vki, physDevice, VK_FORMAT_D24_UNORM_S8_UINT))
9596
9597 CopyRegion copyDepthRegion;
9598 CopyRegion copyStencilRegion;
9599 TestParams params;
9600 const tcu::TextureFormat format = mapVkFormat(config.format);
9601 const bool hasDepth = tcu::hasDepthComponent(format.order);
9602 const bool hasStencil = tcu::hasStencilComponent(format.order);
9603 std::string description = config.name;
9604
9605 if (offset)
9606 {
9607 copyDepthRegion.bufferImageCopy = bufferDepthCopyOffset;
9608 copyStencilRegion.bufferImageCopy = bufferStencilCopyOffset;
9609 description = "buffer_offset_" + description;
9610 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9611 }
9612 else
9613 {
9614 copyDepthRegion.bufferImageCopy = bufferDepthCopy;
9615 copyStencilRegion.bufferImageCopy = bufferStencilCopy;
9616 params.src.buffer.size = defaultSize * defaultSize;
9617 }
9618
9619 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9620 params.dst.image.format = config.format;
9621 params.dst.image.extent = defaultExtent;
9622 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9623 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9624 params.allocationKind = allocationKind;
9625 params.extensionUse = extensionUse;
9626
9627 if (hasDepth && hasStencil)
9628 {
9629 params.singleCommand = DE_TRUE;
9630
9631 params.regions.push_back(copyDepthRegion);
9632 params.regions.push_back(copyStencilRegion);
9633
9634 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_DS", "Copy from depth&stencil to image", params));
9635
9636 params.singleCommand = DE_FALSE;
9637
9638 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D_S", "Copy from depth then stencil to image", params));
9639
9640 params.regions.clear();
9641 params.regions.push_back(copyStencilRegion);
9642 params.regions.push_back(copyDepthRegion);
9643
9644 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S_D", "Copy from depth then stencil to image", params));
9645
9646 params.singleCommand = DE_TRUE;
9647 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_SD", "Copy from depth&stencil to image", params));
9648 }
9649
9650 if (hasStencil)
9651 {
9652 params.regions.clear();
9653 params.regions.push_back(copyStencilRegion);
9654
9655 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_S", "Copy from stencil to image", params));
9656 }
9657
9658 if (hasDepth)
9659 {
9660 params.regions.clear();
9661 params.regions.push_back(copyDepthRegion);
9662
9663 group->addChild(new CopyBufferToDepthStencilTestCase(testCtx, description + "_D", "Copy from depth to image", params));
9664 }
9665 }
9666 }
9667
addBufferToImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9668 void addBufferToImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9669 {
9670 tcu::TestContext& testCtx = group->getTestContext();
9671
9672 {
9673 TestParams params;
9674 params.src.buffer.size = defaultSize * defaultSize;
9675 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9676 params.dst.image.format = VK_FORMAT_R8G8B8A8_UINT;
9677 params.dst.image.extent = defaultExtent;
9678 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9679 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9680 params.allocationKind = allocationKind;
9681 params.extensionUse = extensionUse;
9682
9683 const VkBufferImageCopy bufferImageCopy =
9684 {
9685 0u, // VkDeviceSize bufferOffset;
9686 0u, // deUint32 bufferRowLength;
9687 0u, // deUint32 bufferImageHeight;
9688 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9689 {0, 0, 0}, // VkOffset3D imageOffset;
9690 defaultExtent // VkExtent3D imageExtent;
9691 };
9692 CopyRegion copyRegion;
9693 copyRegion.bufferImageCopy = bufferImageCopy;
9694
9695 params.regions.push_back(copyRegion);
9696
9697 group->addChild(new CopyBufferToImageTestCase(testCtx, "whole", "Copy from buffer to image", params));
9698 }
9699
9700 {
9701 TestParams params;
9702 params.src.buffer.size = defaultSize * defaultSize;
9703 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9704 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9705 params.dst.image.extent = defaultExtent;
9706 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9707 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9708 params.allocationKind = allocationKind;
9709 params.extensionUse = extensionUse;
9710
9711 CopyRegion region;
9712 deUint32 divisor = 1;
9713 for (int offset = 0; (offset + defaultFourthSize / divisor < defaultSize) && (defaultFourthSize > divisor); offset += defaultFourthSize / divisor++)
9714 {
9715 const VkBufferImageCopy bufferImageCopy =
9716 {
9717 0u, // VkDeviceSize bufferOffset;
9718 0u, // deUint32 bufferRowLength;
9719 0u, // deUint32 bufferImageHeight;
9720 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9721 {offset, defaultHalfSize, 0}, // VkOffset3D imageOffset;
9722 {defaultFourthSize / divisor, defaultFourthSize / divisor, 1} // VkExtent3D imageExtent;
9723 };
9724 region.bufferImageCopy = bufferImageCopy;
9725 params.regions.push_back(region);
9726 }
9727
9728 group->addChild(new CopyBufferToImageTestCase(testCtx, "regions", "Copy from buffer to image with multiple regions", params));
9729 }
9730
9731 {
9732 TestParams params;
9733 params.src.buffer.size = defaultSize * defaultSize;
9734 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9735 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9736 params.dst.image.extent = defaultExtent;
9737 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9738 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9739 params.allocationKind = allocationKind;
9740 params.extensionUse = extensionUse;
9741
9742 const VkBufferImageCopy bufferImageCopy =
9743 {
9744 defaultFourthSize, // VkDeviceSize bufferOffset;
9745 defaultHalfSize + defaultFourthSize, // deUint32 bufferRowLength;
9746 defaultHalfSize + defaultFourthSize, // deUint32 bufferImageHeight;
9747 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9748 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9749 defaultHalfExtent // VkExtent3D imageExtent;
9750 };
9751 CopyRegion copyRegion;
9752 copyRegion.bufferImageCopy = bufferImageCopy;
9753
9754 params.regions.push_back(copyRegion);
9755
9756 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset", "Copy from buffer to image with buffer offset", params));
9757 }
9758
9759 {
9760 TestParams params;
9761 params.src.buffer.size = defaultSize * defaultSize;
9762 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9763 params.dst.image.format = VK_FORMAT_R8_UNORM;
9764 params.dst.image.extent = defaultExtent;
9765 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9766 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9767 params.allocationKind = allocationKind;
9768 params.extensionUse = extensionUse;
9769
9770 const VkBufferImageCopy bufferImageCopy =
9771 {
9772 defaultFourthSize + 1u, // VkDeviceSize bufferOffset;
9773 defaultHalfSize + defaultFourthSize, // deUint32 bufferRowLength;
9774 defaultHalfSize + defaultFourthSize, // deUint32 bufferImageHeight;
9775 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9776 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9777 defaultHalfExtent // VkExtent3D imageExtent;
9778 };
9779 CopyRegion copyRegion;
9780 copyRegion.bufferImageCopy = bufferImageCopy;
9781
9782 params.regions.push_back(copyRegion);
9783
9784 group->addChild(new CopyBufferToImageTestCase(testCtx, "buffer_offset_relaxed", "Copy from buffer to image with buffer offset not a multiple of 4", params));
9785 }
9786
9787 {
9788 TestParams params;
9789 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize;
9790 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9791 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9792 params.dst.image.extent = defaultExtent;
9793 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9794 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9795 params.allocationKind = allocationKind;
9796 params.extensionUse = extensionUse;
9797
9798 const VkBufferImageCopy bufferImageCopy =
9799 {
9800 0u, // VkDeviceSize bufferOffset;
9801 defaultSize, // deUint32 bufferRowLength;
9802 defaultSize, // deUint32 bufferImageHeight;
9803 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9804 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9805 defaultHalfExtent // VkExtent3D imageExtent;
9806 };
9807 CopyRegion copyRegion;
9808 copyRegion.bufferImageCopy = bufferImageCopy;
9809
9810 params.regions.push_back(copyRegion);
9811
9812 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer", "Copy from buffer that is just large enough to contain the accessed elements", params));
9813 }
9814
9815 {
9816 TestParams params;
9817 params.src.buffer.size = (defaultHalfSize - 1u) * defaultSize + defaultHalfSize + defaultFourthSize;
9818 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9819 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9820 params.dst.image.extent = defaultExtent;
9821 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9822 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9823 params.allocationKind = allocationKind;
9824 params.extensionUse = extensionUse;
9825
9826 const VkBufferImageCopy bufferImageCopy =
9827 {
9828 defaultFourthSize, // VkDeviceSize bufferOffset;
9829 defaultSize, // deUint32 bufferRowLength;
9830 defaultSize, // deUint32 bufferImageHeight;
9831 defaultSourceLayer, // VkImageSubresourceLayers imageSubresource;
9832 {defaultFourthSize, defaultFourthSize, 0}, // VkOffset3D imageOffset;
9833 defaultHalfExtent // VkExtent3D imageExtent;
9834 };
9835 CopyRegion copyRegion;
9836 copyRegion.bufferImageCopy = bufferImageCopy;
9837
9838 params.regions.push_back(copyRegion);
9839
9840 group->addChild(new CopyBufferToImageTestCase(testCtx, "tightly_sized_buffer_offset", "Copy from buffer that is just large enough to contain the accessed elements", params));
9841 }
9842
9843 {
9844 TestParams params;
9845 deUint32 arrayLayers = 16u;
9846 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
9847 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9848 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9849 params.dst.image.extent = defaultHalfExtent;
9850 params.dst.image.extent.depth = arrayLayers;
9851 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9852 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9853 params.allocationKind = allocationKind;
9854 params.extensionUse = extensionUse;
9855
9856 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9857 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9858 {
9859 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9860 const VkBufferImageCopy bufferImageCopy =
9861 {
9862 offset, // VkDeviceSize bufferOffset;
9863 0u, // deUint32 bufferRowLength;
9864 0u, // deUint32 bufferImageHeight;
9865 {
9866 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9867 0u, // deUint32 mipLevel;
9868 arrayLayerNdx, // deUint32 baseArrayLayer;
9869 1u, // deUint32 layerCount;
9870 }, // VkImageSubresourceLayers imageSubresource;
9871 {0, 0, 0}, // VkOffset3D imageOffset;
9872 defaultHalfExtent // VkExtent3D imageExtent;
9873 };
9874 CopyRegion copyRegion;
9875 copyRegion.bufferImageCopy = bufferImageCopy;
9876
9877 params.regions.push_back(copyRegion);
9878 }
9879 group->addChild(new CopyBufferToImageTestCase(testCtx, "array", "Copy from a different part of the buffer to each layer", params));
9880 }
9881
9882 {
9883 TestParams params;
9884 deUint32 arrayLayers = 16u;
9885 params.src.buffer.size = defaultHalfSize * defaultHalfSize * arrayLayers;
9886 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
9887 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
9888 params.dst.image.extent = defaultHalfExtent;
9889 params.dst.image.extent.depth = arrayLayers;
9890 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
9891 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
9892 params.allocationKind = allocationKind;
9893 params.extensionUse = extensionUse;
9894
9895 const int pixelSize = tcu::getPixelSize(mapVkFormat(params.dst.image.format));
9896 for (deUint32 arrayLayerNdx = 0; arrayLayerNdx < arrayLayers; arrayLayerNdx++)
9897 {
9898 const VkDeviceSize offset = defaultHalfSize * defaultHalfSize * pixelSize * arrayLayerNdx;
9899 const VkBufferImageCopy bufferImageCopy =
9900 {
9901 offset, // VkDeviceSize bufferOffset;
9902 defaultHalfSize, // deUint32 bufferRowLength;
9903 defaultHalfSize, // deUint32 bufferImageHeight;
9904 {
9905 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
9906 0u, // deUint32 mipLevel;
9907 arrayLayerNdx, // deUint32 baseArrayLayer;
9908 1u, // deUint32 layerCount;
9909 }, // VkImageSubresourceLayers imageSubresource;
9910 {0, 0, 0}, // VkOffset3D imageOffset;
9911 defaultHalfExtent // VkExtent3D imageExtent;
9912 };
9913 CopyRegion copyRegion;
9914 copyRegion.bufferImageCopy = bufferImageCopy;
9915
9916 params.regions.push_back(copyRegion);
9917 }
9918 group->addChild(new CopyBufferToImageTestCase(testCtx, "array_tightly_sized_buffer", "Copy from different part of tightly sized buffer to each layer", params));
9919 }
9920 }
9921
addBufferToBufferTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)9922 void addBufferToBufferTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
9923 {
9924 tcu::TestContext& testCtx = group->getTestContext();
9925
9926 {
9927 TestParams params;
9928 params.src.buffer.size = defaultSize;
9929 params.dst.buffer.size = defaultSize;
9930 params.allocationKind = allocationKind;
9931 params.extensionUse = extensionUse;
9932
9933 const VkBufferCopy bufferCopy =
9934 {
9935 0u, // VkDeviceSize srcOffset;
9936 0u, // VkDeviceSize dstOffset;
9937 defaultSize, // VkDeviceSize size;
9938 };
9939
9940 CopyRegion copyRegion;
9941 copyRegion.bufferCopy = bufferCopy;
9942 params.regions.push_back(copyRegion);
9943
9944 group->addChild(new BufferToBufferTestCase(testCtx, "whole", "Whole buffer", params));
9945 }
9946
9947 // Filter is VK_FILTER_NEAREST.
9948 {
9949 TestParams params;
9950 params.src.buffer.size = defaultFourthSize;
9951 params.dst.buffer.size = defaultFourthSize;
9952 params.allocationKind = allocationKind;
9953 params.extensionUse = extensionUse;
9954
9955 const VkBufferCopy bufferCopy =
9956 {
9957 12u, // VkDeviceSize srcOffset;
9958 4u, // VkDeviceSize dstOffset;
9959 1u, // VkDeviceSize size;
9960 };
9961
9962 CopyRegion copyRegion;
9963 copyRegion.bufferCopy = bufferCopy;
9964 params.regions.push_back(copyRegion);
9965
9966 group->addChild(new BufferToBufferTestCase(testCtx, "partial", "Partial", params));
9967 }
9968
9969 {
9970 const deUint32 size = 16;
9971 TestParams params;
9972 params.src.buffer.size = size;
9973 params.dst.buffer.size = size * (size + 1);
9974 params.allocationKind = allocationKind;
9975 params.extensionUse = extensionUse;
9976
9977 // Copy region with size 1..size
9978 for (unsigned int i = 1; i <= size; i++)
9979 {
9980 const VkBufferCopy bufferCopy =
9981 {
9982 0, // VkDeviceSize srcOffset;
9983 i * size, // VkDeviceSize dstOffset;
9984 i, // VkDeviceSize size;
9985 };
9986
9987 CopyRegion copyRegion;
9988 copyRegion.bufferCopy = bufferCopy;
9989 params.regions.push_back(copyRegion);
9990 }
9991
9992 group->addChild(new BufferToBufferTestCase(testCtx, "regions", "Multiple regions", params));
9993 }
9994 }
9995
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,TestParams & params)9996 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, TestParams& params)
9997 {
9998 tcu::TestContext& testCtx = group->getTestContext();
9999
10000 // Filter is VK_FILTER_NEAREST.
10001 {
10002 params.filter = VK_FILTER_NEAREST;
10003 const std::string description = "Nearest filter";
10004
10005 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10006 group->addChild(new BlitImageTestCase(testCtx, "nearest", description, params));
10007
10008 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
10009 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)");
10010 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToR32, params));
10011
10012 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
10013 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
10014 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_nearest", descriptionOfRGBAToBGRA, params));
10015 }
10016
10017 // Filter is VK_FILTER_LINEAR.
10018 {
10019 params.filter = VK_FILTER_LINEAR;
10020 const std::string description = "Linear filter";
10021
10022 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10023 group->addChild(new BlitImageTestCase(testCtx, "linear", description, params));
10024
10025 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
10026 const std::string descriptionOfRGBAToR32 (description + " and different formats (R8G8B8A8 -> R32)");
10027 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToR32, params));
10028
10029 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
10030 const std::string descriptionOfRGBAToBGRA (description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
10031 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_linear", descriptionOfRGBAToBGRA, params));
10032 }
10033
10034 // Filter is VK_FILTER_CUBIC_EXT.
10035 // Cubic filtering can only be used with 2D images.
10036 if (params.dst.image.imageType == VK_IMAGE_TYPE_2D)
10037 {
10038 params.filter = VK_FILTER_CUBIC_EXT;
10039 const std::string description = "Cubic filter";
10040
10041 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10042 group->addChild(new BlitImageTestCase(testCtx, "cubic", description, params));
10043
10044 params.dst.image.format = VK_FORMAT_R32_SFLOAT;
10045 const std::string descriptionOfRGBAToR32(description + " and different formats (R8G8B8A8 -> R32)");
10046 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToR32, params));
10047
10048 params.dst.image.format = VK_FORMAT_B8G8R8A8_UNORM;
10049 const std::string descriptionOfRGBAToBGRA(description + " and different formats (R8G8B8A8 -> B8G8R8A8)");
10050 group->addChild(new BlitImageTestCase(testCtx, getFormatCaseName(params.dst.image.format) + "_cubic", descriptionOfRGBAToBGRA, params));
10051 }
10052 }
10053
addBlittingImageSimpleWholeTests(tcu::TestCaseGroup * group,TestParams params)10054 void addBlittingImageSimpleWholeTests (tcu::TestCaseGroup* group, TestParams params)
10055 {
10056 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10057 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10058 params.src.image.extent = defaultExtent;
10059 params.dst.image.extent = defaultExtent;
10060 params.src.image.extent.depth = imageDepth;
10061 params.dst.image.extent.depth = imageDepth;
10062
10063 {
10064 const VkImageBlit imageBlit =
10065 {
10066 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10067 {
10068 { 0, 0, 0 },
10069 { defaultSize, defaultSize, imageDepth }
10070 }, // VkOffset3D srcOffsets[2];
10071
10072 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10073 {
10074 { 0, 0, 0 },
10075 { defaultSize, defaultSize, imageDepth }
10076 } // VkOffset3D dstOffset[2];
10077 };
10078
10079 CopyRegion region;
10080 region.imageBlit = imageBlit;
10081 params.regions.push_back(region);
10082 }
10083
10084 addBlittingImageSimpleTests(group, params);
10085 }
10086
addBlittingImageSimpleMirrorXYTests(tcu::TestCaseGroup * group,TestParams params)10087 void addBlittingImageSimpleMirrorXYTests (tcu::TestCaseGroup* group, TestParams params)
10088 {
10089 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10090 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10091 params.src.image.extent = defaultExtent;
10092 params.dst.image.extent = defaultExtent;
10093 params.src.image.extent.depth = imageDepth;
10094 params.dst.image.extent.depth = imageDepth;
10095
10096 {
10097 const VkImageBlit imageBlit =
10098 {
10099 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10100 {
10101 {0, 0, 0},
10102 {defaultSize, defaultSize, imageDepth}
10103 }, // VkOffset3D srcOffsets[2];
10104
10105 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10106 {
10107 {defaultSize, defaultSize, 0},
10108 {0, 0, imageDepth}
10109 } // VkOffset3D dstOffset[2];
10110 };
10111
10112 CopyRegion region;
10113 region.imageBlit = imageBlit;
10114 params.regions.push_back(region);
10115 }
10116
10117 addBlittingImageSimpleTests(group, params);
10118 }
10119
addBlittingImageSimpleMirrorXTests(tcu::TestCaseGroup * group,TestParams params)10120 void addBlittingImageSimpleMirrorXTests (tcu::TestCaseGroup* group, TestParams params)
10121 {
10122 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10123 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10124 params.src.image.extent = defaultExtent;
10125 params.dst.image.extent = defaultExtent;
10126 params.src.image.extent.depth = imageDepth;
10127 params.dst.image.extent.depth = imageDepth;
10128
10129 {
10130 const VkImageBlit imageBlit =
10131 {
10132 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10133 {
10134 {0, 0, 0},
10135 {defaultSize, defaultSize, imageDepth}
10136 }, // VkOffset3D srcOffsets[2];
10137
10138 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10139 {
10140 {defaultSize, 0, 0},
10141 {0, defaultSize, imageDepth}
10142 } // VkOffset3D dstOffset[2];
10143 };
10144
10145 CopyRegion region;
10146 region.imageBlit = imageBlit;
10147 params.regions.push_back(region);
10148 }
10149
10150 addBlittingImageSimpleTests(group, params);
10151 }
10152
addBlittingImageSimpleMirrorYTests(tcu::TestCaseGroup * group,TestParams params)10153 void addBlittingImageSimpleMirrorYTests (tcu::TestCaseGroup* group, TestParams params)
10154 {
10155 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10156 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10157 params.src.image.extent = defaultExtent;
10158 params.dst.image.extent = defaultExtent;
10159 params.src.image.extent.depth = imageDepth;
10160 params.dst.image.extent.depth = imageDepth;
10161
10162 {
10163 const VkImageBlit imageBlit =
10164 {
10165 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10166 {
10167 {0, 0, 0},
10168 {defaultSize, defaultSize, imageDepth}
10169 }, // VkOffset3D srcOffsets[2];
10170
10171 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10172 {
10173 {0, defaultSize, 0},
10174 {defaultSize, 0, imageDepth}
10175 } // VkOffset3D dstOffset[2];
10176 };
10177
10178 CopyRegion region;
10179 region.imageBlit = imageBlit;
10180 params.regions.push_back(region);
10181 }
10182
10183 addBlittingImageSimpleTests(group, params);
10184 }
10185
addBlittingImageSimpleMirrorZTests(tcu::TestCaseGroup * group,TestParams params)10186 void addBlittingImageSimpleMirrorZTests (tcu::TestCaseGroup* group, TestParams params)
10187 {
10188 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10189 DE_ASSERT(params.src.image.imageType == VK_IMAGE_TYPE_3D);
10190 params.src.image.extent = defaultExtent;
10191 params.dst.image.extent = defaultExtent;
10192 params.src.image.extent.depth = defaultSize;
10193 params.dst.image.extent.depth = defaultSize;
10194
10195 {
10196 const VkImageBlit imageBlit =
10197 {
10198 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10199 {
10200 {0, 0, 0},
10201 {defaultSize, defaultSize, defaultSize}
10202 }, // VkOffset3D srcOffsets[2];
10203
10204 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10205 {
10206 {0, 0, defaultSize},
10207 {defaultSize, defaultSize, 0}
10208 } // VkOffset3D dstOffset[2];
10209 };
10210
10211 CopyRegion region;
10212 region.imageBlit = imageBlit;
10213 params.regions.push_back(region);
10214 }
10215
10216 addBlittingImageSimpleTests(group, params);
10217 }
10218
addBlittingImageSimpleMirrorSubregionsTests(tcu::TestCaseGroup * group,TestParams params)10219 void addBlittingImageSimpleMirrorSubregionsTests (tcu::TestCaseGroup* group, TestParams params)
10220 {
10221 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10222 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10223 params.src.image.extent = defaultExtent;
10224 params.dst.image.extent = defaultExtent;
10225 params.src.image.extent.depth = imageDepth;
10226 params.dst.image.extent.depth = imageDepth;
10227
10228 // No mirroring.
10229 {
10230 const VkImageBlit imageBlit =
10231 {
10232 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10233 {
10234 {0, 0, 0},
10235 {defaultHalfSize, defaultHalfSize, imageDepth}
10236 }, // VkOffset3D srcOffsets[2];
10237
10238 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10239 {
10240 {0, 0, 0},
10241 {defaultHalfSize, defaultHalfSize, imageDepth}
10242 } // VkOffset3D dstOffset[2];
10243 };
10244
10245 CopyRegion region;
10246 region.imageBlit = imageBlit;
10247 params.regions.push_back(region);
10248 }
10249
10250 // Flipping y coordinates.
10251 {
10252 const VkImageBlit imageBlit =
10253 {
10254 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10255 {
10256 {defaultHalfSize, 0, 0},
10257 {defaultSize, defaultHalfSize, imageDepth}
10258 }, // VkOffset3D srcOffsets[2];
10259
10260 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10261 {
10262 {defaultHalfSize, defaultHalfSize, 0},
10263 {defaultSize, 0, imageDepth}
10264 } // VkOffset3D dstOffset[2];
10265 };
10266 CopyRegion region;
10267 region.imageBlit = imageBlit;
10268 params.regions.push_back(region);
10269 }
10270
10271 // Flipping x coordinates.
10272 {
10273 const VkImageBlit imageBlit =
10274 {
10275 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10276 {
10277 {0, defaultHalfSize, 0},
10278 {defaultHalfSize, defaultSize, imageDepth}
10279 }, // VkOffset3D srcOffsets[2];
10280
10281 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10282 {
10283 {defaultHalfSize, defaultHalfSize, 0},
10284 {0, defaultSize, imageDepth}
10285 } // VkOffset3D dstOffset[2];
10286 };
10287
10288 CopyRegion region;
10289 region.imageBlit = imageBlit;
10290 params.regions.push_back(region);
10291 }
10292
10293 // Flipping x and y coordinates.
10294 {
10295 const VkImageBlit imageBlit =
10296 {
10297 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10298 {
10299 {defaultHalfSize, defaultHalfSize, 0},
10300 {defaultSize, defaultSize, imageDepth}
10301 }, // VkOffset3D srcOffsets[2];
10302
10303 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10304 {
10305 {defaultSize, defaultSize, 0},
10306 {defaultHalfSize, defaultHalfSize, imageDepth}
10307 } // VkOffset3D dstOffset[2];
10308 };
10309
10310 CopyRegion region;
10311 region.imageBlit = imageBlit;
10312 params.regions.push_back(region);
10313 }
10314
10315 addBlittingImageSimpleTests(group, params);
10316 }
10317
addBlittingImageSimpleScalingWhole1Tests(tcu::TestCaseGroup * group,TestParams params)10318 void addBlittingImageSimpleScalingWhole1Tests (tcu::TestCaseGroup* group, TestParams params)
10319 {
10320 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10321 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10322 const deInt32 halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
10323 params.src.image.extent = defaultExtent;
10324 params.dst.image.extent = defaultHalfExtent;
10325 params.src.image.extent.depth = imageDepth;
10326 params.dst.image.extent.depth = halfImageDepth;
10327
10328 {
10329 const VkImageBlit imageBlit =
10330 {
10331 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10332 {
10333 {0, 0, 0},
10334 {defaultSize, defaultSize, imageDepth}
10335 }, // VkOffset3D srcOffsets[2];
10336
10337 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10338 {
10339 {0, 0, 0},
10340 {defaultHalfSize, defaultHalfSize, halfImageDepth}
10341 } // VkOffset3D dstOffset[2];
10342 };
10343
10344 CopyRegion region;
10345 region.imageBlit = imageBlit;
10346 params.regions.push_back(region);
10347 }
10348
10349 addBlittingImageSimpleTests(group, params);
10350 }
10351
addBlittingImageSimpleScalingWhole2Tests(tcu::TestCaseGroup * group,TestParams params)10352 void addBlittingImageSimpleScalingWhole2Tests (tcu::TestCaseGroup* group, TestParams params)
10353 {
10354 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10355 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10356 const deInt32 halfImageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultHalfSize : 1;
10357 params.src.image.extent = defaultHalfExtent;
10358 params.dst.image.extent = defaultExtent;
10359 params.src.image.extent.depth = halfImageDepth;
10360 params.dst.image.extent.depth = imageDepth;
10361
10362 {
10363 const VkImageBlit imageBlit =
10364 {
10365 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10366 {
10367 {0, 0, 0},
10368 {defaultHalfSize, defaultHalfSize, halfImageDepth}
10369 }, // VkOffset3D srcOffsets[2];
10370
10371 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10372 {
10373 {0, 0, 0},
10374 {defaultSize, defaultSize, imageDepth}
10375 } // VkOffset3D dstOffset[2];
10376 };
10377
10378 CopyRegion region;
10379 region.imageBlit = imageBlit;
10380 params.regions.push_back(region);
10381 }
10382
10383 addBlittingImageSimpleTests(group, params);
10384 }
10385
addBlittingImageSimpleScalingAndOffsetTests(tcu::TestCaseGroup * group,TestParams params)10386 void addBlittingImageSimpleScalingAndOffsetTests (tcu::TestCaseGroup* group, TestParams params)
10387 {
10388 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10389 const deInt32 imageDepth = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultSize : 1;
10390 const deInt32 srcDepthOffset = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize : 0;
10391 const deInt32 srcDepthSize = params.src.image.imageType == VK_IMAGE_TYPE_3D ? defaultFourthSize * 3 : 1;
10392 params.src.image.extent = defaultExtent;
10393 params.dst.image.extent = defaultExtent;
10394 params.src.image.extent.depth = imageDepth;
10395 params.dst.image.extent.depth = imageDepth;
10396
10397 {
10398 const VkImageBlit imageBlit =
10399 {
10400 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10401 {
10402 {defaultFourthSize, defaultFourthSize, srcDepthOffset},
10403 {defaultFourthSize*3, defaultFourthSize*3, srcDepthSize}
10404 }, // VkOffset3D srcOffsets[2];
10405
10406 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10407 {
10408 {0, 0, 0},
10409 {defaultSize, defaultSize, imageDepth}
10410 } // VkOffset3D dstOffset[2];
10411 };
10412
10413 CopyRegion region;
10414 region.imageBlit = imageBlit;
10415 params.regions.push_back(region);
10416 }
10417
10418 addBlittingImageSimpleTests(group, params);
10419 }
10420
addBlittingImageSimpleWithoutScalingPartialTests(tcu::TestCaseGroup * group,TestParams params)10421 void addBlittingImageSimpleWithoutScalingPartialTests (tcu::TestCaseGroup* group, TestParams params)
10422 {
10423 DE_ASSERT(params.src.image.imageType == params.dst.image.imageType);
10424 const bool is3dBlit = params.src.image.imageType == VK_IMAGE_TYPE_3D;
10425 params.src.image.extent = defaultExtent;
10426 params.dst.image.extent = defaultExtent;
10427
10428 if (is3dBlit)
10429 {
10430 params.src.image.extent.depth = defaultSize;
10431 params.dst.image.extent.depth = defaultSize;
10432 }
10433
10434 {
10435 CopyRegion region;
10436 for (int i = 0; i < defaultSize; i += defaultFourthSize)
10437 {
10438 const VkImageBlit imageBlit =
10439 {
10440 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
10441 {
10442 {defaultSize - defaultFourthSize - i, defaultSize - defaultFourthSize - i, is3dBlit ? defaultSize - defaultFourthSize - i : 0},
10443 {defaultSize - i, defaultSize - i, is3dBlit ? defaultSize - i : 1}
10444 }, // VkOffset3D srcOffsets[2];
10445
10446 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
10447 {
10448 {i, i, is3dBlit ? i : 0},
10449 {i + defaultFourthSize, i + defaultFourthSize, is3dBlit ? i + defaultFourthSize : 1}
10450 } // VkOffset3D dstOffset[2];
10451 };
10452 region.imageBlit = imageBlit;
10453 params.regions.push_back(region);
10454 }
10455 }
10456
10457 addBlittingImageSimpleTests(group, params);
10458 }
10459
addBlittingImageSimpleTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)10460 void addBlittingImageSimpleTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
10461 {
10462 TestParams params;
10463 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
10464 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10465 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
10466 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
10467 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
10468 params.allocationKind = allocationKind;
10469 params.extensionUse = extensionUse;
10470 params.src.image.imageType = VK_IMAGE_TYPE_2D;
10471 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
10472 addTestGroup(group, "whole", "Blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10473 addTestGroup(group, "mirror_xy", "Flipping x and y coordinates (whole)", addBlittingImageSimpleMirrorXYTests, params);
10474 addTestGroup(group, "mirror_x", "Flipping x coordinates (whole)", addBlittingImageSimpleMirrorXTests, params);
10475 addTestGroup(group, "mirror_y", "Flipping y coordinates (whole)", addBlittingImageSimpleMirrorYTests, params);
10476 addTestGroup(group, "mirror_subregions", "Mirroring subregions in image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10477 addTestGroup(group, "scaling_whole1", "Blit with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10478 addTestGroup(group, "scaling_whole2", "Blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10479 addTestGroup(group, "scaling_and_offset", "Blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10480 addTestGroup(group, "without_scaling_partial", "Blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10481
10482 params.src.image.imageType = VK_IMAGE_TYPE_3D;
10483 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
10484 addTestGroup(group, "whole_3d", "3D blit without scaling (whole)", addBlittingImageSimpleWholeTests, params);
10485 addTestGroup(group, "mirror_xy_3d", "Flipping x and y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXYTests, params);
10486 addTestGroup(group, "mirror_x_3d", "Flipping x coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorXTests, params);
10487 addTestGroup(group, "mirror_y_3d", "Flipping y coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorYTests, params);
10488 addTestGroup(group, "mirror_z_3d", "Flipping z coordinates of a 3D image (whole)", addBlittingImageSimpleMirrorZTests, params);
10489 addTestGroup(group, "mirror_subregions_3d", "Mirroring subregions in a 3D image (no flip, y flip, x flip, xy flip)", addBlittingImageSimpleMirrorSubregionsTests, params);
10490 addTestGroup(group, "scaling_whole1_3d", "3D blit a with scaling (whole, src extent bigger)", addBlittingImageSimpleScalingWhole1Tests, params);
10491 addTestGroup(group, "scaling_whole2_3d", "3D blit with scaling (whole, dst extent bigger)", addBlittingImageSimpleScalingWhole2Tests, params);
10492 addTestGroup(group, "scaling_and_offset_3d", "3D blit with scaling and offset (whole, dst extent bigger)", addBlittingImageSimpleScalingAndOffsetTests, params);
10493 addTestGroup(group, "without_scaling_partial_3d", "3D blit without scaling (partial)", addBlittingImageSimpleWithoutScalingPartialTests, params);
10494 }
10495
10496 enum FilterMaskBits
10497 {
10498 FILTER_MASK_NEAREST = 0, // Always tested.
10499 FILTER_MASK_LINEAR = (1u << 0),
10500 FILTER_MASK_CUBIC = (1u << 1),
10501 };
10502
10503 using FilterMask = deUint32;
10504
makeFilterMask(bool onlyNearest,bool discardCubicFilter)10505 FilterMask makeFilterMask (bool onlyNearest, bool discardCubicFilter)
10506 {
10507 FilterMask mask = FILTER_MASK_NEAREST;
10508
10509 if (!onlyNearest)
10510 {
10511 mask |= FILTER_MASK_LINEAR;
10512 if (!discardCubicFilter)
10513 mask |= FILTER_MASK_CUBIC;
10514 }
10515
10516 return mask;
10517 }
10518
10519 struct BlitColorTestParams
10520 {
10521 TestParams params;
10522 const VkFormat* compatibleFormats;
10523 FilterMask testFilters;
10524 };
10525
isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams & testParams)10526 bool isAllowedBlittingAllFormatsColorSrcFormatTests(const BlitColorTestParams& testParams)
10527 {
10528 bool result = true;
10529
10530 if (testParams.params.allocationKind == ALLOCATION_KIND_DEDICATED)
10531 {
10532 DE_ASSERT(!dedicatedAllocationBlittingFormatsToTestSet.empty());
10533
10534 result =
10535 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.dst.image.format) ||
10536 de::contains(dedicatedAllocationBlittingFormatsToTestSet, testParams.params.src.image.format);
10537 }
10538
10539 return result;
10540 }
10541
10542 const VkFormat linearOtherImageFormatsToTest[] =
10543 {
10544 // From compatibleFormats8Bit
10545 VK_FORMAT_R4G4_UNORM_PACK8,
10546 VK_FORMAT_R8_SRGB,
10547
10548 // From compatibleFormats16Bit
10549 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10550 VK_FORMAT_R16_SFLOAT,
10551
10552 // From compatibleFormats24Bit
10553 VK_FORMAT_R8G8B8_UNORM,
10554 VK_FORMAT_B8G8R8_SRGB,
10555
10556 // From compatibleFormats32Bit
10557 VK_FORMAT_R8G8B8A8_UNORM,
10558 VK_FORMAT_R32_SFLOAT,
10559
10560 // From compatibleFormats48Bit
10561 VK_FORMAT_R16G16B16_UNORM,
10562 VK_FORMAT_R16G16B16_SFLOAT,
10563
10564 // From compatibleFormats64Bit
10565 VK_FORMAT_R16G16B16A16_UNORM,
10566 VK_FORMAT_R64_SFLOAT,
10567
10568 // From compatibleFormats96Bit
10569 VK_FORMAT_R32G32B32_UINT,
10570 VK_FORMAT_R32G32B32_SFLOAT,
10571
10572 // From compatibleFormats128Bit
10573 VK_FORMAT_R32G32B32A32_UINT,
10574 VK_FORMAT_R64G64_SFLOAT,
10575
10576 // From compatibleFormats192Bit
10577 VK_FORMAT_R64G64B64_UINT,
10578 VK_FORMAT_R64G64B64_SFLOAT,
10579
10580 // From compatibleFormats256Bit
10581 VK_FORMAT_R64G64B64A64_UINT,
10582 VK_FORMAT_R64G64B64A64_SFLOAT,
10583 };
10584
getBlitImageTilingLayoutCaseName(VkImageTiling tiling,VkImageLayout layout)10585 std::string getBlitImageTilingLayoutCaseName (VkImageTiling tiling, VkImageLayout layout)
10586 {
10587 switch (tiling)
10588 {
10589 case VK_IMAGE_TILING_OPTIMAL:
10590 return getImageLayoutCaseName(layout);
10591 case VK_IMAGE_TILING_LINEAR:
10592 return "linear";
10593 default:
10594 DE_ASSERT(false);
10595 return "";
10596 }
10597 }
10598
addBlittingImageAllFormatsColorSrcFormatDstFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)10599 void addBlittingImageAllFormatsColorSrcFormatDstFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10600 {
10601 tcu::TestContext& testCtx = group->getTestContext();
10602
10603 FormatSet linearOtherImageFormatsToTestSet;
10604 const int numOfOtherImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(linearOtherImageFormatsToTest);
10605 for (int otherImageFormatsIndex = 0; otherImageFormatsIndex < numOfOtherImageFormatsToTestFilter; ++otherImageFormatsIndex)
10606 linearOtherImageFormatsToTestSet.insert(linearOtherImageFormatsToTest[otherImageFormatsIndex]);
10607
10608 const VkImageTiling blitSrcTilings[] =
10609 {
10610 VK_IMAGE_TILING_OPTIMAL,
10611 VK_IMAGE_TILING_LINEAR,
10612 };
10613 const VkImageLayout blitSrcLayouts[] =
10614 {
10615 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
10616 VK_IMAGE_LAYOUT_GENERAL
10617 };
10618 const VkImageTiling blitDstTilings[] =
10619 {
10620 VK_IMAGE_TILING_OPTIMAL,
10621 VK_IMAGE_TILING_LINEAR,
10622 };
10623 const VkImageLayout blitDstLayouts[] =
10624 {
10625 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
10626 VK_IMAGE_LAYOUT_GENERAL
10627 };
10628
10629 for (int srcTilingNdx = 0u; srcTilingNdx < DE_LENGTH_OF_ARRAY(blitSrcTilings); ++srcTilingNdx)
10630 {
10631 testParams.params.src.image.tiling = blitSrcTilings[srcTilingNdx];
10632
10633 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
10634 {
10635 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
10636
10637 // Don't bother testing VK_IMAGE_TILING_LINEAR + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL as it's likely to be the same as VK_IMAGE_LAYOUT_GENERAL
10638 if (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
10639 continue;
10640
10641 for (int dstTilingNdx = 0u; dstTilingNdx < DE_LENGTH_OF_ARRAY(blitDstTilings); ++dstTilingNdx)
10642 {
10643 testParams.params.dst.image.tiling = blitDstTilings[dstTilingNdx];
10644
10645 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
10646 {
10647 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
10648
10649 // Don't bother testing VK_IMAGE_TILING_LINEAR + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL as it's likely to be the same as VK_IMAGE_LAYOUT_GENERAL
10650 if (testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && testParams.params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)
10651 continue;
10652
10653 if ((testParams.params.dst.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.src.image.format)) ||
10654 (testParams.params.src.image.tiling == VK_IMAGE_TILING_LINEAR && !de::contains(linearOtherImageFormatsToTestSet, testParams.params.dst.image.format)))
10655 continue;
10656
10657 testParams.params.filter = VK_FILTER_NEAREST;
10658 const std::string testName = getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) + "_" +
10659 getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10660 const std::string description = "Blit from layout " + getBlitImageTilingLayoutCaseName(testParams.params.src.image.tiling, testParams.params.src.image.operationLayout) +
10661 " to " + getBlitImageTilingLayoutCaseName(testParams.params.dst.image.tiling, testParams.params.dst.image.operationLayout);
10662 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest", description, testParams.params));
10663
10664 if (testParams.testFilters & FILTER_MASK_LINEAR)
10665 {
10666 testParams.params.filter = VK_FILTER_LINEAR;
10667 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear", description, testParams.params));
10668 }
10669
10670 if (testParams.testFilters & FILTER_MASK_CUBIC)
10671 {
10672 testParams.params.filter = VK_FILTER_CUBIC_EXT;
10673 group->addChild(new BlitImageTestCase(testCtx, testName + "_cubic", description, testParams.params));
10674 }
10675
10676 if ((testParams.params.src.image.imageType == VK_IMAGE_TYPE_3D) && !isCompressedFormat(testParams.params.src.image.format))
10677 {
10678 const struct
10679 {
10680 FillMode mode;
10681 const char* name;
10682 } modeList[] =
10683 {
10684 { FILL_MODE_BLUE_RED_X, "x" },
10685 { FILL_MODE_BLUE_RED_Y, "y" },
10686 { FILL_MODE_BLUE_RED_Z, "z" },
10687 };
10688
10689 auto otherParams = testParams;
10690 otherParams.params.dst.image.fillMode = FILL_MODE_WHITE;
10691
10692 for (int i = 0; i < DE_LENGTH_OF_ARRAY(modeList); ++i)
10693 {
10694 otherParams.params.src.image.fillMode = modeList[i].mode;
10695
10696 otherParams.params.filter = VK_FILTER_LINEAR;
10697 group->addChild(new BlitImageTestCase(testCtx, testName + "_linear_stripes_" + modeList[i].name, description, otherParams.params));
10698
10699 otherParams.params.filter = VK_FILTER_NEAREST;
10700 group->addChild(new BlitImageTestCase(testCtx, testName + "_nearest_stripes_" + modeList[i].name, description, otherParams.params));
10701 }
10702 }
10703 }
10704 }
10705 }
10706 }
10707 }
10708
addBlittingImageAllFormatsColorSrcFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)10709 void addBlittingImageAllFormatsColorSrcFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
10710 {
10711 VkFormat srcFormat = testParams.params.src.image.format;
10712
10713 if (testParams.compatibleFormats)
10714 {
10715 for (int dstFormatIndex = 0; testParams.compatibleFormats[dstFormatIndex] != VK_FORMAT_UNDEFINED; ++dstFormatIndex)
10716 {
10717 testParams.params.dst.image.format = testParams.compatibleFormats[dstFormatIndex];
10718 if (!isSupportedByFramework(testParams.params.dst.image.format))
10719 continue;
10720
10721 if (!isAllowedBlittingAllFormatsColorSrcFormatTests(testParams))
10722 continue;
10723
10724 const std::string description = "Blit destination format " + getFormatCaseName(testParams.params.dst.image.format);
10725 addTestGroup(group, getFormatCaseName(testParams.params.dst.image.format), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10726 }
10727 }
10728
10729 // If testParams.compatibleFormats is nullptr, the destination format will be copied from the source format
10730 // When testParams.compatibleFormats is not nullptr but format is compressed we also need to add that format
10731 // as it is not on compatibleFormats list
10732 if (!testParams.compatibleFormats || isCompressedFormat(srcFormat))
10733 {
10734 testParams.params.dst.image.format = srcFormat;
10735
10736 const std::string description = "Blit destination format " + getFormatCaseName(srcFormat);
10737 addTestGroup(group, getFormatCaseName(srcFormat), description, addBlittingImageAllFormatsColorSrcFormatDstFormatTests, testParams);
10738 }
10739 }
10740
10741 const VkFormat compatibleFormatsUInts[] =
10742 {
10743 VK_FORMAT_R8_UINT,
10744 VK_FORMAT_R8G8_UINT,
10745 VK_FORMAT_R8G8B8_UINT,
10746 VK_FORMAT_B8G8R8_UINT,
10747 VK_FORMAT_R8G8B8A8_UINT,
10748 VK_FORMAT_B8G8R8A8_UINT,
10749 VK_FORMAT_A8B8G8R8_UINT_PACK32,
10750 VK_FORMAT_A2R10G10B10_UINT_PACK32,
10751 VK_FORMAT_A2B10G10R10_UINT_PACK32,
10752 VK_FORMAT_R16_UINT,
10753 VK_FORMAT_R16G16_UINT,
10754 VK_FORMAT_R16G16B16_UINT,
10755 VK_FORMAT_R16G16B16A16_UINT,
10756 VK_FORMAT_R32_UINT,
10757 VK_FORMAT_R32G32_UINT,
10758 VK_FORMAT_R32G32B32_UINT,
10759 VK_FORMAT_R32G32B32A32_UINT,
10760 VK_FORMAT_R64_UINT,
10761 VK_FORMAT_R64G64_UINT,
10762 VK_FORMAT_R64G64B64_UINT,
10763 VK_FORMAT_R64G64B64A64_UINT,
10764
10765 VK_FORMAT_UNDEFINED
10766 };
10767 const VkFormat compatibleFormatsSInts[] =
10768 {
10769 VK_FORMAT_R8_SINT,
10770 VK_FORMAT_R8G8_SINT,
10771 VK_FORMAT_R8G8B8_SINT,
10772 VK_FORMAT_B8G8R8_SINT,
10773 VK_FORMAT_R8G8B8A8_SINT,
10774 VK_FORMAT_B8G8R8A8_SINT,
10775 VK_FORMAT_A8B8G8R8_SINT_PACK32,
10776 VK_FORMAT_A2R10G10B10_SINT_PACK32,
10777 VK_FORMAT_A2B10G10R10_SINT_PACK32,
10778 VK_FORMAT_R16_SINT,
10779 VK_FORMAT_R16G16_SINT,
10780 VK_FORMAT_R16G16B16_SINT,
10781 VK_FORMAT_R16G16B16A16_SINT,
10782 VK_FORMAT_R32_SINT,
10783 VK_FORMAT_R32G32_SINT,
10784 VK_FORMAT_R32G32B32_SINT,
10785 VK_FORMAT_R32G32B32A32_SINT,
10786 VK_FORMAT_R64_SINT,
10787 VK_FORMAT_R64G64_SINT,
10788 VK_FORMAT_R64G64B64_SINT,
10789 VK_FORMAT_R64G64B64A64_SINT,
10790
10791 VK_FORMAT_UNDEFINED
10792 };
10793 const VkFormat compatibleFormatsFloats[] =
10794 {
10795 VK_FORMAT_R4G4_UNORM_PACK8,
10796 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
10797 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
10798 VK_FORMAT_R5G6B5_UNORM_PACK16,
10799 VK_FORMAT_B5G6R5_UNORM_PACK16,
10800 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
10801 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
10802 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
10803 VK_FORMAT_R8_UNORM,
10804 VK_FORMAT_R8_SNORM,
10805 VK_FORMAT_R8_USCALED,
10806 VK_FORMAT_R8_SSCALED,
10807 VK_FORMAT_R8G8_UNORM,
10808 VK_FORMAT_R8G8_SNORM,
10809 VK_FORMAT_R8G8_USCALED,
10810 VK_FORMAT_R8G8_SSCALED,
10811 VK_FORMAT_R8G8B8_UNORM,
10812 VK_FORMAT_R8G8B8_SNORM,
10813 VK_FORMAT_R8G8B8_USCALED,
10814 VK_FORMAT_R8G8B8_SSCALED,
10815 VK_FORMAT_B8G8R8_UNORM,
10816 VK_FORMAT_B8G8R8_SNORM,
10817 VK_FORMAT_B8G8R8_USCALED,
10818 VK_FORMAT_B8G8R8_SSCALED,
10819 VK_FORMAT_R8G8B8A8_UNORM,
10820 VK_FORMAT_R8G8B8A8_SNORM,
10821 VK_FORMAT_R8G8B8A8_USCALED,
10822 VK_FORMAT_R8G8B8A8_SSCALED,
10823 VK_FORMAT_B8G8R8A8_UNORM,
10824 VK_FORMAT_B8G8R8A8_SNORM,
10825 VK_FORMAT_B8G8R8A8_USCALED,
10826 VK_FORMAT_B8G8R8A8_SSCALED,
10827 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
10828 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
10829 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10830 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10831 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
10832 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
10833 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
10834 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
10835 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
10836 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
10837 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
10838 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
10839 VK_FORMAT_R16_UNORM,
10840 VK_FORMAT_R16_SNORM,
10841 VK_FORMAT_R16_USCALED,
10842 VK_FORMAT_R16_SSCALED,
10843 VK_FORMAT_R16_SFLOAT,
10844 VK_FORMAT_R16G16_UNORM,
10845 VK_FORMAT_R16G16_SNORM,
10846 VK_FORMAT_R16G16_USCALED,
10847 VK_FORMAT_R16G16_SSCALED,
10848 VK_FORMAT_R16G16_SFLOAT,
10849 VK_FORMAT_R16G16B16_UNORM,
10850 VK_FORMAT_R16G16B16_SNORM,
10851 VK_FORMAT_R16G16B16_USCALED,
10852 VK_FORMAT_R16G16B16_SSCALED,
10853 VK_FORMAT_R16G16B16_SFLOAT,
10854 VK_FORMAT_R16G16B16A16_UNORM,
10855 VK_FORMAT_R16G16B16A16_SNORM,
10856 VK_FORMAT_R16G16B16A16_USCALED,
10857 VK_FORMAT_R16G16B16A16_SSCALED,
10858 VK_FORMAT_R16G16B16A16_SFLOAT,
10859 VK_FORMAT_R32_SFLOAT,
10860 VK_FORMAT_R32G32_SFLOAT,
10861 VK_FORMAT_R32G32B32_SFLOAT,
10862 VK_FORMAT_R32G32B32A32_SFLOAT,
10863 VK_FORMAT_R64_SFLOAT,
10864 VK_FORMAT_R64G64_SFLOAT,
10865 VK_FORMAT_R64G64B64_SFLOAT,
10866 VK_FORMAT_R64G64B64A64_SFLOAT,
10867 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
10868 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10869
10870 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
10871 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
10872
10873 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16,
10874
10875 VK_FORMAT_UNDEFINED
10876 };
10877
10878 const VkFormat compressedFormatsFloats[] =
10879 {
10880 VK_FORMAT_BC1_RGB_UNORM_BLOCK,
10881 VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
10882 VK_FORMAT_BC2_UNORM_BLOCK,
10883 VK_FORMAT_BC3_UNORM_BLOCK,
10884 VK_FORMAT_BC4_UNORM_BLOCK,
10885 VK_FORMAT_BC4_SNORM_BLOCK,
10886 VK_FORMAT_BC5_UNORM_BLOCK,
10887 VK_FORMAT_BC5_SNORM_BLOCK,
10888 VK_FORMAT_BC6H_UFLOAT_BLOCK,
10889 VK_FORMAT_BC6H_SFLOAT_BLOCK,
10890 VK_FORMAT_BC7_UNORM_BLOCK,
10891 VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
10892 VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
10893 VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
10894 VK_FORMAT_EAC_R11_UNORM_BLOCK,
10895 VK_FORMAT_EAC_R11_SNORM_BLOCK,
10896 VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
10897 VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
10898 VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
10899 VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
10900 VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
10901 VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
10902 VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
10903 VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
10904 VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
10905 VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
10906 VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
10907 VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
10908 VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
10909 VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
10910 VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
10911 VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
10912
10913 VK_FORMAT_UNDEFINED
10914 };
10915
10916 const VkFormat compatibleFormatsSrgb[] =
10917 {
10918 VK_FORMAT_R8_SRGB,
10919 VK_FORMAT_R8G8_SRGB,
10920 VK_FORMAT_R8G8B8_SRGB,
10921 VK_FORMAT_B8G8R8_SRGB,
10922 VK_FORMAT_R8G8B8A8_SRGB,
10923 VK_FORMAT_B8G8R8A8_SRGB,
10924 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10925
10926 VK_FORMAT_UNDEFINED
10927 };
10928
10929 const VkFormat compressedFormatsSrgb[] =
10930 {
10931 VK_FORMAT_BC1_RGB_SRGB_BLOCK,
10932 VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
10933 VK_FORMAT_BC2_SRGB_BLOCK,
10934 VK_FORMAT_BC3_SRGB_BLOCK,
10935 VK_FORMAT_BC7_SRGB_BLOCK,
10936 VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
10937 VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
10938 VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
10939 VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
10940 VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
10941 VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
10942 VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
10943 VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
10944 VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
10945 VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
10946 VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
10947 VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
10948 VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
10949 VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
10950 VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
10951 VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
10952 VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
10953
10954 VK_FORMAT_UNDEFINED
10955 };
10956
10957 const VkFormat dedicatedAllocationBlittingFormatsToTest[] =
10958 {
10959 // compatibleFormatsUInts
10960 VK_FORMAT_R8_UINT,
10961 VK_FORMAT_R64G64B64A64_UINT,
10962
10963 // compatibleFormatsSInts
10964 VK_FORMAT_R8_SINT,
10965 VK_FORMAT_R64G64B64A64_SINT,
10966
10967 // compatibleFormatsFloats
10968 VK_FORMAT_R4G4_UNORM_PACK8,
10969 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
10970
10971 // compatibleFormatsSrgb
10972 VK_FORMAT_R8_SRGB,
10973 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
10974 };
10975
10976 // skip cubic filtering test for the following data formats
10977 const FormatSet onlyNearestAndLinearFormatsToTest =
10978 {
10979 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
10980 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
10981 VK_FORMAT_A8B8G8R8_UINT_PACK32,
10982 VK_FORMAT_A8B8G8R8_SINT_PACK32
10983 };
10984
10985 // astc formats have diferent block sizes and thus require diferent resolutions for images
10986 enum class AstcImageSizeType
10987 {
10988 SIZE_64_64 = 0,
10989 SIZE_60_64,
10990 SIZE_64_60,
10991 SIZE_60_60,
10992 };
10993
10994 const std::map<VkFormat, AstcImageSizeType> astcSizes
10995 {
10996 { VK_FORMAT_ASTC_4x4_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64 },
10997 { VK_FORMAT_ASTC_4x4_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64 },
10998 { VK_FORMAT_ASTC_5x4_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64 },
10999 { VK_FORMAT_ASTC_5x4_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64 },
11000 { VK_FORMAT_ASTC_5x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11001 { VK_FORMAT_ASTC_5x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
11002 { VK_FORMAT_ASTC_6x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11003 { VK_FORMAT_ASTC_6x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
11004 { VK_FORMAT_ASTC_6x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11005 { VK_FORMAT_ASTC_6x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
11006 { VK_FORMAT_ASTC_8x5_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60 },
11007 { VK_FORMAT_ASTC_8x5_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60 },
11008 { VK_FORMAT_ASTC_8x6_SRGB_BLOCK, AstcImageSizeType::SIZE_64_60 },
11009 { VK_FORMAT_ASTC_8x6_UNORM_BLOCK, AstcImageSizeType::SIZE_64_60 },
11010 { VK_FORMAT_ASTC_8x8_SRGB_BLOCK, AstcImageSizeType::SIZE_64_64 },
11011 { VK_FORMAT_ASTC_8x8_UNORM_BLOCK, AstcImageSizeType::SIZE_64_64 },
11012 { VK_FORMAT_ASTC_10x5_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11013 { VK_FORMAT_ASTC_10x5_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
11014 { VK_FORMAT_ASTC_10x6_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11015 { VK_FORMAT_ASTC_10x6_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
11016 { VK_FORMAT_ASTC_10x8_SRGB_BLOCK, AstcImageSizeType::SIZE_60_64 },
11017 { VK_FORMAT_ASTC_10x8_UNORM_BLOCK, AstcImageSizeType::SIZE_60_64 },
11018 { VK_FORMAT_ASTC_10x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11019 { VK_FORMAT_ASTC_10x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
11020 { VK_FORMAT_ASTC_12x10_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11021 { VK_FORMAT_ASTC_12x10_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 },
11022 { VK_FORMAT_ASTC_12x12_SRGB_BLOCK, AstcImageSizeType::SIZE_60_60 },
11023 { VK_FORMAT_ASTC_12x12_UNORM_BLOCK, AstcImageSizeType::SIZE_60_60 }
11024 };
11025
create2DCopyRegions(deInt32 srcWidth,deInt32 srcHeight,deInt32 dstWidth,deInt32 dstHeight)11026 std::vector<CopyRegion> create2DCopyRegions(deInt32 srcWidth, deInt32 srcHeight, deInt32 dstWidth, deInt32 dstHeight)
11027 {
11028 CopyRegion region;
11029 std::vector<CopyRegion> regionsVector;
11030
11031 deInt32 fourthOfSrcWidth = srcWidth / 4;
11032 deInt32 fourthOfSrcHeight = srcHeight / 4;
11033 deInt32 fourthOfDstWidth = dstWidth / 4;
11034 deInt32 fourthOfDstHeight = dstHeight / 4;
11035
11036 // to the top of resulting image copy whole source image but with increasingly smaller sizes
11037 for (int i = 0, j = 1; (i + fourthOfDstWidth / j < dstWidth) && (fourthOfDstWidth > j); i += fourthOfDstWidth / j++)
11038 {
11039 region.imageBlit =
11040 {
11041 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
11042 {
11043 {0, 0, 0},
11044 {srcWidth, srcHeight, 1}
11045 }, // VkOffset3D srcOffsets[2];
11046
11047 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
11048 {
11049 {i, 0, 0},
11050 {i + fourthOfDstWidth / j, fourthOfDstHeight / j, 1}
11051 } // VkOffset3D dstOffset[2];
11052 };
11053 regionsVector.push_back(region);
11054 }
11055
11056 // to the bottom of resulting image copy parts of source image;
11057 for (int i = 0; i < 4; ++i)
11058 {
11059 int srcX = i * fourthOfSrcWidth;
11060 int srcY = i * fourthOfSrcHeight;
11061 int dstX = i * fourthOfDstWidth;
11062
11063 region.imageBlit =
11064 {
11065 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
11066 {
11067 {srcX, srcY, 0},
11068 {srcX + fourthOfSrcWidth, srcY + fourthOfSrcHeight, 1}
11069 }, // VkOffset3D srcOffsets[2];
11070
11071 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
11072 {
11073 {dstX, 2 * fourthOfDstHeight, 0},
11074 {dstX + fourthOfDstWidth, 3 * fourthOfDstHeight, 1}
11075 } // VkOffset3D dstOffset[2];
11076 };
11077
11078 regionsVector.push_back(region);
11079 }
11080
11081 return regionsVector;
11082 }
11083
addBlittingImageAllFormatsColorTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11084 void addBlittingImageAllFormatsColorTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11085 {
11086 const struct {
11087 const VkFormat* sourceFormats;
11088 const VkFormat* destinationFormats;
11089 const bool onlyNearest;
11090 } colorImageFormatsToTestBlit[] =
11091 {
11092 { compatibleFormatsUInts, compatibleFormatsUInts, true },
11093 { compatibleFormatsSInts, compatibleFormatsSInts, true },
11094 { compatibleFormatsFloats, compatibleFormatsFloats, false },
11095 { compressedFormatsFloats, compatibleFormatsFloats, false },
11096 { compatibleFormatsSrgb, compatibleFormatsSrgb, false },
11097 { compressedFormatsSrgb, compatibleFormatsSrgb, false },
11098 };
11099
11100 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11101
11102 if (allocationKind == ALLOCATION_KIND_DEDICATED)
11103 {
11104 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11105 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11106 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11107 }
11108
11109 // 2D tests.
11110 {
11111 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
11112
11113 TestParams params;
11114 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11115 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11116 params.src.image.extent = defaultExtent;
11117 params.dst.image.extent = defaultExtent;
11118 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11119 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11120 params.allocationKind = allocationKind;
11121 params.extensionUse = extensionUse;
11122
11123 // create all required copy regions
11124 const std::map<AstcImageSizeType, std::vector<CopyRegion> > imageRegions
11125 {
11126 { AstcImageSizeType::SIZE_64_64, create2DCopyRegions(64, 64, 64, 64) },
11127 { AstcImageSizeType::SIZE_60_64, create2DCopyRegions(60, 64, 60, 64) },
11128 { AstcImageSizeType::SIZE_64_60, create2DCopyRegions(64, 60, 64, 60) },
11129 { AstcImageSizeType::SIZE_60_60, create2DCopyRegions(60, 60, 60, 60) },
11130 };
11131
11132 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11133 {
11134 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
11135 const VkFormat* destinationFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].destinationFormats;
11136 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11137 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11138 {
11139 VkFormat srcFormat = sourceFormats[srcFormatIndex];
11140 params.src.image.format = srcFormat;
11141
11142 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11143
11144 // most of tests are using regions caluculated for 64x64 size but astc formats require custom regions
11145 params.regions = imageRegions.at(AstcImageSizeType::SIZE_64_64);
11146 if (isCompressedFormat(srcFormat) && isAstcFormat(mapVkCompressedFormat(srcFormat)))
11147 params.regions = imageRegions.at(astcSizes.at(srcFormat));
11148
11149 // use the fact that first region contains the size of full source image
11150 // and make source and destination the same size - this is needed for astc formats
11151 const VkOffset3D& srcImageSize = params.regions[0].imageBlit.srcOffsets[1];
11152 VkExtent3D& srcImageExtent = params.src.image.extent;
11153 VkExtent3D& dstImageExtent = params.dst.image.extent;
11154 srcImageExtent.width = srcImageSize.x;
11155 srcImageExtent.height = srcImageSize.y;
11156 dstImageExtent.width = srcImageSize.x;
11157 dstImageExtent.height = srcImageSize.y;
11158
11159 BlitColorTestParams testParams
11160 {
11161 params,
11162 destinationFormats,
11163 makeFilterMask(onlyNearest, onlyNearestAndLinear)
11164 };
11165
11166 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
11167 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
11168 }
11169 }
11170
11171 group->addChild(subGroup.release());
11172 }
11173
11174 // 1D tests.
11175 {
11176 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
11177
11178 TestParams params;
11179 params.src.image.imageType = VK_IMAGE_TYPE_1D;
11180 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11181 params.src.image.extent = default1dExtent;
11182 params.dst.image.extent = default1dExtent;
11183 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11184 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11185 params.allocationKind = allocationKind;
11186 params.extensionUse = extensionUse;
11187
11188 CopyRegion region;
11189 for (int i = 0; i < defaultSize; i += defaultSize / 2)
11190 {
11191 const VkImageBlit imageBlit =
11192 {
11193 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
11194 {
11195 {0, 0, 0},
11196 {defaultSize, 1, 1}
11197 }, // VkOffset3D srcOffsets[2];
11198
11199 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
11200 {
11201 {i, 0, 0},
11202 {i + defaultFourthSize, 1, 1}
11203 } // VkOffset3D dstOffset[2];
11204 };
11205 region.imageBlit = imageBlit;
11206 params.regions.push_back(region);
11207 }
11208
11209 {
11210 const VkImageBlit imageBlit =
11211 {
11212 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
11213 {
11214 {0, 0, 0},
11215 {defaultFourthSize, 1, 1}
11216 }, // VkOffset3D srcOffsets[2];
11217
11218 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
11219 {
11220 {defaultFourthSize, 0, 0},
11221 {2 * defaultFourthSize, 1, 1}
11222 } // VkOffset3D dstOffset[2];
11223 };
11224 region.imageBlit = imageBlit;
11225 params.regions.push_back(region);
11226 }
11227
11228 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11229 {
11230 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
11231 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11232 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11233 {
11234 params.src.image.format = sourceFormats[srcFormatIndex];
11235 if (!isSupportedByFramework(params.src.image.format))
11236 continue;
11237
11238 // Cubic filtering can only be used with 2D images.
11239 const bool onlyNearestAndLinear = true;
11240
11241 BlitColorTestParams testParams
11242 {
11243 params,
11244 nullptr,
11245 makeFilterMask(onlyNearest, onlyNearestAndLinear)
11246 };
11247
11248 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
11249 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
11250 }
11251 }
11252
11253 group->addChild(subGroup.release());
11254 }
11255
11256 // 3D tests. Note we use smaller dimensions here for performance reasons.
11257 {
11258 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
11259
11260 TestParams params;
11261 params.src.image.imageType = VK_IMAGE_TYPE_3D;
11262 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
11263 params.src.image.extent = default3dExtent;
11264 params.dst.image.extent = default3dExtent;
11265 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11266 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11267 params.allocationKind = allocationKind;
11268 params.extensionUse = extensionUse;
11269
11270 CopyRegion region;
11271 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
11272 {
11273 const VkImageBlit imageBlit =
11274 {
11275 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
11276 {
11277 {0, 0, 0},
11278 {defaultFourthSize, defaultFourthSize, defaultFourthSize}
11279 }, // VkOffset3D srcOffsets[2];
11280
11281 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
11282 {
11283 {i, 0, i},
11284 {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j}
11285 } // VkOffset3D dstOffset[2];
11286 };
11287 region.imageBlit = imageBlit;
11288 params.regions.push_back(region);
11289 }
11290 for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
11291 {
11292 const VkImageBlit imageBlit =
11293 {
11294 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
11295 {
11296 {i, i, i},
11297 {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize}
11298 }, // VkOffset3D srcOffsets[2];
11299
11300 defaultSourceLayer, // VkImageSubresourceLayers dstSubresource;
11301 {
11302 {i, defaultFourthSize / 2, i},
11303 {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize}
11304 } // VkOffset3D dstOffset[2];
11305 };
11306 region.imageBlit = imageBlit;
11307 params.regions.push_back(region);
11308 }
11309
11310 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11311 {
11312 const VkFormat* sourceFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].sourceFormats;
11313 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11314 for (int srcFormatIndex = 0; sourceFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11315 {
11316 params.src.image.format = sourceFormats[srcFormatIndex];
11317 if (!isSupportedByFramework(params.src.image.format))
11318 continue;
11319
11320 // Cubic filtering can only be used with 2D images.
11321 const bool onlyNearestAndLinear = true;
11322
11323 BlitColorTestParams testParams
11324 {
11325 params,
11326 nullptr,
11327 makeFilterMask(onlyNearest, onlyNearestAndLinear)
11328 };
11329
11330 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
11331 addTestGroup(subGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsColorSrcFormatTests, testParams);
11332 }
11333 }
11334
11335 group->addChild(subGroup.release());
11336 }
11337 }
11338
addBlittingImageAllFormatsDepthStencilFormatsTests(tcu::TestCaseGroup * group,TestParams params)11339 void addBlittingImageAllFormatsDepthStencilFormatsTests (tcu::TestCaseGroup* group, TestParams params)
11340 {
11341 const VkImageLayout blitSrcLayouts[] =
11342 {
11343 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
11344 VK_IMAGE_LAYOUT_GENERAL
11345 };
11346 const VkImageLayout blitDstLayouts[] =
11347 {
11348 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
11349 VK_IMAGE_LAYOUT_GENERAL
11350 };
11351
11352 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
11353 {
11354 params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
11355
11356 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
11357 {
11358 params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
11359 params.filter = VK_FILTER_NEAREST;
11360
11361 const std::string testName = getImageLayoutCaseName(params.src.image.operationLayout) + "_" +
11362 getImageLayoutCaseName(params.dst.image.operationLayout);
11363 const std::string description = "Blit from " + getImageLayoutCaseName(params.src.image.operationLayout) +
11364 " to " + getImageLayoutCaseName(params.dst.image.operationLayout);
11365
11366 group->addChild(new BlitImageTestCase(group->getTestContext(), testName + "_nearest", description, params));
11367 }
11368 }
11369 }
11370
addBlittingImageAllFormatsDepthStencilTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11371 void addBlittingImageAllFormatsDepthStencilTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11372 {
11373 const VkFormat depthAndStencilFormats[] =
11374 {
11375 VK_FORMAT_D16_UNORM,
11376 VK_FORMAT_X8_D24_UNORM_PACK32,
11377 VK_FORMAT_D32_SFLOAT,
11378 VK_FORMAT_S8_UINT,
11379 VK_FORMAT_D16_UNORM_S8_UINT,
11380 VK_FORMAT_D24_UNORM_S8_UINT,
11381 VK_FORMAT_D32_SFLOAT_S8_UINT,
11382 };
11383
11384 const VkImageSubresourceLayers defaultDepthSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 0u, 1u };
11385 const VkImageSubresourceLayers defaultStencilSourceLayer = { VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
11386 const VkImageSubresourceLayers defaultDSSourceLayer = { VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 0u, 1u };
11387
11388 // 2D tests
11389 {
11390 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "2d", "2D blitting tests"));
11391
11392 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11393 {
11394 TestParams params;
11395 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11396 params.src.image.extent = defaultExtent;
11397 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11398 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11399 params.dst.image.extent = defaultExtent;
11400 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11401 params.dst.image.format = params.src.image.format;
11402 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11403 params.allocationKind = allocationKind;
11404 params.extensionUse = extensionUse;
11405 params.separateDepthStencilLayouts = DE_FALSE;
11406
11407 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11408 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11409
11410 CopyRegion region;
11411 for (int i = 0, j = 1; (i + defaultFourthSize / j < defaultSize) && (defaultFourthSize > j); i += defaultFourthSize / j++)
11412 {
11413 const VkOffset3D srcOffset0 = {0, 0, 0};
11414 const VkOffset3D srcOffset1 = {defaultSize, defaultSize, 1};
11415 const VkOffset3D dstOffset0 = {i, 0, 0};
11416 const VkOffset3D dstOffset1 = {i + defaultFourthSize / j, defaultFourthSize / j, 1};
11417
11418 if (hasDepth)
11419 {
11420 const VkImageBlit imageBlit =
11421 {
11422 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11423 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
11424 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11425 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
11426 };
11427 region.imageBlit = imageBlit;
11428 params.regions.push_back(region);
11429 }
11430 if (hasStencil)
11431 {
11432 const VkImageBlit imageBlit =
11433 {
11434 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11435 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
11436 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11437 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
11438 };
11439 region.imageBlit = imageBlit;
11440 params.regions.push_back(region);
11441 }
11442 }
11443 for (int i = 0; i < defaultSize; i += defaultFourthSize)
11444 {
11445 const VkOffset3D srcOffset0 = {i, i, 0};
11446 const VkOffset3D srcOffset1 = {i + defaultFourthSize, i + defaultFourthSize, 1};
11447 const VkOffset3D dstOffset0 = {i, defaultSize / 2, 0};
11448 const VkOffset3D dstOffset1 = {i + defaultFourthSize, defaultSize / 2 + defaultFourthSize, 1};
11449
11450 if (hasDepth)
11451 {
11452 const VkImageBlit imageBlit =
11453 {
11454 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11455 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11456 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11457 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
11458 };
11459 region.imageBlit = imageBlit;
11460 params.regions.push_back(region);
11461 }
11462 if (hasStencil)
11463 {
11464 const VkImageBlit imageBlit =
11465 {
11466 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11467 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11468 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11469 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
11470 };
11471 region.imageBlit = imageBlit;
11472 params.regions.push_back(region);
11473 }
11474 if (hasDepth && hasStencil)
11475 {
11476 const VkOffset3D dstDSOffset0 = {i, 3 * defaultFourthSize, 0};
11477 const VkOffset3D dstDSOffset1 = {i + defaultFourthSize, defaultSize, 1};
11478 const VkImageBlit imageBlit =
11479 {
11480 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11481 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11482 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11483 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
11484 };
11485 region.imageBlit = imageBlit;
11486 params.regions.push_back(region);
11487 }
11488 }
11489
11490 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11491 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
11492 " to " + getFormatCaseName(params.dst.image.format);
11493 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11494
11495 if (hasDepth && hasStencil)
11496 {
11497 params.separateDepthStencilLayouts = DE_TRUE;
11498 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11499 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11500 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
11501 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11502 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11503 }
11504 }
11505
11506 group->addChild(subGroup.release());
11507 }
11508
11509 // 1D tests
11510 {
11511 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "1d", "1D blitting tests"));
11512
11513 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11514 {
11515 TestParams params;
11516 params.src.image.imageType = VK_IMAGE_TYPE_1D;
11517 params.dst.image.imageType = VK_IMAGE_TYPE_1D;
11518 params.src.image.extent = default1dExtent;
11519 params.dst.image.extent = default1dExtent;
11520 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11521 params.dst.image.format = params.src.image.format;
11522 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11523 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11524 params.allocationKind = allocationKind;
11525 params.extensionUse = extensionUse;
11526
11527 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11528 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11529
11530 CopyRegion region;
11531 for (int i = 0; i < defaultSize; i += defaultSize / 2)
11532 {
11533 const VkOffset3D srcOffset0 = {0, 0, 0};
11534 const VkOffset3D srcOffset1 = {defaultSize, 1, 1};
11535 const VkOffset3D dstOffset0 = {i, 0, 0};
11536 const VkOffset3D dstOffset1 = {i + defaultFourthSize, 1, 1};
11537
11538 if (hasDepth)
11539 {
11540 const VkImageBlit imageBlit =
11541 {
11542 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11543 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
11544 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11545 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
11546 };
11547 region.imageBlit = imageBlit;
11548 params.regions.push_back(region);
11549 }
11550 if (hasStencil)
11551 {
11552 const VkImageBlit imageBlit =
11553 {
11554 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11555 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
11556 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11557 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
11558 };
11559 region.imageBlit = imageBlit;
11560 params.regions.push_back(region);
11561 }
11562 }
11563
11564 {
11565 const VkOffset3D srcOffset0 = {0, 0, 0};
11566 const VkOffset3D srcOffset1 = {defaultFourthSize, 1, 1};
11567 const VkOffset3D dstOffset0 = {defaultFourthSize, 0, 0};
11568 const VkOffset3D dstOffset1 = {2 * defaultFourthSize, 1, 1};
11569
11570 if (hasDepth)
11571 {
11572 const VkImageBlit imageBlit =
11573 {
11574 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11575 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11576 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11577 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
11578 };
11579 region.imageBlit = imageBlit;
11580 params.regions.push_back(region);
11581 }
11582 if (hasStencil)
11583 {
11584 const VkImageBlit imageBlit =
11585 {
11586 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11587 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11588 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11589 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
11590 };
11591 region.imageBlit = imageBlit;
11592 params.regions.push_back(region);
11593 }
11594 if (hasDepth && hasStencil)
11595 {
11596 const VkOffset3D dstDSOffset0 = {3 * defaultFourthSize, 0, 0};
11597 const VkOffset3D dstDSOffset1 = {3 * defaultFourthSize + defaultFourthSize / 2, 1, 1};
11598 const VkImageBlit imageBlit =
11599 {
11600 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11601 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11602 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11603 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
11604 };
11605 region.imageBlit = imageBlit;
11606 params.regions.push_back(region);
11607 }
11608 }
11609
11610 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11611 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
11612 " to " + getFormatCaseName(params.dst.image.format);
11613 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11614
11615 if (hasDepth && hasStencil)
11616 {
11617 params.separateDepthStencilLayouts = DE_TRUE;
11618 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11619 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11620 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
11621 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11622 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11623 }
11624 }
11625
11626 group->addChild(subGroup.release());
11627 }
11628
11629 // 3D tests. Note we use smaller dimensions here for performance reasons.
11630 {
11631 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "3d", "3D blitting tests"));
11632
11633 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < DE_LENGTH_OF_ARRAY(depthAndStencilFormats); ++compatibleFormatsIndex)
11634 {
11635 TestParams params;
11636 params.src.image.imageType = VK_IMAGE_TYPE_3D;
11637 params.dst.image.imageType = VK_IMAGE_TYPE_3D;
11638 params.src.image.extent = default3dExtent;
11639 params.dst.image.extent = default3dExtent;
11640 params.src.image.format = depthAndStencilFormats[compatibleFormatsIndex];
11641 params.dst.image.format = params.src.image.format;
11642 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11643 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11644 params.allocationKind = allocationKind;
11645 params.extensionUse = extensionUse;
11646
11647 bool hasDepth = tcu::hasDepthComponent(mapVkFormat(params.src.image.format).order);
11648 bool hasStencil = tcu::hasStencilComponent(mapVkFormat(params.src.image.format).order);
11649
11650 CopyRegion region;
11651 for (int i = 0, j = 1; (i + defaultSixteenthSize / j < defaultFourthSize) && (defaultSixteenthSize > j); i += defaultSixteenthSize / j++)
11652 {
11653 const VkOffset3D srcOffset0 = {0, 0, 0};
11654 const VkOffset3D srcOffset1 = {defaultFourthSize, defaultFourthSize, defaultFourthSize};
11655 const VkOffset3D dstOffset0 = {i, 0, i};
11656 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize / j, defaultSixteenthSize / j, i + defaultSixteenthSize / j};
11657
11658 if (hasDepth)
11659 {
11660 const VkImageBlit imageBlit =
11661 {
11662 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11663 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
11664 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11665 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
11666 };
11667 region.imageBlit = imageBlit;
11668 params.regions.push_back(region);
11669 }
11670 if (hasStencil)
11671 {
11672 const VkImageBlit imageBlit =
11673 {
11674 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11675 { srcOffset0 , srcOffset1 }, // VkOffset3D srcOffsets[2];
11676 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11677 { dstOffset0 , dstOffset1 }, // VkOffset3D dstOffset[2];
11678 };
11679 region.imageBlit = imageBlit;
11680 params.regions.push_back(region);
11681 }
11682 }
11683 for (int i = 0; i < defaultFourthSize; i += defaultSixteenthSize)
11684 {
11685 const VkOffset3D srcOffset0 = {i, i, i};
11686 const VkOffset3D srcOffset1 = {i + defaultSixteenthSize, i + defaultSixteenthSize, i + defaultSixteenthSize};
11687 const VkOffset3D dstOffset0 = {i, defaultFourthSize / 2, i};
11688 const VkOffset3D dstOffset1 = {i + defaultSixteenthSize, defaultFourthSize / 2 + defaultSixteenthSize, i + defaultSixteenthSize};
11689
11690 if (hasDepth)
11691 {
11692 const VkImageBlit imageBlit =
11693 {
11694 defaultDepthSourceLayer, // VkImageSubresourceLayers srcSubresource;
11695 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11696 defaultDepthSourceLayer, // VkImageSubresourceLayers dstSubresource;
11697 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
11698 };
11699 region.imageBlit = imageBlit;
11700 params.regions.push_back(region);
11701 }
11702 if (hasStencil)
11703 {
11704 const VkImageBlit imageBlit =
11705 {
11706 defaultStencilSourceLayer, // VkImageSubresourceLayers srcSubresource;
11707 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11708 defaultStencilSourceLayer, // VkImageSubresourceLayers dstSubresource;
11709 { dstOffset0, dstOffset1 } // VkOffset3D dstOffset[2];
11710 };
11711 region.imageBlit = imageBlit;
11712 params.regions.push_back(region);
11713 }
11714 if (hasDepth && hasStencil)
11715 {
11716 const VkOffset3D dstDSOffset0 = {i, 3 * defaultSixteenthSize, i};
11717 const VkOffset3D dstDSOffset1 = {i + defaultSixteenthSize, defaultFourthSize, i + defaultSixteenthSize};
11718 const VkImageBlit imageBlit =
11719 {
11720 defaultDSSourceLayer, // VkImageSubresourceLayers srcSubresource;
11721 { srcOffset0, srcOffset1 }, // VkOffset3D srcOffsets[2];
11722 defaultDSSourceLayer, // VkImageSubresourceLayers dstSubresource;
11723 { dstDSOffset0, dstDSOffset1 } // VkOffset3D dstOffset[2];
11724 };
11725 region.imageBlit = imageBlit;
11726 params.regions.push_back(region);
11727 }
11728 }
11729
11730 const std::string testName = getFormatCaseName(params.src.image.format) + "_" + getFormatCaseName(params.dst.image.format);
11731 const std::string description = "Blit from " + getFormatCaseName(params.src.image.format) +
11732 " to " + getFormatCaseName(params.dst.image.format);
11733 addTestGroup(subGroup.get(), testName, description, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11734
11735 if (hasDepth && hasStencil)
11736 {
11737 params.separateDepthStencilLayouts = DE_TRUE;
11738 const std::string testName2 = getFormatCaseName(params.src.image.format) + "_" +
11739 getFormatCaseName(params.dst.image.format) + "_separate_layouts";
11740 const std::string description2 = "Blit from " + getFormatCaseName(params.src.image.format) +
11741 " to " + getFormatCaseName(params.dst.image.format) + " with separate depth/stencil layouts";
11742 addTestGroup(subGroup.get(), testName2, description2, addBlittingImageAllFormatsDepthStencilFormatsTests, params);
11743 }
11744 }
11745
11746 group->addChild(subGroup.release());
11747 }
11748 }
11749
addBlittingImageAllFormatsMipmapFormatTests(tcu::TestCaseGroup * group,BlitColorTestParams testParams)11750 void addBlittingImageAllFormatsMipmapFormatTests (tcu::TestCaseGroup* group, BlitColorTestParams testParams)
11751 {
11752 tcu::TestContext& testCtx = group->getTestContext();
11753
11754 const VkImageLayout blitSrcLayouts[] =
11755 {
11756 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
11757 VK_IMAGE_LAYOUT_GENERAL
11758 };
11759 const VkImageLayout blitDstLayouts[] =
11760 {
11761 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
11762 VK_IMAGE_LAYOUT_GENERAL
11763 };
11764
11765 for (int srcLayoutNdx = 0u; srcLayoutNdx < DE_LENGTH_OF_ARRAY(blitSrcLayouts); ++srcLayoutNdx)
11766 {
11767 testParams.params.src.image.operationLayout = blitSrcLayouts[srcLayoutNdx];
11768 for (int dstLayoutNdx = 0u; dstLayoutNdx < DE_LENGTH_OF_ARRAY(blitDstLayouts); ++dstLayoutNdx)
11769 {
11770 testParams.params.dst.image.operationLayout = blitDstLayouts[dstLayoutNdx];
11771
11772 testParams.params.filter = VK_FILTER_NEAREST;
11773 const std::string testName = getImageLayoutCaseName(testParams.params.src.image.operationLayout) + "_" +
11774 getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11775 const std::string description = "Blit from layout " + getImageLayoutCaseName(testParams.params.src.image.operationLayout) +
11776 " to " + getImageLayoutCaseName(testParams.params.dst.image.operationLayout);
11777 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_nearest", description, testParams.params));
11778
11779 if (testParams.testFilters & FILTER_MASK_LINEAR)
11780 {
11781 testParams.params.filter = VK_FILTER_LINEAR;
11782 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_linear", description, testParams.params));
11783 }
11784
11785 if (testParams.testFilters & FILTER_MASK_CUBIC)
11786 {
11787 testParams.params.filter = VK_FILTER_CUBIC_EXT;
11788 group->addChild(new BlitMipmapTestCase(testCtx, testName + "_cubic", description, testParams.params));
11789 }
11790 }
11791 }
11792 }
11793
addBlittingImageAllFormatsBaseLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11794 void addBlittingImageAllFormatsBaseLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11795 {
11796 const struct
11797 {
11798 const VkFormat* const compatibleFormats;
11799 const bool onlyNearest;
11800 } colorImageFormatsToTestBlit[] =
11801 {
11802 { compatibleFormatsUInts, true },
11803 { compatibleFormatsSInts, true },
11804 { compatibleFormatsFloats, false },
11805 { compatibleFormatsSrgb, false },
11806 };
11807
11808 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11809
11810 const int layerCountsToTest[] =
11811 {
11812 1,
11813 6
11814 };
11815
11816 TestParams params;
11817 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11818 params.src.image.extent = defaultExtent;
11819 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11820 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11821 params.dst.image.extent = defaultExtent;
11822 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11823 params.allocationKind = allocationKind;
11824 params.extensionUse = extensionUse;
11825 params.mipLevels = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11826 params.singleCommand = DE_TRUE;
11827
11828 CopyRegion region;
11829 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11830 {
11831 VkImageSubresourceLayers destLayer = defaultSourceLayer;
11832 destLayer.mipLevel = mipLevelNdx;
11833
11834 const VkImageBlit imageBlit =
11835 {
11836 defaultSourceLayer, // VkImageSubresourceLayers srcSubresource;
11837 {
11838 {0, 0, 0},
11839 {defaultSize, defaultSize, 1}
11840 }, // VkOffset3D srcOffsets[2];
11841
11842 destLayer, // VkImageSubresourceLayers dstSubresource;
11843 {
11844 {0, 0, 0},
11845 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11846 } // VkOffset3D dstOffset[2];
11847 };
11848 region.imageBlit = imageBlit;
11849 params.regions.push_back(region);
11850 }
11851
11852 if (allocationKind == ALLOCATION_KIND_DEDICATED)
11853 {
11854 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11855 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11856 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11857 }
11858
11859 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11860 {
11861 const int layerCount = layerCountsToTest[layerCountIndex];
11862 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
11863 const std::string layerGroupDesc = "Blit mipmaps with layerCount = " + de::toString(layerCount);
11864
11865 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11866
11867 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11868 {
11869 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11870 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11871
11872 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11873 {
11874 params.src.image.format = compatibleFormats[srcFormatIndex];
11875 params.dst.image.format = compatibleFormats[srcFormatIndex];
11876
11877 if (!isSupportedByFramework(params.src.image.format))
11878 continue;
11879
11880 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11881
11882 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
11883
11884 BlitColorTestParams testParams;
11885 testParams.params = params;
11886 testParams.compatibleFormats = compatibleFormats;
11887 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
11888
11889 testParams.params.src.image.extent.depth = layerCount;
11890 testParams.params.dst.image.extent.depth = layerCount;
11891
11892 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
11893 {
11894 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
11895 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
11896 }
11897
11898 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
11899 }
11900 }
11901 group->addChild(layerCountGroup.release());
11902 }
11903 }
11904
addBlittingImageAllFormatsPreviousLevelMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)11905 void addBlittingImageAllFormatsPreviousLevelMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
11906 {
11907 const struct
11908 {
11909 const VkFormat* const compatibleFormats;
11910 const bool onlyNearest;
11911 } colorImageFormatsToTestBlit[] =
11912 {
11913 { compatibleFormatsUInts, true },
11914 { compatibleFormatsSInts, true },
11915 { compatibleFormatsFloats, false },
11916 { compatibleFormatsSrgb, false },
11917 };
11918
11919 const int numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTestBlit);
11920
11921 const int layerCountsToTest[] =
11922 {
11923 1,
11924 6
11925 };
11926
11927 TestParams params;
11928 params.src.image.imageType = VK_IMAGE_TYPE_2D;
11929 params.src.image.extent = defaultExtent;
11930 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11931 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
11932 params.dst.image.extent = defaultExtent;
11933 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
11934 params.allocationKind = allocationKind;
11935 params.extensionUse = extensionUse;
11936 params.mipLevels = deLog2Floor32(deMinu32(defaultExtent.width, defaultExtent.height)) + 1u;
11937 params.singleCommand = DE_FALSE;
11938
11939 CopyRegion region;
11940 for (deUint32 mipLevelNdx = 1u; mipLevelNdx < params.mipLevels; mipLevelNdx++)
11941 {
11942 VkImageSubresourceLayers srcLayer = defaultSourceLayer;
11943 VkImageSubresourceLayers destLayer = defaultSourceLayer;
11944
11945 srcLayer.mipLevel = mipLevelNdx - 1u;
11946 destLayer.mipLevel = mipLevelNdx;
11947
11948 const VkImageBlit imageBlit =
11949 {
11950 srcLayer, // VkImageSubresourceLayers srcSubresource;
11951 {
11952 {0, 0, 0},
11953 {defaultSize >> (mipLevelNdx - 1u), defaultSize >> (mipLevelNdx - 1u), 1}
11954 }, // VkOffset3D srcOffsets[2];
11955
11956 destLayer, // VkImageSubresourceLayers dstSubresource;
11957 {
11958 {0, 0, 0},
11959 {defaultSize >> mipLevelNdx, defaultSize >> mipLevelNdx, 1}
11960 } // VkOffset3D dstOffset[2];
11961 };
11962 region.imageBlit = imageBlit;
11963 params.regions.push_back(region);
11964 }
11965
11966 if (allocationKind == ALLOCATION_KIND_DEDICATED)
11967 {
11968 const int numOfColorImageFormatsToTestFilter = DE_LENGTH_OF_ARRAY(dedicatedAllocationBlittingFormatsToTest);
11969 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTestFilter; ++compatibleFormatsIndex)
11970 dedicatedAllocationBlittingFormatsToTestSet.insert(dedicatedAllocationBlittingFormatsToTest[compatibleFormatsIndex]);
11971 }
11972
11973 for (int layerCountIndex = 0; layerCountIndex < DE_LENGTH_OF_ARRAY(layerCountsToTest); layerCountIndex++)
11974 {
11975 const int layerCount = layerCountsToTest[layerCountIndex];
11976 const std::string layerGroupName = "layercount_" + de::toString(layerCount);
11977 const std::string layerGroupDesc = "Blit mipmaps with layerCount = " + de::toString(layerCount);
11978
11979 de::MovePtr<tcu::TestCaseGroup> layerCountGroup (new tcu::TestCaseGroup(group->getTestContext(), layerGroupName.c_str(), layerGroupDesc.c_str()));
11980
11981 for (int compatibleFormatsIndex = 0; compatibleFormatsIndex < numOfColorImageFormatsToTest; ++compatibleFormatsIndex)
11982 {
11983 const VkFormat* compatibleFormats = colorImageFormatsToTestBlit[compatibleFormatsIndex].compatibleFormats;
11984 const bool onlyNearest = colorImageFormatsToTestBlit[compatibleFormatsIndex].onlyNearest;
11985
11986 for (int srcFormatIndex = 0; compatibleFormats[srcFormatIndex] != VK_FORMAT_UNDEFINED; ++srcFormatIndex)
11987 {
11988 params.src.image.format = compatibleFormats[srcFormatIndex];
11989 params.dst.image.format = compatibleFormats[srcFormatIndex];
11990
11991 if (!isSupportedByFramework(params.src.image.format))
11992 continue;
11993
11994 const bool onlyNearestAndLinear = de::contains(onlyNearestAndLinearFormatsToTest, params.src.image.format);
11995
11996 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
11997
11998 BlitColorTestParams testParams;
11999 testParams.params = params;
12000 testParams.compatibleFormats = compatibleFormats;
12001 testParams.testFilters = makeFilterMask(onlyNearest, onlyNearestAndLinear);
12002
12003 testParams.params.src.image.extent.depth = layerCount;
12004 testParams.params.dst.image.extent.depth = layerCount;
12005
12006 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
12007 {
12008 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
12009 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
12010 }
12011
12012 addTestGroup(layerCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
12013 }
12014 }
12015 group->addChild(layerCountGroup.release());
12016 }
12017
12018 for (int multiLayer = 0; multiLayer < 2; multiLayer++)
12019 {
12020 const int layerCount = multiLayer ? 6 : 1;
12021
12022 for (int barrierCount = 1; barrierCount < 4; barrierCount++)
12023 {
12024 if (layerCount != 1 || barrierCount != 1)
12025 {
12026 const std::string barrierGroupName = (multiLayer ? "layerbarriercount_" : "mipbarriercount_") + de::toString(barrierCount);
12027 const std::string barrierGroupDesc = "Use " + de::toString(barrierCount) + " image barriers";
12028
12029 de::MovePtr<tcu::TestCaseGroup> barrierCountGroup(new tcu::TestCaseGroup(group->getTestContext(), barrierGroupName.c_str(), barrierGroupDesc.c_str()));
12030
12031 params.barrierCount = barrierCount;
12032
12033 // Only go through a few common formats
12034 for (int srcFormatIndex = 2; srcFormatIndex < 6; ++srcFormatIndex)
12035 {
12036 params.src.image.format = compatibleFormatsUInts[srcFormatIndex];
12037 params.dst.image.format = compatibleFormatsUInts[srcFormatIndex];
12038
12039 if (!isSupportedByFramework(params.src.image.format))
12040 continue;
12041
12042 const std::string description = "Blit source format " + getFormatCaseName(params.src.image.format);
12043
12044 BlitColorTestParams testParams;
12045 testParams.params = params;
12046 testParams.compatibleFormats = compatibleFormatsUInts;
12047 testParams.testFilters = FILTER_MASK_NEAREST;
12048
12049 testParams.params.src.image.extent.depth = layerCount;
12050 testParams.params.dst.image.extent.depth = layerCount;
12051
12052 for (size_t regionNdx = 0; regionNdx < testParams.params.regions.size(); regionNdx++)
12053 {
12054 testParams.params.regions[regionNdx].imageBlit.srcSubresource.layerCount = layerCount;
12055 testParams.params.regions[regionNdx].imageBlit.dstSubresource.layerCount = layerCount;
12056 }
12057
12058 addTestGroup(barrierCountGroup.get(), getFormatCaseName(params.src.image.format), description, addBlittingImageAllFormatsMipmapFormatTests, testParams);
12059 }
12060 group->addChild(barrierCountGroup.release());
12061 }
12062 }
12063 }
12064 }
12065
addBlittingImageAllFormatsMipmapTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12066 void addBlittingImageAllFormatsMipmapTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12067 {
12068 addTestGroup(group, "from_base_level", "Generate all mipmap levels from base level", addBlittingImageAllFormatsBaseLevelMipmapTests, allocationKind, extensionUse);
12069 addTestGroup(group, "from_previous_level", "Generate next mipmap level from previous level", addBlittingImageAllFormatsPreviousLevelMipmapTests, allocationKind, extensionUse);
12070 }
12071
addBlittingImageAllFormatsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12072 void addBlittingImageAllFormatsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12073 {
12074 addTestGroup(group, "color", "Blitting image with color formats", addBlittingImageAllFormatsColorTests, allocationKind, extensionUse);
12075 addTestGroup(group, "depth_stencil", "Blitting image with depth/stencil formats", addBlittingImageAllFormatsDepthStencilTests, allocationKind, extensionUse);
12076 addTestGroup(group, "generate_mipmaps", "Generating mipmaps with vkCmdBlitImage()", addBlittingImageAllFormatsMipmapTests, allocationKind, extensionUse);
12077 }
12078
addBlittingImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12079 void addBlittingImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12080 {
12081 addTestGroup(group, "simple_tests", "Blitting image simple tests", addBlittingImageSimpleTests, allocationKind, extensionUse);
12082 addTestGroup(group, "all_formats", "Blitting image with all compatible formats", addBlittingImageAllFormatsTests, allocationKind, extensionUse);
12083 }
12084
12085 const VkSampleCountFlagBits samples[] =
12086 {
12087 VK_SAMPLE_COUNT_2_BIT,
12088 VK_SAMPLE_COUNT_4_BIT,
12089 VK_SAMPLE_COUNT_8_BIT,
12090 VK_SAMPLE_COUNT_16_BIT,
12091 VK_SAMPLE_COUNT_32_BIT,
12092 VK_SAMPLE_COUNT_64_BIT
12093 };
12094 const VkExtent3D resolveExtent = {256u, 256u, 1};
12095
addResolveImageWholeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12096 void addResolveImageWholeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12097 {
12098 TestParams params;
12099 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12100 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12101 params.src.image.extent = resolveExtent;
12102 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12103 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12104 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12105 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12106 params.dst.image.extent = resolveExtent;
12107 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12108 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12109 params.allocationKind = allocationKind;
12110 params.extensionUse = extensionUse;
12111
12112 {
12113 const VkImageSubresourceLayers sourceLayer =
12114 {
12115 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12116 0u, // deUint32 mipLevel;
12117 0u, // deUint32 baseArrayLayer;
12118 1u // deUint32 layerCount;
12119 };
12120 const VkImageResolve testResolve =
12121 {
12122 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12123 {0, 0, 0}, // VkOffset3D srcOffset;
12124 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12125 {0, 0, 0}, // VkOffset3D dstOffset;
12126 resolveExtent, // VkExtent3D extent;
12127 };
12128
12129 CopyRegion imageResolve;
12130 imageResolve.imageResolve = testResolve;
12131 params.regions.push_back(imageResolve);
12132 }
12133
12134 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12135 {
12136 params.samples = samples[samplesIndex];
12137 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12138 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
12139 }
12140 }
12141
addResolveImagePartialTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12142 void addResolveImagePartialTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12143 {
12144 TestParams params;
12145 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12146 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12147 params.src.image.extent = resolveExtent;
12148 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12149 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12150 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12151 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12152 params.dst.image.extent = resolveExtent;
12153 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12154 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12155 params.allocationKind = allocationKind;
12156 params.extensionUse = extensionUse;
12157
12158 {
12159 const VkImageSubresourceLayers sourceLayer =
12160 {
12161 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12162 0u, // deUint32 mipLevel;
12163 0u, // deUint32 baseArrayLayer;
12164 1u // deUint32 layerCount;
12165 };
12166 const VkImageResolve testResolve =
12167 {
12168 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12169 {0, 0, 0}, // VkOffset3D srcOffset;
12170 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12171 {64u, 64u, 0}, // VkOffset3D dstOffset;
12172 {128u, 128u, 1u}, // VkExtent3D extent;
12173 };
12174
12175 CopyRegion imageResolve;
12176 imageResolve.imageResolve = testResolve;
12177 params.regions.push_back(imageResolve);
12178 }
12179
12180 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12181 {
12182 params.samples = samples[samplesIndex];
12183 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12184 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
12185 }
12186 }
12187
addResolveImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12188 void addResolveImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12189 {
12190 TestParams params;
12191 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12192 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12193 params.src.image.extent = resolveExtent;
12194 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12195 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12196 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12197 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12198 params.dst.image.extent = resolveExtent;
12199 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12200 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12201 params.allocationKind = allocationKind;
12202 params.extensionUse = extensionUse;
12203
12204 {
12205 const VkImageSubresourceLayers sourceLayer =
12206 {
12207 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12208 0u, // deUint32 mipLevel;
12209 0u, // deUint32 baseArrayLayer;
12210 1u // deUint32 layerCount;
12211 };
12212
12213 for (int i = 0; i < 256; i += 64)
12214 {
12215 const VkImageResolve testResolve =
12216 {
12217 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12218 {i, i, 0}, // VkOffset3D srcOffset;
12219 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12220 {i, 0, 0}, // VkOffset3D dstOffset;
12221 {64u, 64u, 1u}, // VkExtent3D extent;
12222 };
12223
12224 CopyRegion imageResolve;
12225 imageResolve.imageResolve = testResolve;
12226 params.regions.push_back(imageResolve);
12227 }
12228 }
12229
12230 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12231 {
12232 params.samples = samples[samplesIndex];
12233 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12234 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params));
12235 }
12236 }
12237
addResolveImageWholeCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12238 void addResolveImageWholeCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12239 {
12240 TestParams params;
12241 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12242 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12243 params.src.image.extent = defaultExtent;
12244 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12245 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12246 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12247 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12248 params.dst.image.extent = defaultExtent;
12249 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12250 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12251 params.allocationKind = allocationKind;
12252 params.extensionUse = extensionUse;
12253
12254 {
12255 const VkImageSubresourceLayers sourceLayer =
12256 {
12257 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12258 0u, // deUint32 mipLevel;
12259 0u, // deUint32 baseArrayLayer;
12260 1u // deUint32 layerCount;
12261 };
12262
12263 const VkImageResolve testResolve =
12264 {
12265 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12266 {0, 0, 0}, // VkOffset3D srcOffset;
12267 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12268 {0, 0, 0}, // VkOffset3D dstOffset;
12269 defaultExtent, // VkExtent3D extent;
12270 };
12271
12272 CopyRegion imageResolve;
12273 imageResolve.imageResolve = testResolve;
12274 params.regions.push_back(imageResolve);
12275 }
12276
12277 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12278 {
12279 params.samples = samples[samplesIndex];
12280 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12281 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
12282 }
12283 }
12284
addResolveImageWholeCopyWithoutCabBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12285 void addResolveImageWholeCopyWithoutCabBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12286 {
12287 TestParams params;
12288 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12289 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12290 params.src.image.extent = defaultExtent;
12291 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12292 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12293 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12294 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12295 params.dst.image.extent = defaultExtent;
12296 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12297 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12298 params.allocationKind = allocationKind;
12299 params.extensionUse = extensionUse;
12300
12301 {
12302 const VkImageSubresourceLayers sourceLayer =
12303 {
12304 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12305 0u, // deUint32 mipLevel;
12306 0u, // deUint32 baseArrayLayer;
12307 1u // deUint32 layerCount;
12308 };
12309
12310 const VkImageResolve testResolve =
12311 {
12312 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12313 {0, 0, 0}, // VkOffset3D srcOffset;
12314 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12315 {0, 0, 0}, // VkOffset3D dstOffset;
12316 defaultExtent, // VkExtent3D extent;
12317 };
12318
12319 CopyRegion imageResolve;
12320 imageResolve.imageResolve = testResolve;
12321 params.regions.push_back(imageResolve);
12322 }
12323
12324 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12325 {
12326 params.samples = samples[samplesIndex];
12327 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12328 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_NO_CAB));
12329 }
12330 }
12331
addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12332 void addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12333 {
12334 TestParams params;
12335 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12336 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12337 params.src.image.extent = defaultExtent;
12338 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12339 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12340 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12341 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12342 params.dst.image.extent = defaultExtent;
12343 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12344 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12345 params.allocationKind = allocationKind;
12346 params.extensionUse = extensionUse;
12347
12348 {
12349 const VkImageSubresourceLayers sourceLayer =
12350 {
12351 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12352 0u, // deUint32 mipLevel;
12353 0u, // deUint32 baseArrayLayer;
12354 1u // deUint32 layerCount;
12355 };
12356
12357 const VkImageResolve testResolve =
12358 {
12359 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12360 {0, 0, 0}, // VkOffset3D srcOffset;
12361 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12362 {0, 0, 0}, // VkOffset3D dstOffset;
12363 defaultExtent, // VkExtent3D extent;
12364 };
12365
12366 CopyRegion imageResolve;
12367 imageResolve.imageResolve = testResolve;
12368 params.regions.push_back(imageResolve);
12369 }
12370
12371 const struct
12372 {
12373 VkImageLayout layout;
12374 std::string name;
12375 } imageLayouts[] =
12376 {
12377 { VK_IMAGE_LAYOUT_GENERAL, "general" },
12378 { VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, "transfer_src_optimal" },
12379 { VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, "transfer_dst_optimal" }
12380 };
12381
12382 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12383 for (int srcLayoutIndex = 0; srcLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++srcLayoutIndex)
12384 for (int dstLayoutIndex = 0; dstLayoutIndex < DE_LENGTH_OF_ARRAY(imageLayouts); ++dstLayoutIndex)
12385 {
12386 params.src.image.operationLayout = imageLayouts[srcLayoutIndex].layout;
12387 params.dst.image.operationLayout = imageLayouts[dstLayoutIndex].layout;
12388 if (params.src.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL ||
12389 params.dst.image.operationLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL)
12390 continue;
12391 params.samples = samples[samplesIndex];
12392 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12393 std::string testName = getSampleCountCaseName(samples[samplesIndex]) + "_" + imageLayouts[srcLayoutIndex].name + "_" + imageLayouts[dstLayoutIndex].name;
12394 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), testName, description, params, COPY_MS_IMAGE_TO_MS_IMAGE));
12395 }
12396 }
12397
addResolveImageLayerCopyBeforeResolvingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12398 void addResolveImageLayerCopyBeforeResolvingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12399 {
12400 TestParams params;
12401 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12402 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12403 params.src.image.extent = defaultExtent;
12404 params.src.image.extent.depth = 5u;
12405 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12406 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12407 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12408 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12409 params.dst.image.extent = defaultExtent;
12410 params.dst.image.extent.depth = 5u;
12411 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12412 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12413 params.allocationKind = allocationKind;
12414 params.extensionUse = extensionUse;
12415
12416 for (deUint32 layerNdx=0; layerNdx < params.src.image.extent.depth; ++layerNdx)
12417 {
12418 const VkImageSubresourceLayers sourceLayer =
12419 {
12420 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12421 0u, // deUint32 mipLevel;
12422 layerNdx, // deUint32 baseArrayLayer;
12423 1u // deUint32 layerCount;
12424 };
12425
12426 const VkImageResolve testResolve =
12427 {
12428 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12429 {0, 0, 0}, // VkOffset3D srcOffset;
12430 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12431 {0, 0, 0}, // VkOffset3D dstOffset;
12432 defaultExtent, // VkExtent3D extent;
12433 };
12434
12435 CopyRegion imageResolve;
12436 imageResolve.imageResolve = testResolve;
12437 params.regions.push_back(imageResolve);
12438 }
12439
12440 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12441 {
12442 params.samples = samples[samplesIndex];
12443 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12444 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_LAYER_TO_MS_IMAGE));
12445 }
12446 }
12447
addResolveCopyImageWithRegionsTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12448 void addResolveCopyImageWithRegionsTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12449 {
12450 TestParams params;
12451 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12452 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12453 params.src.image.extent = resolveExtent;
12454 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12455 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12456 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12457 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12458 params.dst.image.extent = resolveExtent;
12459 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12460 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12461 params.allocationKind = allocationKind;
12462 params.extensionUse = extensionUse;
12463
12464 int32_t imageHalfWidth = getExtent3D(params.src.image).width / 2;
12465 int32_t imageHalfHeight = getExtent3D(params.src.image).height / 2;
12466 VkExtent3D halfImageExtent = {resolveExtent.width / 2, resolveExtent.height / 2, 1u};
12467
12468 // Lower right corner to lower left corner.
12469 {
12470 const VkImageSubresourceLayers sourceLayer =
12471 {
12472 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12473 0u, // deUint32 mipLevel;
12474 0u, // deUint32 baseArrayLayer;
12475 1u // deUint32 layerCount;
12476 };
12477
12478 const VkImageResolve testResolve =
12479 {
12480 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12481 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D srcOffset;
12482 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12483 {0, imageHalfHeight, 0}, // VkOffset3D dstOffset;
12484 halfImageExtent, // VkExtent3D extent;
12485 };
12486
12487 CopyRegion imageResolve;
12488 imageResolve.imageResolve = testResolve;
12489 params.regions.push_back(imageResolve);
12490 }
12491
12492 // Upper right corner to lower right corner.
12493 {
12494 const VkImageSubresourceLayers sourceLayer =
12495 {
12496 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12497 0u, // deUint32 mipLevel;
12498 0u, // deUint32 baseArrayLayer;
12499 1u // deUint32 layerCount;
12500 };
12501
12502 const VkImageResolve testResolve =
12503 {
12504 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12505 {imageHalfWidth, 0, 0}, // VkOffset3D srcOffset;
12506 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12507 {imageHalfWidth, imageHalfHeight, 0}, // VkOffset3D dstOffset;
12508 halfImageExtent, // VkExtent3D extent;
12509 };
12510
12511 CopyRegion imageResolve;
12512 imageResolve.imageResolve = testResolve;
12513 params.regions.push_back(imageResolve);
12514 }
12515
12516 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12517 {
12518 params.samples = samples[samplesIndex];
12519 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12520 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_MS_IMAGE_MULTIREGION));
12521 }
12522 }
12523
addResolveImageWholeArrayImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12524 void addResolveImageWholeArrayImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12525 {
12526 TestParams params;
12527 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12528 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12529 params.src.image.extent = defaultExtent;
12530 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12531 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12532 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12533 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12534 params.dst.image.extent = defaultExtent;
12535 params.dst.image.extent.depth = 5u;
12536 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12537 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12538 params.allocationKind = allocationKind;
12539 params.extensionUse = extensionUse;
12540
12541 for (deUint32 layerNdx=0; layerNdx < params.dst.image.extent.depth; ++layerNdx)
12542 {
12543 const VkImageSubresourceLayers sourceLayer =
12544 {
12545 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12546 0u, // deUint32 mipLevel;
12547 layerNdx, // deUint32 baseArrayLayer;
12548 1u // deUint32 layerCount;
12549 };
12550
12551 const VkImageResolve testResolve =
12552 {
12553 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12554 {0, 0, 0}, // VkOffset3D srcOffset;
12555 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12556 {0, 0, 0}, // VkOffset3D dstOffset;
12557 defaultExtent, // VkExtent3D extent;
12558 };
12559
12560 CopyRegion imageResolve;
12561 imageResolve.imageResolve = testResolve;
12562 params.regions.push_back(imageResolve);
12563 }
12564
12565 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12566 {
12567 params.samples = samples[samplesIndex];
12568 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12569 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
12570 }
12571 }
12572
addResolveImageWholeArrayImageSingleRegionTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12573 void addResolveImageWholeArrayImageSingleRegionTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12574 {
12575 TestParams params;
12576 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12577 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12578 params.src.image.extent = defaultExtent;
12579 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12580 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12581 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12582 params.dst.image.extent = defaultExtent;
12583 params.dst.image.extent.depth = 5u;
12584 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12585 params.allocationKind = allocationKind;
12586 params.extensionUse = extensionUse;
12587
12588 const VkImageSubresourceLayers sourceLayer =
12589 {
12590 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12591 0u, // uint32_t mipLevel;
12592 0, // uint32_t baseArrayLayer;
12593 params.dst.image.extent.depth // uint32_t layerCount;
12594 };
12595
12596 const VkImageResolve testResolve =
12597 {
12598 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12599 {0, 0, 0}, // VkOffset3D srcOffset;
12600 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12601 {0, 0, 0}, // VkOffset3D dstOffset;
12602 defaultExtent, // VkExtent3D extent;
12603 };
12604
12605 CopyRegion imageResolve;
12606 imageResolve.imageResolve = testResolve;
12607 params.regions.push_back(imageResolve);
12608
12609 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12610 {
12611 params.samples = samples[samplesIndex];
12612 const std::string description = "With " + getSampleCountCaseName(samples[samplesIndex]);
12613 group->addChild(new ResolveImageToImageTestCase(group->getTestContext(), getSampleCountCaseName(samples[samplesIndex]), description, params, COPY_MS_IMAGE_TO_ARRAY_MS_IMAGE));
12614 }
12615 }
12616
addResolveImageDiffImageSizeTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12617 void addResolveImageDiffImageSizeTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12618 {
12619 tcu::TestContext& testCtx = group->getTestContext();
12620 TestParams params;
12621 params.src.image.imageType = VK_IMAGE_TYPE_2D;
12622 params.src.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12623 params.src.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12624 params.src.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
12625 params.dst.image.imageType = VK_IMAGE_TYPE_2D;
12626 params.dst.image.format = VK_FORMAT_R8G8B8A8_UNORM;
12627 params.dst.image.tiling = VK_IMAGE_TILING_OPTIMAL;
12628 params.dst.image.operationLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
12629 params.allocationKind = allocationKind;
12630 params.extensionUse = extensionUse;
12631
12632 {
12633 const VkImageSubresourceLayers sourceLayer =
12634 {
12635 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
12636 0u, // deUint32 mipLevel;
12637 0u, // deUint32 baseArrayLayer;
12638 1u // deUint32 layerCount;
12639 };
12640 const VkImageResolve testResolve =
12641 {
12642 sourceLayer, // VkImageSubresourceLayers srcSubresource;
12643 {0, 0, 0}, // VkOffset3D srcOffset;
12644 sourceLayer, // VkImageSubresourceLayers dstSubresource;
12645 {0, 0, 0}, // VkOffset3D dstOffset;
12646 resolveExtent, // VkExtent3D extent;
12647 };
12648 CopyRegion imageResolve;
12649 imageResolve.imageResolve = testResolve;
12650 params.regions.push_back(imageResolve);
12651 }
12652
12653 const VkExtent3D imageExtents[] =
12654 {
12655 { resolveExtent.width + 10, resolveExtent.height, resolveExtent.depth },
12656 { resolveExtent.width, resolveExtent.height * 2, resolveExtent.depth },
12657 { resolveExtent.width, resolveExtent.height, resolveExtent.depth + 10 }
12658 };
12659
12660 for (int srcImageExtentIndex = 0; srcImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++srcImageExtentIndex)
12661 {
12662 const VkExtent3D& srcImageSize = imageExtents[srcImageExtentIndex];
12663 params.src.image.extent = srcImageSize;
12664 params.dst.image.extent = resolveExtent;
12665 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12666 {
12667 params.samples = samples[samplesIndex];
12668 std::ostringstream testName;
12669 testName << "src_" << srcImageSize.width << "_" << srcImageSize.height << "_" << srcImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
12670 std::ostringstream description;
12671 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and source image size ("
12672 << srcImageSize.width << ", " << srcImageSize.height << ", " << srcImageSize.depth << ")";
12673 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
12674 }
12675 }
12676 for (int dstImageExtentIndex = 0; dstImageExtentIndex < DE_LENGTH_OF_ARRAY(imageExtents); ++dstImageExtentIndex)
12677 {
12678 const VkExtent3D& dstImageSize = imageExtents[dstImageExtentIndex];
12679 params.src.image.extent = resolveExtent;
12680 params.dst.image.extent = dstImageSize;
12681 for (int samplesIndex = 0; samplesIndex < DE_LENGTH_OF_ARRAY(samples); ++samplesIndex)
12682 {
12683 params.samples = samples[samplesIndex];
12684 std::ostringstream testName;
12685 testName << "dst_" << dstImageSize.width << "_" << dstImageSize.height << "_" << dstImageSize.depth << "_" << getSampleCountCaseName(samples[samplesIndex]);
12686 std::ostringstream description;
12687 description << "With " << getSampleCountCaseName(samples[samplesIndex]) << " and destination image size ("
12688 << dstImageSize.width << ", " << dstImageSize.height << ", " << dstImageSize.depth << ")";
12689 group->addChild(new ResolveImageToImageTestCase(testCtx, testName.str(), description.str(), params));
12690 }
12691 }
12692 }
12693
addBufferCopyOffsetTests(tcu::TestCaseGroup * group)12694 void addBufferCopyOffsetTests (tcu::TestCaseGroup* group)
12695 {
12696 de::MovePtr<tcu::TestCaseGroup> subGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer_to_buffer_with_offset", "Copy from buffer to buffer using different offsets in the source and destination buffers"));
12697
12698 for (deUint32 srcOffset = 0u; srcOffset < BufferOffsetParams::kMaxOffset; ++srcOffset)
12699 for (deUint32 dstOffset = 0u; dstOffset < BufferOffsetParams::kMaxOffset; ++dstOffset)
12700 {
12701 BufferOffsetParams params{srcOffset, dstOffset};
12702 addFunctionCase(subGroup.get(), de::toString(srcOffset) + "_" + de::toString(dstOffset), "", bufferOffsetTest, params);
12703 }
12704
12705 group->addChild(subGroup.release());
12706 }
12707
addResolveImageTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12708 void addResolveImageTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12709 {
12710 addTestGroup(group, "whole", "Resolve from image to image (whole)", addResolveImageWholeTests, allocationKind, extensionUse);
12711 addTestGroup(group, "partial", "Resolve from image to image (partial)", addResolveImagePartialTests, allocationKind, extensionUse);
12712 addTestGroup(group, "with_regions", "Resolve from image to image (with regions)", addResolveImageWithRegionsTests, allocationKind, extensionUse);
12713 addTestGroup(group, "whole_copy_before_resolving", "Resolve from image to image (whole copy before resolving)", addResolveImageWholeCopyBeforeResolvingTests, allocationKind, extensionUse);
12714 addTestGroup(group, "whole_copy_before_resolving_no_cab", "Resolve from image to image without using USAGE_COLOR_ATTACHMENT_BIT (whole copy before resolving)", addResolveImageWholeCopyWithoutCabBeforeResolvingTests, allocationKind, extensionUse);
12715 addTestGroup(group, "diff_layout_copy_before_resolving", "Resolve from image to image (whole copy before resolving with different layouts)", addResolveImageWholeCopyDiffLayoutsBeforeResolvingTests, allocationKind, extensionUse);
12716 addTestGroup(group, "layer_copy_before_resolving", "Resolve from image to image (layer copy before resolving)", addResolveImageLayerCopyBeforeResolvingTests, allocationKind, extensionUse);
12717 addTestGroup(group, "copy_with_regions_before_resolving", "Resolve from image to image (region copy before resolving)", addResolveCopyImageWithRegionsTests, allocationKind, extensionUse);
12718 addTestGroup(group, "whole_array_image", "Resolve from image to image (whole array image)", addResolveImageWholeArrayImageTests, allocationKind, extensionUse);
12719 addTestGroup(group, "whole_array_image_one_region", "Resolve from image to image (whole array image with single region)", addResolveImageWholeArrayImageSingleRegionTests, allocationKind, extensionUse);
12720 addTestGroup(group, "diff_image_size", "Resolve from image to image of different size", addResolveImageDiffImageSizeTests, allocationKind, extensionUse);
12721 }
12722
addCopiesAndBlittingTests(tcu::TestCaseGroup * group,AllocationKind allocationKind,ExtensionUse extensionUse)12723 void addCopiesAndBlittingTests (tcu::TestCaseGroup* group, AllocationKind allocationKind, ExtensionUse extensionUse)
12724 {
12725 addTestGroup(group, "image_to_image", "Copy from image to image", addImageToImageTests, allocationKind, extensionUse);
12726 addTestGroup(group, "image_to_buffer", "Copy from image to buffer", addImageToBufferTests, allocationKind, extensionUse);
12727 addTestGroup(group, "buffer_to_image", "Copy from buffer to image", addBufferToImageTests, allocationKind, extensionUse);
12728 addTestGroup(group, "buffer_to_depthstencil", "Copy from buffer to depth/Stencil", addBufferToDepthStencilTests, allocationKind, extensionUse);
12729 addTestGroup(group, "buffer_to_buffer", "Copy from buffer to buffer", addBufferToBufferTests, allocationKind, extensionUse);
12730 addTestGroup(group, "blit_image", "Blitting image", addBlittingImageTests, allocationKind, extensionUse);
12731 addTestGroup(group, "resolve_image", "Resolve image", addResolveImageTests, allocationKind, extensionUse);
12732 }
12733
addCoreCopiesAndBlittingTests(tcu::TestCaseGroup * group)12734 void addCoreCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12735 {
12736 addCopiesAndBlittingTests(group, ALLOCATION_KIND_SUBALLOCATED, EXTENSION_USE_NONE);
12737 addBufferCopyOffsetTests(group);
12738 }
12739
12740
addDedicatedAllocationCopiesAndBlittingTests(tcu::TestCaseGroup * group)12741 void addDedicatedAllocationCopiesAndBlittingTests (tcu::TestCaseGroup* group)
12742 {
12743 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_NONE);
12744 }
12745
addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup * group)12746 void addExtensionCopiesAndBlittingTests(tcu::TestCaseGroup* group)
12747 {
12748 addCopiesAndBlittingTests(group, ALLOCATION_KIND_DEDICATED, EXTENSION_USE_COPY_COMMANDS2);
12749 }
12750
12751 } // anonymous
12752
createCopiesAndBlittingTests(tcu::TestContext & testCtx)12753 tcu::TestCaseGroup* createCopiesAndBlittingTests (tcu::TestContext& testCtx)
12754 {
12755 de::MovePtr<tcu::TestCaseGroup> copiesAndBlittingTests(new tcu::TestCaseGroup(testCtx, "copy_and_blit", "Copies And Blitting Tests"));
12756
12757 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "core", "Core Copies And Blitting Tests", addCoreCopiesAndBlittingTests));
12758 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "dedicated_allocation", "Copies And Blitting Tests For Dedicated Memory Allocation", addDedicatedAllocationCopiesAndBlittingTests));
12759 copiesAndBlittingTests->addChild(createTestGroup(testCtx, "copy_commands2", "Copies And Blitting Tests using KHR_copy_commands2", addExtensionCopiesAndBlittingTests));
12760
12761 return copiesAndBlittingTests.release();
12762 }
12763
12764 } // api
12765 } // vkt
12766